LLVM: lib/Target/Sparc/AsmParser/SparcAsmParser.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
38#include
39#include
40#include
41#include
42
43using namespace llvm;
44
45
46
47namespace llvm {
49
50 using namespace SP;
51
52}
53}
54
55namespace {
56
57class SparcOperand;
58
62
63 enum class TailRelocKind { Load_GOT, Add_TLS, Load_TLS, Call_TLS };
64
65
66
67
68#define GET_ASSEMBLER_HEADER
69#include "SparcGenAsmMatcher.inc"
70
71
72
73
74 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
77 bool MatchingInlineAsm) override;
80 SMLoc &EndLoc) override;
84
86 unsigned Kind) override;
87
88
90
92
94
96
97 template
99
101
103
105
106 ParseStatus parseSparcAsmOperand(std::unique_ptr &Operand);
107
109
110 ParseStatus parseExpression(int64_t &Val);
111
112
114 const MCExpr *subExpr);
115
116
117 bool isPossibleExpression(const AsmToken &Token);
118
119
120 MatchResultTy mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);
121
122
123 MCRegister matchRegisterName(const AsmToken &Tok, unsigned &RegKind);
124
125 bool matchSparcAsmModifiers(const MCExpr *&EVal, SMLoc &EndLoc);
126
128 return getSTI().getTargetTriple().getArch() == Triple::sparcv9;
129 }
130
131 bool expandSET(MCInst &Inst, SMLoc IDLoc,
132 SmallVectorImpl &Instructions);
133
134 bool expandSETSW(MCInst &Inst, SMLoc IDLoc,
135 SmallVectorImpl &Instructions);
136
137 bool expandSETX(MCInst &Inst, SMLoc IDLoc,
138 SmallVectorImpl &Instructions);
139
140 SMLoc getLoc() const { return getParser().getTok().getLoc(); }
141
142public:
143 SparcAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
144 const MCInstrInfo &MII, const MCTargetOptions &Options)
145 : MCTargetAsmParser(Options, sti, MII), Parser(parser),
146 MRI(*Parser.getContext().getRegisterInfo()) {
147 Parser.addAliasForDirective(".half", ".2byte");
148 Parser.addAliasForDirective(".uahalf", ".2byte");
149 Parser.addAliasForDirective(".word", ".4byte");
150 Parser.addAliasForDirective(".uaword", ".4byte");
151 Parser.addAliasForDirective(".nword", is64Bit() ? ".8byte" : ".4byte");
153 Parser.addAliasForDirective(".xword", ".8byte");
154
155
156 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
157 }
158};
159
160}
161
163 Sparc::G0, Sparc::G1, Sparc::G2, Sparc::G3,
164 Sparc::G4, Sparc::G5, Sparc::G6, Sparc::G7,
165 Sparc::O0, Sparc::O1, Sparc::O2, Sparc::O3,
166 Sparc::O4, Sparc::O5, Sparc::O6, Sparc::O7,
167 Sparc::L0, Sparc::L1, Sparc::L2, Sparc::L3,
168 Sparc::L4, Sparc::L5, Sparc::L6, Sparc::L7,
169 Sparc::I0, Sparc::I1, Sparc::I2, Sparc::I3,
170 Sparc::I4, Sparc::I5, Sparc::I6, Sparc::I7 };
171
173 Sparc::D0, Sparc::D1, Sparc::D2, Sparc::D3,
174 Sparc::D4, Sparc::D5, Sparc::D6, Sparc::D7,
175 Sparc::D8, Sparc::D9, Sparc::D10, Sparc::D11,
176 Sparc::D12, Sparc::D13, Sparc::D14, Sparc::D15,
177 Sparc::D16, Sparc::D17, Sparc::D18, Sparc::D19,
178 Sparc::D20, Sparc::D21, Sparc::D22, Sparc::D23,
179 Sparc::D24, Sparc::D25, Sparc::D26, Sparc::D27,
180 Sparc::D28, Sparc::D29, Sparc::D30, Sparc::D31 };
181
183 Sparc::Q0, Sparc::Q1, Sparc::Q2, Sparc::Q3,
184 Sparc::Q4, Sparc::Q5, Sparc::Q6, Sparc::Q7,
185 Sparc::Q8, Sparc::Q9, Sparc::Q10, Sparc::Q11,
186 Sparc::Q12, Sparc::Q13, Sparc::Q14, Sparc::Q15 };
187
189 Sparc::G0_G1, Sparc::G2_G3, Sparc::G4_G5, Sparc::G6_G7,
190 Sparc::O0_O1, Sparc::O2_O3, Sparc::O4_O5, Sparc::O6_O7,
191 Sparc::L0_L1, Sparc::L2_L3, Sparc::L4_L5, Sparc::L6_L7,
192 Sparc::I0_I1, Sparc::I2_I3, Sparc::I4_I5, Sparc::I6_I7};
193
195 Sparc::C0_C1, Sparc::C2_C3, Sparc::C4_C5, Sparc::C6_C7,
196 Sparc::C8_C9, Sparc::C10_C11, Sparc::C12_C13, Sparc::C14_C15,
197 Sparc::C16_C17, Sparc::C18_C19, Sparc::C20_C21, Sparc::C22_C23,
198 Sparc::C24_C25, Sparc::C26_C27, Sparc::C28_C29, Sparc::C30_C31};
199
200namespace {
201
202
203
205public:
206 enum RegisterKind {
207 rk_None,
208 rk_IntReg,
209 rk_IntPairReg,
210 rk_FloatReg,
211 rk_DoubleReg,
212 rk_QuadReg,
213 rk_CoprocReg,
214 rk_CoprocPairReg,
215 rk_Special,
216 };
217
218private:
219 enum KindTy {
220 k_Token,
221 k_Register,
222 k_Immediate,
223 k_MemoryReg,
224 k_MemoryImm,
225 k_ASITag,
226 k_PrefetchTag,
227 k_TailRelocSym,
228 } Kind;
229
230 SMLoc StartLoc, EndLoc;
231
232 struct Token {
233 const char *Data;
234 unsigned Length;
235 };
236
237 struct RegOp {
238 MCRegister Reg;
239 RegisterKind Kind;
240 };
241
242 struct ImmOp {
243 const MCExpr *Val;
244 };
245
246 struct MemOp {
247 MCRegister Base;
248 MCRegister OffsetReg;
249 const MCExpr *Off;
250 };
251
252 union {
253 struct Token Tok;
254 struct RegOp Reg;
255 struct ImmOp Imm;
256 struct MemOp Mem;
257 unsigned ASI;
259 };
260
261public:
262 SparcOperand(KindTy K) : Kind(K) {}
263
264 bool isToken() const override { return Kind == k_Token; }
265 bool isReg() const override { return Kind == k_Register; }
266 bool isImm() const override { return Kind == k_Immediate; }
267 bool isMem() const override { return isMEMrr() || isMEMri(); }
268 bool isMEMrr() const { return Kind == k_MemoryReg; }
269 bool isMEMri() const { return Kind == k_MemoryImm; }
270 bool isMembarTag() const { return Kind == k_Immediate; }
271 bool isASITag() const { return Kind == k_ASITag; }
272 bool isPrefetchTag() const { return Kind == k_PrefetchTag; }
273 bool isTailRelocSym() const { return Kind == k_TailRelocSym; }
274
275 bool isCallTarget() const {
276 if (!isImm())
277 return false;
278
280 return CE->getValue() % 4 == 0;
281
282 return true;
283 }
284
285 bool isShiftAmtImm5() const {
286 if (!isImm())
287 return false;
288
291
292 return false;
293 }
294
295 bool isShiftAmtImm6() const {
296 if (!isImm())
297 return false;
298
301
302 return false;
303 }
304
306 return (Kind == k_Register && Reg.Kind == rk_IntReg);
307 }
308
309 bool isFloatReg() const {
310 return (Kind == k_Register && Reg.Kind == rk_FloatReg);
311 }
312
313 bool isFloatOrDoubleReg() const {
314 return (Kind == k_Register && (Reg.Kind == rk_FloatReg
315 || Reg.Kind == rk_DoubleReg));
316 }
317
318 bool isCoprocReg() const {
319 return (Kind == k_Register && Reg.Kind == rk_CoprocReg);
320 }
321
323 assert(Kind == k_Token && "Invalid access!");
324 return StringRef(Tok.Data, Tok.Length);
325 }
326
327 MCRegister getReg() const override {
328 assert((Kind == k_Register) && "Invalid access!");
329 return Reg.Reg;
330 }
331
332 const MCExpr *getImm() const {
333 assert((Kind == k_Immediate) && "Invalid access!");
334 return Imm.Val;
335 }
336
337 MCRegister getMemBase() const {
338 assert((Kind == k_MemoryReg || Kind == k_MemoryImm) && "Invalid access!");
339 return Mem.Base;
340 }
341
342 MCRegister getMemOffsetReg() const {
343 assert((Kind == k_MemoryReg) && "Invalid access!");
344 return Mem.OffsetReg;
345 }
346
347 const MCExpr *getMemOff() const {
348 assert((Kind == k_MemoryImm) && "Invalid access!");
349 return Mem.Off;
350 }
351
352 unsigned getASITag() const {
353 assert((Kind == k_ASITag) && "Invalid access!");
354 return ASI;
355 }
356
357 unsigned getPrefetchTag() const {
358 assert((Kind == k_PrefetchTag) && "Invalid access!");
360 }
361
362 const MCExpr *getTailRelocSym() const {
363 assert((Kind == k_TailRelocSym) && "Invalid access!");
364 return Imm.Val;
365 }
366
367
368 SMLoc getStartLoc() const override {
369 return StartLoc;
370 }
371
372 SMLoc getEndLoc() const override {
373 return EndLoc;
374 }
375
376 void print(raw_ostream &OS, const MCAsmInfo &MAI) const override {
377 switch (Kind) {
378 case k_Token: OS << "Token: " << getToken() << "\n"; break;
379 case k_Register:
380 OS << "Reg: #" << getReg().id() << "\n";
381 break;
382 case k_Immediate: OS << "Imm: " << getImm() << "\n"; break;
383 case k_MemoryReg:
384 OS << "Mem: " << getMemBase().id() << "+" << getMemOffsetReg().id()
385 << "\n";
386 break;
387 case k_MemoryImm: assert(getMemOff() != nullptr);
388 OS << "Mem: " << getMemBase().id() << "+";
390 OS << "\n";
391 break;
392 case k_ASITag:
393 OS << "ASI tag: " << getASITag() << "\n";
394 break;
395 case k_PrefetchTag:
396 OS << "Prefetch tag: " << getPrefetchTag() << "\n";
397 break;
398 case k_TailRelocSym:
399 OS << "TailReloc: " << getTailRelocSym() << "\n";
400 break;
401 }
402 }
403
404 void addRegOperands(MCInst &Inst, unsigned N) const {
405 assert(N == 1 && "Invalid number of operands!");
407 }
408
409 void addImmOperands(MCInst &Inst, unsigned N) const {
410 assert(N == 1 && "Invalid number of operands!");
411 const MCExpr *Expr = getImm();
412 addExpr(Inst, Expr);
413 }
414
415 void addShiftAmtImm5Operands(MCInst &Inst, unsigned N) const {
416 assert(N == 1 && "Invalid number of operands!");
417 addExpr(Inst, getImm());
418 }
419 void addShiftAmtImm6Operands(MCInst &Inst, unsigned N) const {
420 assert(N == 1 && "Invalid number of operands!");
421 addExpr(Inst, getImm());
422 }
423
424 void addExpr(MCInst &Inst, const MCExpr *Expr) const{
425
426 if (!Expr)
430 else
432 }
433
434 void addMEMrrOperands(MCInst &Inst, unsigned N) const {
435 assert(N == 2 && "Invalid number of operands!");
436
438
439 assert(getMemOffsetReg().isValid() && "Invalid offset");
441 }
442
443 void addMEMriOperands(MCInst &Inst, unsigned N) const {
444 assert(N == 2 && "Invalid number of operands!");
445
447
448 const MCExpr *Expr = getMemOff();
449 addExpr(Inst, Expr);
450 }
451
452 void addASITagOperands(MCInst &Inst, unsigned N) const {
453 assert(N == 1 && "Invalid number of operands!");
455 }
456
457 void addPrefetchTagOperands(MCInst &Inst, unsigned N) const {
458 assert(N == 1 && "Invalid number of operands!");
460 }
461
462 void addMembarTagOperands(MCInst &Inst, unsigned N) const {
463 assert(N == 1 && "Invalid number of operands!");
464 const MCExpr *Expr = getImm();
465 addExpr(Inst, Expr);
466 }
467
469 assert(N == 1 && "Invalid number of operands!");
470 addExpr(Inst, getImm());
471 }
472
473 void addTailRelocSymOperands(MCInst &Inst, unsigned N) const {
474 assert(N == 1 && "Invalid number of operands!");
475 addExpr(Inst, getTailRelocSym());
476 }
477
478 static std::unique_ptr CreateToken(StringRef Str, SMLoc S) {
479 auto Op = std::make_unique(k_Token);
480 Op->Tok.Data = Str.data();
481 Op->Tok.Length = Str.size();
482 Op->StartLoc = S;
483 Op->EndLoc = S;
484 return Op;
485 }
486
487 static std::unique_ptr CreateReg(MCRegister Reg, unsigned Kind,
488 SMLoc S, SMLoc E) {
489 auto Op = std::make_unique(k_Register);
491 Op->Reg.Kind = (SparcOperand::RegisterKind)Kind;
492 Op->StartLoc = S;
494 return Op;
495 }
496
497 static std::unique_ptr CreateImm(const MCExpr *Val, SMLoc S,
498 SMLoc E) {
499 auto Op = std::make_unique(k_Immediate);
500 Op->Imm.Val = Val;
501 Op->StartLoc = S;
503 return Op;
504 }
505
506 static std::unique_ptr CreateASITag(unsigned Val, SMLoc S,
507 SMLoc E) {
508 auto Op = std::make_unique(k_ASITag);
509 Op->ASI = Val;
510 Op->StartLoc = S;
512 return Op;
513 }
514
515 static std::unique_ptr CreatePrefetchTag(unsigned Val, SMLoc S,
516 SMLoc E) {
517 auto Op = std::make_unique(k_PrefetchTag);
518 Op->Prefetch = Val;
519 Op->StartLoc = S;
521 return Op;
522 }
523
524 static std::unique_ptr CreateTailRelocSym(const MCExpr *Val,
525 SMLoc S, SMLoc E) {
526 auto Op = std::make_unique(k_TailRelocSym);
527 Op->Imm.Val = Val;
528 Op->StartLoc = S;
530 return Op;
531 }
532
533 static bool MorphToIntPairReg(SparcOperand &Op) {
534 MCRegister Reg = Op.getReg();
535 assert(Op.Reg.Kind == rk_IntReg);
536 unsigned regIdx = 32;
537 if (Reg >= Sparc::G0 && Reg <= Sparc::G7)
538 regIdx = Reg - Sparc::G0;
539 else if (Reg >= Sparc::O0 && Reg <= Sparc::O7)
540 regIdx = Reg - Sparc::O0 + 8;
541 else if (Reg >= Sparc::L0 && Reg <= Sparc::L7)
542 regIdx = Reg - Sparc::L0 + 16;
543 else if (Reg >= Sparc::I0 && Reg <= Sparc::I7)
544 regIdx = Reg - Sparc::I0 + 24;
545 if (regIdx % 2 || regIdx > 31)
546 return false;
548 Op.Reg.Kind = rk_IntPairReg;
549 return true;
550 }
551
552 static bool MorphToDoubleReg(SparcOperand &Op) {
553 MCRegister Reg = Op.getReg();
554 assert(Op.Reg.Kind == rk_FloatReg);
555 unsigned regIdx = Reg - Sparc::F0;
556 if (regIdx % 2 || regIdx > 31)
557 return false;
559 Op.Reg.Kind = rk_DoubleReg;
560 return true;
561 }
562
563 static bool MorphToQuadReg(SparcOperand &Op) {
564 MCRegister Reg = Op.getReg();
565 unsigned regIdx = 0;
566 switch (Op.Reg.Kind) {
568 case rk_FloatReg:
569 regIdx = Reg - Sparc::F0;
570 if (regIdx % 4 || regIdx > 31)
571 return false;
573 break;
574 case rk_DoubleReg:
575 regIdx = Reg - Sparc::D0;
576 if (regIdx % 2 || regIdx > 31)
577 return false;
579 break;
580 }
582 Op.Reg.Kind = rk_QuadReg;
583 return true;
584 }
585
586 static bool MorphToCoprocPairReg(SparcOperand &Op) {
587 MCRegister Reg = Op.getReg();
588 assert(Op.Reg.Kind == rk_CoprocReg);
589 unsigned regIdx = 32;
590 if (Reg >= Sparc::C0 && Reg <= Sparc::C31)
591 regIdx = Reg - Sparc::C0;
592 if (regIdx % 2 || regIdx > 31)
593 return false;
595 Op.Reg.Kind = rk_CoprocPairReg;
596 return true;
597 }
598
599 static std::unique_ptr
600 MorphToMEMrr(MCRegister Base, std::unique_ptr Op) {
601 MCRegister offsetReg = Op->getReg();
602 Op->Kind = k_MemoryReg;
604 Op->Mem.OffsetReg = offsetReg;
605 Op->Mem.Off = nullptr;
606 return Op;
607 }
608
609 static std::unique_ptr CreateMEMr(MCRegister Base, SMLoc S,
610 SMLoc E) {
611 auto Op = std::make_unique(k_MemoryReg);
613 Op->Mem.OffsetReg = Sparc::G0;
614 Op->Mem.Off = nullptr;
615 Op->StartLoc = S;
617 return Op;
618 }
619
620 static std::unique_ptr
621 MorphToMEMri(MCRegister Base, std::unique_ptr Op) {
622 const MCExpr *Imm = Op->getImm();
623 Op->Kind = k_MemoryImm;
625 Op->Mem.OffsetReg = MCRegister();
627 return Op;
628 }
629};
630
631}
632
633#define GET_MATCHER_IMPLEMENTATION
634#define GET_REGISTER_MATCHER
635#define GET_MNEMONIC_SPELL_CHECKER
636#include "SparcGenAsmMatcher.inc"
637
638
639
640SparcAsmParser::MatchResultTy
641SparcAsmParser::mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {
642
644
645
646 const MatchEntry *Start, *End;
647 switch (VariantID) {
648 default:
650 case 0:
651 Start = std::begin(MatchTable0);
652 End = std::end(MatchTable0);
653 break;
654 }
655
656
657 auto MnemonicRange = std::equal_range(Start, End, Mnemonic, LessOpcode());
658
659 if (MnemonicRange.first == MnemonicRange.second)
660 return Match_MnemonicFail;
661
662 for (const MatchEntry *it = MnemonicRange.first, *ie = MnemonicRange.second;
663 it != ie; ++it) {
665 FeatureBitsets[it->RequiredFeaturesIdx];
666 if ((getAvailableFeatures() & RequiredFeatures) == RequiredFeatures)
667 return Match_Success;
668 }
669 return Match_MissingFeature;
670}
671
672bool SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
673 SmallVectorImpl &Instructions) {
674 MCOperand MCRegOp = Inst.getOperand(0);
675 MCOperand MCValOp = Inst.getOperand(1);
678
679
681 int64_t RawImmValue = IsImm ? MCValOp.getImm() : 0;
682
683
684 if (RawImmValue < -2147483648LL || RawImmValue > 4294967295LL) {
685 return Error(IDLoc,
686 "set: argument must be between -2147483648 and 4294967295");
687 }
688
689
690
691 int32_t ImmValue = RawImmValue;
692
693
694
695 bool IsEffectivelyImm13 =
696 IsImm && ((is64Bit() ? 0 : -4096) <= ImmValue && ImmValue < 4096);
697 const MCExpr *ValExpr;
698 if (IsImm)
700 else
701 ValExpr = MCValOp.getExpr();
702
704
705
706
707
708 if (!IsEffectivelyImm13) {
709 MCInst TmpInst;
710 const MCExpr *Expr = adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr);
711 TmpInst.setLoc(IDLoc);
716 PrevReg = MCRegOp;
717 }
718
719
720
721
722
723
724
725
726
727
728
729 if (!IsImm || IsEffectivelyImm13 || (ImmValue & 0x3ff)) {
730 MCInst TmpInst;
731 const MCExpr *Expr;
732 if (IsEffectivelyImm13)
733 Expr = ValExpr;
734 else
735 Expr = adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr);
736 TmpInst.setLoc(IDLoc);
742 }
743 return false;
744}
745
746bool SparcAsmParser::expandSETSW(MCInst &Inst, SMLoc IDLoc,
747 SmallVectorImpl &Instructions) {
748 MCOperand MCRegOp = Inst.getOperand(0);
749 MCOperand MCValOp = Inst.getOperand(1);
752
753
755 int64_t ImmValue = IsImm ? MCValOp.getImm() : 0;
758
759 bool IsSmallImm = IsImm && isInt<13>(ImmValue);
760 bool NoLowBitsImm = IsImm && ((ImmValue & 0x3FF) == 0);
761
763
765 return Error(IDLoc,
766 "set: argument must be between -2147483648 and 2147483647");
767 }
768
769
770 if (!IsSmallImm) {
771
773 MCInstBuilder(SP::SETHIi)
774 .addReg(MCRegOp.getReg())
775 .addExpr(adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr)));
776
777 PrevReg = MCRegOp;
778 }
779
780
781 if (!NoLowBitsImm || IsSmallImm) {
782 const MCExpr *Expr =
783 IsSmallImm ? ValExpr : adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr);
784
785
786 Instructions.push_back(MCInstBuilder(SP::ORri)
787 .addReg(MCRegOp.getReg())
788 .addReg(PrevReg.getReg())
789 .addExpr(Expr));
790
791
792 if (IsSmallImm)
793 return false;
794 }
795
796
797 if (!IsImm || ImmValue < 0) {
798
799 Instructions.push_back(MCInstBuilder(SP::SRArr)
800 .addReg(MCRegOp.getReg())
801 .addReg(MCRegOp.getReg())
802 .addReg(Sparc::G0));
803 }
804
805 return false;
806}
807
808bool SparcAsmParser::expandSETX(MCInst &Inst, SMLoc IDLoc,
809 SmallVectorImpl &Instructions) {
810 MCOperand MCRegOp = Inst.getOperand(0);
811 MCOperand MCValOp = Inst.getOperand(1);
812 MCOperand MCTmpOp = Inst.getOperand(2);
815
816
817 bool IsImm = MCValOp.isImm();
818 int64_t ImmValue = IsImm ? MCValOp.getImm() : 0;
819
822
823
824 if (IsImm && isInt<13>(ImmValue)) {
825
826 Instructions.push_back(MCInstBuilder(SP::ORri)
827 .addReg(MCRegOp.getReg())
828 .addReg(Sparc::G0)
829 .addExpr(ValExpr));
830 return false;
831 }
832
833
834
835
837 MCInstBuilder(SP::SETHIi)
838 .addReg(MCRegOp.getReg())
839 .addExpr(adjustPICRelocation(ELF::R_SPARC_HI22, ValExpr)));
840
842 MCInstBuilder(SP::ORri)
843 .addReg(MCRegOp.getReg())
844 .addReg(MCRegOp.getReg())
845 .addExpr(adjustPICRelocation(ELF::R_SPARC_LO10, ValExpr)));
846
847
848
850 return false;
851
852
853
854
855
856 Instructions.push_back(MCInstBuilder(SP::SETHIi)
857 .addReg(MCTmpOp.getReg())
859 ValExpr, ELF::R_SPARC_HH22, getContext())));
860
861 Instructions.push_back(MCInstBuilder(SP::ORri)
862 .addReg(MCTmpOp.getReg())
863 .addReg(MCTmpOp.getReg())
865 ValExpr, ELF::R_SPARC_HM10, getContext())));
866
867 Instructions.push_back(MCInstBuilder(SP::SLLXri)
868 .addReg(MCTmpOp.getReg())
869 .addReg(MCTmpOp.getReg())
870 .addImm(32));
871
872 Instructions.push_back(MCInstBuilder(SP::ORrr)
873 .addReg(MCRegOp.getReg())
874 .addReg(MCTmpOp.getReg())
875 .addReg(MCRegOp.getReg()));
876
877 return false;
878}
879
880bool SparcAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
882 MCStreamer &Out,
883 uint64_t &ErrorInfo,
884 bool MatchingInlineAsm) {
885 MCInst Inst;
887 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
888 MatchingInlineAsm);
889 switch (MatchResult) {
890 case Match_Success: {
892 default:
895 break;
896 case SP::SET:
897 if (expandSET(Inst, IDLoc, Instructions))
898 return true;
899 break;
900 case SP::SETSW:
901 if (expandSETSW(Inst, IDLoc, Instructions))
902 return true;
903 break;
904 case SP::SETX:
905 if (expandSETX(Inst, IDLoc, Instructions))
906 return true;
907 break;
908 }
909
910 for (const MCInst &I : Instructions) {
912 }
913 return false;
914 }
915
916 case Match_MissingFeature:
917 return Error(IDLoc,
918 "instruction requires a CPU feature not currently enabled");
919
920 case Match_InvalidOperand: {
921 SMLoc ErrorLoc = IDLoc;
922 if (ErrorInfo != ~0ULL) {
923 if (ErrorInfo >= Operands.size())
924 return Error(IDLoc, "too few operands for instruction");
925
926 ErrorLoc = ((SparcOperand &)*Operands[ErrorInfo]).getStartLoc();
927 if (ErrorLoc == SMLoc())
928 ErrorLoc = IDLoc;
929 }
930
931 return Error(ErrorLoc, "invalid operand for instruction");
932 }
933 case Match_MnemonicFail:
934 return Error(IDLoc, "invalid instruction mnemonic");
935 }
937}
938
939bool SparcAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
940 SMLoc &EndLoc) {
941 if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())
942 return Error(StartLoc, "invalid register name");
943 return false;
944}
945
946ParseStatus SparcAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
947 SMLoc &EndLoc) {
948 const AsmToken &Tok = Parser.getTok();
949 StartLoc = Tok.getLoc();
951 Reg = Sparc::NoRegister;
954 Parser.Lex();
955 unsigned RegKind = SparcOperand::rk_None;
956 Reg = matchRegisterName(Tok, RegKind);
957 if (Reg) {
958 Parser.Lex();
960 }
961
962 getLexer().UnLex(Tok);
964}
965
966bool SparcAsmParser::parseInstruction(ParseInstructionInfo &Info,
967 StringRef Name, SMLoc NameLoc,
969
970
971
972
973
974
975
976
977
978 MatchResultTy MS = mnemonicIsValid(Name, 0);
979 switch (MS) {
980 case Match_Success:
981 break;
982 case Match_MissingFeature:
983 return Error(NameLoc,
984 "instruction requires a CPU feature not currently enabled");
985 case Match_MnemonicFail:
986 return Error(NameLoc,
987 "invalid instruction mnemonic" +
988 SparcMnemonicSpellCheck(Name, getAvailableFeatures(), 0));
989 default:
991 }
992
993
994 Operands.push_back(SparcOperand::CreateToken(Name, NameLoc));
995
996
998
1000
1002 if (!parseBranchModifiers(Operands).isSuccess()) {
1003 SMLoc Loc = getLexer().getLoc();
1004 return Error(Loc, "unexpected token");
1005 }
1006 }
1007 if (!parseOperand(Operands, Name).isSuccess()) {
1008 SMLoc Loc = getLexer().getLoc();
1009 return Error(Loc, "unexpected token");
1010 }
1011
1014
1016 }
1017 Parser.Lex();
1018
1019 if (!parseOperand(Operands, Name).isSuccess()) {
1020 SMLoc Loc = getLexer().getLoc();
1021 return Error(Loc, "unexpected token");
1022 }
1023 }
1024 }
1026 SMLoc Loc = getLexer().getLoc();
1027 return Error(Loc, "unexpected token");
1028 }
1029 Parser.Lex();
1030 return false;
1031}
1032
1033ParseStatus SparcAsmParser::parseDirective(AsmToken DirectiveID) {
1034 StringRef IDVal = DirectiveID.getString();
1035
1036 if (IDVal == ".register") {
1037
1040 }
1041 if (IDVal == ".proc") {
1042
1043
1046 }
1047
1048
1050}
1051
1052ParseStatus SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
1053 SMLoc S, E;
1054
1055 std::unique_ptr LHS;
1056 if (!parseSparcAsmOperand(LHS).isSuccess())
1058
1059
1060 if (LHS->isImm()) {
1061 Operands.push_back(SparcOperand::MorphToMEMri(Sparc::G0, std::move(LHS)));
1063 }
1064
1065 if (->isIntReg())
1066 return Error(LHS->getStartLoc(), "invalid register kind for this operand");
1067
1068 AsmToken Tok = getLexer().getTok();
1069
1070
1073
1074 std::unique_ptr RHS;
1075 if (!parseSparcAsmOperand(RHS).isSuccess())
1077
1078 if (RHS->isReg() && ->isIntReg())
1079 return Error(RHS->getStartLoc(),
1080 "invalid register kind for this operand");
1081
1083 RHS->isImm()
1084 ? SparcOperand::MorphToMEMri(LHS->getReg(), std::move(RHS))
1085 : SparcOperand::MorphToMEMrr(LHS->getReg(), std::move(RHS)));
1086
1088 }
1089
1090 Operands.push_back(SparcOperand::CreateMEMr(LHS->getReg(), S, E));
1092}
1093
1094template
1095ParseStatus SparcAsmParser::parseShiftAmtImm(OperandVector &Operands) {
1098
1099
1102
1103 const MCExpr *Expr;
1104 if (getParser().parseExpression(Expr))
1106
1108 if (!CE)
1109 return Error(S, "constant expression expected");
1110
1112 return Error(S, "immediate shift value out of range");
1113
1114 Operands.push_back(SparcOperand::CreateImm(Expr, S, E));
1116}
1117
1118template <SparcAsmParser::TailRelocKind Kind>
1119ParseStatus SparcAsmParser::parseTailRelocSym(OperandVector &Operands) {
1120 SMLoc S = getLoc();
1122
1123 auto MatchesKind = [](uint16_t RelType) -> bool {
1124 switch (Kind) {
1125 case TailRelocKind::Load_GOT:
1126
1127
1128 return RelType == ELF::R_SPARC_GOTDATA_OP;
1129 case TailRelocKind::Add_TLS:
1130
1131
1132 switch (RelType) {
1133 case ELF::R_SPARC_TLS_GD_ADD:
1134 case ELF::R_SPARC_TLS_IE_ADD:
1135 case ELF::R_SPARC_TLS_LDM_ADD:
1136 case ELF::R_SPARC_TLS_LDO_ADD:
1137 return true;
1138 default:
1139 return false;
1140 }
1141 case TailRelocKind::Load_TLS:
1142
1143
1144 switch (RelType) {
1145 case ELF::R_SPARC_TLS_IE_LD:
1146 case ELF::R_SPARC_TLS_IE_LDX:
1147 return true;
1148 default:
1149 return false;
1150 }
1151 case TailRelocKind::Call_TLS:
1152
1153
1154 switch (RelType) {
1155 case ELF::R_SPARC_TLS_GD_CALL:
1156 case ELF::R_SPARC_TLS_LDM_CALL:
1157 return true;
1158 default:
1159 return false;
1160 }
1161 }
1162 llvm_unreachable("Unhandled SparcAsmParser::TailRelocKind enum");
1163 };
1164
1167
1168 const AsmToken Tok = Parser.getTok();
1169 getParser().Lex();
1170
1172 return Error(getLoc(), "expected valid identifier for operand modifier");
1173
1174 StringRef Name = getParser().getTok().getIdentifier();
1176 if (RelType == 0)
1177 return Error(getLoc(), "invalid relocation specifier");
1178
1179 if (!MatchesKind(RelType)) {
1180
1181 getLexer().UnLex(Tok);
1183 }
1184
1185 Parser.Lex();
1187 return Error(getLoc(), "expected '('");
1188
1189 getParser().Lex();
1190 const MCExpr *SubExpr;
1191 if (getParser().parseParenExpression(SubExpr, E))
1193
1194 const MCExpr *Val = adjustPICRelocation(RelType, SubExpr);
1195 Operands.push_back(SparcOperand::CreateTailRelocSym(Val, S, E));
1197}
1198
1199ParseStatus SparcAsmParser::parseMembarTag(OperandVector &Operands) {
1201 const MCExpr *EVal;
1202 int64_t ImmVal = 0;
1203
1204 std::unique_ptr Mask;
1205 if (parseSparcAsmOperand(Mask).isSuccess()) {
1206 if (->isImm() ||
->getImm()->evaluateAsAbsolute(ImmVal) ||
1207 ImmVal < 0 || ImmVal > 127)
1208 return Error(S, "invalid membar mask number");
1209 }
1210
1212 SMLoc TagStart = getLexer().getLoc();
1213 Parser.Lex();
1214 unsigned MaskVal = StringSwitch(Parser.getTok().getString())
1215 .Case("LoadLoad", 0x1)
1216 .Case("StoreLoad", 0x2)
1217 .Case("LoadStore", 0x4)
1218 .Case("StoreStore", 0x8)
1219 .Case("Lookaside", 0x10)
1220 .Case("MemIssue", 0x20)
1221 .Case("Sync", 0x40)
1222 .Default(0);
1223
1224 Parser.Lex();
1225
1226 if (!MaskVal)
1227 return Error(TagStart, "unknown membar tag");
1228
1229 ImmVal |= MaskVal;
1230
1232 Parser.Lex();
1233 }
1234
1237 Operands.push_back(SparcOperand::CreateImm(EVal, S, E));
1239}
1240
1241ParseStatus SparcAsmParser::parseASITag(OperandVector &Operands) {
1244 int64_t ASIVal = 0;
1245
1247
1248
1249 ParseStatus ParseExprStatus = parseExpression(ASIVal);
1250 if (!ParseExprStatus.isSuccess())
1251 return ParseExprStatus;
1252
1254 return Error(S, "invalid ASI number, must be between 0 and 255");
1255
1256 Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));
1258 }
1259
1260
1261
1262 SMLoc TagStart = getLexer().peekTok(false).getLoc();
1263 Parser.Lex();
1265 const SparcASITag::ASITag *ASITag = SparcASITag::lookupASITagByName(ASIName);
1266 if (!ASITag)
1267 ASITag = SparcASITag::lookupASITagByAltName(ASIName);
1268 Parser.Lex();
1269
1270 if (!ASITag)
1271 return Error(TagStart, "unknown ASI tag");
1272
1274
1275 Operands.push_back(SparcOperand::CreateASITag(ASIVal, S, E));
1277}
1278
1279ParseStatus SparcAsmParser::parsePrefetchTag(OperandVector &Operands) {
1282 int64_t PrefetchVal = 0;
1283
1285
1286
1287 ParseStatus ParseExprStatus = parseExpression(PrefetchVal);
1288 if (!ParseExprStatus.isSuccess())
1289 return ParseExprStatus;
1290
1292 return Error(S, "invalid prefetch number, must be between 0 and 31");
1293
1294 Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E));
1296 }
1297
1298 SMLoc TagStart = getLexer().peekTok(false).getLoc();
1299 Parser.Lex();
1300 const StringRef PrefetchName = Parser.getTok().getString();
1301 const SparcPrefetchTag::PrefetchTag *PrefetchTag =
1302 SparcPrefetchTag::lookupPrefetchTagByName(PrefetchName);
1303 Parser.Lex();
1304
1305 if (!PrefetchTag)
1306 return Error(TagStart, "unknown prefetch tag");
1307
1308 PrefetchVal = PrefetchTag->Encoding;
1309
1310 Operands.push_back(SparcOperand::CreatePrefetchTag(PrefetchVal, S, E));
1312}
1313
1314ParseStatus SparcAsmParser::parseCallTarget(OperandVector &Operands) {
1317
1318 switch (getLexer().getKind()) {
1319 default:
1325 break;
1326 }
1327
1328 const MCExpr *DestValue;
1329 if (getParser().parseExpression(DestValue))
1331
1332 Operands.push_back(SparcOperand::CreateImm(DestValue, S, E));
1334}
1335
1336ParseStatus SparcAsmParser::parseOperand(OperandVector &Operands,
1337 StringRef Mnemonic) {
1338
1339 ParseStatus Res = MatchOperandParserImpl(Operands, Mnemonic);
1340
1341
1342
1343
1345 return Res;
1346
1348
1349 Operands.push_back(SparcOperand::CreateToken("[",
1351 Parser.Lex();
1352
1353 if (Mnemonic == "cas" || Mnemonic == "casl" || Mnemonic == "casa" ||
1354 Mnemonic == "casx" || Mnemonic == "casxl" || Mnemonic == "casxa") {
1358 Parser.Lex();
1359
1360 unsigned RegKind;
1361 MCRegister Reg = matchRegisterName(Parser.getTok(), RegKind);
1362 if ()
1364
1365 Parser.Lex();
1367 Operands.push_back(SparcOperand::CreateReg(Reg, RegKind, S, E));
1369 } else {
1370 Res = parseMEMOperand(Operands);
1371 }
1372
1374 return Res;
1375
1378
1379 Operands.push_back(SparcOperand::CreateToken("]",
1381 Parser.Lex();
1382
1383
1384
1385
1390 S, "malformed ASI tag, must be a constant integer expression");
1391
1392 Parser.Lex();
1393 const AsmToken Tok = Parser.getTok();
1395
1396
1397
1398
1399
1400 SparcOperand &OldMemOp = (SparcOperand &)*Operands[Operands.size() - 2];
1401 if (OldMemOp.isMEMrr()) {
1402 if (OldMemOp.getMemOffsetReg() != Sparc::G0) {
1403 return Error(S, "invalid operand for instruction");
1404 }
1405 Operands[Operands.size() - 2] = SparcOperand::MorphToMEMri(
1406 OldMemOp.getMemBase(),
1408 OldMemOp.getStartLoc(),
1409 OldMemOp.getEndLoc()));
1410 }
1411 Parser.Lex();
1412
1413
1414
1415
1416 Operands.push_back(SparcOperand::CreateToken("%asi", S));
1418 }
1419
1420 return Error(S, "malformed ASI tag, must be %asi, a constant integer "
1421 "expression, or a named tag");
1422 }
1423
1424
1425
1428 return parseASITag(Operands);
1430 }
1431
1432 std::unique_ptr Op;
1433
1434 Res = parseSparcAsmOperand(Op);
1437
1438
1440
1442}
1443
1444ParseStatus
1445SparcAsmParser::parseSparcAsmOperand(std::unique_ptr &Op) {
1448 const MCExpr *EVal;
1449
1450 Op = nullptr;
1451 switch (getLexer().getKind()) {
1452 default: break;
1453
1455 Parser.Lex();
1456 unsigned RegKind;
1457 if (MCRegister Reg = matchRegisterName(Parser.getTok(), RegKind)) {
1459 Parser.Lex();
1461 if (Reg == Sparc::ICC && Name == "xcc")
1462 Op = SparcOperand::CreateToken("%xcc", S);
1463 else
1464 Op = SparcOperand::CreateReg(Reg, RegKind, S, E);
1465 break;
1466 }
1467 if (matchSparcAsmModifiers(EVal, E)) {
1469 Op = SparcOperand::CreateImm(EVal, S, E);
1470 }
1471 break;
1472 }
1473
1480 if (getParser().parseExpression(EVal, E))
1481 break;
1482
1483 Op = SparcOperand::CreateImm(EVal, S, E);
1484 break;
1485 }
1487}
1488
1489ParseStatus SparcAsmParser::parseBranchModifiers(OperandVector &Operands) {
1490
1491
1493 Parser.Lex();
1494
1498 if (modName == "a" || modName == "pn" || modName == "pt") {
1499 Operands.push_back(SparcOperand::CreateToken(modName,
1501 Parser.Lex();
1502 }
1503 }
1505}
1506
1507ParseStatus SparcAsmParser::parseExpression(int64_t &Val) {
1508 AsmToken Tok = getLexer().getTok();
1509
1510 if (!isPossibleExpression(Tok))
1512
1513 return getParser().parseAbsoluteExpression(Val);
1514}
1515
1516MCRegister SparcAsmParser::matchRegisterName(const AsmToken &Tok,
1517 unsigned &RegKind) {
1518 RegKind = SparcOperand::rk_None;
1520 return SP::NoRegister;
1521
1524 if ()
1526
1527 if (Reg) {
1528
1529
1530
1531
1532
1533
1534 if (Reg == SP::ASR4 && Name == "tick") {
1535 RegKind = SparcOperand::rk_Special;
1536 return SP::TICK;
1537 }
1538
1539 if (MRI.getRegClass(SP::IntRegsRegClassID).contains(Reg)) {
1540 RegKind = SparcOperand::rk_IntReg;
1541 return Reg;
1542 }
1543 if (MRI.getRegClass(SP::FPRegsRegClassID).contains(Reg)) {
1544 RegKind = SparcOperand::rk_FloatReg;
1545 return Reg;
1546 }
1547 if (MRI.getRegClass(SP::CoprocRegsRegClassID).contains(Reg)) {
1548 RegKind = SparcOperand::rk_CoprocReg;
1549 return Reg;
1550 }
1551
1552
1553 if (MRI.getRegClass(SP::IntPairRegClassID).contains(Reg)) {
1554 RegKind = SparcOperand::rk_IntReg;
1555 return MRI.getSubReg(Reg, SP::sub_even);
1556 }
1557
1558
1559 if (MRI.getRegClass(SP::DFPRegsRegClassID).contains(Reg)) {
1560
1561 if (MCRegister SubReg = MRI.getSubReg(Reg, SP::sub_even)) {
1562 RegKind = SparcOperand::rk_FloatReg;
1564 }
1565 RegKind = SparcOperand::rk_DoubleReg;
1566 return Reg;
1567 }
1568
1569
1570
1571 assert(.getRegClass(SP::QFPRegsRegClassID).contains(Reg));
1572
1573
1574 if (MRI.getRegClass(SP::CoprocPairRegClassID).contains(Reg)) {
1575 RegKind = SparcOperand::rk_CoprocReg;
1576 return MRI.getSubReg(Reg, SP::sub_even);
1577 }
1578
1579
1580 RegKind = SparcOperand::rk_Special;
1581 return Reg;
1582 }
1583
1584
1585
1586
1587
1588 int64_t RegNo = 0;
1589 if (Name.starts_with_insensitive("r") &&
1590 .substr(1, 2).getAsInteger(10, RegNo) && RegNo < 31) {
1591 RegKind = SparcOperand::rk_IntReg;
1593 }
1594
1595 if (Name == "xcc") {
1596
1597 RegKind = SparcOperand::rk_Special;
1598 return SP::ICC;
1599 }
1600
1601
1602
1603 if (Name == "pcr") {
1604 RegKind = SparcOperand::rk_Special;
1605 return SP::ASR16;
1606 }
1607 if (Name == "pic") {
1608 RegKind = SparcOperand::rk_Special;
1609 return SP::ASR17;
1610 }
1611 if (Name == "dcr") {
1612 RegKind = SparcOperand::rk_Special;
1613 return SP::ASR18;
1614 }
1615 if (Name == "gsr") {
1616 RegKind = SparcOperand::rk_Special;
1617 return SP::ASR19;
1618 }
1619 if (Name == "set_softint") {
1620 RegKind = SparcOperand::rk_Special;
1621 return SP::ASR20;
1622 }
1623 if (Name == "clear_softint") {
1624 RegKind = SparcOperand::rk_Special;
1625 return SP::ASR21;
1626 }
1627 if (Name == "softint") {
1628 RegKind = SparcOperand::rk_Special;
1629 return SP::ASR22;
1630 }
1631 if (Name == "tick_cmpr") {
1632 RegKind = SparcOperand::rk_Special;
1633 return SP::ASR23;
1634 }
1635 if (Name == "stick" || Name == "sys_tick") {
1636 RegKind = SparcOperand::rk_Special;
1637 return SP::ASR24;
1638 }
1639 if (Name == "stick_cmpr" || Name == "sys_tick_cmpr") {
1640 RegKind = SparcOperand::rk_Special;
1641 return SP::ASR25;
1642 }
1643
1644 return SP::NoRegister;
1645}
1646
1647
1648
1650 switch (Expr->getKind()) {
1654 break;
1655
1657 break;
1658
1662 }
1663
1666 return (SymRef.getSymbol().getName() == "_GLOBAL_OFFSET_TABLE_");
1667 }
1668
1671
1674 }
1675 return false;
1676}
1677
1678const MCSpecifierExpr *
1679SparcAsmParser::adjustPICRelocation(uint16_t RelType, const MCExpr *subExpr) {
1680
1681
1682
1683
1684
1685 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1686 switch (RelType) {
1687 default: break;
1688 case ELF::R_SPARC_LO10:
1689 RelType =
1690 hasGOTReference(subExpr) ? ELF::R_SPARC_PC10 : ELF::R_SPARC_GOT10;
1691 break;
1692 case ELF::R_SPARC_HI22:
1693 RelType =
1694 hasGOTReference(subExpr) ? ELF::R_SPARC_PC22 : ELF::R_SPARC_GOT22;
1695 break;
1696 }
1697 }
1698
1700}
1701
1702bool SparcAsmParser::matchSparcAsmModifiers(const MCExpr *&EVal,
1703 SMLoc &EndLoc) {
1704 AsmToken Tok = Parser.getTok();
1706 return false;
1707
1709
1711 switch (VK) {
1712 case 0:
1713 Error(getLoc(), "invalid relocation specifier");
1714 return false;
1715
1716 case ELF::R_SPARC_GOTDATA_OP:
1717 case ELF::R_SPARC_TLS_GD_ADD:
1718 case ELF::R_SPARC_TLS_GD_CALL:
1719 case ELF::R_SPARC_TLS_IE_ADD:
1720 case ELF::R_SPARC_TLS_IE_LD:
1721 case ELF::R_SPARC_TLS_IE_LDX:
1722 case ELF::R_SPARC_TLS_LDM_ADD:
1723 case ELF::R_SPARC_TLS_LDM_CALL:
1724 case ELF::R_SPARC_TLS_LDO_ADD:
1725
1726 return false;
1727
1728 default:
1729 break;
1730 }
1731
1732 Parser.Lex();
1734 return false;
1735
1736 Parser.Lex();
1737 const MCExpr *subExpr;
1739 return false;
1740
1741 EVal = adjustPICRelocation(VK, subExpr);
1742 return true;
1743}
1744
1745bool SparcAsmParser::isPossibleExpression(const AsmToken &Token) {
1746 switch (Token.getKind()) {
1753 return true;
1754 default:
1755 return false;
1756 }
1757}
1758
1765
1766unsigned SparcAsmParser::validateTargetOperandClass(MCParsedAsmOperand &GOp,
1767 unsigned Kind) {
1768 SparcOperand &Op = (SparcOperand &)GOp;
1769 if (Op.isFloatOrDoubleReg()) {
1770 switch (Kind) {
1771 default: break;
1772 case MCK_DFPRegs:
1773 if (.isFloatReg() || SparcOperand::MorphToDoubleReg(Op))
1775 break;
1776 case MCK_QFPRegs:
1777 if (SparcOperand::MorphToQuadReg(Op))
1779 break;
1780 }
1781 }
1782 if (Op.isIntReg() && Kind == MCK_IntPair) {
1783 if (SparcOperand::MorphToIntPairReg(Op))
1785 }
1786 if (Op.isCoprocReg() && Kind == MCK_CoprocPair) {
1787 if (SparcOperand::MorphToCoprocPairReg(Op))
1789 }
1790 return Match_InvalidOperand;
1791}
unsigned const MachineRegisterInfo * MRI
static MCRegister MatchRegisterName(StringRef Name)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static bool addCallTargetOperands(MachineInstrBuilder &CallInst, MachineIRBuilder &MIRBuilder, AMDGPUCallLowering::CallLoweringInfo &Info, bool IsDynamicVGPRChainCall=false)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static MCRegister MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
loop data Loop Data Prefetch
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
This file defines the SmallVector class.
static const MCPhysReg DoubleRegs[32]
Definition SparcAsmParser.cpp:172
static bool hasGOTReference(const MCExpr *Expr)
Definition SparcAsmParser.cpp:1649
static const MCPhysReg IntRegs[32]
Definition SparcAsmParser.cpp:162
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcAsmParser()
Definition SparcAsmParser.cpp:1760
static const MCPhysReg IntPairRegs[]
Definition SparcAsmParser.cpp:188
static const MCPhysReg QuadFPRegs[32]
Definition SparcAsmParser.cpp:182
static const MCPhysReg CoprocPairRegs[]
Definition SparcAsmParser.cpp:194
static bool is64Bit(const char *name)
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() const
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
TokenKind getKind() const
LLVM_ABI SMLoc getEndLoc() const
Base class for user error types.
Container class for subtarget features.
void printExpr(raw_ostream &, const MCExpr &) const
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression, assuming that an initial '(' has already been consumed.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
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.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
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.
@ Specifier
Expression with a relocation specifier.
@ Binary
Binary expressions.
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
constexpr unsigned id() const
Extension point for target-specific MCExpr subclasses with a relocation specifier,...
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
StringRef getName() const
getName - Get the symbol name.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
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
void push_back(const T &Elt)
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
bool isIntReg(MCRegister Reg)
MCExpr const & getExpr(MCExpr const &Expr)
Definition SparcAsmParser.cpp:48
uint16_t parseSpecifier(StringRef name)
@ CE
Windows NT (Windows on ARM)
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
Target & getTheSparcTarget()
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
Target & getTheSparcV9Target()
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
Target & getTheSparcelTarget()
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...