56 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
61 unsigned matchRegisterNameAlias(
StringRef Name,
bool isVector);
62 int tryParseRegister();
65 bool parseSymbolicImmVal(
const MCExpr *&ImmVal);
70 void Warning(
SMLoc L,
const Twine &Msg) { getParser().Warning(L, Msg); }
71 bool Error(
SMLoc L,
const Twine &Msg) {
return getParser().Error(L, Msg); }
72 bool showMatchError(
SMLoc Loc,
unsigned ErrCode);
74 bool parseDirectiveWord(
unsigned Size,
SMLoc L);
75 bool parseDirectiveInst(
SMLoc L);
77 bool parseDirectiveTLSDescCall(
SMLoc L);
80 bool parseDirectiveLtorg(
SMLoc L);
83 bool parseDirectiveUnreq(
SMLoc L);
86 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
89 bool MatchingInlineAsm)
override;
93 #define GET_ASSEMBLER_HEADER
94 #include "AArch64GenAsmMatcher.inc"
113 enum AArch64MatchResultTy {
114 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
115 #define GET_OPERAND_DIAGNOSTIC_TYPES
116 #include "AArch64GenAsmMatcher.inc"
127 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
132 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
133 bool ParseDirective(
AsmToken DirectiveID)
override;
135 unsigned Kind)
override;
137 static bool classifySymbolRef(
const MCExpr *Expr,
166 SMLoc StartLoc, EndLoc;
179 struct VectorListOp {
182 unsigned NumElements;
183 unsigned ElementKind;
186 struct VectorIndexOp {
194 struct ShiftedImmOp {
196 unsigned ShiftAmount;
218 uint32_t PStateField;
231 struct ShiftExtendOp {
234 bool HasExplicitAmount;
244 struct VectorListOp VectorList;
245 struct VectorIndexOp VectorIndex;
247 struct ShiftedImmOp ShiftedImm;
249 struct FPImmOp FPImm;
251 struct SysRegOp SysReg;
252 struct SysCRImmOp SysCRImm;
254 struct ShiftExtendOp ShiftExtend;
262 AArch64Operand(KindTy K,
MCContext &Ctx) :
Kind(K), Ctx(Ctx) {}
266 StartLoc = o.StartLoc;
276 ShiftedImm = o.ShiftedImm;
291 VectorList = o.VectorList;
294 VectorIndex = o.VectorIndex;
300 SysCRImm = o.SysCRImm;
306 ShiftExtend = o.ShiftExtend;
312 SMLoc getStartLoc()
const override {
return StartLoc; }
314 SMLoc getEndLoc()
const override {
return EndLoc; }
317 assert(
Kind == k_Token &&
"Invalid access!");
321 bool isTokenSuffix()
const {
322 assert(
Kind == k_Token &&
"Invalid access!");
326 const MCExpr *getImm()
const {
327 assert(
Kind == k_Immediate &&
"Invalid access!");
331 const MCExpr *getShiftedImmVal()
const {
332 assert(
Kind == k_ShiftedImm &&
"Invalid access!");
333 return ShiftedImm.Val;
336 unsigned getShiftedImmShift()
const {
337 assert(
Kind == k_ShiftedImm &&
"Invalid access!");
338 return ShiftedImm.ShiftAmount;
342 assert(
Kind == k_CondCode &&
"Invalid access!");
346 unsigned getFPImm()
const {
347 assert(
Kind == k_FPImm &&
"Invalid access!");
351 unsigned getBarrier()
const {
352 assert(
Kind == k_Barrier &&
"Invalid access!");
357 assert(
Kind == k_Barrier &&
"Invalid access!");
361 unsigned getReg()
const override {
362 assert(
Kind == k_Register &&
"Invalid access!");
366 unsigned getVectorListStart()
const {
367 assert(
Kind == k_VectorList &&
"Invalid access!");
368 return VectorList.RegNum;
371 unsigned getVectorListCount()
const {
372 assert(
Kind == k_VectorList &&
"Invalid access!");
373 return VectorList.Count;
376 unsigned getVectorIndex()
const {
377 assert(
Kind == k_VectorIndex &&
"Invalid access!");
378 return VectorIndex.Val;
382 assert(
Kind == k_SysReg &&
"Invalid access!");
383 return StringRef(SysReg.Data, SysReg.Length);
386 unsigned getSysCR()
const {
387 assert(
Kind == k_SysCR &&
"Invalid access!");
391 unsigned getPrefetch()
const {
392 assert(
Kind == k_Prefetch &&
"Invalid access!");
397 assert(
Kind == k_Prefetch &&
"Invalid access!");
402 assert(
Kind == k_ShiftExtend &&
"Invalid access!");
403 return ShiftExtend.Type;
406 unsigned getShiftExtendAmount()
const {
407 assert(
Kind == k_ShiftExtend &&
"Invalid access!");
408 return ShiftExtend.Amount;
411 bool hasShiftExtendAmount()
const {
412 assert(
Kind == k_ShiftExtend &&
"Invalid access!");
413 return ShiftExtend.HasExplicitAmount;
416 bool isImm()
const override {
return Kind == k_Immediate; }
417 bool isMem()
const override {
return false; }
418 bool isSImm9()
const {
425 return (Val >= -256 && Val < 256);
427 bool isSImm7s4()
const {
434 return (Val >= -256 && Val <= 252 && (Val & 3) == 0);
436 bool isSImm7s8()
const {
443 return (Val >= -512 && Val <= 504 && (Val & 7) == 0);
445 bool isSImm7s16()
const {
452 return (Val >= -1024 && Val <= 1008 && (Val & 15) == 0);
455 bool isSymbolicUImm12Offset(
const MCExpr *Expr,
unsigned Scale)
const {
459 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
478 return Addend >= 0 && (Addend % Scale) == 0;
488 template <
int Scale>
bool isUImm12Offset()
const {
494 return isSymbolicUImm12Offset(getImm(), Scale);
497 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
500 bool isImm0_7()
const {
507 return (Val >= 0 && Val < 8);
509 bool isImm1_8()
const {
516 return (Val > 0 && Val < 9);
518 bool isImm0_15()
const {
525 return (Val >= 0 && Val < 16);
527 bool isImm1_16()
const {
534 return (Val > 0 && Val < 17);
536 bool isImm0_31()
const {
543 return (Val >= 0 && Val < 32);
545 bool isImm1_31()
const {
552 return (Val >= 1 && Val < 32);
554 bool isImm1_32()
const {
561 return (Val >= 1 && Val < 33);
563 bool isImm0_63()
const {
570 return (Val >= 0 && Val < 64);
572 bool isImm1_63()
const {
579 return (Val >= 1 && Val < 64);
581 bool isImm1_64()
const {
588 return (Val >= 1 && Val < 65);
590 bool isImm0_127()
const {
597 return (Val >= 0 && Val < 128);
599 bool isImm0_255()
const {
606 return (Val >= 0 && Val < 256);
608 bool isImm0_65535()
const {
615 return (Val >= 0 && Val < 65536);
617 bool isImm32_63()
const {
624 return (Val >= 32 && Val < 64);
626 bool isLogicalImm32()
const {
633 if (Val >> 32 != 0 && Val >> 32 != ~0LL)
638 bool isLogicalImm64()
const {
646 bool isLogicalImm32Not()
const {
652 int64_t Val = ~MCE->
getValue() & 0xFFFFFFFF;
655 bool isLogicalImm64Not()
const {
663 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
664 bool isAddSubImm()
const {
665 if (!isShiftedImm() && !isImm())
671 if (isShiftedImm()) {
672 unsigned Shift = ShiftedImm.ShiftAmount;
673 Expr = ShiftedImm.Val;
674 if (Shift != 0 && Shift != 12)
683 if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
684 DarwinRefKind, Addend)) {
702 bool isAddSubImmNeg()
const {
703 if (!isShiftedImm() && !isImm())
709 if (isShiftedImm()) {
710 unsigned Shift = ShiftedImm.ShiftAmount;
711 Expr = ShiftedImm.Val;
712 if (Shift != 0 && Shift != 12)
721 bool isCondCode()
const {
return Kind == k_CondCode; }
722 bool isSIMDImmType10()
const {
730 bool isBranchTarget26()
const {
739 return (Val >= -(0x2000000 << 2) && Val <= (0x1ffffff << 2));
741 bool isPCRelLabel19()
const {
750 return (Val >= -(0x40000 << 2) && Val <= (0x3ffff << 2));
752 bool isBranchTarget14()
const {
761 return (Val >= -(0x2000 << 2) && Val <= (0x1fff << 2));
772 if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind,
773 DarwinRefKind, Addend)) {
779 for (
unsigned i = 0; i != AllowedModifiers.
size(); ++i) {
780 if (ELFRefKind == AllowedModifiers[i])
787 bool isMovZSymbolG3()
const {
791 bool isMovZSymbolG2()
const {
797 bool isMovZSymbolG1()
const {
798 return isMovWSymbol({
805 bool isMovZSymbolG0()
const {
811 bool isMovKSymbolG3()
const {
815 bool isMovKSymbolG2()
const {
819 bool isMovKSymbolG1()
const {
825 bool isMovKSymbolG0()
const {
831 template<
int RegW
idth,
int Shift>
832 bool isMOVZMovAlias()
const {
833 if (!isImm())
return false;
836 if (!CE)
return false;
840 Value &= 0xffffffffULL;
843 if (Value == 0 && Shift != 0)
846 return (Value & ~(0xffffULL << Shift)) == 0;
849 template<
int RegW
idth,
int Shift>
850 bool isMOVNMovAlias()
const {
851 if (!isImm())
return false;
854 if (!CE)
return false;
858 for (
int MOVZShift = 0; MOVZShift <= 48; MOVZShift += 16)
859 if ((Value & ~(0xffffULL << MOVZShift)) == 0)
864 Value &= 0xffffffffULL;
866 return (Value & ~(0xffffULL << Shift)) == 0;
869 bool isFPImm()
const {
return Kind == k_FPImm; }
870 bool isBarrier()
const {
return Kind == k_Barrier; }
871 bool isSysReg()
const {
return Kind == k_SysReg; }
872 bool isMRSSystemRegister()
const {
873 if (!isSysReg())
return false;
875 return SysReg.MRSReg != -1U;
877 bool isMSRSystemRegister()
const {
878 if (!isSysReg())
return false;
880 return SysReg.MSRReg != -1U;
882 bool isSystemPStateField()
const {
883 if (!isSysReg())
return false;
885 return SysReg.PStateField != -1U;
887 bool isReg()
const override {
return Kind == k_Register && !
Reg.isVector; }
888 bool isVectorReg()
const {
return Kind == k_Register &&
Reg.isVector; }
889 bool isVectorRegLo()
const {
890 return Kind == k_Register &&
Reg.isVector &&
891 AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
894 bool isGPR32as64()
const {
895 return Kind == k_Register && !
Reg.isVector &&
896 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(
Reg.RegNum);
898 bool isWSeqPair()
const {
899 return Kind == k_Register && !
Reg.isVector &&
900 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
903 bool isXSeqPair()
const {
904 return Kind == k_Register && !
Reg.isVector &&
905 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
909 bool isGPR64sp0()
const {
910 return Kind == k_Register && !
Reg.isVector &&
911 AArch64MCRegisterClasses[AArch64::GPR64spRegClassID].contains(
Reg.RegNum);
916 template <
unsigned NumRegs>
bool isImplicitlyTypedVectorList()
const {
917 return Kind == k_VectorList && VectorList.Count == NumRegs &&
918 !VectorList.ElementKind;
921 template <
unsigned NumRegs,
unsigned NumElements,
char ElementKind>
922 bool isTypedVectorList()
const {
923 if (
Kind != k_VectorList)
925 if (VectorList.Count != NumRegs)
927 if (VectorList.ElementKind != ElementKind)
929 return VectorList.NumElements == NumElements;
932 bool isVectorIndex1()
const {
933 return Kind == k_VectorIndex && VectorIndex.Val == 1;
935 bool isVectorIndexB()
const {
936 return Kind == k_VectorIndex && VectorIndex.Val < 16;
938 bool isVectorIndexH()
const {
939 return Kind == k_VectorIndex && VectorIndex.Val < 8;
941 bool isVectorIndexS()
const {
942 return Kind == k_VectorIndex && VectorIndex.Val < 4;
944 bool isVectorIndexD()
const {
945 return Kind == k_VectorIndex && VectorIndex.Val < 2;
947 bool isToken()
const override {
return Kind == k_Token; }
951 bool isSysCR()
const {
return Kind == k_SysCR; }
952 bool isPrefetch()
const {
return Kind == k_Prefetch; }
953 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
954 bool isShifter()
const {
955 if (!isShiftExtend())
963 bool isExtend()
const {
964 if (!isShiftExtend())
973 getShiftExtendAmount() <= 4;
976 bool isExtend64()
const {
983 bool isExtendLSL64()
const {
989 getShiftExtendAmount() <= 4;
992 template<
int W
idth>
bool isMemXExtend()
const {
997 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
998 getShiftExtendAmount() == 0);
1001 template<
int W
idth>
bool isMemWExtend()
const {
1006 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1007 getShiftExtendAmount() == 0);
1010 template <
unsigned w
idth>
1011 bool isArithmeticShifter()
const {
1021 template <
unsigned w
idth>
1022 bool isLogicalShifter()
const {
1030 getShiftExtendAmount() < width;
1033 bool isMovImm32Shifter()
const {
1041 uint64_t Val = getShiftExtendAmount();
1042 return (Val == 0 || Val == 16);
1045 bool isMovImm64Shifter()
const {
1053 uint64_t Val = getShiftExtendAmount();
1054 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1057 bool isLogicalVecShifter()
const {
1062 unsigned Shift = getShiftExtendAmount();
1064 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1067 bool isLogicalVecHalfWordShifter()
const {
1068 if (!isLogicalVecShifter())
1072 unsigned Shift = getShiftExtendAmount();
1074 (Shift == 0 || Shift == 8);
1077 bool isMoveVecShifter()
const {
1078 if (!isShiftExtend())
1082 unsigned Shift = getShiftExtendAmount();
1084 (Shift == 8 || Shift == 16);
1093 bool isSImm9OffsetFB()
const {
1094 return isSImm9() && !isUImm12Offset<Width / 8>();
1097 bool isAdrpLabel()
const {
1103 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1105 int64_t Min = - (4096 * (1LL << (21 - 1)));
1106 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1107 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1113 bool isAdrLabel()
const {
1119 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1121 int64_t Min = - (1LL << (21 - 1));
1122 int64_t
Max = ((1LL << (21 - 1)) - 1);
1123 return Val >= Min && Val <=
Max;
1133 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1139 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1140 assert(N == 1 &&
"Invalid number of operands!");
1144 void addGPR32as64Operands(
MCInst &Inst,
unsigned N)
const {
1145 assert(N == 1 &&
"Invalid number of operands!");
1147 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].
contains(
getReg()));
1156 void addVectorReg64Operands(
MCInst &Inst,
unsigned N)
const {
1157 assert(N == 1 &&
"Invalid number of operands!");
1159 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1163 void addVectorReg128Operands(
MCInst &Inst,
unsigned N)
const {
1164 assert(N == 1 &&
"Invalid number of operands!");
1166 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1170 void addVectorRegLoOperands(
MCInst &Inst,
unsigned N)
const {
1171 assert(N == 1 &&
"Invalid number of operands!");
1175 template <
unsigned NumRegs>
1176 void addVectorList64Operands(
MCInst &Inst,
unsigned N)
const {
1177 assert(N == 1 &&
"Invalid number of operands!");
1178 static unsigned FirstRegs[] = { AArch64::D0, AArch64::D0_D1,
1179 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 };
1180 unsigned FirstReg = FirstRegs[NumRegs - 1];
1186 template <
unsigned NumRegs>
1187 void addVectorList128Operands(
MCInst &Inst,
unsigned N)
const {
1188 assert(N == 1 &&
"Invalid number of operands!");
1189 static unsigned FirstRegs[] = { AArch64::Q0, AArch64::Q0_Q1,
1190 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 };
1191 unsigned FirstReg = FirstRegs[NumRegs - 1];
1197 void addVectorIndex1Operands(
MCInst &Inst,
unsigned N)
const {
1198 assert(N == 1 &&
"Invalid number of operands!");
1202 void addVectorIndexBOperands(
MCInst &Inst,
unsigned N)
const {
1203 assert(N == 1 &&
"Invalid number of operands!");
1207 void addVectorIndexHOperands(
MCInst &Inst,
unsigned N)
const {
1208 assert(N == 1 &&
"Invalid number of operands!");
1212 void addVectorIndexSOperands(
MCInst &Inst,
unsigned N)
const {
1213 assert(N == 1 &&
"Invalid number of operands!");
1217 void addVectorIndexDOperands(
MCInst &Inst,
unsigned N)
const {
1218 assert(N == 1 &&
"Invalid number of operands!");
1222 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1223 assert(N == 1 &&
"Invalid number of operands!");
1227 addExpr(Inst, getImm());
1230 void addAddSubImmOperands(
MCInst &Inst,
unsigned N)
const {
1231 assert(N == 2 &&
"Invalid number of operands!");
1232 if (isShiftedImm()) {
1233 addExpr(Inst, getShiftedImmVal());
1236 addExpr(Inst, getImm());
1241 void addAddSubImmNegOperands(
MCInst &Inst,
unsigned N)
const {
1242 assert(N == 2 &&
"Invalid number of operands!");
1244 const MCExpr *MCE = isShiftedImm() ? getShiftedImmVal() : getImm();
1247 unsigned ShiftAmt = isShiftedImm() ? ShiftedImm.ShiftAmount : 0;
1253 void addCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
1254 assert(N == 1 &&
"Invalid number of operands!");
1258 void addAdrpLabelOperands(
MCInst &Inst,
unsigned N)
const {
1259 assert(N == 1 &&
"Invalid number of operands!");
1262 addExpr(Inst, getImm());
1267 void addAdrLabelOperands(
MCInst &Inst,
unsigned N)
const {
1268 addImmOperands(Inst, N);
1272 void addUImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
1273 assert(N == 1 &&
"Invalid number of operands!");
1283 void addSImm9Operands(
MCInst &Inst,
unsigned N)
const {
1284 assert(N == 1 &&
"Invalid number of operands!");
1289 void addSImm7s4Operands(
MCInst &Inst,
unsigned N)
const {
1290 assert(N == 1 &&
"Invalid number of operands!");
1295 void addSImm7s8Operands(
MCInst &Inst,
unsigned N)
const {
1296 assert(N == 1 &&
"Invalid number of operands!");
1301 void addSImm7s16Operands(
MCInst &Inst,
unsigned N)
const {
1302 assert(N == 1 &&
"Invalid number of operands!");
1307 void addImm0_7Operands(
MCInst &Inst,
unsigned N)
const {
1308 assert(N == 1 &&
"Invalid number of operands!");
1313 void addImm1_8Operands(
MCInst &Inst,
unsigned N)
const {
1314 assert(N == 1 &&
"Invalid number of operands!");
1319 void addImm0_15Operands(
MCInst &Inst,
unsigned N)
const {
1320 assert(N == 1 &&
"Invalid number of operands!");
1325 void addImm1_16Operands(
MCInst &Inst,
unsigned N)
const {
1326 assert(N == 1 &&
"Invalid number of operands!");
1328 assert(MCE &&
"Invalid constant immediate operand!");
1332 void addImm0_31Operands(
MCInst &Inst,
unsigned N)
const {
1333 assert(N == 1 &&
"Invalid number of operands!");
1338 void addImm1_31Operands(
MCInst &Inst,
unsigned N)
const {
1339 assert(N == 1 &&
"Invalid number of operands!");
1344 void addImm1_32Operands(
MCInst &Inst,
unsigned N)
const {
1345 assert(N == 1 &&
"Invalid number of operands!");
1350 void addImm0_63Operands(
MCInst &Inst,
unsigned N)
const {
1351 assert(N == 1 &&
"Invalid number of operands!");
1356 void addImm1_63Operands(
MCInst &Inst,
unsigned N)
const {
1357 assert(N == 1 &&
"Invalid number of operands!");
1362 void addImm1_64Operands(
MCInst &Inst,
unsigned N)
const {
1363 assert(N == 1 &&
"Invalid number of operands!");
1368 void addImm0_127Operands(
MCInst &Inst,
unsigned N)
const {
1369 assert(N == 1 &&
"Invalid number of operands!");
1374 void addImm0_255Operands(
MCInst &Inst,
unsigned N)
const {
1375 assert(N == 1 &&
"Invalid number of operands!");
1380 void addImm0_65535Operands(
MCInst &Inst,
unsigned N)
const {
1381 assert(N == 1 &&
"Invalid number of operands!");
1386 void addImm32_63Operands(
MCInst &Inst,
unsigned N)
const {
1387 assert(N == 1 &&
"Invalid number of operands!");
1392 void addLogicalImm32Operands(
MCInst &Inst,
unsigned N)
const {
1393 assert(N == 1 &&
"Invalid number of operands!");
1400 void addLogicalImm64Operands(
MCInst &Inst,
unsigned N)
const {
1401 assert(N == 1 &&
"Invalid number of operands!");
1407 void addLogicalImm32NotOperands(
MCInst &Inst,
unsigned N)
const {
1408 assert(N == 1 &&
"Invalid number of operands!");
1410 int64_t Val = ~MCE->
getValue() & 0xFFFFFFFF;
1415 void addLogicalImm64NotOperands(
MCInst &Inst,
unsigned N)
const {
1416 assert(N == 1 &&
"Invalid number of operands!");
1423 void addSIMDImmType10Operands(
MCInst &Inst,
unsigned N)
const {
1424 assert(N == 1 &&
"Invalid number of operands!");
1430 void addBranchTarget26Operands(
MCInst &Inst,
unsigned N)
const {
1434 assert(N == 1 &&
"Invalid number of operands!");
1437 addExpr(Inst, getImm());
1440 assert(MCE &&
"Invalid constant immediate operand!");
1444 void addPCRelLabel19Operands(
MCInst &Inst,
unsigned N)
const {
1448 assert(N == 1 &&
"Invalid number of operands!");
1451 addExpr(Inst, getImm());
1454 assert(MCE &&
"Invalid constant immediate operand!");
1458 void addBranchTarget14Operands(
MCInst &Inst,
unsigned N)
const {
1462 assert(N == 1 &&
"Invalid number of operands!");
1465 addExpr(Inst, getImm());
1468 assert(MCE &&
"Invalid constant immediate operand!");
1472 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1473 assert(N == 1 &&
"Invalid number of operands!");
1477 void addBarrierOperands(
MCInst &Inst,
unsigned N)
const {
1478 assert(N == 1 &&
"Invalid number of operands!");
1482 void addMRSSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
1483 assert(N == 1 &&
"Invalid number of operands!");
1488 void addMSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
1489 assert(N == 1 &&
"Invalid number of operands!");
1494 void addSystemPStateFieldOperands(
MCInst &Inst,
unsigned N)
const {
1495 assert(N == 1 &&
"Invalid number of operands!");
1500 void addSysCROperands(
MCInst &Inst,
unsigned N)
const {
1501 assert(N == 1 &&
"Invalid number of operands!");
1505 void addPrefetchOperands(
MCInst &Inst,
unsigned N)
const {
1506 assert(N == 1 &&
"Invalid number of operands!");
1510 void addShifterOperands(
MCInst &Inst,
unsigned N)
const {
1511 assert(N == 1 &&
"Invalid number of operands!");
1517 void addExtendOperands(
MCInst &Inst,
unsigned N)
const {
1518 assert(N == 1 &&
"Invalid number of operands!");
1525 void addExtend64Operands(
MCInst &Inst,
unsigned N)
const {
1526 assert(N == 1 &&
"Invalid number of operands!");
1533 void addMemExtendOperands(
MCInst &Inst,
unsigned N)
const {
1534 assert(N == 2 &&
"Invalid number of operands!");
1545 void addMemExtend8Operands(
MCInst &Inst,
unsigned N)
const {
1546 assert(N == 2 &&
"Invalid number of operands!");
1554 void addMOVZMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
1555 assert(N == 1 &&
"Invalid number of operands!");
1563 void addMOVNMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
1564 assert(N == 1 &&
"Invalid number of operands!");
1573 static std::unique_ptr<AArch64Operand>
1575 auto Op = make_unique<AArch64Operand>(k_Token, Ctx);
1576 Op->Tok.Data = Str.
data();
1577 Op->Tok.Length = Str.
size();
1578 Op->Tok.IsSuffix = IsSuffix;
1584 static std::unique_ptr<AArch64Operand>
1586 auto Op = make_unique<AArch64Operand>(k_Register, Ctx);
1587 Op->Reg.RegNum = RegNum;
1588 Op->Reg.isVector = isVector;
1594 static std::unique_ptr<AArch64Operand>
1595 CreateVectorList(
unsigned RegNum,
unsigned Count,
unsigned NumElements,
1597 auto Op = make_unique<AArch64Operand>(k_VectorList, Ctx);
1598 Op->VectorList.RegNum = RegNum;
1599 Op->VectorList.Count = Count;
1600 Op->VectorList.NumElements = NumElements;
1601 Op->VectorList.ElementKind = ElementKind;
1607 static std::unique_ptr<AArch64Operand>
1609 auto Op = make_unique<AArch64Operand>(k_VectorIndex, Ctx);
1610 Op->VectorIndex.Val = Idx;
1616 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val,
SMLoc S,
1618 auto Op = make_unique<AArch64Operand>(k_Immediate, Ctx);
1625 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
1626 unsigned ShiftAmount,
1629 auto Op = make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
1630 Op->ShiftedImm .Val = Val;
1631 Op->ShiftedImm.ShiftAmount = ShiftAmount;
1637 static std::unique_ptr<AArch64Operand>
1639 auto Op = make_unique<AArch64Operand>(k_CondCode, Ctx);
1640 Op->CondCode.Code =
Code;
1646 static std::unique_ptr<AArch64Operand> CreateFPImm(
unsigned Val,
SMLoc S,
1648 auto Op = make_unique<AArch64Operand>(k_FPImm, Ctx);
1649 Op->FPImm.Val = Val;
1655 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
1659 auto Op = make_unique<AArch64Operand>(k_Barrier, Ctx);
1660 Op->Barrier.Val = Val;
1661 Op->Barrier.Data = Str.
data();
1662 Op->Barrier.Length = Str.
size();
1668 static std::unique_ptr<AArch64Operand> CreateSysReg(
StringRef Str,
SMLoc S,
1671 uint32_t PStateField,
1673 auto Op = make_unique<AArch64Operand>(k_SysReg, Ctx);
1674 Op->SysReg.Data = Str.
data();
1675 Op->SysReg.Length = Str.
size();
1676 Op->SysReg.MRSReg = MRSReg;
1677 Op->SysReg.MSRReg = MSRReg;
1678 Op->SysReg.PStateField = PStateField;
1684 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val,
SMLoc S,
1686 auto Op = make_unique<AArch64Operand>(k_SysCR, Ctx);
1687 Op->SysCRImm.Val = Val;
1693 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
1697 auto Op = make_unique<AArch64Operand>(k_Prefetch, Ctx);
1698 Op->Prefetch.Val = Val;
1699 Op->Barrier.Data = Str.
data();
1700 Op->Barrier.Length = Str.
size();
1706 static std::unique_ptr<AArch64Operand>
1709 auto Op = make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
1710 Op->ShiftExtend.Type = ShOp;
1711 Op->ShiftExtend.Amount = Val;
1712 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
1721 void AArch64Operand::print(
raw_ostream &OS)
const {
1724 OS <<
"<fpimm " << getFPImm() <<
"("
1730 OS <<
"<barrier " << Name <<
">";
1732 OS <<
"<barrier invalid #" << getBarrier() <<
">";
1738 case k_ShiftedImm: {
1739 unsigned Shift = getShiftedImmShift();
1740 OS <<
"<shiftedimm ";
1741 OS << *getShiftedImmVal();
1746 OS <<
"<condcode " << getCondCode() <<
">";
1749 OS <<
"<register " <<
getReg() <<
">";
1751 case k_VectorList: {
1752 OS <<
"<vectorlist ";
1753 unsigned Reg = getVectorListStart();
1754 for (
unsigned i = 0, e = getVectorListCount(); i != e; ++i)
1755 OS << Reg + i <<
" ";
1760 OS <<
"<vectorindex " << getVectorIndex() <<
">";
1763 OS <<
"<sysreg: " << getSysReg() <<
'>';
1769 OS <<
"c" << getSysCR();
1774 OS <<
"<prfop " << Name <<
">";
1776 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
1779 case k_ShiftExtend: {
1781 << getShiftExtendAmount();
1782 if (!hasShiftExtendAmount())
1793 static unsigned MatchRegisterName(StringRef Name);
1797 static unsigned matchVectorRegName(StringRef Name) {
1798 return StringSwitch<unsigned>(Name.lower())
1799 .Case("v0", AArch64::Q0)
1800 .Case("v1", AArch64::Q1)
1801 .Case("v2", AArch64::Q2)
1802 .Case("v3", AArch64::Q3)
1803 .Case("v4", AArch64::Q4)
1804 .Case("v5", AArch64::Q5)
1805 .Case("v6", AArch64::Q6)
1806 .Case("v7", AArch64::Q7)
1807 .Case("v8", AArch64::Q8)
1808 .Case("v9", AArch64::Q9)
1809 .Case("v10", AArch64::Q10)
1810 .Case("v11", AArch64::Q11)
1811 .Case("v12", AArch64::Q12)
1812 .Case("v13", AArch64::Q13)
1813 .Case("v14", AArch64::Q14)
1814 .Case("v15", AArch64::Q15)
1815 .Case("v16", AArch64::Q16)
1816 .Case("v17", AArch64::Q17)
1817 .Case("v18", AArch64::Q18)
1818 .Case("v19", AArch64::Q19)
1819 .Case("v20", AArch64::Q20)
1820 .Case("v21", AArch64::Q21)
1821 .Case("v22", AArch64::Q22)
1822 .Case("v23", AArch64::Q23)
1823 .Case("v24", AArch64::Q24)
1824 .Case("v25", AArch64::Q25)
1825 .Case("v26", AArch64::Q26)
1826 .Case("v27", AArch64::Q27)
1827 .Case("v28", AArch64::Q28)
1828 .Case("v29", AArch64::Q29)
1829 .Case("v30", AArch64::Q30)
1830 .Case("v31", AArch64::Q31)
1834 static bool isValidVectorKind(StringRef Name) {
1835 return StringSwitch<bool>(Name.lower())
1845 // Accept the width neutral ones, too, for verbose syntax. If those
1846 // aren't used in the right places, the token operand won
't match so
1847 // all will work out.
1855 static void parseValidVectorKind(StringRef Name, unsigned &NumElements,
1856 char &ElementKind) {
1857 assert(isValidVectorKind(Name));
1859 ElementKind = Name.lower()[Name.size() - 1];
1862 if (Name.size() == 2)
1865 // Parse the lane count
1866 Name = Name.drop_front();
1867 while (isdigit(Name.front())) {
1868 NumElements = 10 * NumElements + (Name.front() - '0
');
1869 Name = Name.drop_front();
1873 bool AArch64AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1875 StartLoc = getLoc();
1876 RegNo = tryParseRegister();
1877 EndLoc = SMLoc::getFromPointer(getLoc().getPointer() - 1);
1878 return (RegNo == (unsigned)-1);
1881 // Matches a register name or register alias previously defined by '.req
'
1882 unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
1884 unsigned RegNum = isVector ? matchVectorRegName(Name)
1885 : MatchRegisterName(Name);
1888 // Check for aliases registered via .req. Canonicalize to lower case.
1889 // That's more consistent since
register names are
case insensitive, and
1891 auto Entry = RegisterReqs.find(Name.
lower());
1892 if (Entry == RegisterReqs.end())
1895 if (isVector == Entry->getValue().first)
1896 RegNum = Entry->getValue().second;
1904 int AArch64AsmParser::tryParseRegister() {
1910 unsigned RegNum = matchRegisterNameAlias(lowerCase,
false);
1914 .Case(
"fp", AArch64::FP)
1915 .
Case(
"lr", AArch64::LR)
1916 .
Case(
"x31", AArch64::XZR)
1917 .
Case(
"w31", AArch64::WZR)
1929 int AArch64AsmParser::tryMatchVectorRegister(
StringRef &
Kind,
bool expected) {
1932 TokError(
"vector register expected");
1939 size_t Start = 0, Next = Name.
find(
'.');
1941 unsigned RegNum = matchRegisterNameAlias(Head,
true);
1947 TokError(
"invalid vector kind qualifier");
1956 TokError(
"vector register expected");
1961 AArch64AsmParser::OperandMatchResultTy
1967 Error(S,
"Expected cN operand where 0 <= N <= 15");
1968 return MatchOperand_ParseFail;
1972 if (Tok[0] !=
'c' && Tok[0] !=
'C') {
1973 Error(S,
"Expected cN operand where 0 <= N <= 15");
1974 return MatchOperand_ParseFail;
1979 if (BadNum || CRNum > 15) {
1980 Error(S,
"Expected cN operand where 0 <= N <= 15");
1981 return MatchOperand_ParseFail;
1986 AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
1987 return MatchOperand_Success;
1991 AArch64AsmParser::OperandMatchResultTy
1992 AArch64AsmParser::tryParsePrefetch(
OperandVector &Operands) {
2002 if (getParser().parseExpression(ImmVal))
2003 return MatchOperand_ParseFail;
2007 TokError(
"immediate value expected for prefetch operand");
2008 return MatchOperand_ParseFail;
2012 TokError(
"prefetch operand out of range, [0,31] expected");
2013 return MatchOperand_ParseFail;
2019 Mapper.toString(MCE->
getValue(), STI.getFeatureBits(), Valid);
2020 Operands.
push_back(AArch64Operand::CreatePrefetch(prfop, Name,
2022 return MatchOperand_Success;
2026 TokError(
"pre-fetch hint expected");
2027 return MatchOperand_ParseFail;
2033 Mapper.fromString(Tok.
getString(), STI.getFeatureBits(), Valid);
2035 TokError(
"pre-fetch hint expected");
2036 return MatchOperand_ParseFail;
2042 return MatchOperand_Success;
2047 AArch64AsmParser::OperandMatchResultTy
2048 AArch64AsmParser::tryParseAdrpLabel(
OperandVector &Operands) {
2057 if (parseSymbolicImmVal(Expr))
2058 return MatchOperand_ParseFail;
2063 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
2073 Error(S,
"gotpage label reference not allowed an addend");
2074 return MatchOperand_ParseFail;
2082 Error(S,
"page or gotpage label reference expected");
2083 return MatchOperand_ParseFail;
2091 Operands.
push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2093 return MatchOperand_Success;
2098 AArch64AsmParser::OperandMatchResultTy
2099 AArch64AsmParser::tryParseAdrLabel(
OperandVector &Operands) {
2108 if (getParser().parseExpression(Expr))
2109 return MatchOperand_ParseFail;
2112 Operands.
push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2114 return MatchOperand_Success;
2118 AArch64AsmParser::OperandMatchResultTy
2130 bool isNegative =
false;
2141 uint64_t
IntVal = RealVal.bitcastToAPInt().getZExtValue();
2147 if (Val == -1 && !RealVal.isPosZero()) {
2148 TokError(
"expected compatible register or floating-point constant");
2149 return MatchOperand_ParseFail;
2151 Operands.
push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
2152 return MatchOperand_Success;
2158 if (Val > 255 || Val < 0) {
2159 TokError(
"encoded floating point value out of range");
2160 return MatchOperand_ParseFail;
2166 IntVal ^= (uint64_t)isNegative << 63;
2170 Operands.
push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
2171 return MatchOperand_Success;
2175 return MatchOperand_NoMatch;
2177 TokError(
"invalid floating point immediate");
2178 return MatchOperand_ParseFail;
2182 AArch64AsmParser::OperandMatchResultTy
2183 AArch64AsmParser::tryParseAddSubImm(
OperandVector &Operands) {
2191 return MatchOperand_NoMatch;
2194 if (parseSymbolicImmVal(Imm))
2195 return MatchOperand_ParseFail;
2197 uint64_t ShiftAmount = 0;
2201 if (Val > 0xfff && (Val & 0xfff) == 0) {
2207 Operands.
push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S, E,
2209 return MatchOperand_Success;
2219 return MatchOperand_ParseFail;
2231 return MatchOperand_ParseFail;
2236 if (ShiftAmount < 0) {
2238 return MatchOperand_ParseFail;
2243 Operands.
push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount,
2244 S, E, getContext()));
2245 return MatchOperand_Success;
2274 bool AArch64AsmParser::parseCondCode(
OperandVector &Operands,
2275 bool invertCondCode) {
2284 return TokError(
"invalid condition code");
2287 if (invertCondCode) {
2289 return TokError(
"condition codes AL and NV are invalid for this instruction");
2294 AArch64Operand::CreateCondCode(CC, S, getLoc(), getContext()));
2300 AArch64AsmParser::OperandMatchResultTy
2301 AArch64AsmParser::tryParseOptionalShiftExtend(
OperandVector &Operands) {
2323 return MatchOperand_NoMatch;
2334 TokError(
"expected #imm after shift specifier");
2335 return MatchOperand_ParseFail;
2341 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S, E, getContext()));
2342 return MatchOperand_Success;
2352 Error(E,
"expected integer shift amount");
2353 return MatchOperand_ParseFail;
2357 if (getParser().parseExpression(ImmVal))
2358 return MatchOperand_ParseFail;
2362 Error(E,
"expected constant '#imm' after shift specifier");
2363 return MatchOperand_ParseFail;
2367 Operands.
push_back(AArch64Operand::CreateShiftExtend(
2368 ShOp, MCE->
getValue(),
true, S, E, getContext()));
2369 return MatchOperand_Success;
2374 bool AArch64AsmParser::parseSysAlias(
StringRef Name,
SMLoc NameLoc,
2377 return TokError(
"invalid operand");
2381 AArch64Operand::CreateToken(
"sys",
false, NameLoc, getContext()));
2388 const MCExpr *Expr =
nullptr;
2390 #define SYS_ALIAS(op1, Cn, Cm, op2) \
2392 Expr = MCConstantExpr::create(op1, getContext()); \
2393 Operands.push_back( \
2394 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); \
2395 Operands.push_back( \
2396 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext())); \
2397 Operands.push_back( \
2398 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext())); \
2399 Expr = MCConstantExpr::create(op2, getContext()); \
2400 Operands.push_back( \
2401 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); \
2404 if (Mnemonic ==
"ic") {
2415 return TokError(
"invalid operand for IC instruction");
2417 }
else if (Mnemonic ==
"dc") {
2443 return TokError(
"invalid operand for DC instruction");
2445 }
else if (Mnemonic ==
"at") {
2483 return TokError(
"invalid operand for AT instruction");
2485 }
else if (Mnemonic ==
"tlbi") {
2583 return TokError(
"invalid operand for TLBI instruction");
2592 bool HasRegister =
false;
2599 return TokError(
"expected register operand");
2606 return TokError(
"unexpected token in argument list");
2609 if (ExpectRegister && !HasRegister) {
2610 return TokError(
"specified " + Mnemonic +
" op requires a register");
2612 else if (!ExpectRegister && HasRegister) {
2613 return TokError(
"specified " + Mnemonic +
" op does not use a register");
2620 AArch64AsmParser::OperandMatchResultTy
2621 AArch64AsmParser::tryParseBarrierOperand(
OperandVector &Operands) {
2632 SMLoc ExprLoc = getLoc();
2633 if (getParser().parseExpression(ImmVal))
2634 return MatchOperand_ParseFail;
2637 Error(ExprLoc,
"immediate value expected for barrier operand");
2638 return MatchOperand_ParseFail;
2641 Error(ExprLoc,
"barrier operand out of range");
2642 return MatchOperand_ParseFail;
2647 Mapper.toString(MCE->
getValue(), STI.getFeatureBits(), Valid);
2649 ExprLoc, getContext()));
2650 return MatchOperand_Success;
2654 TokError(
"invalid operand for instruction");
2655 return MatchOperand_ParseFail;
2661 Mapper.fromString(Tok.
getString(), STI.getFeatureBits(), Valid);
2663 TokError(
"invalid barrier option name");
2664 return MatchOperand_ParseFail;
2669 TokError(
"'sy' or #imm operand expected");
2670 return MatchOperand_ParseFail;
2674 getLoc(), getContext()));
2677 return MatchOperand_Success;
2680 AArch64AsmParser::OperandMatchResultTy
2686 return MatchOperand_NoMatch;
2690 uint32_t MRSReg = MRSMapper.fromString(Tok.
getString(), STI.getFeatureBits(),
2692 assert(IsKnown == (MRSReg != -1U) &&
2693 "register should be -1 if and only if it's unknown");
2696 uint32_t MSRReg = MSRMapper.fromString(Tok.
getString(), STI.getFeatureBits(),
2698 assert(IsKnown == (MSRReg != -1U) &&
2699 "register should be -1 if and only if it's unknown");
2702 uint32_t PStateField =
2703 PStateMapper.fromString(Tok.
getString(), STI.getFeatureBits(), IsKnown);
2704 assert(IsKnown == (PStateField != -1U) &&
2705 "register should be -1 if and only if it's unknown");
2707 Operands.
push_back(AArch64Operand::CreateSysReg(
2708 Tok.
getString(), getLoc(), MRSReg, MSRReg, PStateField, getContext()));
2711 return MatchOperand_Success;
2715 bool AArch64AsmParser::tryParseVectorRegister(
OperandVector &Operands) {
2723 int64_t Reg = tryMatchVectorRegister(Kind,
false);
2727 AArch64Operand::CreateReg(Reg,
true, S, getLoc(), getContext()));
2732 AArch64Operand::CreateToken(Kind,
false, S, getContext()));
2736 SMLoc SIdx = getLoc();
2740 if (getParser().parseExpression(ImmVal))
2744 TokError(
"immediate value expected for vector index");
2750 Error(E,
"']' expected");
2764 bool AArch64AsmParser::parseRegister(
OperandVector &Operands) {
2768 if (!tryParseVectorRegister(Operands))
2772 int64_t Reg = tryParseRegister();
2776 AArch64Operand::CreateReg(Reg,
false, S, getLoc(), getContext()));
2781 SMLoc LBracS = getLoc();
2785 SMLoc IntS = getLoc();
2790 SMLoc RBracS = getLoc();
2793 AArch64Operand::CreateToken(
"[",
false, LBracS, getContext()));
2795 AArch64Operand::CreateToken(
"1",
false, IntS, getContext()));
2797 AArch64Operand::CreateToken(
"]",
false, RBracS, getContext()));
2807 bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
2809 bool HasELFModifier =
false;
2814 HasELFModifier =
true;
2818 "expect relocation specifier in operand after ':'");
2863 "expect relocation specifier in operand after ':'");
2876 if (getParser().parseExpression(ImmVal))
2886 bool AArch64AsmParser::parseVectorList(
OperandVector &Operands) {
2892 int64_t FirstReg = tryMatchVectorRegister(Kind,
true);
2895 int64_t PrevReg = FirstReg;
2901 SMLoc Loc = getLoc();
2903 int64_t Reg = tryMatchVectorRegister(NextKind,
true);
2907 if (Kind != NextKind)
2908 return Error(Loc,
"mismatched register size suffix");
2910 unsigned Space = (PrevReg <
Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg);
2912 if (Space == 0 || Space > 3) {
2913 return Error(Loc,
"invalid number of vectors");
2922 SMLoc Loc = getLoc();
2924 int64_t Reg = tryMatchVectorRegister(NextKind,
true);
2928 if (Kind != NextKind)
2929 return Error(Loc,
"mismatched register size suffix");
2932 if (getContext().getRegisterInfo()->getEncodingValue(Reg) !=
2933 (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32)
2934 return Error(Loc,
"registers must be sequential");
2942 return Error(getLoc(),
"'}' expected");
2946 return Error(S,
"invalid number of vectors");
2948 unsigned NumElements = 0;
2949 char ElementKind = 0;
2953 Operands.
push_back(AArch64Operand::CreateVectorList(
2954 FirstReg, Count, NumElements, ElementKind, S, getLoc(), getContext()));
2958 SMLoc SIdx = getLoc();
2962 if (getParser().parseExpression(ImmVal))
2966 TokError(
"immediate value expected for vector index");
2972 Error(E,
"']' expected");
2984 AArch64AsmParser::OperandMatchResultTy
2985 AArch64AsmParser::tryParseGPR64sp0Operand(
OperandVector &Operands) {
2989 return MatchOperand_NoMatch;
2991 unsigned RegNum = matchRegisterNameAlias(Tok.
getString().
lower(),
false);
2996 return MatchOperand_NoMatch;
3003 AArch64Operand::CreateReg(RegNum,
false, S, getLoc(), Ctx));
3004 return MatchOperand_Success;
3012 Error(getLoc(),
"index must be absent or #0");
3013 return MatchOperand_ParseFail;
3018 cast<MCConstantExpr>(ImmVal)->getValue() != 0) {
3019 Error(getLoc(),
"index must be absent or #0");
3020 return MatchOperand_ParseFail;
3024 AArch64Operand::CreateReg(RegNum,
false, S, getLoc(), Ctx));
3025 return MatchOperand_Success;
3030 bool AArch64AsmParser::parseOperand(
OperandVector &Operands,
bool isCondCode,
3031 bool invertCondCode) {
3035 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3036 if (ResTy == MatchOperand_Success)
3041 if (ResTy == MatchOperand_ParseFail)
3046 switch (getLexer().getKind()) {
3050 if (parseSymbolicImmVal(Expr))
3051 return Error(S,
"invalid operand");
3054 Operands.
push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
3059 Operands.
push_back(AArch64Operand::CreateToken(
"[",
false, Loc,
3065 return parseOperand(Operands,
false,
false);
3068 return parseVectorList(Operands);
3072 return parseCondCode(Operands, invertCondCode);
3075 if (!parseRegister(Operands))
3079 OperandMatchResultTy GotShift = tryParseOptionalShiftExtend(Operands);
3081 if (GotShift != MatchOperand_NoMatch)
3088 if (getParser().parseExpression(IdVal))
3092 Operands.
push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
3104 bool isNegative =
false;
3120 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
3121 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
3122 Mnemonic !=
"fcmlt")
3123 return TokError(
"unexpected floating point literal");
3124 else if (IntVal != 0 || isNegative)
3125 return TokError(
"expected floating-point constant #0.0");
3129 AArch64Operand::CreateToken(
"#0",
false, S, getContext()));
3131 AArch64Operand::CreateToken(
".0",
false, S, getContext()));
3136 if (parseSymbolicImmVal(ImmVal))
3140 Operands.
push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
3145 if (Mnemonic !=
"ldr")
3146 return Error(Loc,
"unexpected token in operand");
3148 const MCExpr *SubExprVal;
3149 if (getParser().parseExpression(SubExprVal))
3152 if (Operands.
size() < 2 ||
3153 !
static_cast<AArch64Operand &
>(*Operands[1]).
isReg())
3157 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3163 if (isa<MCConstantExpr>(SubExprVal)) {
3164 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
3165 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
3170 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
3171 Operands[0] = AArch64Operand::CreateToken(
"movz",
false, Loc, Ctx);
3172 Operands.
push_back(AArch64Operand::CreateImm(
3176 ShiftAmt,
true, S, E, Ctx));
3182 return Error(Loc,
"Immediate too large for register");
3186 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4);
3187 Operands.
push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
3200 .Case(
"beq",
"b.eq")
3201 .
Case(
"bne",
"b.ne")
3202 .
Case(
"bhs",
"b.hs")
3203 .
Case(
"bcs",
"b.cs")
3204 .
Case(
"blo",
"b.lo")
3205 .
Case(
"bcc",
"b.cc")
3206 .
Case(
"bmi",
"b.mi")
3207 .
Case(
"bpl",
"b.pl")
3208 .
Case(
"bvs",
"b.vs")
3209 .
Case(
"bvc",
"b.vc")
3210 .
Case(
"bhi",
"b.hi")
3211 .
Case(
"bls",
"b.ls")
3212 .
Case(
"bge",
"b.ge")
3213 .
Case(
"blt",
"b.lt")
3214 .
Case(
"bgt",
"b.gt")
3215 .
Case(
"ble",
"b.le")
3216 .
Case(
"bal",
"b.al")
3217 .
Case(
"bnv",
"b.nv")
3223 parseDirectiveReq(Name, NameLoc);
3230 size_t Start = 0, Next = Name.
find(
'.');
3234 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi") {
3235 bool IsError = parseSysAlias(Head, NameLoc, Operands);
3242 AArch64Operand::CreateToken(Head,
false, NameLoc, getContext()));
3248 Next = Name.
find(
'.', Start + 1);
3249 Head = Name.
slice(Start + 1, Next);
3255 return Error(SuffixLoc,
"invalid condition code");
3257 AArch64Operand::CreateToken(
".",
true, SuffixLoc, getContext()));
3259 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext()));
3265 Next = Name.
find(
'.', Start + 1);
3266 Head = Name.
slice(Start, Next);
3270 AArch64Operand::CreateToken(Head,
true, SuffixLoc, getContext()));
3275 bool condCodeFourthOperand =
3276 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
3277 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
3278 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
3286 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
3287 bool condCodeThirdOperand =
3288 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
3293 if (parseOperand(Operands,
false,
false)) {
3303 if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) ||
3304 (N == 3 && condCodeThirdOperand) ||
3305 (N == 2 && condCodeSecondOperand),
3306 condCodeSecondOperand || condCodeThirdOperand)) {
3321 Operands.
push_back(AArch64Operand::CreateToken(
"]",
false, Loc,
3328 Operands.
push_back(AArch64Operand::CreateToken(
"!",
false, Loc,
3340 return Error(Loc,
"unexpected token in argument list");
3350 bool AArch64AsmParser::validateInstruction(
MCInst &Inst,
3357 case AArch64::LDPSWpre:
3358 case AArch64::LDPWpost:
3359 case AArch64::LDPWpre:
3360 case AArch64::LDPXpost:
3361 case AArch64::LDPXpre: {
3366 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
3367 "is also a destination");
3369 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
3370 "is also a destination");
3373 case AArch64::LDPDi:
3374 case AArch64::LDPQi:
3375 case AArch64::LDPSi:
3376 case AArch64::LDPSWi:
3377 case AArch64::LDPWi:
3378 case AArch64::LDPXi: {
3382 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
3385 case AArch64::LDPDpost:
3386 case AArch64::LDPDpre:
3387 case AArch64::LDPQpost:
3388 case AArch64::LDPQpre:
3389 case AArch64::LDPSpost:
3390 case AArch64::LDPSpre:
3391 case AArch64::LDPSWpost: {
3395 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
3398 case AArch64::STPDpost:
3399 case AArch64::STPDpre:
3400 case AArch64::STPQpost:
3401 case AArch64::STPQpre:
3402 case AArch64::STPSpost:
3403 case AArch64::STPSpre:
3404 case AArch64::STPWpost:
3405 case AArch64::STPWpre:
3406 case AArch64::STPXpost:
3407 case AArch64::STPXpre: {
3412 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
3413 "is also a source");
3415 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
3416 "is also a source");
3419 case AArch64::LDRBBpre:
3420 case AArch64::LDRBpre:
3421 case AArch64::LDRHHpre:
3422 case AArch64::LDRHpre:
3423 case AArch64::LDRSBWpre:
3424 case AArch64::LDRSBXpre:
3425 case AArch64::LDRSHWpre:
3426 case AArch64::LDRSHXpre:
3427 case AArch64::LDRSWpre:
3428 case AArch64::LDRWpre:
3429 case AArch64::LDRXpre:
3430 case AArch64::LDRBBpost:
3431 case AArch64::LDRBpost:
3432 case AArch64::LDRHHpost:
3433 case AArch64::LDRHpost:
3434 case AArch64::LDRSBWpost:
3435 case AArch64::LDRSBXpost:
3436 case AArch64::LDRSHWpost:
3437 case AArch64::LDRSHXpost:
3438 case AArch64::LDRSWpost:
3439 case AArch64::LDRWpost:
3440 case AArch64::LDRXpost: {
3444 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
3445 "is also a source");
3448 case AArch64::STRBBpost:
3449 case AArch64::STRBpost:
3450 case AArch64::STRHHpost:
3451 case AArch64::STRHpost:
3452 case AArch64::STRWpost:
3453 case AArch64::STRXpost:
3454 case AArch64::STRBBpre:
3455 case AArch64::STRBpre:
3456 case AArch64::STRHHpre:
3457 case AArch64::STRHpre:
3458 case AArch64::STRWpre:
3459 case AArch64::STRXpre: {
3463 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
3464 "is also a source");
3473 case AArch64::ADDSWri:
3474 case AArch64::ADDSXri:
3475 case AArch64::ADDWri:
3476 case AArch64::ADDXri:
3477 case AArch64::SUBSWri:
3478 case AArch64::SUBSXri:
3479 case AArch64::SUBWri:
3480 case AArch64::SUBXri: {
3488 if (!classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3489 return Error(Loc[2],
"invalid immediate expression");
3512 return Error(Loc[2],
"invalid immediate expression");
3521 bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode) {
3523 case Match_MissingFeature:
3525 "instruction requires a CPU feature not currently enabled");
3526 case Match_InvalidOperand:
3527 return Error(Loc,
"invalid operand for instruction");
3528 case Match_InvalidSuffix:
3529 return Error(Loc,
"invalid type suffix for instruction");
3530 case Match_InvalidCondCode:
3531 return Error(Loc,
"expected AArch64 condition code");
3532 case Match_AddSubRegExtendSmall:
3534 "expected '[su]xt[bhw]' or 'lsl' with optional integer in range [0, 4]");
3535 case Match_AddSubRegExtendLarge:
3537 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
3538 case Match_AddSubSecondSource:
3540 "expected compatible register, symbol or integer in range [0, 4095]");
3541 case Match_LogicalSecondSource:
3542 return Error(Loc,
"expected compatible register or logical immediate");
3543 case Match_InvalidMovImm32Shift:
3544 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
3545 case Match_InvalidMovImm64Shift:
3546 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
3547 case Match_AddSubRegShift32:
3549 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
3550 case Match_AddSubRegShift64:
3552 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
3553 case Match_InvalidFPImm:
3555 "expected compatible register or floating-point constant");
3556 case Match_InvalidMemoryIndexedSImm9:
3557 return Error(Loc,
"index must be an integer in range [-256, 255].");
3558 case Match_InvalidMemoryIndexed4SImm7:
3559 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
3560 case Match_InvalidMemoryIndexed8SImm7:
3561 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
3562 case Match_InvalidMemoryIndexed16SImm7:
3563 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
3564 case Match_InvalidMemoryWExtend8:
3566 "expected 'uxtw' or 'sxtw' with optional shift of #0");
3567 case Match_InvalidMemoryWExtend16:
3569 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
3570 case Match_InvalidMemoryWExtend32:
3572 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
3573 case Match_InvalidMemoryWExtend64:
3575 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
3576 case Match_InvalidMemoryWExtend128:
3578 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
3579 case Match_InvalidMemoryXExtend8:
3581 "expected 'lsl' or 'sxtx' with optional shift of #0");
3582 case Match_InvalidMemoryXExtend16:
3584 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
3585 case Match_InvalidMemoryXExtend32:
3587 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
3588 case Match_InvalidMemoryXExtend64:
3590 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
3591 case Match_InvalidMemoryXExtend128:
3593 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
3594 case Match_InvalidMemoryIndexed1:
3595 return Error(Loc,
"index must be an integer in range [0, 4095].");
3596 case Match_InvalidMemoryIndexed2:
3597 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
3598 case Match_InvalidMemoryIndexed4:
3599 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
3600 case Match_InvalidMemoryIndexed8:
3601 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
3602 case Match_InvalidMemoryIndexed16:
3603 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
3604 case Match_InvalidImm0_7:
3605 return Error(Loc,
"immediate must be an integer in range [0, 7].");
3606 case Match_InvalidImm0_15:
3607 return Error(Loc,
"immediate must be an integer in range [0, 15].");
3608 case Match_InvalidImm0_31:
3609 return Error(Loc,
"immediate must be an integer in range [0, 31].");
3610 case Match_InvalidImm0_63:
3611 return Error(Loc,
"immediate must be an integer in range [0, 63].");
3612 case Match_InvalidImm0_127:
3613 return Error(Loc,
"immediate must be an integer in range [0, 127].");
3614 case Match_InvalidImm0_65535:
3615 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
3616 case Match_InvalidImm1_8:
3617 return Error(Loc,
"immediate must be an integer in range [1, 8].");
3618 case Match_InvalidImm1_16:
3619 return Error(Loc,
"immediate must be an integer in range [1, 16].");
3620 case Match_InvalidImm1_32:
3621 return Error(Loc,
"immediate must be an integer in range [1, 32].");
3622 case Match_InvalidImm1_64:
3623 return Error(Loc,
"immediate must be an integer in range [1, 64].");
3624 case Match_InvalidIndex1:
3625 return Error(Loc,
"expected lane specifier '[1]'");
3626 case Match_InvalidIndexB:
3627 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
3628 case Match_InvalidIndexH:
3629 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
3630 case Match_InvalidIndexS:
3631 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
3632 case Match_InvalidIndexD:
3633 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
3634 case Match_InvalidLabel:
3635 return Error(Loc,
"expected label or encodable integer pc offset");
3637 return Error(Loc,
"expected readable system register");
3639 return Error(Loc,
"expected writable system register or pstate");
3640 case Match_MnemonicFail:
3641 return Error(Loc,
"unrecognized instruction mnemonic");
3649 bool AArch64AsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
3652 uint64_t &ErrorInfo,
3653 bool MatchingInlineAsm) {
3654 assert(!Operands.
empty() &&
"Unexpect empty operand list!");
3655 AArch64Operand &Op =
static_cast<AArch64Operand &
>(*Operands[0]);
3656 assert(Op.isToken() &&
"Leading operand should always be a mnemonic!");
3659 unsigned NumOperands = Operands.
size();
3661 if (NumOperands == 4 && Tok ==
"lsl") {
3662 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*Operands[2]);
3663 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
3664 if (Op2.isReg() && Op3.isImm()) {
3667 uint64_t Op3Val = Op3CE->
getValue();
3668 uint64_t NewOp3Val = 0;
3669 uint64_t NewOp4Val = 0;
3670 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].
contains(
3672 NewOp3Val = (32 - Op3Val) & 0x1f;
3673 NewOp4Val = 31 - Op3Val;
3675 NewOp3Val = (64 - Op3Val) & 0x3f;
3676 NewOp4Val = 63 - Op3Val;
3682 Operands[0] = AArch64Operand::CreateToken(
3683 "ubfm",
false, Op.getStartLoc(), getContext());
3684 Operands.
push_back(AArch64Operand::CreateImm(
3685 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
3686 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
3687 Op3.getEndLoc(), getContext());
3690 }
else if (NumOperands == 4 && Tok ==
"bfc") {
3692 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
3693 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*Operands[2]);
3694 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*Operands[3]);
3696 if (Op1.isReg() && LSBOp.isImm() && WidthOp.isImm()) {
3700 if (LSBCE && WidthCE) {
3702 uint64_t Width = WidthCE->getValue();
3704 uint64_t RegWidth = 0;
3705 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
3711 if (LSB >= RegWidth)
3712 return Error(LSBOp.getStartLoc(),
3713 "expected integer in range [0, 31]");
3714 if (Width < 1 || Width > RegWidth)
3715 return Error(WidthOp.getStartLoc(),
3716 "expected integer in range [1, 32]");
3720 ImmR = (32 - LSB) & 0x1f;
3722 ImmR = (64 - LSB) & 0x3f;
3724 uint64_t ImmS = Width - 1;
3726 if (ImmR != 0 && ImmS >= ImmR)
3727 return Error(WidthOp.getStartLoc(),
3728 "requested insert overflows register");
3732 Operands[0] = AArch64Operand::CreateToken(
3733 "bfm",
false, Op.getStartLoc(), getContext());
3734 Operands[2] = AArch64Operand::CreateReg(
3735 RegWidth == 32 ? AArch64::WZR : AArch64::XZR,
false,
SMLoc(),
3736 SMLoc(), getContext());
3737 Operands[3] = AArch64Operand::CreateImm(
3738 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
3739 Operands.emplace_back(
3740 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
3741 WidthOp.getEndLoc(), getContext()));
3744 }
else if (NumOperands == 5) {
3747 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
3748 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
3749 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
3750 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
3752 if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3756 if (Op3CE && Op4CE) {
3757 uint64_t Op3Val = Op3CE->
getValue();
3758 uint64_t Op4Val = Op4CE->getValue();
3760 uint64_t RegWidth = 0;
3761 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
3767 if (Op3Val >= RegWidth)
3768 return Error(Op3.getStartLoc(),
3769 "expected integer in range [0, 31]");
3770 if (Op4Val < 1 || Op4Val > RegWidth)
3771 return Error(Op4.getStartLoc(),
3772 "expected integer in range [1, 32]");
3774 uint64_t NewOp3Val = 0;
3776 NewOp3Val = (32 - Op3Val) & 0x1f;
3778 NewOp3Val = (64 - Op3Val) & 0x3f;
3780 uint64_t NewOp4Val = Op4Val - 1;
3782 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
3783 return Error(Op4.getStartLoc(),
3784 "requested insert overflows register");
3790 Operands[3] = AArch64Operand::CreateImm(
3791 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
3792 Operands[4] = AArch64Operand::CreateImm(
3793 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
3795 Operands[0] = AArch64Operand::CreateToken(
3796 "bfm",
false, Op.getStartLoc(), getContext());
3797 else if (Tok ==
"sbfiz")
3798 Operands[0] = AArch64Operand::CreateToken(
3799 "sbfm",
false, Op.getStartLoc(), getContext());
3800 else if (Tok ==
"ubfiz")
3801 Operands[0] = AArch64Operand::CreateToken(
3802 "ubfm",
false, Op.getStartLoc(), getContext());
3810 }
else if (NumOperands == 5 &&
3811 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
3812 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
3813 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
3814 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
3816 if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3820 if (Op3CE && Op4CE) {
3821 uint64_t Op3Val = Op3CE->
getValue();
3822 uint64_t Op4Val = Op4CE->getValue();
3824 uint64_t RegWidth = 0;
3825 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
3831 if (Op3Val >= RegWidth)
3832 return Error(Op3.getStartLoc(),
3833 "expected integer in range [0, 31]");
3834 if (Op4Val < 1 || Op4Val > RegWidth)
3835 return Error(Op4.getStartLoc(),
3836 "expected integer in range [1, 32]");
3838 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
3840 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
3841 return Error(Op4.getStartLoc(),
3842 "requested extract overflows register");
3846 Operands[4] = AArch64Operand::CreateImm(
3847 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
3849 Operands[0] = AArch64Operand::CreateToken(
3850 "bfm",
false, Op.getStartLoc(), getContext());
3851 else if (Tok ==
"sbfx")
3852 Operands[0] = AArch64Operand::CreateToken(
3853 "sbfm",
false, Op.getStartLoc(), getContext());
3854 else if (Tok ==
"ubfx")
3855 Operands[0] = AArch64Operand::CreateToken(
3856 "ubfm",
false, Op.getStartLoc(), getContext());
3866 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
3869 AArch64Operand &Op =
static_cast<AArch64Operand &
>(*Operands[2]);
3872 Operands[2] = AArch64Operand::CreateReg(Reg,
false, Op.getStartLoc(),
3873 Op.getEndLoc(), getContext());
3877 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
3878 AArch64Operand &Op =
static_cast<AArch64Operand &
>(*Operands[1]);
3880 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3884 AArch64Operand &Op =
static_cast<AArch64Operand &
>(*Operands[2]);
3887 Operands[2] = AArch64Operand::CreateReg(Reg,
false, Op.getStartLoc(),
3888 Op.getEndLoc(), getContext());
3893 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
3894 AArch64Operand &Op =
static_cast<AArch64Operand &
>(*Operands[1]);
3896 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3900 AArch64Operand &Op =
static_cast<AArch64Operand &
>(*Operands[1]);
3903 Operands[1] = AArch64Operand::CreateReg(Reg,
false, Op.getStartLoc(),
3904 Op.getEndLoc(), getContext());
3910 if (NumOperands == 3 && Tok ==
"fmov") {
3911 AArch64Operand &RegOp =
static_cast<AArch64Operand &
>(*Operands[1]);
3912 AArch64Operand &ImmOp =
static_cast<AArch64Operand &
>(*Operands[2]);
3913 if (RegOp.isReg() && ImmOp.isFPImm() && ImmOp.getFPImm() == (
unsigned)-1) {
3915 AArch64MCRegisterClasses[AArch64::FPR32RegClassID].contains(
3919 Operands[2] = AArch64Operand::CreateReg(zreg,
false, Op.getStartLoc(),
3920 Op.getEndLoc(), getContext());
3927 unsigned MatchResult =
3928 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 1);
3932 if (MatchResult != Match_Success)
3934 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 0);
3936 switch (MatchResult) {
3937 case Match_Success: {
3940 NumOperands = Operands.size();
3941 for (
unsigned i = 1; i < NumOperands; ++i)
3942 OperandLocs.
push_back(Operands[i]->getStartLoc());
3943 if (validateInstruction(Inst, OperandLocs))
3950 case Match_MissingFeature: {
3951 assert(ErrorInfo &&
"Unknown missing feature!");
3954 std::string Msg =
"instruction requires:";
3956 for (
unsigned i = 0; i < (
sizeof(ErrorInfo)*8-1); ++i) {
3957 if (ErrorInfo & Mask) {
3963 return Error(IDLoc, Msg);
3965 case Match_MnemonicFail:
3966 return showMatchError(IDLoc, MatchResult);
3967 case Match_InvalidOperand: {
3968 SMLoc ErrorLoc = IDLoc;
3969 if (ErrorInfo != ~0ULL) {
3970 if (ErrorInfo >= Operands.size())
3971 return Error(IDLoc,
"too few operands for instruction");
3973 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
3974 if (ErrorLoc ==
SMLoc())
3979 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
3980 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
3981 MatchResult = Match_InvalidSuffix;
3983 return showMatchError(ErrorLoc, MatchResult);
3985 case Match_InvalidMemoryIndexed1:
3986 case Match_InvalidMemoryIndexed2:
3987 case Match_InvalidMemoryIndexed4:
3988 case Match_InvalidMemoryIndexed8:
3989 case Match_InvalidMemoryIndexed16:
3990 case Match_InvalidCondCode:
3991 case Match_AddSubRegExtendSmall:
3992 case Match_AddSubRegExtendLarge:
3993 case Match_AddSubSecondSource:
3994 case Match_LogicalSecondSource:
3995 case Match_AddSubRegShift32:
3996 case Match_AddSubRegShift64:
3997 case Match_InvalidMovImm32Shift:
3998 case Match_InvalidMovImm64Shift:
3999 case Match_InvalidFPImm:
4000 case Match_InvalidMemoryWExtend8:
4001 case Match_InvalidMemoryWExtend16:
4002 case Match_InvalidMemoryWExtend32:
4003 case Match_InvalidMemoryWExtend64:
4004 case Match_InvalidMemoryWExtend128:
4005 case Match_InvalidMemoryXExtend8:
4006 case Match_InvalidMemoryXExtend16:
4007 case Match_InvalidMemoryXExtend32:
4008 case Match_InvalidMemoryXExtend64:
4009 case Match_InvalidMemoryXExtend128:
4010 case Match_InvalidMemoryIndexed4SImm7:
4011 case Match_InvalidMemoryIndexed8SImm7:
4012 case Match_InvalidMemoryIndexed16SImm7:
4013 case Match_InvalidMemoryIndexedSImm9:
4014 case Match_InvalidImm0_7:
4015 case Match_InvalidImm0_15:
4016 case Match_InvalidImm0_31:
4017 case Match_InvalidImm0_63:
4018 case Match_InvalidImm0_127:
4019 case Match_InvalidImm0_65535:
4020 case Match_InvalidImm1_8:
4021 case Match_InvalidImm1_16:
4022 case Match_InvalidImm1_32:
4023 case Match_InvalidImm1_64:
4024 case Match_InvalidIndex1:
4025 case Match_InvalidIndexB:
4026 case Match_InvalidIndexH:
4027 case Match_InvalidIndexS:
4028 case Match_InvalidIndexD:
4029 case Match_InvalidLabel:
4032 if (ErrorInfo >= Operands.size())
4033 return Error(IDLoc,
"too few operands for instruction");
4036 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
4037 if (ErrorLoc ==
SMLoc())
4039 return showMatchError(ErrorLoc, MatchResult);
4047 bool AArch64AsmParser::ParseDirective(
AsmToken DirectiveID) {
4049 getContext().getObjectFileInfo()->getObjectFileType();
4055 if (IDVal ==
".hword")
4056 return parseDirectiveWord(2, Loc);
4057 if (IDVal ==
".word")
4058 return parseDirectiveWord(4, Loc);
4059 if (IDVal ==
".xword")
4060 return parseDirectiveWord(8, Loc);
4061 if (IDVal ==
".tlsdesccall")
4062 return parseDirectiveTLSDescCall(Loc);
4063 if (IDVal ==
".ltorg" || IDVal ==
".pool")
4064 return parseDirectiveLtorg(Loc);
4065 if (IDVal ==
".unreq")
4066 return parseDirectiveUnreq(Loc);
4068 if (!IsMachO && !IsCOFF) {
4069 if (IDVal ==
".inst")
4070 return parseDirectiveInst(Loc);
4073 return parseDirectiveLOH(IDVal, Loc);
4078 bool AArch64AsmParser::parseDirectiveWord(
unsigned Size,
SMLoc L) {
4083 if (getParser().parseExpression(Value))
4086 getParser().getStreamer().EmitValue(Value, Size);
4093 return Error(L,
"unexpected token in directive");
4104 bool AArch64AsmParser::parseDirectiveInst(
SMLoc Loc) {
4108 Error(Loc,
"expected expression following directive");
4115 if (getParser().parseExpression(Expr)) {
4116 Error(Loc,
"expected expression");
4120 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
4122 Error(Loc,
"expected constant expression");
4126 getTargetStreamer().emitInst(Value->
getValue());
4132 Error(Loc,
"unexpected token in directive");
4145 bool AArch64AsmParser::parseDirectiveTLSDescCall(
SMLoc L) {
4147 if (getParser().parseIdentifier(Name))
4148 return Error(L,
"expected symbol after directive");
4150 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4158 getParser().getStreamer().EmitInstruction(Inst, STI);
4164 bool AArch64AsmParser::parseDirectiveLOH(
StringRef IDVal,
SMLoc Loc) {
4170 return TokError(
"expected an identifier or a number in directive");
4173 int64_t
Id = getParser().getTok().getIntVal();
4175 return TokError(
"invalid numeric identifier in directive");
4178 StringRef Name = getTok().getIdentifier();
4184 return TokError(
"invalid identifier in directive");
4192 assert(NbArgs != -1 &&
"Invalid number of arguments");
4195 for (
int Idx = 0; Idx < NbArgs; ++Idx) {
4197 if (getParser().parseIdentifier(Name))
4198 return TokError(
"expected identifier in directive");
4199 Args.
push_back(getContext().getOrCreateSymbol(Name));
4201 if (Idx + 1 == NbArgs)
4204 return TokError(
"unexpected token in '" +
Twine(IDVal) +
"' directive");
4208 return TokError(
"unexpected token in '" +
Twine(IDVal) +
"' directive");
4210 getStreamer().EmitLOHDirective((
MCLOHType)Kind, Args);
4216 bool AArch64AsmParser::parseDirectiveLtorg(
SMLoc L) {
4217 getTargetStreamer().emitCurrentConstantPool();
4223 bool AArch64AsmParser::parseDirectiveReq(
StringRef Name,
SMLoc L) {
4226 SMLoc SRegLoc = getLoc();
4227 unsigned RegNum = tryParseRegister();
4228 bool IsVector =
false;
4230 if (RegNum == static_cast<unsigned>(-1)) {
4232 RegNum = tryMatchVectorRegister(Kind,
false);
4233 if (!Kind.
empty()) {
4234 Error(SRegLoc,
"vector register without type specifier expected");
4240 if (RegNum == static_cast<unsigned>(-1)) {
4242 Error(SRegLoc,
"register name or alias expected");
4255 auto pair = std::make_pair(IsVector, RegNum);
4256 if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair)
4257 Warning(L,
"ignoring redefinition of register alias '" + Name +
"'");
4264 bool AArch64AsmParser::parseDirectiveUnreq(
SMLoc L) {
4277 AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
4285 if (
const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
4286 ELFRefKind = AE->getKind();
4287 Expr = AE->getSubExpr();
4293 DarwinRefKind = SE->
getKind();
4304 DarwinRefKind = SE->
getKind();
4333 #define GET_REGISTER_MATCHER
4334 #define GET_SUBTARGET_FEATURE_NAME
4335 #define GET_MATCHER_IMPLEMENTATION
4336 #include "AArch64GenAsmMatcher.inc"
4342 AArch64Operand &Op =
static_cast<AArch64Operand &
>(AsmOp);
4346 int64_t ExpectedVal;
4349 return Match_InvalidOperand;
4391 return Match_InvalidOperand;
4394 return Match_InvalidOperand;
4396 return Match_Success;
4397 return Match_InvalidOperand;
4401 AArch64AsmParser::OperandMatchResultTy
4402 AArch64AsmParser::tryParseGPRSeqPair(
OperandVector &Operands) {
4407 Error(S,
"expected register");
4408 return MatchOperand_ParseFail;
4411 int FirstReg = tryParseRegister();
4412 if (FirstReg == -1) {
4413 return MatchOperand_ParseFail;
4416 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
4418 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
4420 bool isXReg = XRegClass.
contains(FirstReg),
4421 isWReg = WRegClass.
contains(FirstReg);
4422 if (!isXReg && !isWReg) {
4423 Error(S,
"expected first even register of a "
4424 "consecutive same-size even/odd register pair");
4425 return MatchOperand_ParseFail;
4431 if (FirstEncoding & 0x1) {
4432 Error(S,
"expected first even register of a "
4433 "consecutive same-size even/odd register pair");
4434 return MatchOperand_ParseFail;
4439 Error(M,
"expected comma");
4440 return MatchOperand_ParseFail;
4446 int SecondReg = tryParseRegister();
4447 if (SecondReg ==-1) {
4448 return MatchOperand_ParseFail;
4452 (isXReg && !XRegClass.
contains(SecondReg)) ||
4453 (isWReg && !WRegClass.
contains(SecondReg))) {
4454 Error(E,
"expected second odd register of a "
4455 "consecutive same-size even/odd register pair");
4456 return MatchOperand_ParseFail;
4462 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
4465 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
4468 Operands.
push_back(AArch64Operand::CreateReg(Pair,
false, S, getLoc(),
4471 return MatchOperand_Success;
static bool isValidVectorKind(StringRef Name)
static bool isReg(const MCInst &MI, unsigned OpNo)
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
void push_back(const T &Elt)
int compare_lower(StringRef RHS) const
compare_lower - Compare two strings, ignoring case.
static float getFPImmFloat(unsigned Imm)
uint64_t getZExtValue() const
Get zero extended value.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
virtual const AsmToken peekTok(bool ShouldSkipSpace=true)=0
Look ahead at the next token to be lexed.
const char * getPointer() const
size_t size() const
size - Get the string size.
static const fltSemantics IEEEdouble
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
static const AArch64MCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
static MCOperand createExpr(const MCExpr *Val)
MCTargetAsmParser - Generic interface to target specific assembly parsers.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static CondCode getInvertedCondCode(CondCode Code)
Target specific streamer interface.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
bool isNot(TokenKind K) const
static unsigned getXRegFromWReg(unsigned Reg)
#define SYS_ALIAS(op1, Cn, Cm, op2)
StringSwitch & Case(const char(&S)[N], const T &Value)
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
bool isSubRegisterEq(unsigned RegA, unsigned RegB) const
Returns true if RegB is a sub-register of RegA or if RegB == RegA.
static MCOperand createReg(unsigned Reg)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
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 ...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Base class for the full range of assembler expressions which are needed for parsing.
Reg
All possible values of the reg field in the ModR/M byte.
Target independent representation for an assembler token.
Represent a reference to a symbol from inside an expression.
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
Windows NT (Windows on ARM)
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
This file implements a class to represent arbitrary precision integral constant values and operations...
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
Context object for machine code objects.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
unsigned getReg() const
Returns the register number.
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out...
int64_t getIntVal() const
MCRegisterClass - Base class of TargetRegisterClass.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
size_t size() const
size - Get the array size.
Instances of this class represent a single low-level machine instruction.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
ppc loop data PPC Loop Data Prefetch
static unsigned getWRegFromXReg(unsigned Reg)
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
A self-contained host- and target-independent arbitrary-precision floating-point software implementat...
const MCExpr * getExpr() const
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
A switch()-like statement whose cases are string literals.
Streaming machine code generation interface.
MCTargetStreamer * getTargetStreamer()
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
static const char * getShiftExtendName(AArch64_AM::ShiftExtendType ST)
getShiftName - Get the string encoding for the shift type.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
static int MCLOHNameToId(StringRef Name)
Interface to description of machine instruction set.
unsigned getRegister(unsigned i) const
getRegister - Return the specified register in the class.
virtual MCAsmLexer & getLexer()=0
MCLOHType
Linker Optimization Hint Type.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
Binary assembler expressions.
unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg...
Target TheAArch64leTarget
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
static int getFP64Imm(const APInt &Imm)
getFP64Imm - Return an 8-bit floating-point version of the 64-bit floating-point value.
void setOpcode(unsigned Op)
Target TheAArch64beTarget
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
bool contains(unsigned Reg) const
contains - Return true if the specified register is included in this register class.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
const FeatureBitset & getFeatureBits() const
getFeatureBits - Return the feature bits.
bool is(TokenKind K) const
static StringRef MCLOHDirectiveName()
R Default(const T &Value) const
unsigned Log2_32(uint32_t Value)
Log2_32 - This function returns the floor log base 2 of the specified value, -1 if the value is zero...
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
unsigned getOpcode() const
Class for arbitrary precision integers.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
static uint8_t encodeAdvSIMDModImmType10(uint64_t Imm)
APInt bitcastToAPInt() const
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
static unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET, unsigned Imm)
getArithExtendImm - Encode the extend type and shift amount for an arithmetic instruction: imm: 3-bit...
static SMLoc getFromPointer(const char *Ptr)
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static bool isAdvSIMDModImmType10(uint64_t Imm)
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string...
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
Opcode getOpcode() const
Get the kind of this binary expression.
static bool isValidMCLOHType(unsigned Kind)
MCSubtargetInfo - Generic base class for all target subtargets.
static bool isMem(const MachineInstr *MI, unsigned Op)
VariantKind getKind() const
const ARM::ArchExtKind Kind
static int MCLOHIdToNbArgs(MCLOHType Kind)
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream...
std::string Hash(const Unit &U)
void addOperand(const MCOperand &Op)
StringRef - Represent a constant reference to a string, i.e.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Represents a location in source code.
static const char * getSubtargetFeatureName(uint64_t Val)
static MCOperand createImm(int64_t Val)
std::string lower() const
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
const MCOperand & getOperand(unsigned i) const
static void parseValidVectorKind(StringRef Name, unsigned &NumElements, char &ElementKind)
void LLVMInitializeAArch64AsmParser()
Force static initialization.
bool empty() const
empty - Check if the string is empty.