36#define DEBUG_TYPE "ve-asmparser"
48#define GET_ASSEMBLER_HEADER
49#include "VEGenAsmMatcher.inc"
57 bool MatchingInlineAsm)
override;
61 SMLoc &EndLoc)
override;
67 unsigned Kind)
override;
76 ParseStatus parseVEAsmOperand(std::unique_ptr<VEOperand> &Operand);
82 bool parseExpression(
const MCExpr *&EVal);
88 bool parseLiteralValues(
unsigned Size,
SMLoc L);
102 VE::SW0, VE::SW1, VE::SW2, VE::SW3, VE::SW4, VE::SW5, VE::SW6,
103 VE::SW7, VE::SW8, VE::SW9, VE::SW10, VE::SW11, VE::SW12, VE::SW13,
104 VE::SW14, VE::SW15, VE::SW16, VE::SW17, VE::SW18, VE::SW19, VE::SW20,
105 VE::SW21, VE::SW22, VE::SW23, VE::SW24, VE::SW25, VE::SW26, VE::SW27,
106 VE::SW28, VE::SW29, VE::SW30, VE::SW31, VE::SW32, VE::SW33, VE::SW34,
107 VE::SW35, VE::SW36, VE::SW37, VE::SW38, VE::SW39, VE::SW40, VE::SW41,
108 VE::SW42, VE::SW43, VE::SW44, VE::SW45, VE::SW46, VE::SW47, VE::SW48,
109 VE::SW49, VE::SW50, VE::SW51, VE::SW52, VE::SW53, VE::SW54, VE::SW55,
110 VE::SW56, VE::SW57, VE::SW58, VE::SW59, VE::SW60, VE::SW61, VE::SW62,
114 VE::SF0, VE::SF1, VE::SF2, VE::SF3, VE::SF4, VE::SF5, VE::SF6,
115 VE::SF7, VE::SF8, VE::SF9, VE::SF10, VE::SF11, VE::SF12, VE::SF13,
116 VE::SF14, VE::SF15, VE::SF16, VE::SF17, VE::SF18, VE::SF19, VE::SF20,
117 VE::SF21, VE::SF22, VE::SF23, VE::SF24, VE::SF25, VE::SF26, VE::SF27,
118 VE::SF28, VE::SF29, VE::SF30, VE::SF31, VE::SF32, VE::SF33, VE::SF34,
119 VE::SF35, VE::SF36, VE::SF37, VE::SF38, VE::SF39, VE::SF40, VE::SF41,
120 VE::SF42, VE::SF43, VE::SF44, VE::SF45, VE::SF46, VE::SF47, VE::SF48,
121 VE::SF49, VE::SF50, VE::SF51, VE::SF52, VE::SF53, VE::SF54, VE::SF55,
122 VE::SF56, VE::SF57, VE::SF58, VE::SF59, VE::SF60, VE::SF61, VE::SF62,
126 VE::Q0, VE::Q1, VE::Q2, VE::Q3, VE::Q4, VE::Q5, VE::Q6, VE::Q7,
127 VE::Q8, VE::Q9, VE::Q10, VE::Q11, VE::Q12, VE::Q13, VE::Q14, VE::Q15,
128 VE::Q16, VE::Q17, VE::Q18, VE::Q19, VE::Q20, VE::Q21, VE::Q22, VE::Q23,
129 VE::Q24, VE::Q25, VE::Q26, VE::Q27, VE::Q28, VE::Q29, VE::Q30, VE::Q31};
132 VE::VMP4, VE::VMP5, VE::VMP6, VE::VMP7};
135 VE::USRCC, VE::PSW, VE::SAR, VE::NoRegister,
136 VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::PMMR,
137 VE::PMCR0, VE::PMCR1, VE::PMCR2, VE::PMCR3,
138 VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::NoRegister,
139 VE::PMC0, VE::PMC1, VE::PMC2, VE::PMC3,
140 VE::PMC4, VE::PMC5, VE::PMC6, VE::PMC7,
141 VE::PMC8, VE::PMC9, VE::PMC10, VE::PMC11,
142 VE::PMC12, VE::PMC13, VE::PMC14};
168 SMLoc StartLoc, EndLoc;
214 VEOperand(KindTy K) :
Kind(
K) {}
216 bool isToken()
const override {
return Kind == k_Token; }
217 bool isReg()
const override {
return Kind == k_Register; }
218 bool isImm()
const override {
return Kind == k_Immediate; }
219 bool isMem()
const override {
220 return isMEMrri() || isMEMrii() || isMEMzri() || isMEMzii() || isMEMri() ||
223 bool isMEMrri()
const {
return Kind == k_MemoryRegRegImm; }
224 bool isMEMrii()
const {
return Kind == k_MemoryRegImmImm; }
225 bool isMEMzri()
const {
return Kind == k_MemoryZeroRegImm; }
226 bool isMEMzii()
const {
return Kind == k_MemoryZeroImmImm; }
227 bool isMEMri()
const {
return Kind == k_MemoryRegImm; }
228 bool isMEMzi()
const {
return Kind == k_MemoryZeroImm; }
229 bool isCCOp()
const {
return Kind == k_CCOp; }
230 bool isRDOp()
const {
return Kind == k_RDOp; }
236 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
237 int64_t
Value = ConstExpr->getValue();
247 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
248 int64_t
Value = ConstExpr->getValue();
258 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
259 int64_t
Value = ConstExpr->getValue();
260 return isUInt<1>(
Value);
269 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
270 int64_t
Value = ConstExpr->getValue();
271 return isUInt<2>(
Value);
280 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
281 int64_t
Value = ConstExpr->getValue();
282 return isUInt<3>(
Value);
291 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
292 int64_t
Value = ConstExpr->getValue();
293 return isUInt<4>(
Value);
302 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
303 int64_t
Value = ConstExpr->getValue();
304 return isUInt<6>(
Value);
313 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
314 int64_t
Value = ConstExpr->getValue();
315 return isUInt<7>(
Value);
324 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
325 int64_t
Value = ConstExpr->getValue();
326 return isInt<7>(
Value);
331 if (Kind != k_MImmOp)
335 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(MImm.Val)) {
336 int64_t
Value = ConstExpr->getValue();
337 return isUInt<6>(
Value);
343 assert(Kind == k_Token &&
"Invalid access!");
348 assert((Kind == k_Register) &&
"Invalid access!");
352 const MCExpr *getImm()
const {
353 assert((Kind == k_Immediate) &&
"Invalid access!");
357 unsigned getMemBase()
const {
358 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
359 Kind == k_MemoryRegImm) &&
364 unsigned getMemIndexReg()
const {
365 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryZeroRegImm) &&
370 const MCExpr *getMemIndex()
const {
371 assert((Kind == k_MemoryRegImmImm || Kind == k_MemoryZeroImmImm) &&
376 const MCExpr *getMemOffset()
const {
377 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
378 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm ||
379 Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) &&
384 void setMemOffset(
const MCExpr *off) {
385 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
386 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm ||
387 Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) &&
392 unsigned getCCVal()
const {
393 assert((Kind == k_CCOp) &&
"Invalid access!");
397 unsigned getRDVal()
const {
398 assert((Kind == k_RDOp) &&
"Invalid access!");
402 const MCExpr *getMImmVal()
const {
403 assert((Kind == k_MImmOp) &&
"Invalid access!");
406 bool getM0Flag()
const {
407 assert((Kind == k_MImmOp) &&
"Invalid access!");
419 OS <<
"Token: " << getToken() <<
"\n";
425 OS <<
"Imm: " << getImm() <<
"\n";
427 case k_MemoryRegRegImm:
428 assert(getMemOffset() !=
nullptr);
429 OS <<
"Mem: #" << getMemBase() <<
"+#" << getMemIndexReg() <<
"+"
430 << *getMemOffset() <<
"\n";
432 case k_MemoryRegImmImm:
433 assert(getMemIndex() !=
nullptr && getMemOffset() !=
nullptr);
434 OS <<
"Mem: #" << getMemBase() <<
"+" << *getMemIndex() <<
"+"
435 << *getMemOffset() <<
"\n";
437 case k_MemoryZeroRegImm:
438 assert(getMemOffset() !=
nullptr);
439 OS <<
"Mem: 0+#" << getMemIndexReg() <<
"+" << *getMemOffset() <<
"\n";
441 case k_MemoryZeroImmImm:
442 assert(getMemIndex() !=
nullptr && getMemOffset() !=
nullptr);
443 OS <<
"Mem: 0+" << *getMemIndex() <<
"+" << *getMemOffset() <<
"\n";
446 assert(getMemOffset() !=
nullptr);
447 OS <<
"Mem: #" << getMemBase() <<
"+" << *getMemOffset() <<
"\n";
449 case k_MemoryZeroImm:
450 assert(getMemOffset() !=
nullptr);
451 OS <<
"Mem: 0+" << *getMemOffset() <<
"\n";
454 OS <<
"CCOp: " << getCCVal() <<
"\n";
457 OS <<
"RDOp: " << getRDVal() <<
"\n";
460 OS <<
"MImm: (" << getMImmVal() << (getM0Flag() ?
")0" :
")1") <<
"\n";
465 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
466 assert(
N == 1 &&
"Invalid number of operands!");
470 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
471 assert(
N == 1 &&
"Invalid number of operands!");
472 const MCExpr *Expr = getImm();
476 void addZeroOperands(
MCInst &Inst,
unsigned N)
const {
477 addImmOperands(Inst,
N);
480 void addUImm0to2Operands(
MCInst &Inst,
unsigned N)
const {
481 addImmOperands(Inst,
N);
484 void addUImm1Operands(
MCInst &Inst,
unsigned N)
const {
485 addImmOperands(Inst,
N);
488 void addUImm2Operands(
MCInst &Inst,
unsigned N)
const {
489 addImmOperands(Inst,
N);
492 void addUImm3Operands(
MCInst &Inst,
unsigned N)
const {
493 addImmOperands(Inst,
N);
496 void addUImm4Operands(
MCInst &Inst,
unsigned N)
const {
497 addImmOperands(Inst,
N);
500 void addUImm6Operands(
MCInst &Inst,
unsigned N)
const {
501 addImmOperands(Inst,
N);
504 void addUImm7Operands(
MCInst &Inst,
unsigned N)
const {
505 addImmOperands(Inst,
N);
508 void addSImm7Operands(
MCInst &Inst,
unsigned N)
const {
509 addImmOperands(Inst,
N);
516 else if (
const auto *CE = dyn_cast<MCConstantExpr>(Expr))
522 void addMEMrriOperands(
MCInst &Inst,
unsigned N)
const {
523 assert(
N == 3 &&
"Invalid number of operands!");
527 addExpr(Inst, getMemOffset());
530 void addMEMriiOperands(
MCInst &Inst,
unsigned N)
const {
531 assert(
N == 3 &&
"Invalid number of operands!");
534 addExpr(Inst, getMemIndex());
535 addExpr(Inst, getMemOffset());
538 void addMEMzriOperands(
MCInst &Inst,
unsigned N)
const {
539 assert(
N == 3 &&
"Invalid number of operands!");
543 addExpr(Inst, getMemOffset());
546 void addMEMziiOperands(
MCInst &Inst,
unsigned N)
const {
547 assert(
N == 3 &&
"Invalid number of operands!");
550 addExpr(Inst, getMemIndex());
551 addExpr(Inst, getMemOffset());
554 void addMEMriOperands(
MCInst &Inst,
unsigned N)
const {
555 assert(
N == 2 &&
"Invalid number of operands!");
558 addExpr(Inst, getMemOffset());
561 void addMEMziOperands(
MCInst &Inst,
unsigned N)
const {
562 assert(
N == 2 &&
"Invalid number of operands!");
565 addExpr(Inst, getMemOffset());
568 void addCCOpOperands(
MCInst &Inst,
unsigned N)
const {
569 assert(
N == 1 &&
"Invalid number of operands!");
574 void addRDOpOperands(
MCInst &Inst,
unsigned N)
const {
575 assert(
N == 1 &&
"Invalid number of operands!");
580 void addMImmOperands(
MCInst &Inst,
unsigned N)
const {
581 assert(
N == 1 &&
"Invalid number of operands!");
582 const auto *ConstExpr = dyn_cast<MCConstantExpr>(getMImmVal());
583 assert(ConstExpr &&
"Null operands!");
584 int64_t
Value = ConstExpr->getValue();
590 static std::unique_ptr<VEOperand> CreateToken(
StringRef Str,
SMLoc S) {
591 auto Op = std::make_unique<VEOperand>(k_Token);
592 Op->Tok.Data = Str.data();
593 Op->Tok.Length = Str.size();
599 static std::unique_ptr<VEOperand> CreateReg(
unsigned RegNum,
SMLoc S,
601 auto Op = std::make_unique<VEOperand>(k_Register);
602 Op->Reg.RegNum = RegNum;
608 static std::unique_ptr<VEOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
610 auto Op = std::make_unique<VEOperand>(k_Immediate);
617 static std::unique_ptr<VEOperand> CreateCCOp(
unsigned CCVal,
SMLoc S,
619 auto Op = std::make_unique<VEOperand>(k_CCOp);
620 Op->CC.CCVal = CCVal;
626 static std::unique_ptr<VEOperand> CreateRDOp(
unsigned RDVal,
SMLoc S,
628 auto Op = std::make_unique<VEOperand>(k_RDOp);
629 Op->RD.RDVal = RDVal;
635 static std::unique_ptr<VEOperand> CreateMImm(
const MCExpr *Val,
bool Flag,
637 auto Op = std::make_unique<VEOperand>(k_MImmOp);
645 static bool MorphToI32Reg(VEOperand &
Op) {
646 unsigned Reg =
Op.getReg();
647 unsigned regIdx =
Reg - VE::SX0;
654 static bool MorphToF32Reg(VEOperand &
Op) {
655 unsigned Reg =
Op.getReg();
656 unsigned regIdx =
Reg - VE::SX0;
663 static bool MorphToF128Reg(VEOperand &
Op) {
664 unsigned Reg =
Op.getReg();
665 unsigned regIdx =
Reg - VE::SX0;
666 if (regIdx % 2 || regIdx > 63)
672 static bool MorphToVM512Reg(VEOperand &
Op) {
673 unsigned Reg =
Op.getReg();
674 unsigned regIdx =
Reg - VE::VM0;
675 if (regIdx % 2 || regIdx > 15)
681 static bool MorphToMISCReg(VEOperand &
Op) {
682 const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Op.getImm());
685 unsigned regIdx = ConstExpr->getValue();
686 if (regIdx > 31 ||
MISCRegs[regIdx] == VE::NoRegister)
688 Op.Kind = k_Register;
693 static std::unique_ptr<VEOperand>
694 MorphToMEMri(
unsigned Base, std::unique_ptr<VEOperand>
Op) {
696 Op->Kind = k_MemoryRegImm;
698 Op->Mem.IndexReg = 0;
699 Op->Mem.Index =
nullptr;
700 Op->Mem.Offset =
Imm;
704 static std::unique_ptr<VEOperand>
705 MorphToMEMzi(std::unique_ptr<VEOperand>
Op) {
707 Op->Kind = k_MemoryZeroImm;
709 Op->Mem.IndexReg = 0;
710 Op->Mem.Index =
nullptr;
711 Op->Mem.Offset =
Imm;
715 static std::unique_ptr<VEOperand>
716 MorphToMEMrri(
unsigned Base,
unsigned Index, std::unique_ptr<VEOperand>
Op) {
718 Op->Kind = k_MemoryRegRegImm;
721 Op->Mem.Index =
nullptr;
722 Op->Mem.Offset =
Imm;
726 static std::unique_ptr<VEOperand>
728 std::unique_ptr<VEOperand>
Op) {
730 Op->Kind = k_MemoryRegImmImm;
732 Op->Mem.IndexReg = 0;
734 Op->Mem.Offset =
Imm;
738 static std::unique_ptr<VEOperand>
739 MorphToMEMzri(
unsigned Index, std::unique_ptr<VEOperand>
Op) {
741 Op->Kind = k_MemoryZeroRegImm;
744 Op->Mem.Index =
nullptr;
745 Op->Mem.Offset =
Imm;
749 static std::unique_ptr<VEOperand>
750 MorphToMEMzii(
const MCExpr *
Index, std::unique_ptr<VEOperand>
Op) {
752 Op->Kind = k_MemoryZeroImmImm;
754 Op->Mem.IndexReg = 0;
756 Op->Mem.Offset =
Imm;
763bool VEAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
766 bool MatchingInlineAsm) {
768 unsigned MatchResult =
770 switch (MatchResult) {
776 case Match_MissingFeature:
778 "instruction requires a CPU feature not currently enabled");
780 case Match_InvalidOperand: {
781 SMLoc ErrorLoc = IDLoc;
784 return Error(IDLoc,
"too few operands for instruction");
787 if (ErrorLoc ==
SMLoc())
791 return Error(ErrorLoc,
"invalid operand for instruction");
793 case Match_MnemonicFail:
794 return Error(IDLoc,
"invalid instruction mnemonic");
801 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
802 return Error(StartLoc,
"invalid register name");
811 int RegNum = matchFn(
Name);
815 if (RegNum == VE::NoRegister) {
816 RegNum = matchFn(
Name.lower());
835 Reg = VE::NoRegister;
841 if (
Reg == VE::NoRegister)
844 if (
Reg != VE::NoRegister) {
849 getLexer().UnLex(Tok);
854 bool IntegerCC,
bool OmitCC,
SMLoc NameLoc,
868 Operands->push_back(VEOperand::CreateToken(
Name, NameLoc));
872 Operands->push_back(VEOperand::CreateCCOp(CondCode, CondLoc, SuffixLoc));
874 if (!SuffixStr.
empty())
875 Operands->push_back(VEOperand::CreateToken(SuffixStr, SuffixLoc));
877 Operands->push_back(VEOperand::CreateToken(
Name, NameLoc));
892 Operands->push_back(VEOperand::CreateToken(
Name, NameLoc));
901 Operands->push_back(VEOperand::CreateToken(
Name, NameLoc));
913 if (
Name[0] ==
'b') {
916 size_t Next =
Name.find(
'.');
918 if (
Name.size() > 1 &&
Name[1] ==
'r')
922 if (Next + 1 <
Name.size() &&
923 (
Name[Next + 1] ==
'd' ||
Name[Next + 1] ==
's'))
926 }
else if (
Name.starts_with(
"cmov.l.") ||
Name.starts_with(
"cmov.w.") ||
927 Name.starts_with(
"cmov.d.") ||
Name.starts_with(
"cmov.s.")) {
928 bool ICC =
Name[5] ==
'l' ||
Name[5] ==
'w';
930 }
else if (
Name.starts_with(
"cvt.w.d.sx") ||
Name.starts_with(
"cvt.w.d.zx") ||
931 Name.starts_with(
"cvt.w.s.sx") ||
Name.starts_with(
"cvt.w.s.zx")) {
933 }
else if (
Name.starts_with(
"cvt.l.d")) {
935 }
else if (
Name.starts_with(
"vcvt.w.d.sx") ||
936 Name.starts_with(
"vcvt.w.d.zx") ||
937 Name.starts_with(
"vcvt.w.s.sx") ||
938 Name.starts_with(
"vcvt.w.s.zx")) {
940 }
else if (
Name.starts_with(
"vcvt.l.d")) {
942 }
else if (
Name.starts_with(
"pvcvt.w.s.lo") ||
943 Name.starts_with(
"pvcvt.w.s.up")) {
945 }
else if (
Name.starts_with(
"pvcvt.w.s")) {
947 }
else if (
Name.starts_with(
"vfmk.l.") ||
Name.starts_with(
"vfmk.w.") ||
948 Name.starts_with(
"vfmk.d.") ||
Name.starts_with(
"vfmk.s.")) {
949 bool ICC =
Name[5] ==
'l' ||
Name[5] ==
'w' ?
true :
false;
951 }
else if (
Name.starts_with(
"pvfmk.w.lo.") ||
952 Name.starts_with(
"pvfmk.w.up.") ||
953 Name.starts_with(
"pvfmk.s.lo.") ||
954 Name.starts_with(
"pvfmk.s.up.")) {
955 bool ICC =
Name[6] ==
'l' ||
Name[6] ==
'w' ?
true :
false;
958 Operands->push_back(VEOperand::CreateToken(Mnemonic, NameLoc));
981 if (!parseOperand(
Operands, Mnemonic).isSuccess()) {
982 SMLoc Loc = getLexer().getLoc();
983 return Error(Loc,
"unexpected token");
989 if (!parseOperand(
Operands, Mnemonic).isSuccess()) {
990 SMLoc Loc = getLexer().getLoc();
991 return Error(Loc,
"unexpected token");
996 SMLoc Loc = getLexer().getLoc();
997 return Error(Loc,
"unexpected token");
1011 if (IDVal ==
".word")
1012 return parseLiteralValues(4, DirectiveID.
getLoc());
1015 if (IDVal ==
".long")
1016 return parseLiteralValues(8, DirectiveID.
getLoc());
1019 if (IDVal ==
".llong")
1020 return parseLiteralValues(8, DirectiveID.
getLoc());
1030bool VEAsmParser::parseLiteralValues(
unsigned Size,
SMLoc L) {
1031 auto parseOne = [&]() ->
bool {
1033 if (getParser().parseExpression(
Value))
1035 getParser().getStreamer().emitValue(
Value,
Size, L);
1038 return (parseMany(parseOne));
1048VEAsmParser::extractModifierFromExpr(
const MCExpr *
E,
1050 MCContext &Context = getParser().getContext();
1053 switch (
E->getKind()) {
1126 const MCExpr *
LHS = extractModifierFromExpr(BE->
getLHS(), LHSVariant);
1127 const MCExpr *
RHS = extractModifierFromExpr(BE->
getRHS(), RHSVariant);
1141 else if (LHSVariant == RHSVariant)
1153const MCExpr *VEAsmParser::fixupVariantKind(
const MCExpr *
E) {
1154 MCContext &Context = getParser().getContext();
1156 switch (
E->getKind()) {
1185bool VEAsmParser::parseExpression(
const MCExpr *&EVal) {
1187 if (getParser().parseExpression(EVal))
1191 EVal = fixupVariantKind(EVal);
1193 const MCExpr *
E = extractModifierFromExpr(EVal, Variant);
1214 std::unique_ptr<VEOperand>
Offset;
1215 switch (getLexer().getKind()) {
1224 if (!parseExpression(EVal))
1225 Offset = VEOperand::CreateImm(EVal, S,
E);
1238 switch (getLexer().getKind()) {
1243 Operands.push_back(VEOperand::MorphToMEMzii(
1252 const MCExpr *IndexValue =
nullptr;
1255 switch (getLexer().getKind()) {
1257 if (parseRegister(IndexReg, S,
E))
1264 if (getParser().parseExpression(IndexValue,
E))
1274 switch (getLexer().getKind()) {
1281 IndexValue ? VEOperand::MorphToMEMzii(IndexValue, std::move(
Offset))
1282 : VEOperand::MorphToMEMzri(IndexReg, std::move(
Offset)));
1291 if (parseRegister(BaseReg, S,
E))
1300 ? VEOperand::MorphToMEMrii(BaseReg, IndexValue, std::move(
Offset))
1301 : VEOperand::MorphToMEMrri(BaseReg, IndexReg, std::move(
Offset)));
1321 std::unique_ptr<VEOperand>
Offset;
1322 switch (getLexer().getKind()) {
1331 if (!parseExpression(EVal))
1332 Offset = VEOperand::CreateImm(EVal, S,
E);
1339 if (parseRegister(BaseReg, S,
E))
1352 switch (getLexer().getKind()) {
1358 Operands.push_back(BaseReg != VE::NoRegister
1359 ? VEOperand::MorphToMEMri(BaseReg, std::move(
Offset))
1360 : VEOperand::MorphToMEMzi(std::move(
Offset)));
1364 if (BaseReg != VE::NoRegister)
1370 switch (getLexer().getKind()) {
1372 if (parseRegister(BaseReg, S,
E))
1378 if (parseRegister(BaseReg, S,
E))
1390 Operands.push_back(BaseReg != VE::NoRegister
1391 ? VEOperand::MorphToMEMri(BaseReg, std::move(
Offset))
1392 : VEOperand::MorphToMEMzi(std::move(
Offset)));
1411 getLexer().UnLex(Tok1);
1417 getLexer().UnLex(Tok2);
1418 getLexer().UnLex(Tok1);
1425 if (Suffix !=
"1" && Suffix !=
"0") {
1426 getLexer().UnLex(Tok3);
1427 getLexer().UnLex(Tok2);
1428 getLexer().UnLex(Tok1);
1434 VEOperand::CreateMImm(EVal, Suffix ==
"0", Tok1.
getLoc(), EndLoc));
1449 switch (getLexer().getKind()) {
1457 if (!tryParseRegister(Reg1,
S1, E1).isSuccess()) {
1458 getLexer().UnLex(Tok1);
1468 if (!tryParseRegister(Reg2, S2, E2).isSuccess())
1475 Operands.push_back(VEOperand::CreateReg(Reg1,
S1, E1));
1476 Operands.push_back(VEOperand::CreateReg(Reg2, S2, E2));
1483 std::unique_ptr<VEOperand>
Op;
1484 Res = parseVEAsmOperand(
Op);
1495 std::unique_ptr<VEOperand> Op1 = VEOperand::CreateToken(
1499 std::unique_ptr<VEOperand> Op2;
1500 Res = parseVEAsmOperand(Op2);
1507 Operands.push_back(std::move(Op1));
1508 Operands.push_back(std::move(Op2));
1519ParseStatus VEAsmParser::parseVEAsmOperand(std::unique_ptr<VEOperand> &
Op) {
1526 switch (getLexer().getKind()) {
1532 if (tryParseRegister(
Reg, S,
E).isSuccess())
1533 Op = VEOperand::CreateReg(
Reg, S,
E);
1540 if (!parseExpression(EVal))
1541 Op = VEOperand::CreateImm(EVal, S,
E);
1552#define GET_REGISTER_MATCHER
1553#define GET_MATCHER_IMPLEMENTATION
1554#include "VEGenAsmMatcher.inc"
1558 VEOperand &
Op = (VEOperand &)GOp;
1567 if (
Op.isReg() && VEOperand::MorphToF32Reg(
Op))
1571 if (
Op.isReg() && VEOperand::MorphToI32Reg(
Op))
1575 if (
Op.isReg() && VEOperand::MorphToF128Reg(
Op))
1579 if (
Op.isReg() && VEOperand::MorphToVM512Reg(
Op))
1583 if (
Op.isImm() && VEOperand::MorphToMISCReg(
Op))
1587 return Match_InvalidOperand;
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 createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
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 parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
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...
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
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,...