33#define DEBUG_TYPE "ve-asmparser"
45#define GET_ASSEMBLER_HEADER
46#include "VEGenAsmMatcher.inc"
54 bool MatchingInlineAsm)
override;
58 SMLoc &EndLoc)
override;
64 unsigned Kind)
override;
73 ParseStatus parseVEAsmOperand(std::unique_ptr<VEOperand> &Operand);
79 bool parseExpression(
const MCExpr *&EVal);
85 bool parseLiteralValues(
unsigned Size,
SMLoc L);
99 VE::SW0, VE::SW1, VE::SW2, VE::SW3, VE::SW4, VE::SW5, VE::SW6,
100 VE::SW7, VE::SW8, VE::SW9, VE::SW10, VE::SW11, VE::SW12, VE::SW13,
101 VE::SW14, VE::SW15, VE::SW16, VE::SW17, VE::SW18, VE::SW19, VE::SW20,
102 VE::SW21, VE::SW22, VE::SW23, VE::SW24, VE::SW25, VE::SW26, VE::SW27,
103 VE::SW28, VE::SW29, VE::SW30, VE::SW31, VE::SW32, VE::SW33, VE::SW34,
104 VE::SW35, VE::SW36, VE::SW37, VE::SW38, VE::SW39, VE::SW40, VE::SW41,
105 VE::SW42, VE::SW43, VE::SW44, VE::SW45, VE::SW46, VE::SW47, VE::SW48,
106 VE::SW49, VE::SW50, VE::SW51, VE::SW52, VE::SW53, VE::SW54, VE::SW55,
107 VE::SW56, VE::SW57, VE::SW58, VE::SW59, VE::SW60, VE::SW61, VE::SW62,
111 VE::SF0, VE::SF1, VE::SF2, VE::SF3, VE::SF4, VE::SF5, VE::SF6,
112 VE::SF7, VE::SF8, VE::SF9, VE::SF10, VE::SF11, VE::SF12, VE::SF13,
113 VE::SF14, VE::SF15, VE::SF16, VE::SF17, VE::SF18, VE::SF19, VE::SF20,
114 VE::SF21, VE::SF22, VE::SF23, VE::SF24, VE::SF25, VE::SF26, VE::SF27,
115 VE::SF28, VE::SF29, VE::SF30, VE::SF31, VE::SF32, VE::SF33, VE::SF34,
116 VE::SF35, VE::SF36, VE::SF37, VE::SF38, VE::SF39, VE::SF40, VE::SF41,
117 VE::SF42, VE::SF43, VE::SF44, VE::SF45, VE::SF46, VE::SF47, VE::SF48,
118 VE::SF49, VE::SF50, VE::SF51, VE::SF52, VE::SF53, VE::SF54, VE::SF55,
119 VE::SF56, VE::SF57, VE::SF58, VE::SF59, VE::SF60, VE::SF61, VE::SF62,
123 VE::Q0, VE::Q1, VE::Q2, VE::Q3, VE::Q4, VE::Q5, VE::Q6, VE::Q7,
124 VE::Q8, VE::Q9, VE::Q10, VE::Q11, VE::Q12, VE::Q13, VE::Q14, VE::Q15,
125 VE::Q16, VE::Q17, VE::Q18, VE::Q19, VE::Q20, VE::Q21, VE::Q22, VE::Q23,
126 VE::Q24, VE::Q25, VE::Q26, VE::Q27, VE::Q28, VE::Q29, VE::Q30, VE::Q31};
129 VE::VMP4, VE::VMP5, VE::VMP6, VE::VMP7};
132 VE::USRCC, VE::PSW, VE::SAR, VE::NoRegister,
133 VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::PMMR,
134 VE::PMCR0, VE::PMCR1, VE::PMCR2, VE::PMCR3,
135 VE::NoRegister, VE::NoRegister, VE::NoRegister, VE::NoRegister,
136 VE::PMC0, VE::PMC1, VE::PMC2, VE::PMC3,
137 VE::PMC4, VE::PMC5, VE::PMC6, VE::PMC7,
138 VE::PMC8, VE::PMC9, VE::PMC10, VE::PMC11,
139 VE::PMC12, VE::PMC13, VE::PMC14};
165 SMLoc StartLoc, EndLoc;
211 VEOperand(KindTy K) :
Kind(
K) {}
213 bool isToken()
const override {
return Kind == k_Token; }
214 bool isReg()
const override {
return Kind == k_Register; }
215 bool isImm()
const override {
return Kind == k_Immediate; }
216 bool isMem()
const override {
217 return isMEMrri() || isMEMrii() || isMEMzri() || isMEMzii() || isMEMri() ||
220 bool isMEMrri()
const {
return Kind == k_MemoryRegRegImm; }
221 bool isMEMrii()
const {
return Kind == k_MemoryRegImmImm; }
222 bool isMEMzri()
const {
return Kind == k_MemoryZeroRegImm; }
223 bool isMEMzii()
const {
return Kind == k_MemoryZeroImmImm; }
224 bool isMEMri()
const {
return Kind == k_MemoryRegImm; }
225 bool isMEMzi()
const {
return Kind == k_MemoryZeroImm; }
226 bool isCCOp()
const {
return Kind == k_CCOp; }
227 bool isRDOp()
const {
return Kind == k_RDOp; }
233 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
234 int64_t
Value = ConstExpr->getValue();
244 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
245 int64_t
Value = ConstExpr->getValue();
255 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
256 int64_t
Value = ConstExpr->getValue();
257 return isUInt<1>(
Value);
266 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
267 int64_t
Value = ConstExpr->getValue();
268 return isUInt<2>(
Value);
277 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
278 int64_t
Value = ConstExpr->getValue();
279 return isUInt<3>(
Value);
288 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
289 int64_t
Value = ConstExpr->getValue();
290 return isUInt<4>(
Value);
299 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
300 int64_t
Value = ConstExpr->getValue();
301 return isUInt<6>(
Value);
310 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
311 int64_t
Value = ConstExpr->getValue();
312 return isUInt<7>(
Value);
321 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Imm.Val)) {
322 int64_t
Value = ConstExpr->getValue();
323 return isInt<7>(
Value);
328 if (Kind != k_MImmOp)
332 if (
const auto *ConstExpr = dyn_cast<MCConstantExpr>(MImm.Val)) {
333 int64_t
Value = ConstExpr->getValue();
334 return isUInt<6>(
Value);
340 assert(Kind == k_Token &&
"Invalid access!");
345 assert((Kind == k_Register) &&
"Invalid access!");
349 const MCExpr *getImm()
const {
350 assert((Kind == k_Immediate) &&
"Invalid access!");
354 unsigned getMemBase()
const {
355 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
356 Kind == k_MemoryRegImm) &&
361 unsigned getMemIndexReg()
const {
362 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryZeroRegImm) &&
367 const MCExpr *getMemIndex()
const {
368 assert((Kind == k_MemoryRegImmImm || Kind == k_MemoryZeroImmImm) &&
373 const MCExpr *getMemOffset()
const {
374 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
375 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm ||
376 Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) &&
381 void setMemOffset(
const MCExpr *off) {
382 assert((Kind == k_MemoryRegRegImm || Kind == k_MemoryRegImmImm ||
383 Kind == k_MemoryZeroImmImm || Kind == k_MemoryZeroRegImm ||
384 Kind == k_MemoryRegImm || Kind == k_MemoryZeroImm) &&
389 unsigned getCCVal()
const {
390 assert((Kind == k_CCOp) &&
"Invalid access!");
394 unsigned getRDVal()
const {
395 assert((Kind == k_RDOp) &&
"Invalid access!");
399 const MCExpr *getMImmVal()
const {
400 assert((Kind == k_MImmOp) &&
"Invalid access!");
403 bool getM0Flag()
const {
404 assert((Kind == k_MImmOp) &&
"Invalid access!");
416 OS <<
"Token: " << getToken() <<
"\n";
422 OS <<
"Imm: " << getImm() <<
"\n";
424 case k_MemoryRegRegImm:
425 assert(getMemOffset() !=
nullptr);
426 OS <<
"Mem: #" << getMemBase() <<
"+#" << getMemIndexReg() <<
"+"
427 << *getMemOffset() <<
"\n";
429 case k_MemoryRegImmImm:
430 assert(getMemIndex() !=
nullptr && getMemOffset() !=
nullptr);
431 OS <<
"Mem: #" << getMemBase() <<
"+" << *getMemIndex() <<
"+"
432 << *getMemOffset() <<
"\n";
434 case k_MemoryZeroRegImm:
435 assert(getMemOffset() !=
nullptr);
436 OS <<
"Mem: 0+#" << getMemIndexReg() <<
"+" << *getMemOffset() <<
"\n";
438 case k_MemoryZeroImmImm:
439 assert(getMemIndex() !=
nullptr && getMemOffset() !=
nullptr);
440 OS <<
"Mem: 0+" << *getMemIndex() <<
"+" << *getMemOffset() <<
"\n";
443 assert(getMemOffset() !=
nullptr);
444 OS <<
"Mem: #" << getMemBase() <<
"+" << *getMemOffset() <<
"\n";
446 case k_MemoryZeroImm:
447 assert(getMemOffset() !=
nullptr);
448 OS <<
"Mem: 0+" << *getMemOffset() <<
"\n";
451 OS <<
"CCOp: " << getCCVal() <<
"\n";
454 OS <<
"RDOp: " << getRDVal() <<
"\n";
457 OS <<
"MImm: (" << getMImmVal() << (getM0Flag() ?
")0" :
")1") <<
"\n";
462 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
463 assert(
N == 1 &&
"Invalid number of operands!");
467 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
468 assert(
N == 1 &&
"Invalid number of operands!");
469 const MCExpr *Expr = getImm();
473 void addZeroOperands(
MCInst &Inst,
unsigned N)
const {
474 addImmOperands(Inst,
N);
477 void addUImm0to2Operands(
MCInst &Inst,
unsigned N)
const {
478 addImmOperands(Inst,
N);
481 void addUImm1Operands(
MCInst &Inst,
unsigned N)
const {
482 addImmOperands(Inst,
N);
485 void addUImm2Operands(
MCInst &Inst,
unsigned N)
const {
486 addImmOperands(Inst,
N);
489 void addUImm3Operands(
MCInst &Inst,
unsigned N)
const {
490 addImmOperands(Inst,
N);
493 void addUImm4Operands(
MCInst &Inst,
unsigned N)
const {
494 addImmOperands(Inst,
N);
497 void addUImm6Operands(
MCInst &Inst,
unsigned N)
const {
498 addImmOperands(Inst,
N);
501 void addUImm7Operands(
MCInst &Inst,
unsigned N)
const {
502 addImmOperands(Inst,
N);
505 void addSImm7Operands(
MCInst &Inst,
unsigned N)
const {
506 addImmOperands(Inst,
N);
513 else if (
const auto *CE = dyn_cast<MCConstantExpr>(Expr))
519 void addMEMrriOperands(
MCInst &Inst,
unsigned N)
const {
520 assert(
N == 3 &&
"Invalid number of operands!");
524 addExpr(Inst, getMemOffset());
527 void addMEMriiOperands(
MCInst &Inst,
unsigned N)
const {
528 assert(
N == 3 &&
"Invalid number of operands!");
531 addExpr(Inst, getMemIndex());
532 addExpr(Inst, getMemOffset());
535 void addMEMzriOperands(
MCInst &Inst,
unsigned N)
const {
536 assert(
N == 3 &&
"Invalid number of operands!");
540 addExpr(Inst, getMemOffset());
543 void addMEMziiOperands(
MCInst &Inst,
unsigned N)
const {
544 assert(
N == 3 &&
"Invalid number of operands!");
547 addExpr(Inst, getMemIndex());
548 addExpr(Inst, getMemOffset());
551 void addMEMriOperands(
MCInst &Inst,
unsigned N)
const {
552 assert(
N == 2 &&
"Invalid number of operands!");
555 addExpr(Inst, getMemOffset());
558 void addMEMziOperands(
MCInst &Inst,
unsigned N)
const {
559 assert(
N == 2 &&
"Invalid number of operands!");
562 addExpr(Inst, getMemOffset());
565 void addCCOpOperands(
MCInst &Inst,
unsigned N)
const {
566 assert(
N == 1 &&
"Invalid number of operands!");
571 void addRDOpOperands(
MCInst &Inst,
unsigned N)
const {
572 assert(
N == 1 &&
"Invalid number of operands!");
577 void addMImmOperands(
MCInst &Inst,
unsigned N)
const {
578 assert(
N == 1 &&
"Invalid number of operands!");
579 const auto *ConstExpr = dyn_cast<MCConstantExpr>(getMImmVal());
580 assert(ConstExpr &&
"Null operands!");
581 int64_t
Value = ConstExpr->getValue();
587 static std::unique_ptr<VEOperand> CreateToken(
StringRef Str,
SMLoc S) {
588 auto Op = std::make_unique<VEOperand>(k_Token);
589 Op->Tok.Data = Str.data();
590 Op->Tok.Length = Str.size();
596 static std::unique_ptr<VEOperand> CreateReg(
unsigned RegNum,
SMLoc S,
598 auto Op = std::make_unique<VEOperand>(k_Register);
599 Op->Reg.RegNum = RegNum;
605 static std::unique_ptr<VEOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
607 auto Op = std::make_unique<VEOperand>(k_Immediate);
614 static std::unique_ptr<VEOperand> CreateCCOp(
unsigned CCVal,
SMLoc S,
616 auto Op = std::make_unique<VEOperand>(k_CCOp);
617 Op->CC.CCVal = CCVal;
623 static std::unique_ptr<VEOperand> CreateRDOp(
unsigned RDVal,
SMLoc S,
625 auto Op = std::make_unique<VEOperand>(k_RDOp);
626 Op->RD.RDVal = RDVal;
632 static std::unique_ptr<VEOperand> CreateMImm(
const MCExpr *Val,
bool Flag,
634 auto Op = std::make_unique<VEOperand>(k_MImmOp);
642 static bool MorphToI32Reg(VEOperand &
Op) {
643 unsigned Reg =
Op.getReg();
644 unsigned regIdx =
Reg - VE::SX0;
651 static bool MorphToF32Reg(VEOperand &
Op) {
652 unsigned Reg =
Op.getReg();
653 unsigned regIdx =
Reg - VE::SX0;
660 static bool MorphToF128Reg(VEOperand &
Op) {
661 unsigned Reg =
Op.getReg();
662 unsigned regIdx =
Reg - VE::SX0;
663 if (regIdx % 2 || regIdx > 63)
669 static bool MorphToVM512Reg(VEOperand &
Op) {
670 unsigned Reg =
Op.getReg();
671 unsigned regIdx =
Reg - VE::VM0;
672 if (regIdx % 2 || regIdx > 15)
678 static bool MorphToMISCReg(VEOperand &
Op) {
679 const auto *ConstExpr = dyn_cast<MCConstantExpr>(
Op.getImm());
682 unsigned regIdx = ConstExpr->getValue();
683 if (regIdx > 31 ||
MISCRegs[regIdx] == VE::NoRegister)
685 Op.Kind = k_Register;
690 static std::unique_ptr<VEOperand>
691 MorphToMEMri(
unsigned Base, std::unique_ptr<VEOperand>
Op) {
693 Op->Kind = k_MemoryRegImm;
695 Op->Mem.IndexReg = 0;
696 Op->Mem.Index =
nullptr;
697 Op->Mem.Offset =
Imm;
701 static std::unique_ptr<VEOperand>
702 MorphToMEMzi(std::unique_ptr<VEOperand>
Op) {
704 Op->Kind = k_MemoryZeroImm;
706 Op->Mem.IndexReg = 0;
707 Op->Mem.Index =
nullptr;
708 Op->Mem.Offset =
Imm;
712 static std::unique_ptr<VEOperand>
713 MorphToMEMrri(
unsigned Base,
unsigned Index, std::unique_ptr<VEOperand>
Op) {
715 Op->Kind = k_MemoryRegRegImm;
718 Op->Mem.Index =
nullptr;
719 Op->Mem.Offset =
Imm;
723 static std::unique_ptr<VEOperand>
725 std::unique_ptr<VEOperand>
Op) {
727 Op->Kind = k_MemoryRegImmImm;
729 Op->Mem.IndexReg = 0;
731 Op->Mem.Offset =
Imm;
735 static std::unique_ptr<VEOperand>
736 MorphToMEMzri(
unsigned Index, std::unique_ptr<VEOperand>
Op) {
738 Op->Kind = k_MemoryZeroRegImm;
741 Op->Mem.Index =
nullptr;
742 Op->Mem.Offset =
Imm;
746 static std::unique_ptr<VEOperand>
747 MorphToMEMzii(
const MCExpr *
Index, std::unique_ptr<VEOperand>
Op) {
749 Op->Kind = k_MemoryZeroImmImm;
751 Op->Mem.IndexReg = 0;
753 Op->Mem.Offset =
Imm;
760bool VEAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
763 bool MatchingInlineAsm) {
765 unsigned MatchResult =
767 switch (MatchResult) {
773 case Match_MissingFeature:
775 "instruction requires a CPU feature not currently enabled");
777 case Match_InvalidOperand: {
778 SMLoc ErrorLoc = IDLoc;
781 return Error(IDLoc,
"too few operands for instruction");
784 if (ErrorLoc ==
SMLoc())
788 return Error(ErrorLoc,
"invalid operand for instruction");
790 case Match_MnemonicFail:
791 return Error(IDLoc,
"invalid instruction mnemonic");
798 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
799 return Error(StartLoc,
"invalid register name");
808 int RegNum = matchFn(
Name);
812 if (RegNum == VE::NoRegister) {
813 RegNum = matchFn(
Name.lower());
832 Reg = VE::NoRegister;
838 if (
Reg == VE::NoRegister)
841 if (
Reg != VE::NoRegister) {
846 getLexer().UnLex(Tok);
851 bool IntegerCC,
bool OmitCC,
SMLoc NameLoc,
865 Operands->push_back(VEOperand::CreateToken(
Name, NameLoc));
869 Operands->push_back(VEOperand::CreateCCOp(CondCode, CondLoc, SuffixLoc));
871 if (!SuffixStr.
empty())
872 Operands->push_back(VEOperand::CreateToken(SuffixStr, SuffixLoc));
874 Operands->push_back(VEOperand::CreateToken(
Name, NameLoc));
889 Operands->push_back(VEOperand::CreateToken(
Name, NameLoc));
898 Operands->push_back(VEOperand::CreateToken(
Name, NameLoc));
910 if (
Name[0] ==
'b') {
913 size_t Next =
Name.find(
'.');
915 if (
Name.size() > 1 &&
Name[1] ==
'r')
919 if (Next + 1 <
Name.size() &&
920 (
Name[Next + 1] ==
'd' ||
Name[Next + 1] ==
's'))
923 }
else if (
Name.starts_with(
"cmov.l.") ||
Name.starts_with(
"cmov.w.") ||
924 Name.starts_with(
"cmov.d.") ||
Name.starts_with(
"cmov.s.")) {
925 bool ICC =
Name[5] ==
'l' ||
Name[5] ==
'w';
927 }
else if (
Name.starts_with(
"cvt.w.d.sx") ||
Name.starts_with(
"cvt.w.d.zx") ||
928 Name.starts_with(
"cvt.w.s.sx") ||
Name.starts_with(
"cvt.w.s.zx")) {
930 }
else if (
Name.starts_with(
"cvt.l.d")) {
932 }
else if (
Name.starts_with(
"vcvt.w.d.sx") ||
933 Name.starts_with(
"vcvt.w.d.zx") ||
934 Name.starts_with(
"vcvt.w.s.sx") ||
935 Name.starts_with(
"vcvt.w.s.zx")) {
937 }
else if (
Name.starts_with(
"vcvt.l.d")) {
939 }
else if (
Name.starts_with(
"pvcvt.w.s.lo") ||
940 Name.starts_with(
"pvcvt.w.s.up")) {
942 }
else if (
Name.starts_with(
"pvcvt.w.s")) {
944 }
else if (
Name.starts_with(
"vfmk.l.") ||
Name.starts_with(
"vfmk.w.") ||
945 Name.starts_with(
"vfmk.d.") ||
Name.starts_with(
"vfmk.s.")) {
946 bool ICC =
Name[5] ==
'l' ||
Name[5] ==
'w' ?
true :
false;
948 }
else if (
Name.starts_with(
"pvfmk.w.lo.") ||
949 Name.starts_with(
"pvfmk.w.up.") ||
950 Name.starts_with(
"pvfmk.s.lo.") ||
951 Name.starts_with(
"pvfmk.s.up.")) {
952 bool ICC =
Name[6] ==
'l' ||
Name[6] ==
'w' ?
true :
false;
955 Operands->push_back(VEOperand::CreateToken(Mnemonic, NameLoc));
978 if (!parseOperand(
Operands, Mnemonic).isSuccess()) {
979 SMLoc Loc = getLexer().getLoc();
980 return Error(Loc,
"unexpected token");
986 if (!parseOperand(
Operands, Mnemonic).isSuccess()) {
987 SMLoc Loc = getLexer().getLoc();
988 return Error(Loc,
"unexpected token");
993 SMLoc Loc = getLexer().getLoc();
994 return Error(Loc,
"unexpected token");
1008 if (IDVal ==
".word")
1009 return parseLiteralValues(4, DirectiveID.
getLoc());
1012 if (IDVal ==
".long")
1013 return parseLiteralValues(8, DirectiveID.
getLoc());
1016 if (IDVal ==
".llong")
1017 return parseLiteralValues(8, DirectiveID.
getLoc());
1027bool VEAsmParser::parseLiteralValues(
unsigned Size,
SMLoc L) {
1028 auto parseOne = [&]() ->
bool {
1030 if (getParser().parseExpression(
Value))
1032 getParser().getStreamer().emitValue(
Value,
Size, L);
1035 return (parseMany(parseOne));
1045VEAsmParser::extractModifierFromExpr(
const MCExpr *
E,
1047 MCContext &Context = getParser().getContext();
1050 switch (
E->getKind()) {
1123 const MCExpr *
LHS = extractModifierFromExpr(BE->
getLHS(), LHSVariant);
1124 const MCExpr *
RHS = extractModifierFromExpr(BE->
getRHS(), RHSVariant);
1138 else if (LHSVariant == RHSVariant)
1150const MCExpr *VEAsmParser::fixupVariantKind(
const MCExpr *
E) {
1151 MCContext &Context = getParser().getContext();
1153 switch (
E->getKind()) {
1182bool VEAsmParser::parseExpression(
const MCExpr *&EVal) {
1184 if (getParser().parseExpression(EVal))
1188 EVal = fixupVariantKind(EVal);
1190 const MCExpr *
E = extractModifierFromExpr(EVal, Variant);
1211 std::unique_ptr<VEOperand>
Offset;
1212 switch (getLexer().getKind()) {
1221 if (!parseExpression(EVal))
1222 Offset = VEOperand::CreateImm(EVal, S,
E);
1235 switch (getLexer().getKind()) {
1240 Operands.push_back(VEOperand::MorphToMEMzii(
1249 const MCExpr *IndexValue =
nullptr;
1252 switch (getLexer().getKind()) {
1254 if (parseRegister(IndexReg, S,
E))
1261 if (getParser().parseExpression(IndexValue,
E))
1271 switch (getLexer().getKind()) {
1278 IndexValue ? VEOperand::MorphToMEMzii(IndexValue, std::move(
Offset))
1279 : VEOperand::MorphToMEMzri(IndexReg, std::move(
Offset)));
1288 if (parseRegister(BaseReg, S,
E))
1297 ? VEOperand::MorphToMEMrii(BaseReg, IndexValue, std::move(
Offset))
1298 : VEOperand::MorphToMEMrri(BaseReg, IndexReg, std::move(
Offset)));
1318 std::unique_ptr<VEOperand>
Offset;
1319 switch (getLexer().getKind()) {
1328 if (!parseExpression(EVal))
1329 Offset = VEOperand::CreateImm(EVal, S,
E);
1336 if (parseRegister(BaseReg, S,
E))
1349 switch (getLexer().getKind()) {
1355 Operands.push_back(BaseReg != VE::NoRegister
1356 ? VEOperand::MorphToMEMri(BaseReg, std::move(
Offset))
1357 : VEOperand::MorphToMEMzi(std::move(
Offset)));
1361 if (BaseReg != VE::NoRegister)
1367 switch (getLexer().getKind()) {
1369 if (parseRegister(BaseReg, S,
E))
1375 if (parseRegister(BaseReg, S,
E))
1387 Operands.push_back(BaseReg != VE::NoRegister
1388 ? VEOperand::MorphToMEMri(BaseReg, std::move(
Offset))
1389 : VEOperand::MorphToMEMzi(std::move(
Offset)));
1408 getLexer().UnLex(Tok1);
1414 getLexer().UnLex(Tok2);
1415 getLexer().UnLex(Tok1);
1422 if (Suffix !=
"1" && Suffix !=
"0") {
1423 getLexer().UnLex(Tok3);
1424 getLexer().UnLex(Tok2);
1425 getLexer().UnLex(Tok1);
1431 VEOperand::CreateMImm(EVal, Suffix ==
"0", Tok1.
getLoc(), EndLoc));
1446 switch (getLexer().getKind()) {
1454 if (!tryParseRegister(Reg1,
S1, E1).isSuccess()) {
1455 getLexer().UnLex(Tok1);
1465 if (!tryParseRegister(Reg2, S2, E2).isSuccess())
1472 Operands.push_back(VEOperand::CreateReg(Reg1,
S1, E1));
1473 Operands.push_back(VEOperand::CreateReg(Reg2, S2, E2));
1480 std::unique_ptr<VEOperand>
Op;
1481 Res = parseVEAsmOperand(
Op);
1492 std::unique_ptr<VEOperand> Op1 = VEOperand::CreateToken(
1496 std::unique_ptr<VEOperand> Op2;
1497 Res = parseVEAsmOperand(Op2);
1504 Operands.push_back(std::move(Op1));
1505 Operands.push_back(std::move(Op2));
1516ParseStatus VEAsmParser::parseVEAsmOperand(std::unique_ptr<VEOperand> &
Op) {
1523 switch (getLexer().getKind()) {
1529 if (tryParseRegister(
Reg, S,
E).isSuccess())
1530 Op = VEOperand::CreateReg(
Reg, S,
E);
1537 if (!parseExpression(EVal))
1538 Op = VEOperand::CreateImm(EVal, S,
E);
1549#define GET_REGISTER_MATCHER
1550#define GET_MATCHER_IMPLEMENTATION
1551#include "VEGenAsmMatcher.inc"
1555 VEOperand &
Op = (VEOperand &)GOp;
1564 if (
Op.isReg() && VEOperand::MorphToF32Reg(
Op))
1568 if (
Op.isReg() && VEOperand::MorphToI32Reg(
Op))
1572 if (
Op.isReg() && VEOperand::MorphToF128Reg(
Op))
1576 if (
Op.isReg() && VEOperand::MorphToVM512Reg(
Op))
1580 if (
Op.isImm() && VEOperand::MorphToMISCReg(
Op))
1584 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 createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool isMem() const =0
isMem - Is this a memory operand?
virtual MCRegister getReg() const =0
virtual void print(raw_ostream &OS) const =0
print - Print a debug representation of the operand to the given stream.
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this operand.
Wrapper class representing physical registers. Should be passed by value.
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
const MCSymbol & getSymbol() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
VariantKind getKind() const
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual ParseStatus parseDirective(AsmToken DirectiveID)
Parses a target-specific assembler directive.
virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
Unary assembler expressions.
Opcode getOpcode() const
Get the kind of this unary expression.
static const MCUnaryExpr * create(Opcode Op, const MCExpr *Expr, MCContext &Ctx, SMLoc Loc=SMLoc())
const MCExpr * getSubExpr() const
Get the child of this unary expression.
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
std::string lower() const
static const VEMCExpr * create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::variant< std::monostate, Loc::Single, Loc::Multi, Loc::MMI, Loc::EntryValue > Variant
Alias for the std::variant specialization base class of DbgVariable.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheVETarget()
static VECC::CondCode stringToVEFCondCode(StringRef S)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
DWARFExpression::Operation Op
RoundingMode
Rounding mode.
static VERD::RoundingMode stringToVERD(StringRef S)
static VECC::CondCode stringToVEICondCode(StringRef S)
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...