74 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
78 bool parseCondCode(
OperandVector &Operands,
bool invertCondCode);
80 int tryParseRegister();
83 bool parseSymbolicImmVal(
const MCExpr *&ImmVal);
88 bool showMatchError(
SMLoc Loc,
unsigned ErrCode);
90 bool parseDirectiveArch(
SMLoc L);
91 bool parseDirectiveCPU(
SMLoc L);
92 bool parseDirectiveWord(
unsigned Size,
SMLoc L);
93 bool parseDirectiveInst(
SMLoc L);
95 bool parseDirectiveTLSDescCall(
SMLoc L);
98 bool parseDirectiveLtorg(
SMLoc L);
101 bool parseDirectiveUnreq(
SMLoc L);
104 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
107 bool MatchingInlineAsm)
override;
111 #define GET_ASSEMBLER_HEADER
112 #include "AArch64GenAsmMatcher.inc"
132 enum AArch64MatchResultTy {
133 Match_InvalidSuffix = FIRST_TARGET_MATCH_RESULT_TY,
134 #define GET_OPERAND_DIAGNOSTIC_TYPES
135 #include "AArch64GenAsmMatcher.inc"
149 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
154 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
155 bool ParseDirective(
AsmToken DirectiveID)
override;
157 unsigned Kind)
override;
159 static bool classifySymbolRef(
const MCExpr *Expr,
186 SMLoc StartLoc, EndLoc;
199 struct VectorListOp {
202 unsigned NumElements;
203 unsigned ElementKind;
206 struct VectorIndexOp {
214 struct ShiftedImmOp {
216 unsigned ShiftAmount;
257 struct ShiftExtendOp {
260 bool HasExplicitAmount;
270 struct VectorListOp VectorList;
271 struct VectorIndexOp VectorIndex;
273 struct ShiftedImmOp ShiftedImm;
275 struct FPImmOp FPImm;
277 struct SysRegOp SysReg;
278 struct SysCRImmOp SysCRImm;
280 struct PSBHintOp PSBHint;
281 struct ShiftExtendOp ShiftExtend;
289 AArch64Operand(KindTy K,
MCContext &Ctx) :
Kind(K), Ctx(Ctx) {}
293 StartLoc = o.StartLoc;
303 ShiftedImm = o.ShiftedImm;
318 VectorList = o.VectorList;
321 VectorIndex = o.VectorIndex;
327 SysCRImm = o.SysCRImm;
336 ShiftExtend = o.ShiftExtend;
342 SMLoc getStartLoc()
const override {
return StartLoc; }
344 SMLoc getEndLoc()
const override {
return EndLoc; }
351 bool isTokenSuffix()
const {
356 const MCExpr *getImm()
const {
357 assert(
Kind == k_Immediate &&
"Invalid access!");
361 const MCExpr *getShiftedImmVal()
const {
362 assert(
Kind == k_ShiftedImm &&
"Invalid access!");
363 return ShiftedImm.Val;
366 unsigned getShiftedImmShift()
const {
367 assert(
Kind == k_ShiftedImm &&
"Invalid access!");
368 return ShiftedImm.ShiftAmount;
372 assert(
Kind == k_CondCode &&
"Invalid access!");
376 unsigned getFPImm()
const {
381 unsigned getBarrier()
const {
382 assert(
Kind == k_Barrier &&
"Invalid access!");
387 assert(
Kind == k_Barrier &&
"Invalid access!");
391 unsigned getReg()
const override {
392 assert(
Kind == k_Register &&
"Invalid access!");
396 unsigned getVectorListStart()
const {
397 assert(
Kind == k_VectorList &&
"Invalid access!");
398 return VectorList.RegNum;
401 unsigned getVectorListCount()
const {
402 assert(
Kind == k_VectorList &&
"Invalid access!");
403 return VectorList.Count;
406 unsigned getVectorIndex()
const {
407 assert(
Kind == k_VectorIndex &&
"Invalid access!");
408 return VectorIndex.Val;
412 assert(
Kind == k_SysReg &&
"Invalid access!");
413 return StringRef(SysReg.Data, SysReg.Length);
416 unsigned getSysCR()
const {
421 unsigned getPrefetch()
const {
422 assert(
Kind == k_Prefetch &&
"Invalid access!");
426 unsigned getPSBHint()
const {
427 assert(
Kind == k_PSBHint &&
"Invalid access!");
432 assert(
Kind == k_PSBHint &&
"Invalid access!");
433 return StringRef(PSBHint.Data, PSBHint.Length);
437 assert(
Kind == k_Prefetch &&
"Invalid access!");
442 assert(
Kind == k_ShiftExtend &&
"Invalid access!");
443 return ShiftExtend.Type;
446 unsigned getShiftExtendAmount()
const {
447 assert(
Kind == k_ShiftExtend &&
"Invalid access!");
448 return ShiftExtend.Amount;
451 bool hasShiftExtendAmount()
const {
452 assert(
Kind == k_ShiftExtend &&
"Invalid access!");
453 return ShiftExtend.HasExplicitAmount;
456 bool isImm()
const override {
return Kind == k_Immediate; }
457 bool isMem()
const override {
return false; }
458 bool isSImm9()
const {
465 return (Val >= -256 && Val < 256);
467 bool isSImm7s4()
const {
474 return (Val >= -256 && Val <= 252 && (Val & 3) == 0);
476 bool isSImm7s8()
const {
483 return (Val >= -512 && Val <= 504 && (Val & 7) == 0);
485 bool isSImm7s16()
const {
492 return (Val >= -1024 && Val <= 1008 && (Val & 15) == 0);
495 bool isSymbolicUImm12Offset(
const MCExpr *Expr,
unsigned Scale)
const {
499 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
518 return Addend >= 0 && (Addend % Scale) == 0;
528 template <
int Scale>
bool isUImm12Offset()
const {
534 return isSymbolicUImm12Offset(getImm(), Scale);
537 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
540 bool isImm0_1()
const {
547 return (Val >= 0 && Val < 2);
550 bool isImm0_7()
const {
557 return (Val >= 0 && Val < 8);
560 bool isImm1_8()
const {
567 return (Val > 0 && Val < 9);
570 bool isImm0_15()
const {
577 return (Val >= 0 && Val < 16);
580 bool isImm1_16()
const {
587 return (Val > 0 && Val < 17);
590 bool isImm0_31()
const {
597 return (Val >= 0 && Val < 32);
600 bool isImm1_31()
const {
607 return (Val >= 1 && Val < 32);
610 bool isImm1_32()
const {
617 return (Val >= 1 && Val < 33);
620 bool isImm0_63()
const {
627 return (Val >= 0 && Val < 64);
630 bool isImm1_63()
const {
637 return (Val >= 1 && Val < 64);
640 bool isImm1_64()
const {
647 return (Val >= 1 && Val < 65);
650 bool isImm0_127()
const {
657 return (Val >= 0 && Val < 128);
660 bool isImm0_255()
const {
667 return (Val >= 0 && Val < 256);
670 bool isImm0_65535()
const {
677 return (Val >= 0 && Val < 65536);
680 bool isImm32_63()
const {
687 return (Val >= 32 && Val < 64);
690 bool isLogicalImm32()
const {
697 if (Val >> 32 != 0 && Val >> 32 != ~0LL)
703 bool isLogicalImm64()
const {
712 bool isLogicalImm32Not()
const {
718 int64_t Val = ~MCE->
getValue() & 0xFFFFFFFF;
722 bool isLogicalImm64Not()
const {
731 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
733 bool isAddSubImm()
const {
734 if (!isShiftedImm() && !isImm())
740 if (isShiftedImm()) {
741 unsigned Shift = ShiftedImm.ShiftAmount;
742 Expr = ShiftedImm.Val;
743 if (Shift != 0 && Shift != 12)
752 if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
753 DarwinRefKind, Addend)) {
768 if (
auto *CE = dyn_cast<MCConstantExpr>(Expr))
769 return CE->getValue() >= 0 &&
CE->getValue() <= 0xfff;
776 bool isAddSubImmNeg()
const {
777 if (!isShiftedImm() && !isImm())
783 if (isShiftedImm()) {
784 unsigned Shift = ShiftedImm.ShiftAmount;
785 Expr = ShiftedImm.Val;
786 if (Shift != 0 && Shift != 12)
796 bool isCondCode()
const {
return Kind == k_CondCode; }
798 bool isSIMDImmType10()
const {
807 bool isBranchTarget26()
const {
816 return (Val >= -(0x2000000 << 2) && Val <= (0x1ffffff << 2));
819 bool isPCRelLabel19()
const {
828 return (Val >= -(0x40000 << 2) && Val <= (0x3ffff << 2));
831 bool isBranchTarget14()
const {
840 return (Val >= -(0x2000 << 2) && Val <= (0x1fff << 2));
851 if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind,
852 DarwinRefKind, Addend)) {
858 for (
unsigned i = 0;
i != AllowedModifiers.
size(); ++
i) {
859 if (ELFRefKind == AllowedModifiers[
i])
866 bool isMovZSymbolG3()
const {
870 bool isMovZSymbolG2()
const {
876 bool isMovZSymbolG1()
const {
877 return isMovWSymbol({
884 bool isMovZSymbolG0()
const {
890 bool isMovKSymbolG3()
const {
894 bool isMovKSymbolG2()
const {
898 bool isMovKSymbolG1()
const {
904 bool isMovKSymbolG0()
const {
910 template<
int RegW
idth,
int Shift>
912 if (!isImm())
return false;
915 if (!CE)
return false;
921 template<
int RegW
idth,
int Shift>
923 if (!isImm())
return false;
926 if (!CE)
return false;
932 bool isFPImm()
const {
return Kind == k_FPImm; }
933 bool isBarrier()
const {
return Kind == k_Barrier; }
934 bool isSysReg()
const {
return Kind == k_SysReg; }
936 bool isMRSSystemRegister()
const {
937 if (!isSysReg())
return false;
939 return SysReg.MRSReg != -1U;
942 bool isMSRSystemRegister()
const {
943 if (!isSysReg())
return false;
944 return SysReg.MSRReg != -1U;
947 bool isSystemPStateFieldWithImm0_1()
const {
948 if (!isSysReg())
return false;
949 return (SysReg.PStateField == AArch64PState::PAN ||
950 SysReg.PStateField == AArch64PState::UAO);
953 bool isSystemPStateFieldWithImm0_15()
const {
954 if (!isSysReg() || isSystemPStateFieldWithImm0_1())
return false;
955 return SysReg.PStateField != -1U;
958 bool isReg()
const override {
return Kind == k_Register && !
Reg.isVector; }
959 bool isVectorReg()
const {
return Kind == k_Register &&
Reg.isVector; }
961 bool isVectorRegLo()
const {
962 return Kind == k_Register &&
Reg.isVector &&
963 AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
967 bool isGPR32as64()
const {
968 return Kind == k_Register && !
Reg.isVector &&
969 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(
Reg.RegNum);
972 bool isWSeqPair()
const {
973 return Kind == k_Register && !
Reg.isVector &&
974 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
978 bool isXSeqPair()
const {
979 return Kind == k_Register && !
Reg.isVector &&
980 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
984 bool isGPR64sp0()
const {
985 return Kind == k_Register && !
Reg.isVector &&
986 AArch64MCRegisterClasses[AArch64::GPR64spRegClassID].contains(
Reg.RegNum);
991 template <
unsigned NumRegs>
bool isImplicitlyTypedVectorList()
const {
992 return Kind == k_VectorList && VectorList.Count == NumRegs &&
993 !VectorList.ElementKind;
996 template <
unsigned NumRegs,
unsigned NumElements,
char ElementKind>
997 bool isTypedVectorList()
const {
998 if (
Kind != k_VectorList)
1000 if (VectorList.Count != NumRegs)
1002 if (VectorList.ElementKind != ElementKind)
1004 return VectorList.NumElements == NumElements;
1007 bool isVectorIndex1()
const {
1008 return Kind == k_VectorIndex && VectorIndex.Val == 1;
1011 bool isVectorIndexB()
const {
1012 return Kind == k_VectorIndex && VectorIndex.Val < 16;
1015 bool isVectorIndexH()
const {
1016 return Kind == k_VectorIndex && VectorIndex.Val < 8;
1019 bool isVectorIndexS()
const {
1020 return Kind == k_VectorIndex && VectorIndex.Val < 4;
1023 bool isVectorIndexD()
const {
1024 return Kind == k_VectorIndex && VectorIndex.Val < 2;
1027 bool isToken()
const override {
return Kind == k_Token; }
1029 bool isTokenEqual(
StringRef Str)
const {
1032 bool isSysCR()
const {
return Kind == k_SysCR; }
1033 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1034 bool isPSBHint()
const {
return Kind == k_PSBHint; }
1035 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1036 bool isShifter()
const {
1037 if (!isShiftExtend())
1045 bool isExtend()
const {
1046 if (!isShiftExtend())
1055 getShiftExtendAmount() <= 4;
1058 bool isExtend64()
const {
1066 bool isExtendLSL64()
const {
1072 getShiftExtendAmount() <= 4;
1075 template<
int W
idth>
bool isMemXExtend()
const {
1080 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1081 getShiftExtendAmount() == 0);
1084 template<
int W
idth>
bool isMemWExtend()
const {
1089 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1090 getShiftExtendAmount() == 0);
1093 template <
unsigned w
idth>
1094 bool isArithmeticShifter()
const {
1104 template <
unsigned w
idth>
1105 bool isLogicalShifter()
const {
1113 getShiftExtendAmount() < width;
1116 bool isMovImm32Shifter()
const {
1124 uint64_t Val = getShiftExtendAmount();
1125 return (Val == 0 || Val == 16);
1128 bool isMovImm64Shifter()
const {
1136 uint64_t Val = getShiftExtendAmount();
1137 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1140 bool isLogicalVecShifter()
const {
1145 unsigned Shift = getShiftExtendAmount();
1147 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1150 bool isLogicalVecHalfWordShifter()
const {
1151 if (!isLogicalVecShifter())
1155 unsigned Shift = getShiftExtendAmount();
1157 (Shift == 0 || Shift == 8);
1160 bool isMoveVecShifter()
const {
1161 if (!isShiftExtend())
1165 unsigned Shift = getShiftExtendAmount();
1167 (Shift == 8 || Shift == 16);
1176 bool isSImm9OffsetFB()
const {
1177 return isSImm9() && !isUImm12Offset<Width / 8>();
1180 bool isAdrpLabel()
const {
1186 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1188 int64_t
Min = - (4096 * (1LL << (21 - 1)));
1189 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1190 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1196 bool isAdrLabel()
const {
1202 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
1204 int64_t
Min = - (1LL << (21 - 1));
1205 int64_t
Max = ((1LL << (21 - 1)) - 1);
1206 return Val >= Min && Val <=
Max;
1216 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1222 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1223 assert(N == 1 &&
"Invalid number of operands!");
1227 void addGPR32as64Operands(
MCInst &Inst,
unsigned N)
const {
1228 assert(N == 1 &&
"Invalid number of operands!");
1230 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].
contains(
getReg()));
1239 void addVectorReg64Operands(
MCInst &Inst,
unsigned N)
const {
1240 assert(N == 1 &&
"Invalid number of operands!");
1242 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1246 void addVectorReg128Operands(
MCInst &Inst,
unsigned N)
const {
1247 assert(N == 1 &&
"Invalid number of operands!");
1249 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1253 void addVectorRegLoOperands(
MCInst &Inst,
unsigned N)
const {
1254 assert(N == 1 &&
"Invalid number of operands!");
1258 template <
unsigned NumRegs>
1259 void addVectorList64Operands(
MCInst &Inst,
unsigned N)
const {
1260 assert(N == 1 &&
"Invalid number of operands!");
1261 static const unsigned FirstRegs[] = { AArch64::D0,
1264 AArch64::D0_D1_D2_D3 };
1265 unsigned FirstReg = FirstRegs[NumRegs - 1];
1271 template <
unsigned NumRegs>
1272 void addVectorList128Operands(
MCInst &Inst,
unsigned N)
const {
1273 assert(N == 1 &&
"Invalid number of operands!");
1274 static const unsigned FirstRegs[] = { AArch64::Q0,
1277 AArch64::Q0_Q1_Q2_Q3 };
1278 unsigned FirstReg = FirstRegs[NumRegs - 1];
1284 void addVectorIndex1Operands(
MCInst &Inst,
unsigned N)
const {
1285 assert(N == 1 &&
"Invalid number of operands!");
1289 void addVectorIndexBOperands(
MCInst &Inst,
unsigned N)
const {
1290 assert(N == 1 &&
"Invalid number of operands!");
1294 void addVectorIndexHOperands(
MCInst &Inst,
unsigned N)
const {
1295 assert(N == 1 &&
"Invalid number of operands!");
1299 void addVectorIndexSOperands(
MCInst &Inst,
unsigned N)
const {
1300 assert(N == 1 &&
"Invalid number of operands!");
1304 void addVectorIndexDOperands(
MCInst &Inst,
unsigned N)
const {
1305 assert(N == 1 &&
"Invalid number of operands!");
1309 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1310 assert(N == 1 &&
"Invalid number of operands!");
1314 addExpr(Inst, getImm());
1317 void addAddSubImmOperands(
MCInst &Inst,
unsigned N)
const {
1318 assert(N == 2 &&
"Invalid number of operands!");
1319 if (isShiftedImm()) {
1320 addExpr(Inst, getShiftedImmVal());
1323 addExpr(Inst, getImm());
1328 void addAddSubImmNegOperands(
MCInst &Inst,
unsigned N)
const {
1329 assert(N == 2 &&
"Invalid number of operands!");
1331 const MCExpr *MCE = isShiftedImm() ? getShiftedImmVal() : getImm();
1334 unsigned ShiftAmt = isShiftedImm() ? ShiftedImm.ShiftAmount : 0;
1340 void addCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
1341 assert(N == 1 &&
"Invalid number of operands!");
1345 void addAdrpLabelOperands(
MCInst &Inst,
unsigned N)
const {
1346 assert(N == 1 &&
"Invalid number of operands!");
1349 addExpr(Inst, getImm());
1354 void addAdrLabelOperands(
MCInst &Inst,
unsigned N)
const {
1355 addImmOperands(Inst, N);
1359 void addUImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
1360 assert(N == 1 &&
"Invalid number of operands!");
1370 void addSImm9Operands(
MCInst &Inst,
unsigned N)
const {
1371 assert(N == 1 &&
"Invalid number of operands!");
1376 void addSImm7s4Operands(
MCInst &Inst,
unsigned N)
const {
1377 assert(N == 1 &&
"Invalid number of operands!");
1382 void addSImm7s8Operands(
MCInst &Inst,
unsigned N)
const {
1383 assert(N == 1 &&
"Invalid number of operands!");
1388 void addSImm7s16Operands(
MCInst &Inst,
unsigned N)
const {
1389 assert(N == 1 &&
"Invalid number of operands!");
1394 void addImm0_1Operands(
MCInst &Inst,
unsigned N)
const {
1395 assert(N == 1 &&
"Invalid number of operands!");
1400 void addImm0_7Operands(
MCInst &Inst,
unsigned N)
const {
1401 assert(N == 1 &&
"Invalid number of operands!");
1406 void addImm1_8Operands(
MCInst &Inst,
unsigned N)
const {
1407 assert(N == 1 &&
"Invalid number of operands!");
1412 void addImm0_15Operands(
MCInst &Inst,
unsigned N)
const {
1413 assert(N == 1 &&
"Invalid number of operands!");
1418 void addImm1_16Operands(
MCInst &Inst,
unsigned N)
const {
1419 assert(N == 1 &&
"Invalid number of operands!");
1421 assert(MCE &&
"Invalid constant immediate operand!");
1425 void addImm0_31Operands(
MCInst &Inst,
unsigned N)
const {
1426 assert(N == 1 &&
"Invalid number of operands!");
1431 void addImm1_31Operands(
MCInst &Inst,
unsigned N)
const {
1432 assert(N == 1 &&
"Invalid number of operands!");
1437 void addImm1_32Operands(
MCInst &Inst,
unsigned N)
const {
1438 assert(N == 1 &&
"Invalid number of operands!");
1443 void addImm0_63Operands(
MCInst &Inst,
unsigned N)
const {
1444 assert(N == 1 &&
"Invalid number of operands!");
1449 void addImm1_63Operands(
MCInst &Inst,
unsigned N)
const {
1450 assert(N == 1 &&
"Invalid number of operands!");
1455 void addImm1_64Operands(
MCInst &Inst,
unsigned N)
const {
1456 assert(N == 1 &&
"Invalid number of operands!");
1461 void addImm0_127Operands(
MCInst &Inst,
unsigned N)
const {
1462 assert(N == 1 &&
"Invalid number of operands!");
1467 void addImm0_255Operands(
MCInst &Inst,
unsigned N)
const {
1468 assert(N == 1 &&
"Invalid number of operands!");
1473 void addImm0_65535Operands(
MCInst &Inst,
unsigned N)
const {
1474 assert(N == 1 &&
"Invalid number of operands!");
1479 void addImm32_63Operands(
MCInst &Inst,
unsigned N)
const {
1480 assert(N == 1 &&
"Invalid number of operands!");
1485 void addLogicalImm32Operands(
MCInst &Inst,
unsigned N)
const {
1486 assert(N == 1 &&
"Invalid number of operands!");
1493 void addLogicalImm64Operands(
MCInst &Inst,
unsigned N)
const {
1494 assert(N == 1 &&
"Invalid number of operands!");
1500 void addLogicalImm32NotOperands(
MCInst &Inst,
unsigned N)
const {
1501 assert(N == 1 &&
"Invalid number of operands!");
1503 int64_t Val = ~MCE->
getValue() & 0xFFFFFFFF;
1508 void addLogicalImm64NotOperands(
MCInst &Inst,
unsigned N)
const {
1509 assert(N == 1 &&
"Invalid number of operands!");
1516 void addSIMDImmType10Operands(
MCInst &Inst,
unsigned N)
const {
1517 assert(N == 1 &&
"Invalid number of operands!");
1523 void addBranchTarget26Operands(
MCInst &Inst,
unsigned N)
const {
1527 assert(N == 1 &&
"Invalid number of operands!");
1530 addExpr(Inst, getImm());
1533 assert(MCE &&
"Invalid constant immediate operand!");
1537 void addPCRelLabel19Operands(
MCInst &Inst,
unsigned N)
const {
1541 assert(N == 1 &&
"Invalid number of operands!");
1544 addExpr(Inst, getImm());
1547 assert(MCE &&
"Invalid constant immediate operand!");
1551 void addBranchTarget14Operands(
MCInst &Inst,
unsigned N)
const {
1555 assert(N == 1 &&
"Invalid number of operands!");
1558 addExpr(Inst, getImm());
1561 assert(MCE &&
"Invalid constant immediate operand!");
1565 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1566 assert(N == 1 &&
"Invalid number of operands!");
1570 void addBarrierOperands(
MCInst &Inst,
unsigned N)
const {
1571 assert(N == 1 &&
"Invalid number of operands!");
1575 void addMRSSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
1576 assert(N == 1 &&
"Invalid number of operands!");
1581 void addMSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
1582 assert(N == 1 &&
"Invalid number of operands!");
1587 void addSystemPStateFieldWithImm0_1Operands(
MCInst &Inst,
unsigned N)
const {
1588 assert(N == 1 &&
"Invalid number of operands!");
1593 void addSystemPStateFieldWithImm0_15Operands(
MCInst &Inst,
unsigned N)
const {
1594 assert(N == 1 &&
"Invalid number of operands!");
1599 void addSysCROperands(
MCInst &Inst,
unsigned N)
const {
1600 assert(N == 1 &&
"Invalid number of operands!");
1604 void addPrefetchOperands(
MCInst &Inst,
unsigned N)
const {
1605 assert(N == 1 &&
"Invalid number of operands!");
1609 void addPSBHintOperands(
MCInst &Inst,
unsigned N)
const {
1610 assert(N == 1 &&
"Invalid number of operands!");
1614 void addShifterOperands(
MCInst &Inst,
unsigned N)
const {
1615 assert(N == 1 &&
"Invalid number of operands!");
1621 void addExtendOperands(
MCInst &Inst,
unsigned N)
const {
1622 assert(N == 1 &&
"Invalid number of operands!");
1629 void addExtend64Operands(
MCInst &Inst,
unsigned N)
const {
1630 assert(N == 1 &&
"Invalid number of operands!");
1637 void addMemExtendOperands(
MCInst &Inst,
unsigned N)
const {
1638 assert(N == 2 &&
"Invalid number of operands!");
1649 void addMemExtend8Operands(
MCInst &Inst,
unsigned N)
const {
1650 assert(N == 2 &&
"Invalid number of operands!");
1658 void addMOVZMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
1659 assert(N == 1 &&
"Invalid number of operands!");
1667 void addMOVNMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
1668 assert(N == 1 &&
"Invalid number of operands!");
1677 static std::unique_ptr<AArch64Operand>
1679 auto Op = make_unique<AArch64Operand>(k_Token, Ctx);
1680 Op->Tok.Data = Str.
data();
1681 Op->Tok.Length = Str.
size();
1682 Op->Tok.IsSuffix = IsSuffix;
1688 static std::unique_ptr<AArch64Operand>
1690 auto Op = make_unique<AArch64Operand>(k_Register, Ctx);
1691 Op->Reg.RegNum = RegNum;
1698 static std::unique_ptr<AArch64Operand>
1699 CreateVectorList(
unsigned RegNum,
unsigned Count,
unsigned NumElements,
1701 auto Op = make_unique<AArch64Operand>(k_VectorList, Ctx);
1702 Op->VectorList.RegNum = RegNum;
1703 Op->VectorList.Count = Count;
1704 Op->VectorList.NumElements = NumElements;
1705 Op->VectorList.ElementKind = ElementKind;
1711 static std::unique_ptr<AArch64Operand>
1713 auto Op = make_unique<AArch64Operand>(k_VectorIndex, Ctx);
1714 Op->VectorIndex.Val = Idx;
1720 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val,
SMLoc S,
1722 auto Op = make_unique<AArch64Operand>(k_Immediate, Ctx);
1729 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
1730 unsigned ShiftAmount,
1733 auto Op = make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
1734 Op->ShiftedImm .Val = Val;
1735 Op->ShiftedImm.ShiftAmount = ShiftAmount;
1741 static std::unique_ptr<AArch64Operand>
1743 auto Op = make_unique<AArch64Operand>(k_CondCode, Ctx);
1744 Op->CondCode.Code =
Code;
1750 static std::unique_ptr<AArch64Operand> CreateFPImm(
unsigned Val,
SMLoc S,
1752 auto Op = make_unique<AArch64Operand>(k_FPImm, Ctx);
1753 Op->FPImm.Val = Val;
1759 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
1763 auto Op = make_unique<AArch64Operand>(k_Barrier, Ctx);
1764 Op->Barrier.Val = Val;
1765 Op->Barrier.Data = Str.
data();
1766 Op->Barrier.Length = Str.
size();
1772 static std::unique_ptr<AArch64Operand> CreateSysReg(
StringRef Str,
SMLoc S,
1777 auto Op = make_unique<AArch64Operand>(k_SysReg, Ctx);
1778 Op->SysReg.Data = Str.
data();
1779 Op->SysReg.Length = Str.
size();
1780 Op->SysReg.MRSReg = MRSReg;
1781 Op->SysReg.MSRReg = MSRReg;
1782 Op->SysReg.PStateField = PStateField;
1788 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val,
SMLoc S,
1790 auto Op = make_unique<AArch64Operand>(k_SysCR, Ctx);
1791 Op->SysCRImm.Val = Val;
1797 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
1801 auto Op = make_unique<AArch64Operand>(k_Prefetch, Ctx);
1802 Op->Prefetch.Val = Val;
1803 Op->Barrier.Data = Str.
data();
1804 Op->Barrier.Length = Str.
size();
1810 static std::unique_ptr<AArch64Operand> CreatePSBHint(
unsigned Val,
1814 auto Op = make_unique<AArch64Operand>(k_PSBHint, Ctx);
1815 Op->PSBHint.Val = Val;
1816 Op->PSBHint.Data = Str.
data();
1817 Op->PSBHint.Length = Str.
size();
1823 static std::unique_ptr<AArch64Operand>
1826 auto Op = make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
1827 Op->ShiftExtend.Type = ShOp;
1828 Op->ShiftExtend.Amount = Val;
1829 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
1838 void AArch64Operand::print(
raw_ostream &OS)
const {
1841 OS <<
"<fpimm " << getFPImm() <<
"("
1847 OS <<
"<barrier " << Name <<
">";
1849 OS <<
"<barrier invalid #" << getBarrier() <<
">";
1855 case k_ShiftedImm: {
1856 unsigned Shift = getShiftedImmShift();
1857 OS <<
"<shiftedimm ";
1858 OS << *getShiftedImmVal();
1863 OS <<
"<condcode " << getCondCode() <<
">";
1866 OS <<
"<register " <<
getReg() <<
">";
1868 case k_VectorList: {
1869 OS <<
"<vectorlist ";
1870 unsigned Reg = getVectorListStart();
1871 for (
unsigned i = 0, e = getVectorListCount();
i != e; ++
i)
1872 OS << Reg +
i <<
" ";
1877 OS <<
"<vectorindex " << getVectorIndex() <<
">";
1880 OS <<
"<sysreg: " << getSysReg() <<
'>';
1886 OS <<
"c" << getSysCR();
1891 OS <<
"<prfop " << Name <<
">";
1893 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
1897 OS << getPSBHintName();
1901 << getShiftExtendAmount();
1902 if (!hasShiftExtendAmount())
1912 static unsigned MatchRegisterName(StringRef Name);
1916 static unsigned matchVectorRegName(StringRef Name) {
1917 return StringSwitch<unsigned>(Name.lower())
1918 .Case("v0", AArch64::Q0)
1919 .Case("v1", AArch64::Q1)
1920 .Case("v2", AArch64::Q2)
1921 .Case("v3", AArch64::Q3)
1922 .Case("v4", AArch64::Q4)
1923 .Case("v5", AArch64::Q5)
1924 .Case("v6", AArch64::Q6)
1925 .Case("v7", AArch64::Q7)
1926 .Case("v8", AArch64::Q8)
1927 .Case("v9", AArch64::Q9)
1928 .Case("v10", AArch64::Q10)
1929 .Case("v11", AArch64::Q11)
1930 .Case("v12", AArch64::Q12)
1931 .Case("v13", AArch64::Q13)
1932 .Case("v14", AArch64::Q14)
1933 .Case("v15", AArch64::Q15)
1934 .Case("v16", AArch64::Q16)
1935 .Case("v17", AArch64::Q17)
1936 .Case("v18", AArch64::Q18)
1937 .Case("v19", AArch64::Q19)
1938 .Case("v20", AArch64::Q20)
1939 .Case("v21", AArch64::Q21)
1940 .Case("v22", AArch64::Q22)
1941 .Case("v23", AArch64::Q23)
1942 .Case("v24", AArch64::Q24)
1943 .Case("v25", AArch64::Q25)
1944 .Case("v26", AArch64::Q26)
1945 .Case("v27", AArch64::Q27)
1946 .Case("v28", AArch64::Q28)
1947 .Case("v29", AArch64::Q29)
1948 .Case("v30", AArch64::Q30)
1949 .Case("v31", AArch64::Q31)
1953 static bool isValidVectorKind(StringRef Name) {
1954 return StringSwitch<bool>(Name.lower())
1964 // Accept the width neutral ones, too, for verbose syntax. If those
1965 // aren'
t used in the right places, the token operand won
't match so
1966 // all will work out.
1971 // Needed for fp16 scalar pairwise reductions
1976 static void parseValidVectorKind(StringRef Name, unsigned &NumElements,
1977 char &ElementKind) {
1978 assert(isValidVectorKind(Name));
1980 ElementKind = Name.lower()[Name.size() - 1];
1983 if (Name.size() == 2)
1986 // Parse the lane count
1987 Name = Name.drop_front();
1988 while (isdigit(Name.front())) {
1989 NumElements = 10 * NumElements + (Name.front() - '0
');
1990 Name = Name.drop_front();
1994 bool AArch64AsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1996 StartLoc = getLoc();
1997 RegNo = tryParseRegister();
1998 EndLoc = SMLoc::getFromPointer(getLoc().getPointer() - 1);
1999 return (RegNo == (unsigned)-1);
2002 // Matches a register name or register alias previously defined by '.req
'
2003 unsigned AArch64AsmParser::matchRegisterNameAlias(StringRef Name,
2005 unsigned RegNum = isVector ? matchVectorRegName(Name)
2006 : MatchRegisterName(Name);
2009 // Check for aliases registered via .req. Canonicalize to lower case.
2010 // That's more consistent since
register names are
case insensitive, and
2012 auto Entry = RegisterReqs.find(Name.
lower());
2013 if (Entry == RegisterReqs.end())
2016 if (
isVector == Entry->getValue().first)
2017 RegNum = Entry->getValue().second;
2025 int AArch64AsmParser::tryParseRegister() {
2032 unsigned RegNum = matchRegisterNameAlias(lowerCase,
false);
2036 .Case(
"fp", AArch64::FP)
2037 .
Case(
"lr", AArch64::LR)
2038 .
Case(
"x31", AArch64::XZR)
2039 .
Case(
"w31", AArch64::WZR)
2051 int AArch64AsmParser::tryMatchVectorRegister(
StringRef &
Kind,
bool expected) {
2054 TokError(
"vector register expected");
2061 size_t Start = 0, Next = Name.
find(
'.');
2063 unsigned RegNum = matchRegisterNameAlias(Head,
true);
2069 TokError(
"invalid vector kind qualifier");
2078 TokError(
"vector register expected");
2084 AArch64AsmParser::tryParseSysCROperand(
OperandVector &Operands) {
2089 Error(S,
"Expected cN operand where 0 <= N <= 15");
2094 if (Tok[0] !=
'c' && Tok[0] !=
'C') {
2095 Error(S,
"Expected cN operand where 0 <= N <= 15");
2101 if (BadNum || CRNum > 15) {
2102 Error(S,
"Expected cN operand where 0 <= N <= 15");
2108 AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
2114 AArch64AsmParser::tryParsePrefetch(
OperandVector &Operands) {
2123 if (getParser().parseExpression(ImmVal))
2128 TokError(
"immediate value expected for prefetch operand");
2133 TokError(
"prefetch operand out of range, [0,31] expected");
2137 auto PRFM = AArch64PRFM::lookupPRFMByEncoding(MCE->
getValue());
2138 Operands.
push_back(AArch64Operand::CreatePrefetch(
2139 prfop, PRFM ? PRFM->Name :
"", S, getContext()));
2144 TokError(
"pre-fetch hint expected");
2148 auto PRFM = AArch64PRFM::lookupPRFMByName(Tok.
getString());
2150 TokError(
"pre-fetch hint expected");
2155 Operands.
push_back(AArch64Operand::CreatePrefetch(
2156 PRFM->Encoding, Tok.
getString(), S, getContext()));
2162 AArch64AsmParser::tryParsePSBHint(
OperandVector &Operands) {
2167 TokError(
"invalid operand for instruction");
2171 auto PSB = AArch64PSBHint::lookupPSBByName(Tok.
getString());
2173 TokError(
"invalid operand for instruction");
2178 Operands.
push_back(AArch64Operand::CreatePSBHint(
2179 PSB->Encoding, Tok.
getString(), S, getContext()));
2186 AArch64AsmParser::tryParseAdrpLabel(
OperandVector &Operands) {
2195 if (parseSymbolicImmVal(Expr))
2201 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
2211 Error(S,
"gotpage label reference not allowed an addend");
2220 Error(S,
"page or gotpage label reference expected");
2229 Operands.
push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2237 AArch64AsmParser::tryParseAdrLabel(
OperandVector &Operands) {
2242 if (getParser().parseExpression(Expr))
2246 Operands.
push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
2268 uint64_t
IntVal = RealVal.bitcastToAPInt().getZExtValue();
2274 if (Val == -1 && !RealVal.isPosZero()) {
2275 TokError(
"expected compatible register or floating-point constant");
2278 Operands.
push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
2285 if (Val > 255 || Val < 0) {
2286 TokError(
"encoded floating point value out of range");
2293 IntVal ^= (uint64_t)isNegative << 63;
2297 Operands.
push_back(AArch64Operand::CreateFPImm(Val, S, getContext()));
2304 TokError(
"invalid floating point immediate");
2310 AArch64AsmParser::tryParseAddSubImm(
OperandVector &Operands) {
2321 if (parseSymbolicImmVal(Imm))
2324 uint64_t ShiftAmount = 0;
2328 if (Val > 0xfff && (Val & 0xfff) == 0) {
2334 Operands.
push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S, E,
2361 if (ShiftAmount < 0) {
2368 Operands.
push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount,
2369 S, E, getContext()));
2399 bool AArch64AsmParser::parseCondCode(
OperandVector &Operands,
2400 bool invertCondCode) {
2409 return TokError(
"invalid condition code");
2412 if (invertCondCode) {
2414 return TokError(
"condition codes AL and NV are invalid for this instruction");
2419 AArch64Operand::CreateCondCode(CC, S, getLoc(), getContext()));
2426 AArch64AsmParser::tryParseOptionalShiftExtend(
OperandVector &Operands) {
2460 TokError(
"expected #imm after shift specifier");
2467 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S, E, getContext()));
2477 Error(E,
"expected integer shift amount");
2482 if (getParser().parseExpression(ImmVal))
2487 Error(E,
"expected constant '#imm' after shift specifier");
2492 Operands.
push_back(AArch64Operand::CreateShiftExtend(
2493 ShOp, MCE->
getValue(),
true, S,
E, getContext()));
2499 bool AArch64AsmParser::parseSysAlias(
StringRef Name,
SMLoc NameLoc,
2502 return TokError(
"invalid operand");
2506 AArch64Operand::CreateToken(
"sys",
false, NameLoc, getContext()));
2513 const MCExpr *Expr =
nullptr;
2515 #define SYS_ALIAS(op1, Cn, Cm, op2) \
2517 Expr = MCConstantExpr::create(op1, getContext()); \
2518 Operands.push_back( \
2519 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); \
2520 Operands.push_back( \
2521 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext())); \
2522 Operands.push_back( \
2523 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext())); \
2524 Expr = MCConstantExpr::create(op2, getContext()); \
2525 Operands.push_back( \
2526 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext())); \
2529 if (Mnemonic ==
"ic") {
2540 return TokError(
"invalid operand for IC instruction");
2542 }
else if (Mnemonic ==
"dc") {
2568 if (getSTI().getFeatureBits()[AArch64::HasV8_2aOps]) {
2572 return TokError(
"DC CVAP requires ARMv8.2a");
2575 return TokError(
"invalid operand for DC instruction");
2577 }
else if (Mnemonic ==
"at") {
2615 if (getSTI().getFeatureBits()[AArch64::HasV8_2aOps]) {
2619 return TokError(
"AT S1E1RP requires ARMv8.2a");
2622 if (getSTI().getFeatureBits()[AArch64::HasV8_2aOps]) {
2626 return TokError(
"AT S1E1WP requires ARMv8.2a");
2629 return TokError(
"invalid operand for AT instruction");
2631 }
else if (Mnemonic ==
"tlbi") {
2729 return TokError(
"invalid operand for TLBI instruction");
2738 bool HasRegister =
false;
2743 return TokError(
"expected register operand");
2747 if (ExpectRegister && !HasRegister) {
2748 return TokError(
"specified " + Mnemonic +
" op requires a register");
2750 else if (!ExpectRegister && HasRegister) {
2751 return TokError(
"specified " + Mnemonic +
" op does not use a register");
2761 AArch64AsmParser::tryParseBarrierOperand(
OperandVector &Operands) {
2770 SMLoc ExprLoc = getLoc();
2771 if (getParser().parseExpression(ImmVal))
2775 Error(ExprLoc,
"immediate value expected for barrier operand");
2779 Error(ExprLoc,
"barrier operand out of range");
2782 auto DB = AArch64DB::lookupDBByEncoding(MCE->
getValue());
2783 Operands.
push_back(AArch64Operand::CreateBarrier(
2784 MCE->
getValue(), DB ? DB->Name :
"", ExprLoc, getContext()));
2789 TokError(
"invalid operand for instruction");
2793 auto DB = AArch64DB::lookupDBByName(Tok.
getString());
2795 TokError(
"invalid barrier option name");
2800 if (Mnemonic ==
"isb" && DB->Encoding != AArch64DB::sy) {
2801 TokError(
"'sy' or #imm operand expected");
2805 Operands.
push_back(AArch64Operand::CreateBarrier(
2806 DB->Encoding, Tok.
getString(), getLoc(), getContext()));
2822 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
2823 MRSReg = SysReg->
Readable ? SysReg->Encoding : -1;
2824 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
2828 auto PState = AArch64PState::lookupPStateByName(Tok.
getString());
2829 unsigned PStateImm = -1;
2830 if (PState && PState->haveFeatures(getSTI().getFeatureBits()))
2831 PStateImm = PState->Encoding;
2834 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
2835 PStateImm, getContext()));
2842 bool AArch64AsmParser::tryParseVectorRegister(
OperandVector &Operands) {
2850 int64_t Reg = tryMatchVectorRegister(Kind,
false);
2854 AArch64Operand::CreateReg(Reg,
true, S, getLoc(), getContext()));
2859 AArch64Operand::CreateToken(Kind,
false, S, getContext()));
2862 SMLoc SIdx = getLoc();
2865 if (getParser().parseExpression(ImmVal))
2869 TokError(
"immediate value expected for vector index");
2886 bool AArch64AsmParser::parseRegister(
OperandVector &Operands) {
2890 if (!tryParseVectorRegister(Operands))
2894 int64_t Reg = tryParseRegister();
2898 AArch64Operand::CreateReg(Reg,
false, S, getLoc(), getContext()));
2902 SMLoc LBracS = getLoc();
2906 SMLoc IntS = getLoc();
2910 SMLoc RBracS = getLoc();
2913 AArch64Operand::CreateToken(
"[",
false, LBracS, getContext()));
2915 AArch64Operand::CreateToken(
"1",
false, IntS, getContext()));
2917 AArch64Operand::CreateToken(
"]",
false, RBracS, getContext()));
2927 bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
2929 bool HasELFModifier =
false;
2933 HasELFModifier =
true;
2936 return TokError(
"expect relocation specifier in operand after ':'");
2978 return TokError(
"expect relocation specifier in operand after ':'");
2982 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
2986 if (getParser().parseExpression(ImmVal))
2996 bool AArch64AsmParser::parseVectorList(
OperandVector &Operands) {
3002 int64_t FirstReg = tryMatchVectorRegister(Kind,
true);
3005 int64_t PrevReg = FirstReg;
3009 SMLoc Loc = getLoc();
3011 int64_t Reg = tryMatchVectorRegister(NextKind,
true);
3015 if (Kind != NextKind)
3016 return Error(Loc,
"mismatched register size suffix");
3018 unsigned Space = (PrevReg <
Reg) ? (Reg - PrevReg) : (Reg + 32 - PrevReg);
3020 if (Space == 0 || Space > 3) {
3021 return Error(Loc,
"invalid number of vectors");
3028 SMLoc Loc = getLoc();
3030 int64_t Reg = tryMatchVectorRegister(NextKind,
true);
3034 if (Kind != NextKind)
3035 return Error(Loc,
"mismatched register size suffix");
3038 if (getContext().getRegisterInfo()->getEncodingValue(Reg) !=
3039 (getContext().getRegisterInfo()->getEncodingValue(PrevReg) + 1) % 32)
3040 return Error(Loc,
"registers must be sequential");
3051 return Error(S,
"invalid number of vectors");
3053 unsigned NumElements = 0;
3054 char ElementKind = 0;
3058 Operands.
push_back(AArch64Operand::CreateVectorList(
3059 FirstReg, Count, NumElements, ElementKind, S, getLoc(), getContext()));
3062 SMLoc SIdx = getLoc();
3065 if (getParser().parseExpression(ImmVal))
3069 TokError(
"immediate value expected for vector index");
3084 AArch64AsmParser::tryParseGPR64sp0Operand(
OperandVector &Operands) {
3090 unsigned RegNum = matchRegisterNameAlias(Tok.
getString().
lower(),
false);
3102 AArch64Operand::CreateReg(RegNum,
false, S, getLoc(), Ctx));
3109 Error(getLoc(),
"index must be absent or #0");
3115 cast<MCConstantExpr>(ImmVal)->getValue() != 0) {
3116 Error(getLoc(),
"index must be absent or #0");
3121 AArch64Operand::CreateReg(RegNum,
false, S, getLoc(), Ctx));
3127 bool AArch64AsmParser::parseOperand(
OperandVector &Operands,
bool isCondCode,
3128 bool invertCondCode) {
3143 switch (getLexer().getKind()) {
3147 if (parseSymbolicImmVal(Expr))
3148 return Error(S,
"invalid operand");
3151 Operands.
push_back(AArch64Operand::CreateImm(Expr, S, E, getContext()));
3156 Operands.
push_back(AArch64Operand::CreateToken(
"[",
false, Loc,
3162 return parseOperand(Operands,
false,
false);
3165 return parseVectorList(Operands);
3169 return parseCondCode(Operands, invertCondCode);
3172 if (!parseRegister(Operands))
3185 if (getParser().parseExpression(IdVal))
3188 Operands.
push_back(AArch64Operand::CreateImm(IdVal, S, E, getContext()));
3200 bool isNegative =
false;
3216 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
3217 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
3218 Mnemonic !=
"fcmlt")
3219 return TokError(
"unexpected floating point literal");
3220 else if (IntVal != 0 || isNegative)
3221 return TokError(
"expected floating-point constant #0.0");
3225 AArch64Operand::CreateToken(
"#0",
false, S, getContext()));
3227 AArch64Operand::CreateToken(
".0",
false, S, getContext()));
3232 if (parseSymbolicImmVal(ImmVal))
3236 Operands.
push_back(AArch64Operand::CreateImm(ImmVal, S, E, getContext()));
3240 SMLoc Loc = getLoc();
3241 if (Mnemonic !=
"ldr")
3242 return TokError(
"unexpected token in operand");
3244 const MCExpr *SubExprVal;
3245 if (getParser().parseExpression(SubExprVal))
3248 if (Operands.
size() < 2 ||
3249 !
static_cast<AArch64Operand &
>(*Operands[1]).
isReg())
3250 return Error(Loc,
"Only valid when first operand is register");
3253 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3259 if (isa<MCConstantExpr>(SubExprVal)) {
3260 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
3261 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
3266 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
3267 Operands[0] = AArch64Operand::CreateToken(
"movz",
false, Loc, Ctx);
3268 Operands.
push_back(AArch64Operand::CreateImm(
3272 ShiftAmt,
true, S, E, Ctx));
3278 return Error(Loc,
"Immediate too large for register");
3282 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
3283 Operands.
push_back(AArch64Operand::CreateImm(CPLoc, S, E, Ctx));
3296 .Case(
"beq",
"b.eq")
3297 .
Case(
"bne",
"b.ne")
3298 .
Case(
"bhs",
"b.hs")
3299 .
Case(
"bcs",
"b.cs")
3300 .
Case(
"blo",
"b.lo")
3301 .
Case(
"bcc",
"b.cc")
3302 .
Case(
"bmi",
"b.mi")
3303 .
Case(
"bpl",
"b.pl")
3304 .
Case(
"bvs",
"b.vs")
3305 .
Case(
"bvc",
"b.vc")
3306 .
Case(
"bhi",
"b.hi")
3307 .
Case(
"bls",
"b.ls")
3308 .
Case(
"bge",
"b.ge")
3309 .
Case(
"blt",
"b.lt")
3310 .
Case(
"bgt",
"b.gt")
3311 .
Case(
"ble",
"b.le")
3312 .
Case(
"bal",
"b.al")
3313 .
Case(
"bnv",
"b.nv")
3319 parseDirectiveReq(Name, NameLoc);
3326 size_t Start = 0, Next = Name.
find(
'.');
3330 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi")
3331 return parseSysAlias(Head, NameLoc, Operands);
3334 AArch64Operand::CreateToken(Head,
false, NameLoc, getContext()));
3340 Next = Name.
find(
'.', Start + 1);
3341 Head = Name.
slice(Start + 1, Next);
3347 return Error(SuffixLoc,
"invalid condition code");
3349 AArch64Operand::CreateToken(
".",
true, SuffixLoc, getContext()));
3351 AArch64Operand::CreateCondCode(CC, NameLoc, NameLoc, getContext()));
3357 Next = Name.
find(
'.', Start + 1);
3358 Head = Name.
slice(Start, Next);
3362 AArch64Operand::CreateToken(Head,
true, SuffixLoc, getContext()));
3367 bool condCodeFourthOperand =
3368 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
3369 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
3370 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
3378 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
3379 bool condCodeThirdOperand =
3380 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
3385 if (parseOperand(Operands,
false,
false)) {
3392 if (parseOperand(Operands, (N == 4 && condCodeFourthOperand) ||
3393 (N == 3 && condCodeThirdOperand) ||
3394 (N == 2 && condCodeSecondOperand),
3395 condCodeSecondOperand || condCodeThirdOperand)) {
3411 AArch64Operand::CreateToken(
"]",
false, RLoc, getContext()));
3415 AArch64Operand::CreateToken(
"!",
false, ELoc, getContext()));
3430 bool AArch64AsmParser::validateInstruction(
MCInst &Inst,
3437 case AArch64::LDPSWpre:
3438 case AArch64::LDPWpost:
3439 case AArch64::LDPWpre:
3440 case AArch64::LDPXpost:
3441 case AArch64::LDPXpre: {
3446 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
3447 "is also a destination");
3449 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
3450 "is also a destination");
3453 case AArch64::LDPDi:
3454 case AArch64::LDPQi:
3455 case AArch64::LDPSi:
3456 case AArch64::LDPSWi:
3457 case AArch64::LDPWi:
3458 case AArch64::LDPXi: {
3462 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
3465 case AArch64::LDPDpost:
3466 case AArch64::LDPDpre:
3467 case AArch64::LDPQpost:
3468 case AArch64::LDPQpre:
3469 case AArch64::LDPSpost:
3470 case AArch64::LDPSpre:
3471 case AArch64::LDPSWpost: {
3475 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
3478 case AArch64::STPDpost:
3479 case AArch64::STPDpre:
3480 case AArch64::STPQpost:
3481 case AArch64::STPQpre:
3482 case AArch64::STPSpost:
3483 case AArch64::STPSpre:
3484 case AArch64::STPWpost:
3485 case AArch64::STPWpre:
3486 case AArch64::STPXpost:
3487 case AArch64::STPXpre: {
3492 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
3493 "is also a source");
3495 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
3496 "is also a source");
3499 case AArch64::LDRBBpre:
3500 case AArch64::LDRBpre:
3501 case AArch64::LDRHHpre:
3502 case AArch64::LDRHpre:
3503 case AArch64::LDRSBWpre:
3504 case AArch64::LDRSBXpre:
3505 case AArch64::LDRSHWpre:
3506 case AArch64::LDRSHXpre:
3507 case AArch64::LDRSWpre:
3508 case AArch64::LDRWpre:
3509 case AArch64::LDRXpre:
3510 case AArch64::LDRBBpost:
3511 case AArch64::LDRBpost:
3512 case AArch64::LDRHHpost:
3513 case AArch64::LDRHpost:
3514 case AArch64::LDRSBWpost:
3515 case AArch64::LDRSBXpost:
3516 case AArch64::LDRSHWpost:
3517 case AArch64::LDRSHXpost:
3518 case AArch64::LDRSWpost:
3519 case AArch64::LDRWpost:
3520 case AArch64::LDRXpost: {
3524 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
3525 "is also a source");
3528 case AArch64::STRBBpost:
3529 case AArch64::STRBpost:
3530 case AArch64::STRHHpost:
3531 case AArch64::STRHpost:
3532 case AArch64::STRWpost:
3533 case AArch64::STRXpost:
3534 case AArch64::STRBBpre:
3535 case AArch64::STRBpre:
3536 case AArch64::STRHHpre:
3537 case AArch64::STRHpre:
3538 case AArch64::STRWpre:
3539 case AArch64::STRXpre: {
3543 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
3544 "is also a source");
3553 case AArch64::ADDSWri:
3554 case AArch64::ADDSXri:
3555 case AArch64::ADDWri:
3556 case AArch64::ADDXri:
3557 case AArch64::SUBSWri:
3558 case AArch64::SUBSXri:
3559 case AArch64::SUBWri:
3560 case AArch64::SUBXri: {
3568 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3593 return Error(Loc.
back(),
"invalid immediate expression");
3604 bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode) {
3606 case Match_MissingFeature:
3608 "instruction requires a CPU feature not currently enabled");
3609 case Match_InvalidOperand:
3610 return Error(Loc,
"invalid operand for instruction");
3611 case Match_InvalidSuffix:
3612 return Error(Loc,
"invalid type suffix for instruction");
3613 case Match_InvalidCondCode:
3614 return Error(Loc,
"expected AArch64 condition code");
3615 case Match_AddSubRegExtendSmall:
3617 "expected '[su]xt[bhw]' or 'lsl' with optional integer in range [0, 4]");
3618 case Match_AddSubRegExtendLarge:
3620 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
3621 case Match_AddSubSecondSource:
3623 "expected compatible register, symbol or integer in range [0, 4095]");
3624 case Match_LogicalSecondSource:
3625 return Error(Loc,
"expected compatible register or logical immediate");
3626 case Match_InvalidMovImm32Shift:
3627 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
3628 case Match_InvalidMovImm64Shift:
3629 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
3630 case Match_AddSubRegShift32:
3632 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
3633 case Match_AddSubRegShift64:
3635 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
3636 case Match_InvalidFPImm:
3638 "expected compatible register or floating-point constant");
3639 case Match_InvalidMemoryIndexedSImm9:
3640 return Error(Loc,
"index must be an integer in range [-256, 255].");
3641 case Match_InvalidMemoryIndexed4SImm7:
3642 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
3643 case Match_InvalidMemoryIndexed8SImm7:
3644 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
3645 case Match_InvalidMemoryIndexed16SImm7:
3646 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
3647 case Match_InvalidMemoryWExtend8:
3649 "expected 'uxtw' or 'sxtw' with optional shift of #0");
3650 case Match_InvalidMemoryWExtend16:
3652 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
3653 case Match_InvalidMemoryWExtend32:
3655 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
3656 case Match_InvalidMemoryWExtend64:
3658 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
3659 case Match_InvalidMemoryWExtend128:
3661 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
3662 case Match_InvalidMemoryXExtend8:
3664 "expected 'lsl' or 'sxtx' with optional shift of #0");
3665 case Match_InvalidMemoryXExtend16:
3667 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
3668 case Match_InvalidMemoryXExtend32:
3670 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
3671 case Match_InvalidMemoryXExtend64:
3673 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
3674 case Match_InvalidMemoryXExtend128:
3676 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
3677 case Match_InvalidMemoryIndexed1:
3678 return Error(Loc,
"index must be an integer in range [0, 4095].");
3679 case Match_InvalidMemoryIndexed2:
3680 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
3681 case Match_InvalidMemoryIndexed4:
3682 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
3683 case Match_InvalidMemoryIndexed8:
3684 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
3685 case Match_InvalidMemoryIndexed16:
3686 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
3687 case Match_InvalidImm0_1:
3688 return Error(Loc,
"immediate must be an integer in range [0, 1].");
3689 case Match_InvalidImm0_7:
3690 return Error(Loc,
"immediate must be an integer in range [0, 7].");
3691 case Match_InvalidImm0_15:
3692 return Error(Loc,
"immediate must be an integer in range [0, 15].");
3693 case Match_InvalidImm0_31:
3694 return Error(Loc,
"immediate must be an integer in range [0, 31].");
3695 case Match_InvalidImm0_63:
3696 return Error(Loc,
"immediate must be an integer in range [0, 63].");
3697 case Match_InvalidImm0_127:
3698 return Error(Loc,
"immediate must be an integer in range [0, 127].");
3699 case Match_InvalidImm0_65535:
3700 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
3701 case Match_InvalidImm1_8:
3702 return Error(Loc,
"immediate must be an integer in range [1, 8].");
3703 case Match_InvalidImm1_16:
3704 return Error(Loc,
"immediate must be an integer in range [1, 16].");
3705 case Match_InvalidImm1_32:
3706 return Error(Loc,
"immediate must be an integer in range [1, 32].");
3707 case Match_InvalidImm1_64:
3708 return Error(Loc,
"immediate must be an integer in range [1, 64].");
3709 case Match_InvalidIndex1:
3710 return Error(Loc,
"expected lane specifier '[1]'");
3711 case Match_InvalidIndexB:
3712 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
3713 case Match_InvalidIndexH:
3714 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
3715 case Match_InvalidIndexS:
3716 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
3717 case Match_InvalidIndexD:
3718 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
3719 case Match_InvalidLabel:
3720 return Error(Loc,
"expected label or encodable integer pc offset");
3722 return Error(Loc,
"expected readable system register");
3724 return Error(Loc,
"expected writable system register or pstate");
3725 case Match_MnemonicFail:
3726 return Error(Loc,
"unrecognized instruction mnemonic");
3734 bool AArch64AsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
3738 bool MatchingInlineAsm) {
3739 assert(!Operands.
empty() &&
"Unexpect empty operand list!");
3740 AArch64Operand &Op =
static_cast<AArch64Operand &
>(*Operands[0]);
3741 assert(Op.isToken() &&
"Leading operand should always be a mnemonic!");
3744 unsigned NumOperands = Operands.
size();
3746 if (NumOperands == 4 && Tok ==
"lsl") {
3747 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*Operands[2]);
3748 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
3749 if (Op2.isReg() && Op3.isImm()) {
3752 uint64_t Op3Val = Op3CE->
getValue();
3753 uint64_t NewOp3Val = 0;
3754 uint64_t NewOp4Val = 0;
3755 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].
contains(
3757 NewOp3Val = (32 - Op3Val) & 0x1f;
3758 NewOp4Val = 31 - Op3Val;
3760 NewOp3Val = (64 - Op3Val) & 0x3f;
3761 NewOp4Val = 63 - Op3Val;
3767 Operands[0] = AArch64Operand::CreateToken(
3768 "ubfm",
false, Op.getStartLoc(), getContext());
3769 Operands.
push_back(AArch64Operand::CreateImm(
3770 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
3771 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
3772 Op3.getEndLoc(), getContext());
3775 }
else if (NumOperands == 4 && Tok ==
"bfc") {
3777 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
3778 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*Operands[2]);
3779 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*Operands[3]);
3781 if (Op1.isReg() && LSBOp.isImm() && WidthOp.isImm()) {
3785 if (LSBCE && WidthCE) {
3787 uint64_t Width = WidthCE->getValue();
3789 uint64_t RegWidth = 0;
3790 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
3796 if (LSB >= RegWidth)
3797 return Error(LSBOp.getStartLoc(),
3798 "expected integer in range [0, 31]");
3799 if (Width < 1 || Width > RegWidth)
3800 return Error(WidthOp.getStartLoc(),
3801 "expected integer in range [1, 32]");
3805 ImmR = (32 - LSB) & 0x1f;
3807 ImmR = (64 - LSB) & 0x3f;
3809 uint64_t ImmS = Width - 1;
3811 if (ImmR != 0 && ImmS >= ImmR)
3812 return Error(WidthOp.getStartLoc(),
3813 "requested insert overflows register");
3817 Operands[0] = AArch64Operand::CreateToken(
3818 "bfm",
false, Op.getStartLoc(), getContext());
3819 Operands[2] = AArch64Operand::CreateReg(
3820 RegWidth == 32 ? AArch64::WZR : AArch64::XZR,
false,
SMLoc(),
3821 SMLoc(), getContext());
3822 Operands[3] = AArch64Operand::CreateImm(
3823 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
3824 Operands.emplace_back(
3825 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
3826 WidthOp.getEndLoc(), getContext()));
3829 }
else if (NumOperands == 5) {
3832 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
3833 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
3834 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
3835 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
3837 if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3841 if (Op3CE && Op4CE) {
3842 uint64_t Op3Val = Op3CE->
getValue();
3843 uint64_t Op4Val = Op4CE->getValue();
3845 uint64_t RegWidth = 0;
3846 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
3852 if (Op3Val >= RegWidth)
3853 return Error(Op3.getStartLoc(),
3854 "expected integer in range [0, 31]");
3855 if (Op4Val < 1 || Op4Val > RegWidth)
3856 return Error(Op4.getStartLoc(),
3857 "expected integer in range [1, 32]");
3859 uint64_t NewOp3Val = 0;
3861 NewOp3Val = (32 - Op3Val) & 0x1f;
3863 NewOp3Val = (64 - Op3Val) & 0x3f;
3865 uint64_t NewOp4Val = Op4Val - 1;
3867 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
3868 return Error(Op4.getStartLoc(),
3869 "requested insert overflows register");
3875 Operands[3] = AArch64Operand::CreateImm(
3876 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
3877 Operands[4] = AArch64Operand::CreateImm(
3878 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
3880 Operands[0] = AArch64Operand::CreateToken(
3881 "bfm",
false, Op.getStartLoc(), getContext());
3882 else if (Tok ==
"sbfiz")
3883 Operands[0] = AArch64Operand::CreateToken(
3884 "sbfm",
false, Op.getStartLoc(), getContext());
3885 else if (Tok ==
"ubfiz")
3886 Operands[0] = AArch64Operand::CreateToken(
3887 "ubfm",
false, Op.getStartLoc(), getContext());
3895 }
else if (NumOperands == 5 &&
3896 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
3897 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*Operands[1]);
3898 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*Operands[3]);
3899 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*Operands[4]);
3901 if (Op1.isReg() && Op3.isImm() && Op4.isImm()) {
3905 if (Op3CE && Op4CE) {
3906 uint64_t Op3Val = Op3CE->
getValue();
3907 uint64_t Op4Val = Op4CE->getValue();
3909 uint64_t RegWidth = 0;
3910 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
3916 if (Op3Val >= RegWidth)
3917 return Error(Op3.getStartLoc(),
3918 "expected integer in range [0, 31]");
3919 if (Op4Val < 1 || Op4Val > RegWidth)
3920 return Error(Op4.getStartLoc(),
3921 "expected integer in range [1, 32]");
3923 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
3925 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
3926 return Error(Op4.getStartLoc(),
3927 "requested extract overflows register");
3931 Operands[4] = AArch64Operand::CreateImm(
3932 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
3934 Operands[0] = AArch64Operand::CreateToken(
3935 "bfm",
false, Op.getStartLoc(), getContext());
3936 else if (Tok ==
"sbfx")
3937 Operands[0] = AArch64Operand::CreateToken(
3938 "sbfm",
false, Op.getStartLoc(), getContext());
3939 else if (Tok ==
"ubfx")
3940 Operands[0] = AArch64Operand::CreateToken(
3941 "ubfm",
false, Op.getStartLoc(), getContext());
3951 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
3954 AArch64Operand &Op =
static_cast<AArch64Operand &
>(*Operands[2]);
3957 Operands[2] = AArch64Operand::CreateReg(Reg,
false, Op.getStartLoc(),
3958 Op.getEndLoc(), getContext());
3962 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
3963 AArch64Operand &Op =
static_cast<AArch64Operand &
>(*Operands[1]);
3965 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3969 AArch64Operand &Op =
static_cast<AArch64Operand &
>(*Operands[2]);
3972 Operands[2] = AArch64Operand::CreateReg(Reg,
false, Op.getStartLoc(),
3973 Op.getEndLoc(), getContext());
3978 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
3979 AArch64Operand &Op =
static_cast<AArch64Operand &
>(*Operands[1]);
3981 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
3985 AArch64Operand &Op =
static_cast<AArch64Operand &
>(*Operands[1]);
3988 Operands[1] = AArch64Operand::CreateReg(Reg,
false, Op.getStartLoc(),
3989 Op.getEndLoc(), getContext());
3995 if (NumOperands == 3 && Tok ==
"fmov") {
3996 AArch64Operand &RegOp =
static_cast<AArch64Operand &
>(*Operands[1]);
3997 AArch64Operand &ImmOp =
static_cast<AArch64Operand &
>(*Operands[2]);
3998 if (RegOp.isReg() && ImmOp.isFPImm() && ImmOp.getFPImm() == (
unsigned)-1) {
4000 !AArch64MCRegisterClasses[AArch64::FPR64RegClassID].contains(
4004 Operands[2] = AArch64Operand::CreateReg(zreg,
false, Op.getStartLoc(),
4005 Op.getEndLoc(), getContext());
4012 unsigned MatchResult =
4013 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 1);
4017 if (MatchResult != Match_Success) {
4020 auto ShortFormNEONErrorInfo = ErrorInfo;
4021 auto ShortFormNEONMatchResult = MatchResult;
4024 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm, 0);
4029 if (MatchResult == Match_InvalidOperand && ErrorInfo == 1 &&
4030 Operands.size() > 1 && ((AArch64Operand &)*Operands[1]).isToken() &&
4031 ((AArch64Operand &)*Operands[1]).isTokenSuffix()) {
4032 MatchResult = ShortFormNEONMatchResult;
4033 ErrorInfo = ShortFormNEONErrorInfo;
4037 switch (MatchResult) {
4038 case Match_Success: {
4041 NumOperands = Operands.size();
4042 for (
unsigned i = 1;
i < NumOperands; ++
i)
4043 OperandLocs.
push_back(Operands[
i]->getStartLoc());
4044 if (validateInstruction(Inst, OperandLocs))
4051 case Match_MissingFeature: {
4052 assert(ErrorInfo &&
"Unknown missing feature!");
4055 std::string Msg =
"instruction requires:";
4057 for (
unsigned i = 0;
i < (
sizeof(ErrorInfo)*8-1); ++
i) {
4058 if (ErrorInfo & Mask) {
4064 return Error(IDLoc, Msg);
4066 case Match_MnemonicFail:
4067 return showMatchError(IDLoc, MatchResult);
4068 case Match_InvalidOperand: {
4069 SMLoc ErrorLoc = IDLoc;
4071 if (ErrorInfo != ~0ULL) {
4072 if (ErrorInfo >= Operands.size())
4073 return Error(IDLoc,
"too few operands for instruction",
4074 SMRange(IDLoc, getTok().getLoc()));
4076 ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
4077 if (ErrorLoc ==
SMLoc())
4082 if (((AArch64Operand &)*Operands[ErrorInfo]).isToken() &&
4083 ((AArch64Operand &)*Operands[ErrorInfo]).isTokenSuffix())
4084 MatchResult = Match_InvalidSuffix;
4086 return showMatchError(ErrorLoc, MatchResult);
4088 case Match_InvalidMemoryIndexed1:
4089 case Match_InvalidMemoryIndexed2:
4090 case Match_InvalidMemoryIndexed4:
4091 case Match_InvalidMemoryIndexed8:
4092 case Match_InvalidMemoryIndexed16:
4093 case Match_InvalidCondCode:
4094 case Match_AddSubRegExtendSmall:
4095 case Match_AddSubRegExtendLarge:
4096 case Match_AddSubSecondSource:
4097 case Match_LogicalSecondSource:
4098 case Match_AddSubRegShift32:
4099 case Match_AddSubRegShift64:
4100 case Match_InvalidMovImm32Shift:
4101 case Match_InvalidMovImm64Shift:
4102 case Match_InvalidFPImm:
4103 case Match_InvalidMemoryWExtend8:
4104 case Match_InvalidMemoryWExtend16:
4105 case Match_InvalidMemoryWExtend32:
4106 case Match_InvalidMemoryWExtend64:
4107 case Match_InvalidMemoryWExtend128:
4108 case Match_InvalidMemoryXExtend8:
4109 case Match_InvalidMemoryXExtend16:
4110 case Match_InvalidMemoryXExtend32:
4111 case Match_InvalidMemoryXExtend64:
4112 case Match_InvalidMemoryXExtend128:
4113 case Match_InvalidMemoryIndexed4SImm7:
4114 case Match_InvalidMemoryIndexed8SImm7:
4115 case Match_InvalidMemoryIndexed16SImm7:
4116 case Match_InvalidMemoryIndexedSImm9:
4117 case Match_InvalidImm0_1:
4118 case Match_InvalidImm0_7:
4119 case Match_InvalidImm0_15:
4120 case Match_InvalidImm0_31:
4121 case Match_InvalidImm0_63:
4122 case Match_InvalidImm0_127:
4123 case Match_InvalidImm0_65535:
4124 case Match_InvalidImm1_8:
4125 case Match_InvalidImm1_16:
4126 case Match_InvalidImm1_32:
4127 case Match_InvalidImm1_64:
4128 case Match_InvalidIndex1:
4129 case Match_InvalidIndexB:
4130 case Match_InvalidIndexH:
4131 case Match_InvalidIndexS:
4132 case Match_InvalidIndexD:
4133 case Match_InvalidLabel:
4136 if (ErrorInfo >= Operands.size())
4137 return Error(IDLoc,
"too few operands for instruction",
SMRange(IDLoc, (*Operands.back()).getEndLoc()));
4140 SMLoc ErrorLoc = ((AArch64Operand &)*Operands[ErrorInfo]).getStartLoc();
4141 if (ErrorLoc ==
SMLoc())
4143 return showMatchError(ErrorLoc, MatchResult);
4151 bool AArch64AsmParser::ParseDirective(
AsmToken DirectiveID) {
4153 getContext().getObjectFileInfo()->getObjectFileType();
4159 if (IDVal ==
".arch")
4160 parseDirectiveArch(Loc);
4161 else if (IDVal ==
".cpu")
4162 parseDirectiveCPU(Loc);
4163 else if (IDVal ==
".hword")
4164 parseDirectiveWord(2, Loc);
4165 else if (IDVal ==
".word")
4166 parseDirectiveWord(4, Loc);
4167 else if (IDVal ==
".xword")
4168 parseDirectiveWord(8, Loc);
4169 else if (IDVal ==
".tlsdesccall")
4170 parseDirectiveTLSDescCall(Loc);
4171 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
4172 parseDirectiveLtorg(Loc);
4173 else if (IDVal ==
".unreq")
4174 parseDirectiveUnreq(Loc);
4175 else if (!IsMachO && !IsCOFF) {
4176 if (IDVal ==
".inst")
4177 parseDirectiveInst(Loc);
4181 parseDirectiveLOH(IDVal, Loc);
4187 static const struct {
4191 {
"crc", {AArch64::FeatureCRC} },
4192 {
"crypto", {AArch64::FeatureCrypto} },
4193 {
"fp", {AArch64::FeatureFPARMv8} },
4194 {
"simd", {AArch64::FeatureNEON} },
4195 {
"ras", {AArch64::FeatureRAS} },
4196 {
"lse", {AArch64::FeatureLSE} },
4207 bool AArch64AsmParser::parseDirectiveArch(
SMLoc L) {
4208 SMLoc ArchLoc = getLoc();
4211 std::tie(Arch, ExtensionString) =
4212 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
4215 if (ID == static_cast<unsigned>(AArch64::ArchKind::AK_INVALID))
4216 return Error(ArchLoc,
"unknown arch name");
4222 std::vector<StringRef> AArch64Features;
4228 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
4232 if (!ExtensionString.
empty())
4233 ExtensionString.
split(RequestedExtensions,
'+');
4236 for (
auto Name : RequestedExtensions) {
4237 bool EnableFeature =
true;
4240 EnableFeature =
false;
4245 if (Extension.Name != Name)
4248 if (Extension.Features.none())
4252 ? (~Features & Extension.Features)
4253 : ( Features & Extension.Features);
4255 ComputeAvailableFeatures(STI.
ToggleFeature(ToggleFeatures));
4256 setAvailableFeatures(Features);
4265 bool AArch64AsmParser::parseDirectiveCPU(
SMLoc L) {
4266 SMLoc CPULoc = getLoc();
4269 std::tie(CPU, ExtensionString) =
4270 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
4276 if (!ExtensionString.
empty())
4277 ExtensionString.
split(RequestedExtensions,
'+');
4281 if (!getSTI().isCPUStringValid(CPU)) {
4282 Error(CPULoc,
"unknown CPU name");
4290 for (
auto Name : RequestedExtensions) {
4291 bool EnableFeature =
true;
4294 EnableFeature =
false;
4298 for (
const auto &Extension : ExtensionMap) {
4299 if (Extension.Name != Name)
4302 if (Extension.Features.none())
4306 ? (~Features & Extension.Features)
4307 : ( Features & Extension.Features);
4309 ComputeAvailableFeatures(STI.
ToggleFeature(ToggleFeatures));
4310 setAvailableFeatures(Features);
4320 bool AArch64AsmParser::parseDirectiveWord(
unsigned Size,
SMLoc L) {
4321 auto parseOp = [&]() ->
bool {
4323 if (getParser().parseExpression(Value))
4325 getParser().getStreamer().EmitValue(Value, Size, L);
4329 if (parseMany(parseOp))
4336 bool AArch64AsmParser::parseDirectiveInst(
SMLoc Loc) {
4338 return Error(Loc,
"expected expression following '.inst' directive");
4340 auto parseOp = [&]() ->
bool {
4343 if (check(getParser().parseExpression(Expr), L,
"expected expression"))
4345 const MCConstantExpr *Value = dyn_cast_or_null<MCConstantExpr>(Expr);
4346 if (check(!Value, L,
"expected constant expression"))
4348 getTargetStreamer().emitInst(Value->
getValue());
4352 if (parseMany(parseOp))
4353 return addErrorSuffix(
" in '.inst' directive");
4359 bool AArch64AsmParser::parseDirectiveTLSDescCall(
SMLoc L) {
4361 if (check(getParser().parseIdentifier(Name), L,
4362 "expected symbol after directive") ||
4366 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4374 getParser().getStreamer().EmitInstruction(Inst, getSTI());
4380 bool AArch64AsmParser::parseDirectiveLOH(
StringRef IDVal,
SMLoc Loc) {
4384 return TokError(
"expected an identifier or a number in directive");
4387 int64_t
Id = getParser().getTok().getIntVal();
4389 return TokError(
"invalid numeric identifier in directive");
4392 StringRef Name = getTok().getIdentifier();
4398 return TokError(
"invalid identifier in directive");
4406 assert(NbArgs != -1 &&
"Invalid number of arguments");
4409 for (
int Idx = 0; Idx < NbArgs; ++Idx) {
4411 if (getParser().parseIdentifier(Name))
4412 return TokError(
"expected identifier in directive");
4413 Args.
push_back(getContext().getOrCreateSymbol(Name));
4415 if (Idx + 1 == NbArgs)
4418 "unexpected token in '" +
Twine(IDVal) +
"' directive"))
4422 "unexpected token in '" +
Twine(IDVal) +
"' directive"))
4425 getStreamer().EmitLOHDirective((
MCLOHType)Kind, Args);
4431 bool AArch64AsmParser::parseDirectiveLtorg(
SMLoc L) {
4434 getTargetStreamer().emitCurrentConstantPool();
4440 bool AArch64AsmParser::parseDirectiveReq(
StringRef Name,
SMLoc L) {
4443 SMLoc SRegLoc = getLoc();
4444 unsigned RegNum = tryParseRegister();
4445 bool IsVector =
false;
4447 if (RegNum == static_cast<unsigned>(-1)) {
4449 RegNum = tryMatchVectorRegister(Kind,
false);
4451 return Error(SRegLoc,
"vector register without type specifier expected");
4455 if (RegNum == static_cast<unsigned>(-1))
4456 return Error(SRegLoc,
"register name or alias expected");
4460 "unexpected input in .req directive"))
4463 auto pair = std::make_pair(IsVector, RegNum);
4464 if (RegisterReqs.insert(std::make_pair(Name, pair)).first->second != pair)
4465 Warning(L,
"ignoring redefinition of register alias '" + Name +
"'");
4472 bool AArch64AsmParser::parseDirectiveUnreq(
SMLoc L) {
4475 return TokError(
"unexpected input in .unreq directive.");
4479 return addErrorSuffix(
"in '.unreq' directive");
4484 AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
4492 if (
const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
4493 ELFRefKind = AE->getKind();
4494 Expr = AE->getSubExpr();
4500 DarwinRefKind = SE->
getKind();
4511 DarwinRefKind = SE->
getKind();
4540 #define GET_REGISTER_MATCHER
4541 #define GET_SUBTARGET_FEATURE_NAME
4542 #define GET_MATCHER_IMPLEMENTATION
4543 #include "AArch64GenAsmMatcher.inc"
4549 AArch64Operand &Op =
static_cast<AArch64Operand &
>(AsmOp);
4553 int64_t ExpectedVal;
4556 return Match_InvalidOperand;
4598 return Match_InvalidOperand;
4601 return Match_InvalidOperand;
4603 return Match_Success;
4604 return Match_InvalidOperand;
4608 AArch64AsmParser::tryParseGPRSeqPair(
OperandVector &Operands) {
4613 Error(S,
"expected register");
4617 int FirstReg = tryParseRegister();
4618 if (FirstReg == -1) {
4622 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
4624 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
4626 bool isXReg = XRegClass.
contains(FirstReg),
4627 isWReg = WRegClass.
contains(FirstReg);
4628 if (!isXReg && !isWReg) {
4629 Error(S,
"expected first even register of a "
4630 "consecutive same-size even/odd register pair");
4637 if (FirstEncoding & 0x1) {
4638 Error(S,
"expected first even register of a "
4639 "consecutive same-size even/odd register pair");
4645 Error(M,
"expected comma");
4652 int SecondReg = tryParseRegister();
4653 if (SecondReg ==-1) {
4658 (isXReg && !XRegClass.
contains(SecondReg)) ||
4659 (isWReg && !WRegClass.
contains(SecondReg))) {
4660 Error(E,
"expected second odd register of a "
4661 "consecutive same-size even/odd register pair");
4668 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
4671 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
4674 Operands.
push_back(AArch64Operand::CreateReg(Pair,
false, S, getLoc(),
static bool isValidVectorKind(StringRef Name)
static bool isReg(const MCInst &MI, unsigned OpNo)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
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.
Represents a range in source code.
void push_back(const T &Elt)
Target & getTheAArch64beTarget()
LLVM_NODISCARD 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)
const char * getPointer() const
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
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.
Target & getTheAArch64leTarget()
static MCOperand createExpr(const MCExpr *Val)
MCTargetAsmParser - Generic interface to target specific assembly parsers.
static CondCode getInvertedCondCode(CondCode Code)
Target specific streamer interface.
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
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)
static bool isMOVZMovAlias(uint64_t Value, int Shift, int RegWidth)
#define SYS_ALIAS(op1, Cn, Cm, op2)
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
return AArch64::GPR64RegClass contains(Reg)
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 ...
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.
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
Reg
All possible values of the reg field in the ModR/M byte.
Target independent representation for an assembler token.
APInt bitcastToAPInt() const
Represent a reference to a symbol from inside an expression.
bool getExtensionFeatures(unsigned Extensions, std::vector< StringRef > &Features)
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
Windows NT (Windows on ARM)
Target & getTheARM64Target()
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
static bool isMem(const MachineInstr &MI, unsigned Op)
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...
LLVM_NODISCARD bool empty() const
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
static bool isMOVNMovAlias(uint64_t Value, int Shift, int RegWidth)
Context object for machine code objects.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
unsigned getReg() const
Returns the register number.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
bool getArchFeatures(unsigned ArchKind, std::vector< StringRef > &Features)
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out...
int64_t getIntVal() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
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.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
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 ==...
static unsigned getWRegFromXReg(unsigned Reg)
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
FeatureBitset ToggleFeature(uint64_t FB)
ToggleFeature - Toggle a feature and returns the re-computed feature bits.
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
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...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static const struct @283 ExtensionMap[]
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)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Interface to description of machine instruction set.
unsigned getRegister(unsigned i) const
getRegister - Return the specified register in the class.
virtual MCAsmLexer & getLexer()=0
This file declares a class to represent arbitrary precision floating point values and provide a varie...
LLVM_NODISCARD StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
MCLOHType
Linker Optimization Hint Type.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
Binary assembler expressions.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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...
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.
unsigned parseArch(StringRef Arch)
void setOpcode(unsigned Op)
bool contains(unsigned Reg) const
contains - Return true if the specified register is included in this register class.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool isVector(MCInstrInfo const &MCII, MCInst const &MCI)
const FeatureBitset & getFeatureBits() const
getFeatureBits - Return the feature bits.
bool is(TokenKind K) const
static StringRef MCLOHDirectiveName()
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.
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
static uint8_t encodeAdvSIMDModImmType10(uint64_t Imm)
const SysReg * lookupSysRegByName(StringRef)
Base class for user error types.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
uint32_t parseGenericRegister(StringRef Name)
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 const fltSemantics & IEEEdouble()
loop data Loop Data Prefetch
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.
StringRef getABIName() const
getABIName - If this returns a non-empty string this represents the textual name of the ABI that we w...
Opcode getOpcode() const
Get the kind of this binary expression.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
static bool isValidMCLOHType(unsigned Kind)
MCSubtargetInfo - Generic base class for all target subtargets.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
VariantKind getKind() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static int MCLOHIdToNbArgs(MCLOHType Kind)
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
LLVM Value Representation.
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
const FeatureBitset Features
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
This class implements an extremely fast bulk output stream that can only output to a stream...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
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")
unsigned getDefaultExtensions(StringRef CPU, unsigned ArchKind)
Represents a location in source code.
static const char * getSubtargetFeatureName(uint64_t Val)
LLVM_NODISCARD bool startswith_lower(StringRef Prefix) const
Check if this string starts with the given Prefix, ignoring case.
static MCOperand createImm(int64_t Val)
LLVM_NODISCARD 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.
void setDefaultFeatures(StringRef CPU, StringRef FS)
Set the features to the default for the given CPU with an appended feature string.