34#define DEBUG_TYPE "ve-asmparser"
46#define GET_ASSEMBLER_HEADER
47#include "VEGenAsmMatcher.inc"
55 bool MatchingInlineAsm)
override;
59 SMLoc &EndLoc)
override;
65 unsigned Kind)
override;
74 ParseStatus parseVEAsmOperand(std::unique_ptr<VEOperand> &Operand);
78 bool parseExpression(
const MCExpr *&EVal);
84 bool parseLiteralValues(
unsigned Size,
SMLoc L);
98 VE::SW0, VE::SW1, VE::SW2, VE::SW3, VE::SW4, VE::SW5, VE::SW6,
99 VE::SW7, VE::SW8, VE::SW9, VE::SW10, VE::SW11, VE::SW12, VE::SW13,
100 VE::SW14, VE::SW15, VE::SW16, VE::SW17, VE::SW18, VE::SW19, VE::SW20,
101 VE::SW21, VE::SW22, VE::SW23, VE::SW24, VE::SW25, VE::SW26, VE::SW27,
102 VE::SW28, VE::SW29, VE::SW30, VE::SW31, VE::SW32, VE::SW33, VE::SW34,
103 VE::SW35, VE::SW36, VE::SW37, VE::SW38, VE::SW39, VE::SW40, VE::SW41,
104 VE::SW42, VE::SW43, VE::SW44, VE::SW45, VE::SW46, VE::SW47, VE::SW48,
105 VE::SW49, VE::SW50, VE::SW51, VE::SW52, VE::SW53, VE::SW54, VE::SW55,
106 VE::SW56, VE::SW57, VE::SW58, VE::SW59, VE::SW60, VE::SW61, VE::SW62,
110 VE::SF0, VE::SF1, VE::SF2, VE::SF3, VE::SF4, VE::SF5, VE::SF6,
111 VE::SF7, VE::SF8, VE::SF9, VE::SF10, VE::SF11, VE::SF12, VE::SF13,
112 VE::SF14, VE::SF15, VE::SF16, VE::SF17, VE::SF18, VE::SF19, VE::SF20,
113 VE::SF21, VE::SF22, VE::SF23, VE::SF24, VE::SF25, VE::SF26, VE::SF27,
114 VE::SF28, VE::SF29, VE::SF30, VE::SF31, VE::SF32, VE::SF33, VE::SF34,
115 VE::SF35, VE::SF36, VE::SF37, VE::SF38, VE::SF39, VE::SF40, VE::SF41,
116 VE::SF42, VE::SF43, VE::SF44, VE::SF45, VE::SF46, VE::SF47, VE::SF48,
117 VE::SF49, VE::SF50, VE::SF51, VE::SF52, VE::SF53, VE::SF54, VE::SF55,
118 VE::SF56, VE::SF57, VE::SF58, VE::SF59, VE::SF60, VE::SF61, VE::SF62,
122 VE::Q0, VE::Q1, VE::Q2, VE::Q3, VE::Q4, VE::Q5, VE::Q6, VE::Q7,
123 VE::Q8, VE::Q9, VE::Q10, VE::Q11, VE::Q12, VE::Q13, VE::Q14, VE::Q15,
124 VE::Q16, VE::Q17, VE::Q18, VE::Q19, VE::Q20, VE::Q21, VE::Q22, VE::Q23,
125 VE::Q24, VE::Q25, VE::Q26, VE::Q27, VE::Q28, VE::Q29, VE::Q30, VE::Q31};
128 VE::VMP4, VE::VMP5, VE::VMP6, VE::VMP7};
131 VE::USRCC, VE::PSW, VE::SAR, VE::NoRegister,
132 VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::PMMR,
133 VE::PMCR0, VE::PMCR1, VE::PMCR2, VE::PMCR3,
134 VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::NoRegister,
135 VE::PMC0, VE::PMC1, VE::PMC2, VE::PMC3,
136 VE::PMC4, VE::PMC5, VE::PMC6, VE::PMC7,
137 VE::PMC8, VE::PMC9, VE::PMC10, VE::PMC11,
138 VE::PMC12, VE::PMC13, VE::PMC14};
164 SMLoc StartLoc, EndLoc;
210 VEOperand(KindTy K) :
Kind(
K) {}
212 bool isToken()
const override {
return Kind == k_Token; }
213 bool isReg()
const override {
return Kind == k_Register; }
214 bool isImm()
const override {
return Kind == k_Immediate; }
215 bool isMem()
const override {
216 return isMEMrri() || isMEMrii() || isMEMzri() || isMEMzii() || isMEMri() ||
219 bool isMEMrri()
const {
return Kind == k_MemoryRegRegImm; }
220 bool isMEMrii()
const {
return Kind == k_MemoryRegImmImm; }
221 bool isMEMzri()
const {
return Kind == k_MemoryZeroRegImm; }
222 bool isMEMzii()
const {
return Kind == k_MemoryZeroImmImm; }
223 bool isMEMri()
const {
return Kind == k_MemoryRegImm; }
224 bool isMEMzi()
const {
return Kind == k_MemoryZeroImm; }
225 bool isCCOp()
const {
return Kind == k_CCOp; }
226 bool isRDOp()
const {
return Kind == k_RDOp; }
232 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
233 int64_t
Value = ConstExpr->getValue();
243 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
244 int64_t
Value = ConstExpr->getValue();
254 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
255 int64_t
Value = ConstExpr->getValue();
256 return isUInt<1>(
Value);
265 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
266 int64_t
Value = ConstExpr->getValue();
267 return isUInt<2>(
Value);
276 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
277 int64_t
Value = ConstExpr->getValue();
278 return isUInt<3>(
Value);
287 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
288 int64_t
Value = ConstExpr->getValue();
289 return isUInt<4>(
Value);
298 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
299 int64_t
Value = ConstExpr->getValue();
300 return isUInt<6>(
Value);
309 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
310 int64_t
Value = ConstExpr->getValue();
311 return isUInt<7>(
Value);
320 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
321 int64_t
Value = ConstExpr->getValue();
322 return isInt<7>(
Value);
327 if (Kind != k_MImmOp)
331 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(MImm.Val)) {
332 int64_t
Value = ConstExpr->getValue();
333 return isUInt<6>(
Value);
339 assert(Kind == k_Token &&
"Invalid access!");
344 assert((Kind == k_Register) &&
"Invalid access!");
349 assert((Kind == k_Immediate) &&
"Invalid access!");
353 unsigned getMemBase()
const {
354 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
355 Kind == k_MemoryRegImm) &&
360 unsigned getMemIndexReg()
const {
361 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryZeroRegImm) &&
366 const MCExpr *getMemIndex()
const {
367 assert((Kind == k_MemoryRegImmImm || Kind == k_MemoryZeroImmImm) &&
372 const MCExpr *getMemOffset()
const {
373 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
374 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm ||
375 Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) &&
380 void setMemOffset(
const MCExpr *off) {
381 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
382 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm ||
383 Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) &&
388 unsigned getCCVal()
const {
389 assert((Kind == k_CCOp) &&
"Invalid access!");
393 unsigned getRDVal()
const {
394 assert((Kind == k_RDOp) &&
"Invalid access!");
398 const MCExpr *getMImmVal()
const {
399 assert((Kind == k_MImmOp) &&
"Invalid access!");
402 bool getM0Flag()
const {
403 assert((Kind == k_MImmOp) &&
"Invalid access!");
415 OS <<
"Token: " << getToken() <<
"\n";
423 case k_MemoryRegRegImm:
424 assert(getMemOffset() !=
nullptr);
425 OS <<
"Mem: #" << getMemBase() <<
"+#" << getMemIndexReg() <<
"+";
429 case k_MemoryRegImmImm:
430 assert(getMemIndex() !=
nullptr && getMemOffset() !=
nullptr);
431 OS <<
"Mem: #" << getMemBase() <<
"+";
437 case k_MemoryZeroRegImm:
438 assert(getMemOffset() !=
nullptr);
439 OS <<
"Mem: 0+#" << getMemIndexReg() <<
"+";
443 case k_MemoryZeroImmImm:
444 assert(getMemIndex() !=
nullptr && getMemOffset() !=
nullptr);
452 assert(getMemOffset() !=
nullptr);
453 OS <<
"Mem: #" << getMemBase() <<
"+";
457 case k_MemoryZeroImm:
458 assert(getMemOffset() !=
nullptr);
464 OS <<
"CCOp: " << getCCVal() <<
"\n";
467 OS <<
"RDOp: " << getRDVal() <<
"\n";
470 OS <<
"MImm: (" << getMImmVal() << (getM0Flag() ?
")0" :
")1") <<
"\n";
475 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
476 assert(
N == 1 &&
"Invalid number of operands!");
480 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
481 assert(
N == 1 &&
"Invalid number of operands!");
486 void addZeroOperands(
MCInst &Inst,
unsigned N)
const {
487 addImmOperands(Inst,
N);
490 void addUImm0to2Operands(
MCInst &Inst,
unsigned N)
const {
491 addImmOperands(Inst,
N);
494 void addUImm1Operands(
MCInst &Inst,
unsigned N)
const {
495 addImmOperands(Inst,
N);
498 void addUImm2Operands(
MCInst &Inst,
unsigned N)
const {
499 addImmOperands(Inst,
N);
502 void addUImm3Operands(
MCInst &Inst,
unsigned N)
const {
503 addImmOperands(Inst,
N);
506 void addUImm4Operands(
MCInst &Inst,
unsigned N)
const {
507 addImmOperands(Inst,
N);
510 void addUImm6Operands(
MCInst &Inst,
unsigned N)
const {
511 addImmOperands(Inst,
N);
514 void addUImm7Operands(
MCInst &Inst,
unsigned N)
const {
515 addImmOperands(Inst,
N);
518 void addSImm7Operands(
MCInst &Inst,
unsigned N)
const {
519 addImmOperands(Inst,
N);
526 else if (
const auto *CE = dyn_cast<MCConstantExpr>(Expr))
532 void addMEMrriOperands(
MCInst &Inst,
unsigned N)
const {
533 assert(
N == 3 &&
"Invalid number of operands!");
537 addExpr(Inst, getMemOffset());
540 void addMEMriiOperands(
MCInst &Inst,
unsigned N)
const {
541 assert(
N == 3 &&
"Invalid number of operands!");
544 addExpr(Inst, getMemIndex());
545 addExpr(Inst, getMemOffset());
548 void addMEMzriOperands(
MCInst &Inst,
unsigned N)
const {
549 assert(
N == 3 &&
"Invalid number of operands!");
553 addExpr(Inst, getMemOffset());
556 void addMEMziiOperands(
MCInst &Inst,
unsigned N)
const {
557 assert(
N == 3 &&
"Invalid number of operands!");
560 addExpr(Inst, getMemIndex());
561 addExpr(Inst, getMemOffset());
564 void addMEMriOperands(
MCInst &Inst,
unsigned N)
const {
565 assert(
N == 2 &&
"Invalid number of operands!");
568 addExpr(Inst, getMemOffset());
571 void addMEMziOperands(
MCInst &Inst,
unsigned N)
const {
572 assert(
N == 2 &&
"Invalid number of operands!");
575 addExpr(Inst, getMemOffset());
578 void addCCOpOperands(
MCInst &Inst,
unsigned N)
const {
579 assert(
N == 1 &&
"Invalid number of operands!");
584 void addRDOpOperands(
MCInst &Inst,
unsigned N)
const {
585 assert(
N == 1 &&
"Invalid number of operands!");
590 void addMImmOperands(
MCInst &Inst,
unsigned N)
const {
591 assert(
N == 1 &&
"Invalid number of operands!");
592 const auto *ConstExpr = dyn_cast<MCConstantExpr>(getMImmVal());
593 assert(ConstExpr &&
"Null operands!");
594 int64_t
Value = ConstExpr->getValue();
600 static std::unique_ptr<VEOperand> CreateToken(
StringRef Str,
SMLoc S) {
601 auto Op = std::make_unique<VEOperand>(k_Token);
602 Op->Tok.Data = Str.data();
603 Op->Tok.Length = Str.size();
609 static std::unique_ptr<VEOperand> CreateReg(
unsigned RegNum,
SMLoc S,
611 auto Op = std::make_unique<VEOperand>(k_Register);
612 Op->Reg.RegNum = RegNum;
618 static std::unique_ptr<VEOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
620 auto Op = std::make_unique<VEOperand>(k_Immediate);
627 static std::unique_ptr<VEOperand> CreateCCOp(
unsigned CCVal,
SMLoc S,
629 auto Op = std::make_unique<VEOperand>(k_CCOp);
630 Op->CC.CCVal = CCVal;
636 static std::unique_ptr<VEOperand> CreateRDOp(
unsigned RDVal,
SMLoc S,
638 auto Op = std::make_unique<VEOperand>(k_RDOp);
639 Op->RD.RDVal = RDVal;
645 static std::unique_ptr<VEOperand> CreateMImm(
const MCExpr *Val,
bool Flag,
647 auto Op = std::make_unique<VEOperand>(k_MImmOp);
655 static bool MorphToI32Reg(VEOperand &
Op) {
656 unsigned Reg =
Op.getReg();
657 unsigned regIdx =
Reg - VE::SX0;
664 static bool MorphToF32Reg(VEOperand &
Op) {
665 unsigned Reg =
Op.getReg();
666 unsigned regIdx =
Reg - VE::SX0;
673 static bool MorphToF128Reg(VEOperand &
Op) {
674 unsigned Reg =
Op.getReg();
675 unsigned regIdx =
Reg - VE::SX0;
676 if (regIdx % 2 || regIdx > 63)
682 static bool MorphToVM512Reg(VEOperand &
Op) {
683 unsigned Reg =
Op.getReg();
684 unsigned regIdx =
Reg - VE::VM0;
685 if (regIdx % 2 || regIdx > 15)
691 static bool MorphToMISCReg(VEOperand &
Op) {
692 const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Op.getImm());
695 unsigned regIdx = ConstExpr->getValue();
696 if (regIdx > 31 ||
MISCRegs[regIdx] == VE::NoRegister)
698 Op.Kind = k_Register;
703 static std::unique_ptr<VEOperand>
704 MorphToMEMri(
unsigned Base, std::unique_ptr<VEOperand>
Op) {
706 Op->Kind = k_MemoryRegImm;
708 Op->Mem.IndexReg = 0;
709 Op->Mem.Index =
nullptr;
710 Op->Mem.Offset =
Imm;
714 static std::unique_ptr<VEOperand>
715 MorphToMEMzi(std::unique_ptr<VEOperand>
Op) {
717 Op->Kind = k_MemoryZeroImm;
719 Op->Mem.IndexReg = 0;
720 Op->Mem.Index =
nullptr;
721 Op->Mem.Offset =
Imm;
725 static std::unique_ptr<VEOperand>
726 MorphToMEMrri(
unsigned Base,
unsigned Index, std::unique_ptr<VEOperand>
Op) {
728 Op->Kind = k_MemoryRegRegImm;
731 Op->Mem.Index =
nullptr;
732 Op->Mem.Offset =
Imm;
736 static std::unique_ptr<VEOperand>
738 std::unique_ptr<VEOperand>
Op) {
740 Op->Kind = k_MemoryRegImmImm;
742 Op->Mem.IndexReg = 0;
744 Op->Mem.Offset =
Imm;
748 static std::unique_ptr<VEOperand>
749 MorphToMEMzri(
unsigned Index, std::unique_ptr<VEOperand>
Op) {
751 Op->Kind = k_MemoryZeroRegImm;
754 Op->Mem.Index =
nullptr;
755 Op->Mem.Offset =
Imm;
759 static std::unique_ptr<VEOperand>
760 MorphToMEMzii(
const MCExpr *
Index, std::unique_ptr<VEOperand>
Op) {
762 Op->Kind = k_MemoryZeroImmImm;
764 Op->Mem.IndexReg = 0;
766 Op->Mem.Offset =
Imm;
773bool VEAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
776 bool MatchingInlineAsm) {
778 unsigned MatchResult =
780 switch (MatchResult) {
786 case Match_MissingFeature:
788 "instruction requires a CPU feature not currently enabled");
790 case Match_InvalidOperand: {
791 SMLoc ErrorLoc = IDLoc;
794 return Error(IDLoc,
"too few operands for instruction");
797 if (ErrorLoc ==
SMLoc())
801 return Error(ErrorLoc,
"invalid operand for instruction");
803 case Match_MnemonicFail:
804 return Error(IDLoc,
"invalid instruction mnemonic");
811 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
812 return Error(StartLoc,
"invalid register name");
821 int RegNum = matchFn(
Name);
825 if (RegNum == VE::NoRegister) {
826 RegNum = matchFn(
Name.lower());
845 Reg = VE::NoRegister;
851 if (
Reg == VE::NoRegister)
854 if (
Reg != VE::NoRegister) {
859 getLexer().UnLex(Tok);
864 bool IntegerCC,
bool OmitCC,
SMLoc NameLoc,
878 Operands->push_back(VEOperand::CreateToken(
Name, NameLoc));
882 Operands->push_back(VEOperand::CreateCCOp(CondCode, CondLoc, SuffixLoc));
884 if (!SuffixStr.
empty())
885 Operands->push_back(VEOperand::CreateToken(SuffixStr, SuffixLoc));
887 Operands->push_back(VEOperand::CreateToken(
Name, NameLoc));
902 Operands->push_back(VEOperand::CreateToken(
Name, NameLoc));
911 Operands->push_back(VEOperand::CreateToken(
Name, NameLoc));
923 if (
Name[0] ==
'b') {
926 size_t Next =
Name.find(
'.');
928 if (
Name.size() > 1 &&
Name[1] ==
'r')
932 if (Next + 1 <
Name.size() &&
933 (
Name[Next + 1] ==
'd' ||
Name[Next + 1] ==
's'))
936 }
else if (
Name.starts_with(
"cmov.l.") ||
Name.starts_with(
"cmov.w.") ||
937 Name.starts_with(
"cmov.d.") ||
Name.starts_with(
"cmov.s.")) {
938 bool ICC =
Name[5] ==
'l' ||
Name[5] ==
'w';
940 }
else if (
Name.starts_with(
"cvt.w.d.sx") ||
Name.starts_with(
"cvt.w.d.zx") ||
941 Name.starts_with(
"cvt.w.s.sx") ||
Name.starts_with(
"cvt.w.s.zx")) {
943 }
else if (
Name.starts_with(
"cvt.l.d")) {
945 }
else if (
Name.starts_with(
"vcvt.w.d.sx") ||
946 Name.starts_with(
"vcvt.w.d.zx") ||
947 Name.starts_with(
"vcvt.w.s.sx") ||
948 Name.starts_with(
"vcvt.w.s.zx")) {
950 }
else if (
Name.starts_with(
"vcvt.l.d")) {
952 }
else if (
Name.starts_with(
"pvcvt.w.s.lo") ||
953 Name.starts_with(
"pvcvt.w.s.up")) {
955 }
else if (
Name.starts_with(
"pvcvt.w.s")) {
957 }
else if (
Name.starts_with(
"vfmk.l.") ||
Name.starts_with(
"vfmk.w.") ||
958 Name.starts_with(
"vfmk.d.") ||
Name.starts_with(
"vfmk.s.")) {
959 bool ICC =
Name[5] ==
'l' ||
Name[5] ==
'w' ?
true :
false;
961 }
else if (
Name.starts_with(
"pvfmk.w.lo.") ||
962 Name.starts_with(
"pvfmk.w.up.") ||
963 Name.starts_with(
"pvfmk.s.lo.") ||
964 Name.starts_with(
"pvfmk.s.up.")) {
965 bool ICC =
Name[6] ==
'l' ||
Name[6] ==
'w' ?
true :
false;
968 Operands->push_back(VEOperand::CreateToken(Mnemonic, NameLoc));
991 if (!parseOperand(
Operands, Mnemonic).isSuccess()) {
992 SMLoc Loc = getLexer().getLoc();
993 return Error(Loc,
"unexpected token");
999 if (!parseOperand(
Operands, Mnemonic).isSuccess()) {
1000 SMLoc Loc = getLexer().getLoc();
1001 return Error(Loc,
"unexpected token");
1006 SMLoc Loc = getLexer().getLoc();
1007 return Error(Loc,
"unexpected token");
1021 if (IDVal ==
".word")
1022 return parseLiteralValues(4, DirectiveID.
getLoc());
1025 if (IDVal ==
".long")
1026 return parseLiteralValues(8, DirectiveID.
getLoc());
1029 if (IDVal ==
".llong")
1030 return parseLiteralValues(8, DirectiveID.
getLoc());
1040bool VEAsmParser::parseLiteralValues(
unsigned Size,
SMLoc L) {
1041 auto parseOne = [&]() ->
bool {
1043 if (getParser().parseExpression(
Value))
1045 getParser().getStreamer().emitValue(
Value,
Size, L);
1048 return (parseMany(parseOne));
1062 switch (
E->getKind()) {
1152 else if (LHSVariant == RHSVariant)
1166bool VEAsmParser::parseExpression(
const MCExpr *&EVal) {
1168 if (getParser().parseExpression(EVal))
1173 const MCExpr *
E = extractSpecifier(EVal, Specifier);
1194 std::unique_ptr<VEOperand>
Offset;
1195 switch (getLexer().getKind()) {
1204 if (!parseExpression(EVal))
1205 Offset = VEOperand::CreateImm(EVal, S,
E);
1218 switch (getLexer().getKind()) {
1223 Operands.push_back(VEOperand::MorphToMEMzii(
1232 const MCExpr *IndexValue =
nullptr;
1235 switch (getLexer().getKind()) {
1237 if (parseRegister(IndexReg, S,
E))
1244 if (getParser().parseExpression(IndexValue,
E))
1254 switch (getLexer().getKind()) {
1261 IndexValue ? VEOperand::MorphToMEMzii(IndexValue, std::move(
Offset))
1262 : VEOperand::MorphToMEMzri(IndexReg, std::move(
Offset)));
1271 if (parseRegister(BaseReg, S,
E))
1280 ? VEOperand::MorphToMEMrii(BaseReg, IndexValue, std::move(
Offset))
1281 : VEOperand::MorphToMEMrri(BaseReg, IndexReg, std::move(
Offset)));
1301 std::unique_ptr<VEOperand>
Offset;
1302 switch (getLexer().getKind()) {
1311 if (!parseExpression(EVal))
1312 Offset = VEOperand::CreateImm(EVal, S,
E);
1319 if (parseRegister(BaseReg, S,
E))
1332 switch (getLexer().getKind()) {
1338 Operands.push_back(BaseReg != VE::NoRegister
1339 ? VEOperand::MorphToMEMri(BaseReg, std::move(
Offset))
1340 : VEOperand::MorphToMEMzi(std::move(
Offset)));
1344 if (BaseReg != VE::NoRegister)
1350 switch (getLexer().getKind()) {
1352 if (parseRegister(BaseReg, S,
E))
1358 if (parseRegister(BaseReg, S,
E))
1370 Operands.push_back(BaseReg != VE::NoRegister
1371 ? VEOperand::MorphToMEMri(BaseReg, std::move(
Offset))
1372 : VEOperand::MorphToMEMzi(std::move(
Offset)));
1391 getLexer().UnLex(Tok1);
1397 getLexer().UnLex(Tok2);
1398 getLexer().UnLex(Tok1);
1405 if (Suffix !=
"1" && Suffix !=
"0") {
1406 getLexer().UnLex(Tok3);
1407 getLexer().UnLex(Tok2);
1408 getLexer().UnLex(Tok1);
1414 VEOperand::CreateMImm(EVal, Suffix ==
"0", Tok1.
getLoc(), EndLoc));
1429 switch (getLexer().getKind()) {
1437 if (!tryParseRegister(Reg1,
S1, E1).isSuccess()) {
1438 getLexer().UnLex(Tok1);
1448 if (!tryParseRegister(Reg2, S2, E2).isSuccess())
1455 Operands.push_back(VEOperand::CreateReg(Reg1,
S1, E1));
1456 Operands.push_back(VEOperand::CreateReg(Reg2, S2, E2));
1463 std::unique_ptr<VEOperand>
Op;
1464 Res = parseVEAsmOperand(
Op);
1475 std::unique_ptr<VEOperand> Op1 = VEOperand::CreateToken(
1479 std::unique_ptr<VEOperand> Op2;
1480 Res = parseVEAsmOperand(Op2);
1487 Operands.push_back(std::move(Op1));
1488 Operands.push_back(std::move(Op2));
1499ParseStatus VEAsmParser::parseVEAsmOperand(std::unique_ptr<VEOperand> &
Op) {
1506 switch (getLexer().getKind()) {
1512 if (tryParseRegister(
Reg, S,
E).isSuccess())
1513 Op = VEOperand::CreateReg(
Reg, S,
E);
1520 if (!parseExpression(EVal))
1521 Op = VEOperand::CreateImm(EVal, S,
E);
1532#define GET_REGISTER_MATCHER
1533#define GET_MATCHER_IMPLEMENTATION
1534#include "VEGenAsmMatcher.inc"
1538 VEOperand &
Op = (VEOperand &)GOp;
1547 if (
Op.isReg() && VEOperand::MorphToF32Reg(
Op))
1551 if (
Op.isReg() && VEOperand::MorphToI32Reg(
Op))
1555 if (
Op.isReg() && VEOperand::MorphToF128Reg(
Op))
1559 if (
Op.isReg() && VEOperand::MorphToVM512Reg(
Op))
1563 if (
Op.isImm() && VEOperand::MorphToMISCReg(
Op))
1567 return Match_InvalidOperand;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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
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]
static const MCPhysReg I32Regs[64]
static StringRef parseRD(StringRef Name, unsigned Prefix, SMLoc NameLoc, OperandVector *Operands)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeVEAsmParser()
static bool isMImm(SDValue V)
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
LLVM_ABI SMLoc getEndLoc() 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.
This class is intended to be used as a base class for asm properties and features specific to the tar...
void printExpr(raw_ostream &, const MCExpr &) const
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 LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI 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.
@ Specifier
Expression with a relocation specifier.
@ 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 bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
virtual void print(raw_ostream &, const MCAsmInfo &) const =0
print - Print a debug representation of the operand to the given stream.
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.
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.
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
uint16_t getSpecifier() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
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 LLVM_ABI 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).
LLVM_ABI std::string lower() const
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)
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheVETarget()
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
static VECC::CondCode stringToVEFCondCode(StringRef S)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
@ Sub
Subtraction of integers.
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,...