LLVM: lib/Target/VE/AsmParser/VEAsmParser.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
12#include "VE.h"
29#include
30
31using namespace llvm;
32
33#define DEBUG_TYPE "ve-asmparser"
34
35namespace {
36
37class VEOperand;
38
41
42
43
44
45#define GET_ASSEMBLER_HEADER
46#include "VEGenAsmMatcher.inc"
47
48
49
50
54 bool MatchingInlineAsm) override;
58 SMLoc &EndLoc) override;
62
64 unsigned Kind) override;
65
66
73 ParseStatus parseVEAsmOperand(std::unique_ptr &Operand);
74
75
76 const MCExpr *extractModifierFromExpr(const MCExpr *E,
78 const MCExpr *fixupVariantKind(const MCExpr *E);
79 bool parseExpression(const MCExpr *&EVal);
80
81
84
85 bool parseLiteralValues(unsigned Size, SMLoc L);
86
87public:
91
93 }
94};
95
96}
97
99 VE::SW0, VE::SW1, VE::SW2, VE::SW3, VE::SW4, VE::SW5, VE::SW6,
100 VE::SW7, VE::SW8, VE::SW9, VE::SW10, VE::SW11, VE::SW12, VE::SW13,
101 VE::SW14, VE::SW15, VE::SW16, VE::SW17, VE::SW18, VE::SW19, VE::SW20,
102 VE::SW21, VE::SW22, VE::SW23, VE::SW24, VE::SW25, VE::SW26, VE::SW27,
103 VE::SW28, VE::SW29, VE::SW30, VE::SW31, VE::SW32, VE::SW33, VE::SW34,
104 VE::SW35, VE::SW36, VE::SW37, VE::SW38, VE::SW39, VE::SW40, VE::SW41,
105 VE::SW42, VE::SW43, VE::SW44, VE::SW45, VE::SW46, VE::SW47, VE::SW48,
106 VE::SW49, VE::SW50, VE::SW51, VE::SW52, VE::SW53, VE::SW54, VE::SW55,
107 VE::SW56, VE::SW57, VE::SW58, VE::SW59, VE::SW60, VE::SW61, VE::SW62,
108 VE::SW63};
109
111 VE::SF0, VE::SF1, VE::SF2, VE::SF3, VE::SF4, VE::SF5, VE::SF6,
112 VE::SF7, VE::SF8, VE::SF9, VE::SF10, VE::SF11, VE::SF12, VE::SF13,
113 VE::SF14, VE::SF15, VE::SF16, VE::SF17, VE::SF18, VE::SF19, VE::SF20,
114 VE::SF21, VE::SF22, VE::SF23, VE::SF24, VE::SF25, VE::SF26, VE::SF27,
115 VE::SF28, VE::SF29, VE::SF30, VE::SF31, VE::SF32, VE::SF33, VE::SF34,
116 VE::SF35, VE::SF36, VE::SF37, VE::SF38, VE::SF39, VE::SF40, VE::SF41,
117 VE::SF42, VE::SF43, VE::SF44, VE::SF45, VE::SF46, VE::SF47, VE::SF48,
118 VE::SF49, VE::SF50, VE::SF51, VE::SF52, VE::SF53, VE::SF54, VE::SF55,
119 VE::SF56, VE::SF57, VE::SF58, VE::SF59, VE::SF60, VE::SF61, VE::SF62,
120 VE::SF63};
121
123 VE::Q0, VE::Q1, VE::Q2, VE::Q3, VE::Q4, VE::Q5, VE::Q6, VE::Q7,
124 VE::Q8, VE::Q9, VE::Q10, VE::Q11, VE::Q12, VE::Q13, VE::Q14, VE::Q15,
125 VE::Q16, VE::Q17, VE::Q18, VE::Q19, VE::Q20, VE::Q21, VE::Q22, VE::Q23,
126 VE::Q24, VE::Q25, VE::Q26, VE::Q27, VE::Q28, VE::Q29, VE::Q30, VE::Q31};
127
129 VE::VMP4, VE::VMP5, VE::VMP6, VE::VMP7};
130
132 VE::USRCC, VE::PSW, VE::SAR, VE::NoRegister,
133 VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::PMMR,
134 VE::PMCR0, VE::PMCR1, VE::PMCR2, VE::PMCR3,
135 VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::NoRegister,
136 VE::PMC0, VE::PMC1, VE::PMC2, VE::PMC3,
137 VE::PMC4, VE::PMC5, VE::PMC6, VE::PMC7,
138 VE::PMC8, VE::PMC9, VE::PMC10, VE::PMC11,
139 VE::PMC12, VE::PMC13, VE::PMC14};
140
141namespace {
142
143
144
146private:
147 enum KindTy {
148 k_Token,
149 k_Register,
150 k_Immediate,
151
152 k_MemoryRegRegImm,
153 k_MemoryRegImmImm,
154 k_MemoryZeroRegImm,
155 k_MemoryZeroImmImm,
156
157 k_MemoryRegImm,
158 k_MemoryZeroImm,
159
160 k_CCOp,
161 k_RDOp,
162 k_MImmOp,
164
165 SMLoc StartLoc, EndLoc;
166
167 struct Token {
168 const char *Data;
170 };
171
172 struct RegOp {
173 unsigned RegNum;
174 };
175
176 struct ImmOp {
178 };
179
181 unsigned Base;
182 unsigned IndexReg;
185 };
186
187 struct CCOp {
188 unsigned CCVal;
189 };
190
191 struct RDOp {
192 unsigned RDVal;
193 };
194
195 struct MImmOp {
197 bool M0Flag;
198 };
199
200 union {
201 struct Token Tok;
202 struct RegOp Reg;
203 struct ImmOp Imm;
204 struct MemOp Mem;
205 struct CCOp CC;
206 struct RDOp RD;
207 struct MImmOp MImm;
208 };
209
210public:
211 VEOperand(KindTy K) : Kind(K) {}
212
213 bool isToken() const override { return Kind == k_Token; }
214 bool isReg() const override { return Kind == k_Register; }
215 bool isImm() const override { return Kind == k_Immediate; }
216 bool isMem() const override {
217 return isMEMrri() || isMEMrii() || isMEMzri() || isMEMzii() || isMEMri() ||
218 isMEMzi();
219 }
220 bool isMEMrri() const { return Kind == k_MemoryRegRegImm; }
221 bool isMEMrii() const { return Kind == k_MemoryRegImmImm; }
222 bool isMEMzri() const { return Kind == k_MemoryZeroRegImm; }
223 bool isMEMzii() const { return Kind == k_MemoryZeroImmImm; }
224 bool isMEMri() const { return Kind == k_MemoryRegImm; }
225 bool isMEMzi() const { return Kind == k_MemoryZeroImm; }
226 bool isCCOp() const { return Kind == k_CCOp; }
227 bool isRDOp() const { return Kind == k_RDOp; }
230 return false;
231
232
233 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {
234 int64_t Value = ConstExpr->getValue();
235 return Value == 0;
236 }
237 return false;
238 }
239 bool isUImm0to2() {
241 return false;
242
243
244 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {
245 int64_t Value = ConstExpr->getValue();
247 }
248 return false;
249 }
250 bool isUImm1() {
252 return false;
253
254
255 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {
256 int64_t Value = ConstExpr->getValue();
257 return isUInt<1>(Value);
258 }
259 return false;
260 }
261 bool isUImm2() {
263 return false;
264
265
266 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {
267 int64_t Value = ConstExpr->getValue();
268 return isUInt<2>(Value);
269 }
270 return false;
271 }
272 bool isUImm3() {
274 return false;
275
276
277 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {
278 int64_t Value = ConstExpr->getValue();
279 return isUInt<3>(Value);
280 }
281 return false;
282 }
283 bool isUImm4() {
285 return false;
286
287
288 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {
289 int64_t Value = ConstExpr->getValue();
290 return isUInt<4>(Value);
291 }
292 return false;
293 }
294 bool isUImm6() {
296 return false;
297
298
299 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {
300 int64_t Value = ConstExpr->getValue();
301 return isUInt<6>(Value);
302 }
303 return false;
304 }
305 bool isUImm7() {
307 return false;
308
309
310 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {
311 int64_t Value = ConstExpr->getValue();
312 return isUInt<7>(Value);
313 }
314 return false;
315 }
316 bool isSImm7() {
318 return false;
319
320
321 if (const auto *ConstExpr = dyn_cast(Imm.Val)) {
322 int64_t Value = ConstExpr->getValue();
323 return isInt<7>(Value);
324 }
325 return false;
326 }
327 bool isMImm() const {
328 if (Kind != k_MImmOp)
329 return false;
330
331
332 if (const auto *ConstExpr = dyn_cast(MImm.Val)) {
333 int64_t Value = ConstExpr->getValue();
334 return isUInt<6>(Value);
335 }
336 return false;
337 }
338
340 assert(Kind == k_Token && "Invalid access!");
341 return StringRef(Tok.Data, Tok.Length);
342 }
343
345 assert((Kind == k_Register) && "Invalid access!");
346 return Reg.RegNum;
347 }
348
349 const MCExpr *getImm() const {
350 assert((Kind == k_Immediate) && "Invalid access!");
351 return Imm.Val;
352 }
353
354 unsigned getMemBase() const {
355 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
356 Kind == k_MemoryRegImm) &&
357 "Invalid access!");
358 return Mem.Base;
359 }
360
361 unsigned getMemIndexReg() const {
362 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryZeroRegImm) &&
363 "Invalid access!");
364 return Mem.IndexReg;
365 }
366
367 const MCExpr *getMemIndex() const {
368 assert((Kind == k_MemoryRegImmImm || Kind == k_MemoryZeroImmImm) &&
369 "Invalid access!");
370 return Mem.Index;
371 }
372
373 const MCExpr *getMemOffset() const {
374 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
375 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm ||
376 Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) &&
377 "Invalid access!");
378 return Mem.Offset;
379 }
380
381 void setMemOffset(const MCExpr *off) {
382 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
383 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm ||
384 Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) &&
385 "Invalid access!");
386 Mem.Offset = off;
387 }
388
389 unsigned getCCVal() const {
390 assert((Kind == k_CCOp) && "Invalid access!");
391 return CC.CCVal;
392 }
393
394 unsigned getRDVal() const {
395 assert((Kind == k_RDOp) && "Invalid access!");
396 return RD.RDVal;
397 }
398
399 const MCExpr *getMImmVal() const {
400 assert((Kind == k_MImmOp) && "Invalid access!");
401 return MImm.Val;
402 }
403 bool getM0Flag() const {
404 assert((Kind == k_MImmOp) && "Invalid access!");
405 return MImm.M0Flag;
406 }
407
408
410
412
414 switch (Kind) {
415 case k_Token:
416 OS << "Token: " << getToken() << "\n";
417 break;
418 case k_Register:
419 OS << "Reg: #" << getReg() << "\n";
420 break;
421 case k_Immediate:
422 OS << "Imm: " << getImm() << "\n";
423 break;
424 case k_MemoryRegRegImm:
425 assert(getMemOffset() != nullptr);
426 OS << "Mem: #" << getMemBase() << "+#" << getMemIndexReg() << "+"
427 << *getMemOffset() << "\n";
428 break;
429 case k_MemoryRegImmImm:
430 assert(getMemIndex() != nullptr && getMemOffset() != nullptr);
431 OS << "Mem: #" << getMemBase() << "+" << *getMemIndex() << "+"
432 << *getMemOffset() << "\n";
433 break;
434 case k_MemoryZeroRegImm:
435 assert(getMemOffset() != nullptr);
436 OS << "Mem: 0+#" << getMemIndexReg() << "+" << *getMemOffset() << "\n";
437 break;
438 case k_MemoryZeroImmImm:
439 assert(getMemIndex() != nullptr && getMemOffset() != nullptr);
440 OS << "Mem: 0+" << *getMemIndex() << "+" << *getMemOffset() << "\n";
441 break;
442 case k_MemoryRegImm:
443 assert(getMemOffset() != nullptr);
444 OS << "Mem: #" << getMemBase() << "+" << *getMemOffset() << "\n";
445 break;
446 case k_MemoryZeroImm:
447 assert(getMemOffset() != nullptr);
448 OS << "Mem: 0+" << *getMemOffset() << "\n";
449 break;
450 case k_CCOp:
451 OS << "CCOp: " << getCCVal() << "\n";
452 break;
453 case k_RDOp:
454 OS << "RDOp: " << getRDVal() << "\n";
455 break;
456 case k_MImmOp:
457 OS << "MImm: (" << getMImmVal() << (getM0Flag() ? ")0" : ")1") << "\n";
458 break;
459 }
460 }
461
462 void addRegOperands(MCInst &Inst, unsigned N) const {
463 assert(N == 1 && "Invalid number of operands!");
465 }
466
467 void addImmOperands(MCInst &Inst, unsigned N) const {
468 assert(N == 1 && "Invalid number of operands!");
469 const MCExpr *Expr = getImm();
470 addExpr(Inst, Expr);
471 }
472
473 void addZeroOperands(MCInst &Inst, unsigned N) const {
474 addImmOperands(Inst, N);
475 }
476
477 void addUImm0to2Operands(MCInst &Inst, unsigned N) const {
478 addImmOperands(Inst, N);
479 }
480
481 void addUImm1Operands(MCInst &Inst, unsigned N) const {
482 addImmOperands(Inst, N);
483 }
484
485 void addUImm2Operands(MCInst &Inst, unsigned N) const {
486 addImmOperands(Inst, N);
487 }
488
489 void addUImm3Operands(MCInst &Inst, unsigned N) const {
490 addImmOperands(Inst, N);
491 }
492
493 void addUImm4Operands(MCInst &Inst, unsigned N) const {
494 addImmOperands(Inst, N);
495 }
496
497 void addUImm6Operands(MCInst &Inst, unsigned N) const {
498 addImmOperands(Inst, N);
499 }
500
501 void addUImm7Operands(MCInst &Inst, unsigned N) const {
502 addImmOperands(Inst, N);
503 }
504
505 void addSImm7Operands(MCInst &Inst, unsigned N) const {
506 addImmOperands(Inst, N);
507 }
508
509 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
510
511 if (!Expr)
513 else if (const auto *CE = dyn_cast(Expr))
515 else
517 }
518
519 void addMEMrriOperands(MCInst &Inst, unsigned N) const {
520 assert(N == 3 && "Invalid number of operands!");
521
524 addExpr(Inst, getMemOffset());
525 }
526
527 void addMEMriiOperands(MCInst &Inst, unsigned N) const {
528 assert(N == 3 && "Invalid number of operands!");
529
531 addExpr(Inst, getMemIndex());
532 addExpr(Inst, getMemOffset());
533 }
534
535 void addMEMzriOperands(MCInst &Inst, unsigned N) const {
536 assert(N == 3 && "Invalid number of operands!");
537
540 addExpr(Inst, getMemOffset());
541 }
542
543 void addMEMziiOperands(MCInst &Inst, unsigned N) const {
544 assert(N == 3 && "Invalid number of operands!");
545
547 addExpr(Inst, getMemIndex());
548 addExpr(Inst, getMemOffset());
549 }
550
551 void addMEMriOperands(MCInst &Inst, unsigned N) const {
552 assert(N == 2 && "Invalid number of operands!");
553
555 addExpr(Inst, getMemOffset());
556 }
557
558 void addMEMziOperands(MCInst &Inst, unsigned N) const {
559 assert(N == 2 && "Invalid number of operands!");
560
562 addExpr(Inst, getMemOffset());
563 }
564
565 void addCCOpOperands(MCInst &Inst, unsigned N) const {
566 assert(N == 1 && "Invalid number of operands!");
567
569 }
570
571 void addRDOpOperands(MCInst &Inst, unsigned N) const {
572 assert(N == 1 && "Invalid number of operands!");
573
575 }
576
577 void addMImmOperands(MCInst &Inst, unsigned N) const {
578 assert(N == 1 && "Invalid number of operands!");
579 const auto *ConstExpr = dyn_cast(getMImmVal());
580 assert(ConstExpr && "Null operands!");
581 int64_t Value = ConstExpr->getValue();
582 if (getM0Flag())
585 }
586
587 static std::unique_ptr CreateToken(StringRef Str, SMLoc S) {
588 auto Op = std::make_unique(k_Token);
589 Op->Tok.Data = Str.data();
590 Op->Tok.Length = Str.size();
591 Op->StartLoc = S;
592 Op->EndLoc = S;
593 return Op;
594 }
595
596 static std::unique_ptr CreateReg(unsigned RegNum, SMLoc S,
598 auto Op = std::make_unique(k_Register);
599 Op->Reg.RegNum = RegNum;
600 Op->StartLoc = S;
602 return Op;
603 }
604
605 static std::unique_ptr CreateImm(const MCExpr *Val, SMLoc S,
607 auto Op = std::make_unique(k_Immediate);
608 Op->Imm.Val = Val;
609 Op->StartLoc = S;
611 return Op;
612 }
613
614 static std::unique_ptr CreateCCOp(unsigned CCVal, SMLoc S,
616 auto Op = std::make_unique(k_CCOp);
617 Op->CC.CCVal = CCVal;
618 Op->StartLoc = S;
620 return Op;
621 }
622
623 static std::unique_ptr CreateRDOp(unsigned RDVal, SMLoc S,
625 auto Op = std::make_unique(k_RDOp);
626 Op->RD.RDVal = RDVal;
627 Op->StartLoc = S;
629 return Op;
630 }
631
632 static std::unique_ptr CreateMImm(const MCExpr *Val, bool Flag,
634 auto Op = std::make_unique(k_MImmOp);
635 Op->MImm.Val = Val;
637 Op->StartLoc = S;
639 return Op;
640 }
641
642 static bool MorphToI32Reg(VEOperand &Op) {
643 unsigned Reg = Op.getReg();
644 unsigned regIdx = Reg - VE::SX0;
645 if (regIdx > 63)
646 return false;
648 return true;
649 }
650
651 static bool MorphToF32Reg(VEOperand &Op) {
652 unsigned Reg = Op.getReg();
653 unsigned regIdx = Reg - VE::SX0;
654 if (regIdx > 63)
655 return false;
657 return true;
658 }
659
660 static bool MorphToF128Reg(VEOperand &Op) {
661 unsigned Reg = Op.getReg();
662 unsigned regIdx = Reg - VE::SX0;
663 if (regIdx % 2 || regIdx > 63)
664 return false;
665 Op.Reg.RegNum = F128Regs[regIdx / 2];
666 return true;
667 }
668
669 static bool MorphToVM512Reg(VEOperand &Op) {
670 unsigned Reg = Op.getReg();
671 unsigned regIdx = Reg - VE::VM0;
672 if (regIdx % 2 || regIdx > 15)
673 return false;
675 return true;
676 }
677
678 static bool MorphToMISCReg(VEOperand &Op) {
679 const auto *ConstExpr = dyn_cast(Op.getImm());
680 if (!ConstExpr)
681 return false;
682 unsigned regIdx = ConstExpr->getValue();
683 if (regIdx > 31 || MISCRegs[regIdx] == VE::NoRegister)
684 return false;
685 Op.Kind = k_Register;
687 return true;
688 }
689
690 static std::unique_ptr
691 MorphToMEMri(unsigned Base, std::unique_ptr Op) {
693 Op->Kind = k_MemoryRegImm;
695 Op->Mem.IndexReg = 0;
696 Op->Mem.Index = nullptr;
698 return Op;
699 }
700
701 static std::unique_ptr
702 MorphToMEMzi(std::unique_ptr Op) {
704 Op->Kind = k_MemoryZeroImm;
705 Op->Mem.Base = 0;
706 Op->Mem.IndexReg = 0;
707 Op->Mem.Index = nullptr;
709 return Op;
710 }
711
712 static std::unique_ptr
713 MorphToMEMrri(unsigned Base, unsigned Index, std::unique_ptr Op) {
715 Op->Kind = k_MemoryRegRegImm;
718 Op->Mem.Index = nullptr;
720 return Op;
721 }
722
723 static std::unique_ptr
725 std::unique_ptr Op) {
727 Op->Kind = k_MemoryRegImmImm;
729 Op->Mem.IndexReg = 0;
732 return Op;
733 }
734
735 static std::unique_ptr
736 MorphToMEMzri(unsigned Index, std::unique_ptr Op) {
738 Op->Kind = k_MemoryZeroRegImm;
739 Op->Mem.Base = 0;
741 Op->Mem.Index = nullptr;
743 return Op;
744 }
745
746 static std::unique_ptr
747 MorphToMEMzii(const MCExpr *Index, std::unique_ptr Op) {
749 Op->Kind = k_MemoryZeroImmImm;
750 Op->Mem.Base = 0;
751 Op->Mem.IndexReg = 0;
754 return Op;
755 }
756};
757
758}
759
760bool VEAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
763 bool MatchingInlineAsm) {
765 unsigned MatchResult =
766 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
767 switch (MatchResult) {
768 case Match_Success:
771 return false;
772
773 case Match_MissingFeature:
774 return Error(IDLoc,
775 "instruction requires a CPU feature not currently enabled");
776
777 case Match_InvalidOperand: {
778 SMLoc ErrorLoc = IDLoc;
781 return Error(IDLoc, "too few operands for instruction");
782
784 if (ErrorLoc == SMLoc())
785 ErrorLoc = IDLoc;
786 }
787
788 return Error(ErrorLoc, "invalid operand for instruction");
789 }
790 case Match_MnemonicFail:
791 return Error(IDLoc, "invalid instruction mnemonic");
792 }
794}
795
798 if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())
799 return Error(StartLoc, "invalid register name");
800 return false;
801}
802
803
804
807
808 int RegNum = matchFn(Name);
809
810
811
812 if (RegNum == VE::NoRegister) {
813 RegNum = matchFn(Name.lower());
814 }
815
816 return RegNum;
817}
818
819
820
822
823
824
826
830 StartLoc = Tok.getLoc();
832 Reg = VE::NoRegister;
835 Parser.Lex();
836
838 if (Reg == VE::NoRegister)
840
841 if (Reg != VE::NoRegister) {
842 Parser.Lex();
844 }
845
846 getLexer().UnLex(Tok);
848}
849
851 bool IntegerCC, bool OmitCC, SMLoc NameLoc,
853
854
858
859
863
864 Name = Name.slice(0, Prefix);
865 Operands->push_back(VEOperand::CreateToken(Name, NameLoc));
866
869 Operands->push_back(VEOperand::CreateCCOp(CondCode, CondLoc, SuffixLoc));
870
871 if (!SuffixStr.empty())
872 Operands->push_back(VEOperand::CreateToken(SuffixStr, SuffixLoc));
873 } else {
874 Operands->push_back(VEOperand::CreateToken(Name, NameLoc));
875 }
877}
878
881
882
885
887 Name = Name.slice(0, Prefix);
888
889 Operands->push_back(VEOperand::CreateToken(Name, NameLoc));
890 SMLoc SuffixLoc =
894
897 } else {
898 Operands->push_back(VEOperand::CreateToken(Name, NameLoc));
899 }
901}
902
903
904
907
909
910 if (Name[0] == 'b') {
911
912 size_t Start = 1;
913 size_t Next = Name.find('.');
914
915 if (Name.size() > 1 && Name[1] == 'r')
916 Start = 2;
917
918 bool ICC = true;
919 if (Next + 1 < Name.size() &&
920 (Name[Next + 1] == 'd' || Name[Next + 1] == 's'))
921 ICC = false;
923 } else if (Name.starts_with("cmov.l.") || Name.starts_with("cmov.w.") ||
924 Name.starts_with("cmov.d.") || Name.starts_with("cmov.s.")) {
925 bool ICC = Name[5] == 'l' || Name[5] == 'w';
927 } else if (Name.starts_with("cvt.w.d.sx") || Name.starts_with("cvt.w.d.zx") ||
928 Name.starts_with("cvt.w.s.sx") || Name.starts_with("cvt.w.s.zx")) {
930 } else if (Name.starts_with("cvt.l.d")) {
932 } else if (Name.starts_with("vcvt.w.d.sx") ||
933 Name.starts_with("vcvt.w.d.zx") ||
934 Name.starts_with("vcvt.w.s.sx") ||
935 Name.starts_with("vcvt.w.s.zx")) {
937 } else if (Name.starts_with("vcvt.l.d")) {
939 } else if (Name.starts_with("pvcvt.w.s.lo") ||
940 Name.starts_with("pvcvt.w.s.up")) {
942 } else if (Name.starts_with("pvcvt.w.s")) {
944 } else if (Name.starts_with("vfmk.l.") || Name.starts_with("vfmk.w.") ||
945 Name.starts_with("vfmk.d.") || Name.starts_with("vfmk.s.")) {
946 bool ICC = Name[5] == 'l' || Name[5] == 'w' ? true : false;
948 } else if (Name.starts_with("pvfmk.w.lo.") ||
949 Name.starts_with("pvfmk.w.up.") ||
950 Name.starts_with("pvfmk.s.lo.") ||
951 Name.starts_with("pvfmk.s.up.")) {
952 bool ICC = Name[6] == 'l' || Name[6] == 'w' ? true : false;
954 } else {
955 Operands->push_back(VEOperand::CreateToken(Mnemonic, NameLoc));
956 }
957
958 return Mnemonic;
959}
960
963 unsigned VariantID);
964
967
968
970
971
972
973
975
977
978 if (!parseOperand(Operands, Mnemonic).isSuccess()) {
979 SMLoc Loc = getLexer().getLoc();
980 return Error(Loc, "unexpected token");
981 }
982
984 Parser.Lex();
985
986 if (!parseOperand(Operands, Mnemonic).isSuccess()) {
987 SMLoc Loc = getLexer().getLoc();
988 return Error(Loc, "unexpected token");
989 }
990 }
991 }
993 SMLoc Loc = getLexer().getLoc();
994 return Error(Loc, "unexpected token");
995 }
996 Parser.Lex();
997 return false;
998}
999
1002
1003
1004
1005
1006
1007
1008 if (IDVal == ".word")
1009 return parseLiteralValues(4, DirectiveID.getLoc());
1010
1011
1012 if (IDVal == ".long")
1013 return parseLiteralValues(8, DirectiveID.getLoc());
1014
1015
1016 if (IDVal == ".llong")
1017 return parseLiteralValues(8, DirectiveID.getLoc());
1018
1019
1021}
1022
1023
1024
1025
1026
1027bool VEAsmParser::parseLiteralValues(unsigned Size, SMLoc L) {
1028 auto parseOne = [&]() -> bool {
1030 if (getParser().parseExpression(Value))
1031 return true;
1032 getParser().getStreamer().emitValue(Value, Size, L);
1033 return false;
1034 };
1035 return (parseMany(parseOne));
1036}
1037
1038
1039
1040
1041
1042
1043
1045VEAsmParser::extractModifierFromExpr(const MCExpr *E,
1047 MCContext &Context = getParser().getContext();
1049
1050 switch (E->getKind()) {
1053 return nullptr;
1054
1057
1058 switch (SRE->getKind()) {
1060
1062 break;
1065 break;
1068 break;
1071 break;
1074 break;
1077 break;
1080 break;
1083 break;
1086 break;
1089 break;
1092 break;
1095 break;
1098 break;
1101 break;
1104 break;
1105 default:
1106 return nullptr;
1107 }
1108
1110 }
1111
1113 const MCUnaryExpr *UE = cast(E);
1114 const MCExpr *Sub = extractModifierFromExpr(UE->getSubExpr(), Variant);
1115 if (!Sub)
1116 return nullptr;
1118 }
1119
1123 const MCExpr *LHS = extractModifierFromExpr(BE->getLHS(), LHSVariant);
1124 const MCExpr *RHS = extractModifierFromExpr(BE->getRHS(), RHSVariant);
1125
1127 return nullptr;
1128
1129 if ()
1131 if ()
1133
1138 else if (LHSVariant == RHSVariant)
1140 else
1141 return nullptr;
1142
1144 }
1145 }
1146
1148}
1149
1150const MCExpr *VEAsmParser::fixupVariantKind(const MCExpr *E) {
1151 MCContext &Context = getParser().getContext();
1152
1153 switch (E->getKind()) {
1157 return E;
1158
1160 const MCUnaryExpr *UE = cast(E);
1163 return E;
1165 }
1166
1172 return E;
1174 }
1175 }
1176
1178}
1179
1180
1181
1182bool VEAsmParser::parseExpression(const MCExpr *&EVal) {
1183
1184 if (getParser().parseExpression(EVal))
1185 return true;
1186
1187
1188 EVal = fixupVariantKind(EVal);
1190 const MCExpr *E = extractModifierFromExpr(EVal, Variant);
1191 if (E)
1193
1194 return false;
1195}
1196
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211 std::unique_ptr Offset;
1212 switch (getLexer().getKind()) {
1213 default:
1215
1221 if (!parseExpression(EVal))
1222 Offset = VEOperand::CreateImm(EVal, S, E);
1223 else
1225 break;
1226 }
1227
1229
1232 break;
1233 }
1234
1235 switch (getLexer().getKind()) {
1236 default:
1238
1240 Operands.push_back(VEOperand::MorphToMEMzii(
1243
1245 Parser.Lex();
1246 break;
1247 }
1248
1249 const MCExpr *IndexValue = nullptr;
1251
1252 switch (getLexer().getKind()) {
1253 default:
1254 if (parseRegister(IndexReg, S, E))
1256 break;
1257
1261 if (getParser().parseExpression(IndexValue, E))
1263 break;
1264
1266
1268 break;
1269 }
1270
1271 switch (getLexer().getKind()) {
1272 default:
1274
1276 Parser.Lex();
1278 IndexValue ? VEOperand::MorphToMEMzii(IndexValue, std::move(Offset))
1279 : VEOperand::MorphToMEMzri(IndexReg, std::move(Offset)));
1281
1283 Parser.Lex();
1284 break;
1285 }
1286
1288 if (parseRegister(BaseReg, S, E))
1290
1293
1294 Parser.Lex();
1296 IndexValue
1297 ? VEOperand::MorphToMEMrii(BaseReg, IndexValue, std::move(Offset))
1298 : VEOperand::MorphToMEMrri(BaseReg, IndexReg, std::move(Offset)));
1299
1301}
1302
1308
1309
1310
1311
1312
1313
1314
1315
1316
1318 std::unique_ptr Offset;
1319 switch (getLexer().getKind()) {
1320 default:
1322
1328 if (!parseExpression(EVal))
1329 Offset = VEOperand::CreateImm(EVal, S, E);
1330 else
1332 break;
1333 }
1334
1336 if (parseRegister(BaseReg, S, E))
1340 break;
1341
1343
1346 break;
1347 }
1348
1349 switch (getLexer().getKind()) {
1350 default:
1352
1355 Operands.push_back(BaseReg != VE::NoRegister
1356 ? VEOperand::MorphToMEMri(BaseReg, std::move(Offset))
1357 : VEOperand::MorphToMEMzi(std::move(Offset)));
1359
1361 if (BaseReg != VE::NoRegister)
1363 Parser.Lex();
1364 break;
1365 }
1366
1367 switch (getLexer().getKind()) {
1368 default:
1369 if (parseRegister(BaseReg, S, E))
1371 break;
1372
1374 Parser.Lex();
1375 if (parseRegister(BaseReg, S, E))
1377 break;
1378
1380 break;
1381 }
1382
1385
1386 Parser.Lex();
1387 Operands.push_back(BaseReg != VE::NoRegister
1388 ? VEOperand::MorphToMEMri(BaseReg, std::move(Offset))
1389 : VEOperand::MorphToMEMzi(std::move(Offset)));
1390
1392}
1393
1396
1397
1401
1402 Parser.Lex();
1403
1408 getLexer().UnLex(Tok1);
1410 }
1411
1414 getLexer().UnLex(Tok2);
1415 getLexer().UnLex(Tok1);
1417 }
1418 Parser.Lex();
1419
1422 if (Suffix != "1" && Suffix != "0") {
1423 getLexer().UnLex(Tok3);
1424 getLexer().UnLex(Tok2);
1425 getLexer().UnLex(Tok1);
1427 }
1428 Parser.Lex();
1431 VEOperand::CreateMImm(EVal, Suffix == "0", Tok1.getLoc(), EndLoc));
1433}
1434
1439
1440
1441
1442
1444 return Res;
1445
1446 switch (getLexer().getKind()) {
1448
1450 Parser.Lex();
1451
1454 if (!tryParseRegister(Reg1, S1, E1).isSuccess()) {
1455 getLexer().UnLex(Tok1);
1457 }
1458
1461 Parser.Lex();
1462
1465 if (!tryParseRegister(Reg2, S2, E2).isSuccess())
1467
1470
1472 Operands.push_back(VEOperand::CreateReg(Reg1, S1, E1));
1473 Operands.push_back(VEOperand::CreateReg(Reg2, S2, E2));
1476 Parser.Lex();
1477 break;
1478 }
1479 default: {
1480 std::unique_ptr Op;
1481 Res = parseVEAsmOperand(Op);
1484
1485
1487
1489 break;
1490
1491
1492 std::unique_ptr Op1 = VEOperand::CreateToken(
1494 Parser.Lex();
1495
1496 std::unique_ptr Op2;
1497 Res = parseVEAsmOperand(Op2);
1500
1503
1504 Operands.push_back(std::move(Op1));
1505 Operands.push_back(std::move(Op2));
1508 Parser.Lex();
1509 break;
1510 }
1511 }
1512
1514}
1515
1516ParseStatus VEAsmParser::parseVEAsmOperand(std::unique_ptr &Op) {
1521
1522 Op = nullptr;
1523 switch (getLexer().getKind()) {
1524 default:
1525 break;
1526
1529 if (tryParseRegister(Reg, S, E).isSuccess())
1530 Op = VEOperand::CreateReg(Reg, S, E);
1531 break;
1532 }
1537 if (!parseExpression(EVal))
1538 Op = VEOperand::CreateImm(EVal, S, E);
1539 break;
1540 }
1542}
1543
1544
1547}
1548
1549#define GET_REGISTER_MATCHER
1550#define GET_MATCHER_IMPLEMENTATION
1551#include "VEGenAsmMatcher.inc"
1552
1553unsigned VEAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1554 unsigned Kind) {
1555 VEOperand &Op = (VEOperand &)GOp;
1556
1557
1558
1559
1560 switch (Kind) {
1561 default:
1562 break;
1563 case MCK_F32:
1564 if (Op.isReg() && VEOperand::MorphToF32Reg(Op))
1566 break;
1567 case MCK_I32:
1568 if (Op.isReg() && VEOperand::MorphToI32Reg(Op))
1570 break;
1571 case MCK_F128:
1572 if (Op.isReg() && VEOperand::MorphToF128Reg(Op))
1574 break;
1575 case MCK_VM512:
1576 if (Op.isReg() && VEOperand::MorphToVM512Reg(Op))
1578 break;
1579 case MCK_MISC:
1580 if (Op.isImm() && VEOperand::MorphToMISCReg(Op))
1582 break;
1583 }
1584 return Match_InvalidOperand;
1585}
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
mir Rename Register Operands
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static const MCPhysReg MISCRegs[31]
static MCRegister MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
static const MCPhysReg F128Regs[32]
static MCRegister MatchRegisterName(StringRef Name)
Maps from the set of all register names to a register number.
static const MCPhysReg F32Regs[64]
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static StringRef parseCC(StringRef Name, unsigned Prefix, unsigned Suffix, bool IntegerCC, bool OmitCC, SMLoc NameLoc, OperandVector *Operands)
static const MCPhysReg VM512Regs[8]
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVEAsmParser()
static const MCPhysReg I32Regs[64]
static StringRef parseRD(StringRef Name, unsigned Prefix, SMLoc NameLoc, OperandVector *Operands)
static bool isMImm(SDValue V)
Target independent representation for an assembler token.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Container class for subtarget features.
Generic assembler parser interface, for use by target specific assembly parsers.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Opcode getOpcode() const
Get the kind of this binary expression.
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
@ Unary
Unary expressions.
@ Constant
Constant expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Target
Target specific expression.
@ Binary
Binary expressions.
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
Interface to description of machine instruction set.
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool isMem() const =0
isMem - Is this a memory operand?
virtual MCRegister getReg() const =0
virtual void print(raw_ostream &OS) const =0
print - Print a debug representation of the operand to the given stream.
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this operand.
Wrapper class representing physical registers. Should be passed by value.
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
VariantKind getKind() const
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual ParseStatus parseDirective(AsmToken DirectiveID)
Parses a target-specific assembler directive.
virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
Unary assembler expressions.
Opcode getOpcode() const
Get the kind of this unary expression.
static const MCUnaryExpr * create(Opcode Op, const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
const MCExpr * getSubExpr() const
Get the child of this unary expression.
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
std::string lower() const
static const VEMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheVETarget()
static VECC::CondCode stringToVEFCondCode(StringRef S)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
DWARFExpression::Operation Op
RoundingMode
Rounding mode.
static VERD::RoundingMode stringToVERD(StringRef S)
static VECC::CondCode stringToVEICondCode(StringRef S)
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...