47 #define GET_ASSEMBLER_HEADER
48 #include "AArch64GenAsmMatcher.inc"
51 enum AArch64MatchResultTy {
52 Match_FirstAArch64 = FIRST_TARGET_MATCH_RESULT_TY,
53 #define GET_OPERAND_DIAGNOSTIC_TYPES
54 #include "AArch64GenAsmMatcher.inc"
63 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
67 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc);
72 bool ParseDirective(
AsmToken DirectiveID);
73 bool ParseDirectiveTLSDescCall(
SMLoc L);
74 bool ParseDirectiveWord(
unsigned Size,
SMLoc L);
76 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
79 bool MatchingInlineAsm);
88 OperandMatchResultTy ParseImmediate(
const MCExpr *&ExprVal);
112 template<
typename SomeNamedImmMapper> OperandMatchResultTy
114 return ParseNamedImmOperand(SomeNamedImmMapper(), Operands);
130 bool TryParseVector(uint32_t &RegNum,
SMLoc &RegEndLoc,
StringRef &Layout,
135 bool validateInstruction(
MCInst &Inst,
143 IdentifyRegister(
unsigned &RegNum,
SMLoc &RegEndLoc,
StringRef &LayoutSpec,
144 SMLoc &LayoutLoc)
const;
168 SMLoc StartLoc, EndLoc;
170 struct ImmWithLSLOp {
172 unsigned ShiftAmount;
192 struct ShiftExtendOp {
199 struct VectorListOp {
216 struct ImmWithLSLOp ImmWithLSL;
218 struct FPImmOp FPImm;
221 struct ShiftExtendOp ShiftExtend;
222 struct VectorListOp VectorList;
223 struct SysRegOp SysReg;
234 SMLoc getStartLoc()
const {
return StartLoc; }
235 SMLoc getEndLoc()
const {
return EndLoc; }
240 assert(
Kind == k_Token &&
"Invalid access!");
245 assert((
Kind == k_Register ||
Kind == k_WrappedRegister)
246 &&
"Invalid access!");
250 const MCExpr *getImm()
const {
251 assert(
Kind == k_Immediate &&
"Invalid access!");
256 assert(
Kind == k_CondCode &&
"Invalid access!");
260 static bool isNonConstantExpr(
const MCExpr *E,
262 if (
const AArch64MCExpr *A64E = dyn_cast<AArch64MCExpr>(E)) {
263 Variant = A64E->getKind();
265 }
else if (!isa<MCConstantExpr>(E)) {
273 bool isCondCode()
const {
return Kind == k_CondCode; }
274 bool isToken()
const {
return Kind == k_Token; }
275 bool isReg()
const {
return Kind == k_Register; }
276 bool isImm()
const {
return Kind == k_Immediate; }
277 bool isMem()
const {
return false; }
278 bool isFPImm()
const {
return Kind == k_FPImmediate; }
279 bool isShiftOrExtend()
const {
return Kind == k_ShiftExtend; }
280 bool isSysReg()
const {
return Kind == k_SysReg; }
281 bool isImmWithLSL()
const {
return Kind == k_ImmWithLSL; }
282 bool isWrappedReg()
const {
return Kind == k_WrappedRegister; }
284 bool isAddSubImmLSL0()
const {
285 if (!isImmWithLSL())
return false;
286 if (ImmWithLSL.ShiftAmount != 0)
return false;
289 if (isNonConstantExpr(ImmWithLSL.Val, Variant)) {
303 bool isAddSubImmLSL12()
const {
304 if (!isImmWithLSL())
return false;
305 if (ImmWithLSL.ShiftAmount != 12)
return false;
308 if (isNonConstantExpr(ImmWithLSL.Val, Variant)) {
318 template<
unsigned MemSize,
unsigned RmSize>
bool isAddrRegExtend()
const {
319 if (!isShiftOrExtend())
return false;
328 return ShiftExtend.Amount ==
Log2_32(MemSize) || ShiftExtend.Amount == 0;
331 bool isAdrpLabel()
const {
332 if (!isImm())
return false;
335 if (isNonConstantExpr(getImm(), Variant)) {
342 return isLabel<21, 4096>();
345 template<
unsigned RegW
idth>
bool isBitfieldWidth()
const {
346 if (!isImm())
return false;
349 if (!CE)
return false;
354 template<
int RegW
idth>
355 bool isCVTFixedPos()
const {
356 if (!isImm())
return false;
359 if (!CE)
return false;
364 bool isFMOVImm()
const {
372 bool isFPZero()
const {
376 return RealVal.isPosZero();
379 template<
unsigned field_w
idth,
unsigned scale>
380 bool isLabel()
const {
381 if (!isImm())
return false;
383 if (dyn_cast<MCSymbolRefExpr>(Imm.Val)) {
385 }
else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Imm.Val)) {
387 int64_t Min = - (scale * (1LL << (field_width - 1)));
388 int64_t Max = scale * ((1LL << (field_width - 1)) - 1);
389 return (Val % scale) == 0 && Val >= Min && Val <= Max;
397 bool isLane1()
const {
398 if (!isImm())
return false;
402 return cast<MCConstantExpr>(getImm())->getValue() == 1;
405 bool isLoadLitLabel()
const {
406 if (!isImm())
return false;
409 if (isNonConstantExpr(getImm(), Variant)) {
414 return isLabel<19, 4>();
418 if (!isImm())
return false;
421 if (!CE)
return false;
427 template<
unsigned RegW
idth>
bool isLogicalImmMOV()
const {
428 if (!isLogicalImm<RegWidth>())
return false;
439 template<
int MemSize>
440 bool isOffsetUImm12()
const {
441 if (!isImm())
return false;
455 if ((Val & (MemSize - 1)) != 0)
return false;
458 return Val >= 0 && Val <= 0xfff * MemSize;
461 template<A64SE::ShiftExtSpecifiers SHKind,
bool is64Bit>
463 if (!isShiftOrExtend())
return false;
465 if (ShiftExtend.ShiftType != SHKind)
468 return is64Bit ? ShiftExtend.Amount <= 63 : ShiftExtend.Amount <= 31;
471 bool isMOVN32Imm()
const {
483 return isMoveWideImm(32, PermittedModifiers, NumModifiers);
486 bool isMOVN64Imm()
const {
501 return isMoveWideImm(64, PermittedModifiers, NumModifiers);
505 bool isMOVZ32Imm()
const {
519 return isMoveWideImm(32, PermittedModifiers, NumModifiers);
522 bool isMOVZ64Imm()
const {
541 return isMoveWideImm(64, PermittedModifiers, NumModifiers);
544 bool isMOVK32Imm()
const {
556 return isMoveWideImm(32, PermittedModifiers, NumModifiers);
559 bool isMOVK64Imm()
const {
573 return isMoveWideImm(64, PermittedModifiers, NumModifiers);
576 bool isMoveWideImm(
unsigned RegWidth,
578 unsigned NumModifiers)
const {
579 if (!isImmWithLSL())
return false;
581 if (ImmWithLSL.ShiftAmount % 16 != 0)
return false;
582 if (ImmWithLSL.ShiftAmount >= RegWidth)
return false;
585 if (isNonConstantExpr(ImmWithLSL.Val, Modifier)) {
587 if (!ImmWithLSL.ImplicitAmount)
return false;
589 for (
unsigned i = 0; i < NumModifiers; ++i)
590 if (PermittedModifiers[i] == Modifier)
return true;
599 template<
int RegW
idth,
bool (*isVal
idImm)(
int, u
int64_t,
int&,
int&)>
600 bool isMoveWideMovAlias()
const {
601 if (!isImm())
return false;
604 if (!CE)
return false;
612 if (RegWidth == 32) {
613 if ((Value >> 32) != 0 && (Value >> 32) != 0xffffffff)
616 Value &= 0xffffffffULL;
619 return isValidImm(RegWidth, Value, UImm16, Shift);
622 bool isMSRWithReg()
const {
623 if (!isSysReg())
return false;
625 bool IsKnownRegister;
629 return IsKnownRegister;
632 bool isMSRPState()
const {
633 if (!isSysReg())
return false;
635 bool IsKnownRegister;
639 return IsKnownRegister;
643 if (!isSysReg())
return false;
646 bool IsKnownRegister;
650 return IsKnownRegister;
653 bool isPRFM()
const {
654 if (!isImm())
return false;
664 template<A64SE::ShiftExtSpecifiers SHKind>
bool isRegExtend()
const {
665 if (!isShiftOrExtend())
return false;
667 if (ShiftExtend.ShiftType != SHKind)
670 return ShiftExtend.Amount <= 4;
673 bool isRegExtendLSL()
const {
674 if (!isShiftOrExtend())
return false;
679 return !ShiftExtend.ImplicitAmount && ShiftExtend.Amount <= 4;
683 bool isShrFixedWidth(
int w)
const {
690 return Value > 0 && Value <= w;
693 bool isShrImm8()
const {
return isShrFixedWidth(8); }
695 bool isShrImm16()
const {
return isShrFixedWidth(16); }
697 bool isShrImm32()
const {
return isShrFixedWidth(32); }
699 bool isShrImm64()
const {
return isShrFixedWidth(64); }
702 bool isShlFixedWidth(
int w)
const {
709 return Value >= 0 && Value < w;
712 bool isShlImm8()
const {
return isShlFixedWidth(8); }
714 bool isShlImm16()
const {
return isShlFixedWidth(16); }
716 bool isShlImm32()
const {
return isShlFixedWidth(32); }
718 bool isShlImm64()
const {
return isShlFixedWidth(64); }
720 bool isNeonMovImmShiftLSL()
const {
721 if (!isShiftOrExtend())
728 return ShiftExtend.Amount % 8 == 0 && ShiftExtend.Amount <= 24;
731 bool isNeonMovImmShiftLSLH()
const {
732 if (!isShiftOrExtend())
739 return ShiftExtend.Amount == 0 || ShiftExtend.Amount == 8;
742 bool isNeonMovImmShiftMSL()
const {
743 if (!isShiftOrExtend())
750 return ShiftExtend.Amount == 8 || ShiftExtend.Amount == 16;
753 template <A64Layout::VectorLayout Layout,
unsigned Count>
754 bool isVectorList()
const {
755 return Kind == k_VectorList && VectorList.Layout == Layout &&
756 VectorList.Count == Count;
759 template <
int MemSize>
bool isSImm7Scaled()
const {
764 if (!CE)
return false;
767 if (Val % MemSize != 0)
return false;
771 return Val >= -64 && Val < 64;
774 template<
int BitW
idth>
775 bool isSImm()
const {
776 if (!isImm())
return false;
779 if (!CE)
return false;
781 return CE->
getValue() >= -(1LL << (BitWidth - 1))
782 && CE->
getValue() < (1LL << (BitWidth - 1));
785 template<
int bitW
idth>
786 bool isUImm()
const {
787 if (!isImm())
return false;
790 if (!CE)
return false;
795 bool isUImm()
const {
796 if (!isImm())
return false;
798 return isa<MCConstantExpr>(getImm());
801 bool isNeonUImm64Mask()
const {
812 for (
unsigned i = 0; i < 8; ++i, Value >>= 8)
813 if ((Value & 0xff) != 0 && (Value & 0xff) != 0xff)
820 bool isExactImm()
const {
821 if (!isImm())
return false;
824 if (!CE)
return false;
829 static AArch64Operand *CreateImmWithLSL(
const MCExpr *Val,
830 unsigned ShiftAmount,
833 AArch64Operand *Op =
new AArch64Operand(k_ImmWithLSL, S, E);
834 Op->ImmWithLSL.Val = Val;
835 Op->ImmWithLSL.ShiftAmount = ShiftAmount;
836 Op->ImmWithLSL.ImplicitAmount = ImplicitAmount;
842 AArch64Operand *Op =
new AArch64Operand(k_CondCode, S, E);
843 Op->CondCode.Code =
Code;
847 static AArch64Operand *CreateFPImm(
double Val,
849 AArch64Operand *Op =
new AArch64Operand(k_FPImmediate, S, E);
855 AArch64Operand *Op =
new AArch64Operand(k_Immediate, S, E);
860 static AArch64Operand *CreateReg(
unsigned RegNum,
SMLoc S,
SMLoc E) {
861 AArch64Operand *Op =
new AArch64Operand(k_Register, S, E);
862 Op->Reg.RegNum = RegNum;
866 static AArch64Operand *CreateWrappedReg(
unsigned RegNum,
SMLoc S,
SMLoc E) {
867 AArch64Operand *Op =
new AArch64Operand(k_WrappedRegister, S, E);
868 Op->Reg.RegNum = RegNum;
876 AArch64Operand *Op =
new AArch64Operand(k_ShiftExtend, S, E);
877 Op->ShiftExtend.ShiftType = ShiftTyp;
878 Op->ShiftExtend.Amount = Amount;
879 Op->ShiftExtend.ImplicitAmount = ImplicitAmount;
884 AArch64Operand *Op =
new AArch64Operand(k_SysReg, S, S);
885 Op->Tok.Data = Str.
data();
886 Op->Tok.Length = Str.
size();
890 static AArch64Operand *CreateVectorList(
unsigned RegNum,
unsigned Count,
893 AArch64Operand *Op =
new AArch64Operand(k_VectorList, S, E);
894 Op->VectorList.RegNum = RegNum;
895 Op->VectorList.Count = Count;
896 Op->VectorList.Layout = Layout;
903 AArch64Operand *Op =
new AArch64Operand(k_Token, S, S);
904 Op->Tok.Data = Str.
data();
905 Op->Tok.Length = Str.
size();
918 template<
unsigned RegW
idth>
919 void addBFILSBOperands(
MCInst &Inst,
unsigned N)
const {
920 assert(N == 1 &&
"Invalid number of operands!");
922 unsigned EncodedVal = (RegWidth - CE->
getValue()) % RegWidth;
926 void addBFIWidthOperands(
MCInst &Inst,
unsigned N)
const {
927 assert(N == 1 &&
"Invalid number of operands!");
932 void addBFXWidthOperands(
MCInst &Inst,
unsigned N)
const {
933 assert(N == 1 &&
"Invalid number of operands!");
941 void addCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
942 assert(N == 1 &&
"Invalid number of operands!");
946 void addCVTFixedPosOperands(
MCInst &Inst,
unsigned N)
const {
947 assert(N == 1 &&
"Invalid number of operands!");
953 void addFMOVImmOperands(
MCInst &Inst,
unsigned N)
const {
954 assert(N == 1 &&
"Invalid number of operands!");
963 void addFPZeroOperands(
MCInst &Inst,
unsigned N)
const {
964 assert(N == 1 &&
"Invalid number of operands");
968 void addInvCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
969 assert(N == 1 &&
"Invalid number of operands!");
974 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
975 assert(N == 1 &&
"Invalid number of operands!");
979 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
980 assert(N == 1 &&
"Invalid number of operands!");
981 addExpr(Inst, getImm());
984 template<
int MemSize>
985 void addSImm7ScaledOperands(
MCInst &Inst,
unsigned N)
const {
986 assert(N == 1 &&
"Invalid number of operands!");
989 uint64_t Val = CE->
getValue() / MemSize;
993 template<
int BitW
idth>
994 void addSImmOperands(
MCInst &Inst,
unsigned N)
const {
995 assert(N == 1 &&
"Invalid number of operands!");
1002 void addImmWithLSLOperands(
MCInst &Inst,
unsigned N)
const {
1003 assert (N == 1 &&
"Invalid number of operands!");
1005 addExpr(Inst, ImmWithLSL.Val);
1008 template<
unsigned field_w
idth,
unsigned scale>
1009 void addLabelOperands(
MCInst &Inst,
unsigned N)
const {
1010 assert(N == 1 &&
"Invalid number of operands!");
1015 addExpr(Inst, Imm.Val);
1020 assert(Val % scale == 0 &&
"Unaligned immediate in instruction");
1026 template<
int MemSize>
1027 void addOffsetUImm12Operands(
MCInst &Inst,
unsigned N)
const {
1028 assert(N == 1 &&
"Invalid number of operands!");
1030 if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) {
1037 template<
unsigned RegW
idth>
1038 void addLogicalImmOperands(
MCInst &Inst,
unsigned N)
const {
1039 assert(N == 1 &&
"Invalid number of operands");
1048 void addMRSOperands(
MCInst &Inst,
unsigned N)
const {
1049 assert(N == 1 &&
"Invalid number of operands!");
1058 void addMSRWithRegOperands(
MCInst &Inst,
unsigned N)
const {
1059 assert(N == 1 &&
"Invalid number of operands!");
1068 void addMSRPStateOperands(
MCInst &Inst,
unsigned N)
const {
1069 assert(N == 1 &&
"Invalid number of operands!");
1078 void addMoveWideImmOperands(
MCInst &Inst,
unsigned N)
const {
1079 assert(N == 2 &&
"Invalid number of operands!");
1081 addExpr(Inst, ImmWithLSL.Val);
1084 if (!isNonConstantExpr(ImmWithLSL.Val, Variant)) {
1125 template<
int RegW
idth,
bool isVal
idImm(
int, u
int64_t,
int&,
int&)>
1126 void addMoveWideMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
1127 assert(N == 2 &&
"Invalid number of operands!");
1133 if (RegWidth == 32) {
1134 Value &= 0xffffffffULL;
1137 bool Valid = isValidImm(RegWidth, Value, UImm16, Shift);
1139 assert(Valid &&
"Invalid immediates should have been weeded out by now");
1145 void addPRFMOperands(
MCInst &Inst,
unsigned N)
const {
1146 assert(N == 1 &&
"Invalid number of operands!");
1150 &&
"PRFM operand should be 5-bits");
1156 void addRegExtendOperands(
MCInst &Inst,
unsigned N)
const {
1157 assert(N == 1 &&
"Invalid number of operands!");
1163 void addNeonMovImmShiftLSLOperands(
MCInst &Inst,
unsigned N)
const {
1164 assert(N == 1 &&
"Invalid number of operands!");
1166 if (ShiftExtend.Amount % 8 != 0 || ShiftExtend.Amount > 24)
1170 int64_t Imm = ShiftExtend.Amount / 8;
1174 void addNeonMovImmShiftLSLHOperands(
MCInst &Inst,
unsigned N)
const {
1175 assert(N == 1 &&
"Invalid number of operands!");
1177 if (ShiftExtend.Amount != 0 && ShiftExtend.Amount != 8)
1181 int64_t Imm = ShiftExtend.Amount / 8;
1185 void addNeonMovImmShiftMSLOperands(
MCInst &Inst,
unsigned N)
const {
1186 assert(N == 1 &&
"Invalid number of operands!");
1188 if (ShiftExtend.Amount != 8 && ShiftExtend.Amount != 16)
1192 int64_t Imm = ShiftExtend.Amount / 8 - 1;
1197 template<
unsigned MemSize>
1198 void addAddrRegExtendOperands(
MCInst &Inst,
unsigned N)
const {
1199 addAddrRegExtendOperands(Inst, N, MemSize);
1202 void addAddrRegExtendOperands(
MCInst &Inst,
unsigned N,
1203 unsigned MemSize)
const {
1204 assert(N == 1 &&
"Invalid number of operands!");
1208 unsigned OptionHi = 0;
1209 switch (ShiftExtend.ShiftType) {
1223 if (MemSize == 1 && !ShiftExtend.ImplicitAmount)
1225 else if (MemSize != 1 && ShiftExtend.Amount != 0)
1230 void addShiftOperands(
MCInst &Inst,
unsigned N)
const {
1231 assert(N == 1 &&
"Invalid number of operands!");
1236 void addNeonUImm64MaskOperands(
MCInst &Inst,
unsigned N)
const {
1237 assert(N == 1 &&
"Invalid number of operands!");
1244 for (
unsigned i = 0; i < 8; ++i, Value >>= 8) {
1245 Imm |= (Value & 1) << i;
1250 void addVectorListOperands(
MCInst &Inst,
unsigned N)
const {
1251 assert(N == 1 &&
"Invalid number of operands!");
1258 AArch64AsmParser::OperandMatchResultTy
1263 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1266 if (ResTy != MatchOperand_NoMatch)
1269 switch (getLexer().getKind()) {
1271 Error(Parser.getTok().getLoc(),
"unexpected token in operand");
1272 return MatchOperand_ParseFail;
1275 OperandMatchResultTy GotShift = ParseShiftExtend(Operands);
1278 if (GotShift != MatchOperand_NoMatch)
1282 uint32_t NumLanes = 0;
1283 OperandMatchResultTy GotReg = ParseRegister(Operands, NumLanes);
1284 assert(GotReg != MatchOperand_ParseFail
1285 &&
"register parsing shouldn't partially succeed");
1287 if (GotReg == MatchOperand_Success) {
1289 return ParseNEONLane(Operands, NumLanes);
1291 return MatchOperand_Success;
1302 SMLoc StartLoc = Parser.getTok().getLoc();
1304 const MCExpr *ImmVal = 0;
1306 if (ParseImmediate(ImmVal) != MatchOperand_Success)
1307 return MatchOperand_ParseFail;
1310 Operands.
push_back(AArch64Operand::CreateImm(ImmVal, StartLoc, EndLoc));
1311 return MatchOperand_Success;
1314 SMLoc StartLoc = Parser.getTok().getLoc();
1316 const MCExpr *ImmVal = 0;
1319 if (ParseImmediate(ImmVal) != MatchOperand_Success)
1320 return MatchOperand_ParseFail;
1323 Operands.
push_back(AArch64Operand::CreateImm(ImmVal, StartLoc, EndLoc));
1324 return MatchOperand_Success;
1327 SMLoc Loc = Parser.getTok().getLoc();
1328 Operands.
push_back(AArch64Operand::CreateToken(
"[", Loc));
1333 return ParseOperand(Operands, Mnemonic);
1338 return MatchOperand_ParseFail;
1342 AArch64AsmParser::OperandMatchResultTy
1343 AArch64AsmParser::ParseImmediate(
const MCExpr *&ExprVal) {
1347 OperandMatchResultTy ResTy = ParseRelocPrefix(RefKind);
1348 if (ResTy != MatchOperand_Success)
1351 const MCExpr *SubExprVal;
1352 if (getParser().parseExpression(SubExprVal))
1353 return MatchOperand_ParseFail;
1356 return MatchOperand_Success;
1360 return getParser().parseExpression(ExprVal)
1361 ? MatchOperand_ParseFail : MatchOperand_Success;
1366 AArch64AsmParser::OperandMatchResultTy
1368 uint32_t NumLanes) {
1369 SMLoc Loc = Parser.getTok().getLoc();
1371 assert(Parser.getTok().is(
AsmToken::LBrac) &&
"inappropriate operand");
1372 Operands.
push_back(AArch64Operand::CreateToken(
"[", Loc));
1376 Error(Parser.getTok().getLoc(),
"expected lane number");
1377 return MatchOperand_ParseFail;
1380 if (Parser.getTok().getIntVal() >= NumLanes) {
1381 Error(Parser.getTok().getLoc(),
"lane number incompatible with layout");
1382 return MatchOperand_ParseFail;
1387 SMLoc S = Parser.getTok().getLoc();
1389 SMLoc E = Parser.getTok().getLoc();
1390 Operands.
push_back(AArch64Operand::CreateImm(Lane, S, E));
1394 Error(Parser.getTok().getLoc(),
"expected ']' after lane");
1395 return MatchOperand_ParseFail;
1398 Operands.
push_back(AArch64Operand::CreateToken(
"]", Loc));
1401 return MatchOperand_Success;
1404 AArch64AsmParser::OperandMatchResultTy
1410 Error(Parser.getTok().getLoc(),
1411 "expected relocation specifier in operand after ':'");
1412 return MatchOperand_ParseFail;
1415 std::string LowerCase = Parser.getTok().getIdentifier().lower();
1455 Error(Parser.getTok().getLoc(),
1456 "expected relocation specifier in operand after ':'");
1457 return MatchOperand_ParseFail;
1462 Error(Parser.getTok().getLoc(),
1463 "expected ':' after relocation specifier");
1464 return MatchOperand_ParseFail;
1467 return MatchOperand_Success;
1470 AArch64AsmParser::OperandMatchResultTy
1471 AArch64AsmParser::ParseImmWithLSLOperand(
1475 if (Parser.getTok().isNot(
AsmToken::Hash))
return MatchOperand_NoMatch;
1477 SMLoc S = Parser.getTok().getLoc();
1481 if (ParseImmediate(Imm) != MatchOperand_Success)
1482 return MatchOperand_ParseFail;
1484 SMLoc E = Parser.getTok().getLoc();
1485 Operands.
push_back(AArch64Operand::CreateImmWithLSL(Imm, 0,
true, S, E));
1486 return MatchOperand_Success;
1494 && Parser.getTok().getIdentifier().equals_lower(
"lsl")) {
1501 Error(Parser.getTok().getLoc(),
"only 'lsl #+N' valid after immediate");
1502 return MatchOperand_ParseFail;
1507 int64_t ShiftAmount = Parser.getTok().getIntVal();
1509 if (ShiftAmount < 0) {
1510 Error(Parser.getTok().getLoc(),
"positive shift amount required");
1511 return MatchOperand_ParseFail;
1515 SMLoc E = Parser.getTok().getLoc();
1516 Operands.
push_back(AArch64Operand::CreateImmWithLSL(Imm, ShiftAmount,
1518 return MatchOperand_Success;
1522 AArch64AsmParser::OperandMatchResultTy
1523 AArch64AsmParser::ParseCondCodeOperand(
1526 return MatchOperand_NoMatch;
1528 StringRef Tok = Parser.getTok().getIdentifier();
1532 return MatchOperand_NoMatch;
1534 SMLoc S = Parser.getTok().getLoc();
1536 SMLoc E = Parser.getTok().getLoc();
1538 Operands.
push_back(AArch64Operand::CreateCondCode(CondCode, S, E));
1539 return MatchOperand_Success;
1542 AArch64AsmParser::OperandMatchResultTy
1543 AArch64AsmParser::ParseCRxOperand(
1545 SMLoc S = Parser.getTok().getLoc();
1547 Error(S,
"Expected cN operand where 0 <= N <= 15");
1548 return MatchOperand_ParseFail;
1551 StringRef Tok = Parser.getTok().getIdentifier();
1552 if (Tok[0] !=
'c' && Tok[0] !=
'C') {
1553 Error(S,
"Expected cN operand where 0 <= N <= 15");
1554 return MatchOperand_ParseFail;
1559 if (BadNum || CRNum > 15) {
1560 Error(S,
"Expected cN operand where 0 <= N <= 15");
1561 return MatchOperand_ParseFail;
1567 SMLoc E = Parser.getTok().getLoc();
1569 Operands.
push_back(AArch64Operand::CreateImm(CRImm, S, E));
1570 return MatchOperand_Success;
1573 AArch64AsmParser::OperandMatchResultTy
1574 AArch64AsmParser::ParseFPImmOperand(
1579 if (Parser.getTok().isNot(
AsmToken::Hash))
return MatchOperand_NoMatch;
1581 SMLoc S = Parser.getTok().getLoc();
1584 bool Negative =
false;
1593 Error(S,
"Expected floating-point immediate");
1594 return MatchOperand_ParseFail;
1599 double DblVal = RealVal.convertToDouble();
1602 SMLoc E = Parser.getTok().getLoc();
1604 Operands.
push_back(AArch64Operand::CreateFPImm(DblVal, S, E));
1605 return MatchOperand_Success;
1613 AArch64AsmParser::IdentifyRegister(
unsigned &RegNum,
SMLoc &RegEndLoc,
1615 SMLoc &LayoutLoc)
const {
1616 const AsmToken &Tok = Parser.getTok();
1622 size_t DotPos = LowerReg.find(
'.');
1624 bool IsVec128 =
false;
1628 if (DotPos == std::string::npos) {
1642 .Case(
".q",
".q").
Case(
".1q",
".1q")
1643 .
Case(
".d",
".d").
Case(
".2d",
".2d")
1644 .
Case(
".s",
".s").
Case(
".4s",
".4s")
1645 .
Case(
".h",
".h").
Case(
".8h",
".8h")
1646 .
Case(
".b",
".b").
Case(
".16b",
".16b")
1649 if (Layout.
size() != 0)
1660 if (Layout.
size() == 0) {
1667 if (RegNum == AArch64::NoRegister) {
1669 .Case(
"ip0", AArch64::X16)
1670 .
Case(
"ip1", AArch64::X17)
1671 .
Case(
"fp", AArch64::X29)
1672 .
Case(
"lr", AArch64::X30)
1673 .
Case(
"v0", IsVec128 ? AArch64::Q0 : AArch64::D0)
1674 .
Case(
"v1", IsVec128 ? AArch64::Q1 : AArch64::D1)
1675 .
Case(
"v2", IsVec128 ? AArch64::Q2 : AArch64::D2)
1676 .
Case(
"v3", IsVec128 ? AArch64::Q3 : AArch64::D3)
1677 .
Case(
"v4", IsVec128 ? AArch64::Q4 : AArch64::D4)
1678 .
Case(
"v5", IsVec128 ? AArch64::Q5 : AArch64::D5)
1679 .
Case(
"v6", IsVec128 ? AArch64::Q6 : AArch64::D6)
1680 .
Case(
"v7", IsVec128 ? AArch64::Q7 : AArch64::D7)
1683 .
Case(
"v10", IsVec128 ? AArch64::Q10 : AArch64::D10)
1684 .
Case(
"v11", IsVec128 ? AArch64::Q11 : AArch64::D11)
1685 .
Case(
"v12", IsVec128 ? AArch64::Q12 : AArch64::D12)
1686 .
Case(
"v13", IsVec128 ? AArch64::Q13 : AArch64::D13)
1687 .
Case(
"v14", IsVec128 ? AArch64::Q14 : AArch64::D14)
1688 .
Case(
"v15", IsVec128 ? AArch64::Q15 : AArch64::D15)
1689 .
Case(
"v16", IsVec128 ? AArch64::Q16 : AArch64::D16)
1690 .
Case(
"v17", IsVec128 ? AArch64::Q17 : AArch64::D17)
1691 .
Case(
"v18", IsVec128 ? AArch64::Q18 : AArch64::D18)
1692 .
Case(
"v19", IsVec128 ? AArch64::Q19 : AArch64::D19)
1693 .
Case(
"v20", IsVec128 ? AArch64::Q20 : AArch64::D20)
1694 .
Case(
"v21", IsVec128 ? AArch64::Q21 : AArch64::D21)
1695 .
Case(
"v22", IsVec128 ? AArch64::Q22 : AArch64::D22)
1696 .
Case(
"v23", IsVec128 ? AArch64::Q23 : AArch64::D23)
1697 .
Case(
"v24", IsVec128 ? AArch64::Q24 : AArch64::D24)
1698 .
Case(
"v25", IsVec128 ? AArch64::Q25 : AArch64::D25)
1699 .
Case(
"v26", IsVec128 ? AArch64::Q26 : AArch64::D26)
1700 .
Case(
"v27", IsVec128 ? AArch64::Q27 : AArch64::D27)
1701 .
Case(
"v28", IsVec128 ? AArch64::Q28 : AArch64::D28)
1702 .
Case(
"v29", IsVec128 ? AArch64::Q29 : AArch64::D29)
1703 .
Case(
"v30", IsVec128 ? AArch64::Q30 : AArch64::D30)
1704 .
Case(
"v31", IsVec128 ? AArch64::Q31 : AArch64::D31)
1705 .
Default(AArch64::NoRegister);
1707 if (RegNum == AArch64::NoRegister)
1713 AArch64AsmParser::OperandMatchResultTy
1715 uint32_t &NumLanes) {
1718 SMLoc RegEndLoc, LayoutLoc;
1719 SMLoc S = Parser.getTok().getLoc();
1721 if (!IdentifyRegister(RegNum, RegEndLoc, Layout, LayoutLoc))
1722 return MatchOperand_NoMatch;
1724 Operands.
push_back(AArch64Operand::CreateReg(RegNum, S, RegEndLoc));
1726 if (Layout.
size() != 0) {
1727 unsigned long long TmpLanes = 0;
1729 if (TmpLanes != 0) {
1730 NumLanes = TmpLanes;
1735 switch (Layout.
back()) {
1737 case 'b': NumLanes = 16;
break;
1738 case 'h': NumLanes = 8;
break;
1739 case 's': NumLanes = 4;
break;
1740 case 'd': NumLanes = 2;
break;
1741 case 'q': NumLanes = 1;
break;
1745 Operands.
push_back(AArch64Operand::CreateToken(Layout, LayoutLoc));
1749 return MatchOperand_Success;
1753 AArch64AsmParser::ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
1759 SMLoc RegEndLoc, LayoutLoc;
1760 StartLoc = Parser.getTok().getLoc();
1762 if (!IdentifyRegister(RegNo, RegEndLoc, LayoutSpec, LayoutLoc))
1766 EndLoc = Parser.getTok().getLoc();
1771 AArch64AsmParser::OperandMatchResultTy
1772 AArch64AsmParser::ParseNamedImmOperand(
const NamedImmMapper &Mapper,
1778 const AsmToken &Tok = Parser.getTok();
1786 Error(S,
"operand specifier not recognised");
1787 return MatchOperand_ParseFail;
1792 SMLoc E = Parser.getTok().getLoc();
1794 Operands.
push_back(AArch64Operand::CreateImm(Imm, S, E));
1795 return MatchOperand_Success;
1800 if (ParseImmediate(ImmVal) != MatchOperand_Success)
1801 return MatchOperand_ParseFail;
1805 Error(S,
"Invalid immediate for instruction");
1806 return MatchOperand_ParseFail;
1809 SMLoc E = Parser.getTok().getLoc();
1810 Operands.
push_back(AArch64Operand::CreateImm(ImmVal, S, E));
1811 return MatchOperand_Success;
1814 Error(S,
"unexpected operand for instruction");
1815 return MatchOperand_ParseFail;
1818 AArch64AsmParser::OperandMatchResultTy
1819 AArch64AsmParser::ParseSysRegOperand(
1821 const AsmToken &Tok = Parser.getTok();
1828 return MatchOperand_NoMatch;
1835 return MatchOperand_Success;
1838 AArch64AsmParser::OperandMatchResultTy
1839 AArch64AsmParser::ParseLSXAddressOperand(
1841 SMLoc S = Parser.getTok().getLoc();
1844 SMLoc RegEndLoc, LayoutLoc;
1846 if(!IdentifyRegister(RegNum, RegEndLoc, Layout, LayoutLoc)
1847 || !AArch64MCRegisterClasses[AArch64::GPR64xspRegClassID].contains(RegNum)
1848 || Layout.
size() != 0) {
1851 return MatchOperand_NoMatch;
1857 SMLoc E = Parser.getTok().getLoc();
1858 Operands.
push_back(AArch64Operand::CreateWrappedReg(RegNum, S, E));
1859 return MatchOperand_Success;
1865 Error(Parser.getTok().getLoc(),
"expected ',' or ']' after register");
1866 return MatchOperand_ParseFail;
1871 Error(Parser.getTok().getLoc(),
"expected '#0'");
1872 return MatchOperand_ParseFail;
1877 || Parser.getTok().getIntVal() != 0 ) {
1878 Error(Parser.getTok().getLoc(),
"expected '#0'");
1879 return MatchOperand_ParseFail;
1883 SMLoc E = Parser.getTok().getLoc();
1884 Operands.
push_back(AArch64Operand::CreateWrappedReg(RegNum, S, E));
1885 return MatchOperand_Success;
1888 AArch64AsmParser::OperandMatchResultTy
1889 AArch64AsmParser::ParseShiftExtend(
1891 StringRef IDVal = Parser.getTok().getIdentifier();
1892 std::string LowerID = IDVal.
lower();
1912 return MatchOperand_NoMatch;
1916 S = Parser.getTok().getLoc();
1930 Operands.
push_back(AArch64Operand::CreateShiftExtend(Spec, 0,
true,
1932 return MatchOperand_Success;
1938 Error(Parser.getTok().getLoc(),
1939 "expected #imm after shift specifier");
1940 return MatchOperand_ParseFail;
1946 Error(Parser.getTok().getLoc(),
1947 "expected integer shift amount");
1948 return MatchOperand_ParseFail;
1950 unsigned Amount = Parser.getTok().getIntVal();
1952 E = Parser.getTok().getLoc();
1954 Operands.
push_back(AArch64Operand::CreateShiftExtend(Spec, Amount,
false,
1957 return MatchOperand_Success;
1962 bool AArch64AsmParser::TryParseVector(uint32_t &RegNum,
SMLoc &RegEndLoc,
1964 bool IsVector =
true;
1966 if (!IdentifyRegister(RegNum, RegEndLoc, Layout, LayoutLoc))
1968 else if (!AArch64MCRegisterClasses[AArch64::FPR64RegClassID]
1969 .contains(RegNum) &&
1970 !AArch64MCRegisterClasses[AArch64::FPR128RegClassID]
1973 else if (Layout.
size() == 0)
1977 Error(Parser.getTok().getLoc(),
"expected vector type register");
1989 AArch64AsmParser::OperandMatchResultTy AArch64AsmParser::ParseVectorList(
1992 Error(Parser.getTok().getLoc(),
"'{' expected");
1993 return MatchOperand_ParseFail;
1995 SMLoc SLoc = Parser.getTok().getLoc();
1998 unsigned Reg, Count = 1;
2000 SMLoc RegEndLoc, LayoutLoc;
2001 if (!TryParseVector(Reg, RegEndLoc, LayoutStr, LayoutLoc))
2002 return MatchOperand_ParseFail;
2009 SMLoc RegEndLoc2, LayoutLoc2;
2010 SMLoc RegLoc2 = Parser.getTok().getLoc();
2012 if (!TryParseVector(Reg2, RegEndLoc2, LayoutStr2, LayoutLoc2))
2013 return MatchOperand_ParseFail;
2014 unsigned Space = (Reg < Reg2) ? (Reg2 - Reg) : (Reg2 + 32 -
Reg);
2016 if (LayoutStr != LayoutStr2) {
2017 Error(LayoutLoc2,
"expected the same vector layout");
2018 return MatchOperand_ParseFail;
2020 if (Space == 0 || Space > 3) {
2021 Error(RegLoc2,
"invalid number of vectors");
2022 return MatchOperand_ParseFail;
2027 unsigned LastReg =
Reg;
2032 SMLoc RegEndLoc2, LayoutLoc2;
2033 SMLoc RegLoc2 = Parser.getTok().getLoc();
2035 if (!TryParseVector(Reg2, RegEndLoc2, LayoutStr2, LayoutLoc2))
2036 return MatchOperand_ParseFail;
2037 unsigned Space = (LastReg < Reg2) ? (Reg2 - LastReg)
2038 : (Reg2 + 32 - LastReg);
2044 Error(RegLoc2,
"invalid space between two vectors");
2045 return MatchOperand_ParseFail;
2047 if (LayoutStr != LayoutStr2) {
2048 Error(LayoutLoc2,
"expected the same vector layout");
2049 return MatchOperand_ParseFail;
2052 Error(RegLoc2,
"invalid number of vectors");
2053 return MatchOperand_ParseFail;
2061 Error(Parser.getTok().getLoc(),
"'}' expected");
2062 return MatchOperand_ParseFail;
2064 SMLoc ELoc = Parser.getTok().getLoc();
2070 static unsigned SupRegIDs[3][2] = {
2071 { AArch64::QPairRegClassID, AArch64::DPairRegClassID },
2072 { AArch64::QTripleRegClassID, AArch64::DTripleRegClassID },
2073 { AArch64::QQuadRegClassID, AArch64::DQuadRegClassID }
2075 unsigned SupRegID = SupRegIDs[Count - 2][
static_cast<int>(IsVec64)];
2076 unsigned Sub0 = IsVec64 ? AArch64::dsub_0 : AArch64::qsub_0;
2079 &AArch64MCRegisterClasses[SupRegID]);
2082 AArch64Operand::CreateVectorList(Reg, Count, Layout, SLoc, ELoc));
2085 uint32_t NumLanes = 0;
2092 SMLoc Loc = getLexer().getLoc();
2093 Error(Loc,
"expected comma before next operand");
2094 return MatchOperand_ParseFail;
2096 return ParseNEONLane(Operands, NumLanes);
2098 return MatchOperand_Success;
2103 bool AArch64AsmParser::
2104 validateInstruction(
MCInst &Inst,
2107 case AArch64::BFIwwii:
2108 case AArch64::BFIxxii:
2109 case AArch64::SBFIZwwii:
2110 case AArch64::SBFIZxxii:
2111 case AArch64::UBFIZwwii:
2112 case AArch64::UBFIZxxii: {
2117 if (ImmR != 0 && ImmS >= ImmR) {
2118 return Error(Operands[4]->getStartLoc(),
2119 "requested insert overflows register");
2123 case AArch64::BFXILwwii:
2124 case AArch64::BFXILxxii:
2125 case AArch64::SBFXwwii:
2126 case AArch64::SBFXxxii:
2127 case AArch64::UBFXwwii:
2128 case AArch64::UBFXxxii: {
2132 int64_t RegWidth = 0;
2134 case AArch64::SBFXxxii:
case AArch64::UBFXxxii:
case AArch64::BFXILxxii:
2137 case AArch64::SBFXwwii:
case AArch64::UBFXwwii:
case AArch64::BFXILwwii:
2142 if (ImmS >= RegWidth || ImmS < ImmR) {
2143 return Error(Operands[4]->getStartLoc(),
2144 "requested extract overflows register");
2148 case AArch64::ICix: {
2152 return Error(Operands[1]->getStartLoc(),
2153 "specified IC op does not use a register");
2157 case AArch64::ICi: {
2161 return Error(Operands[1]->getStartLoc(),
2162 "specified IC op requires a register");
2166 case AArch64::TLBIix: {
2170 return Error(Operands[1]->getStartLoc(),
2171 "specified TLBI op does not use a register");
2175 case AArch64::TLBIi: {
2179 return Error(Operands[1]->getStartLoc(),
2180 "specified TLBI op requires a register");
2195 size_t CondCodePos = Name.
find(
'.');
2198 Operands.
push_back(AArch64Operand::CreateToken(Mnemonic, NameLoc));
2209 Error(S,
"invalid condition code");
2210 Parser.eatToEndOfStatement();
2216 Operands.
push_back(AArch64Operand::CreateToken(
".", DotL));
2218 Operands.
push_back(AArch64Operand::CreateCondCode(Code, S, E));
2224 if (ParseOperand(Operands, Mnemonic)) {
2225 Parser.eatToEndOfStatement();
2233 if (ParseOperand(Operands, Mnemonic)) {
2234 Parser.eatToEndOfStatement();
2248 SMLoc Loc = Parser.getTok().getLoc();
2249 Operands.
push_back(AArch64Operand::CreateToken(
"]", Loc));
2254 SMLoc Loc = Parser.getTok().getLoc();
2255 Operands.
push_back(AArch64Operand::CreateToken(
"!", Loc));
2262 SMLoc Loc = getLexer().getLoc();
2263 Parser.eatToEndOfStatement();
2264 return Error(Loc,
"expected comma before next operand");
2273 bool AArch64AsmParser::ParseDirective(
AsmToken DirectiveID) {
2275 if (IDVal ==
".hword")
2276 return ParseDirectiveWord(2, DirectiveID.
getLoc());
2277 else if (IDVal ==
".word")
2278 return ParseDirectiveWord(4, DirectiveID.
getLoc());
2279 else if (IDVal ==
".xword")
2280 return ParseDirectiveWord(8, DirectiveID.
getLoc());
2281 else if (IDVal ==
".tlsdesccall")
2282 return ParseDirectiveTLSDescCall(DirectiveID.
getLoc());
2289 bool AArch64AsmParser::ParseDirectiveWord(
unsigned Size,
SMLoc L) {
2293 if (getParser().parseExpression(Value))
2296 getParser().getStreamer().EmitValue(Value, Size);
2303 return Error(L,
"unexpected token in directive");
2314 bool AArch64AsmParser::ParseDirectiveTLSDescCall(
SMLoc L) {
2316 if (getParser().parseIdentifier(Name))
2317 return Error(L,
"expected symbol after directive");
2319 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2326 getParser().getStreamer().EmitInstruction(Inst);
2331 bool AArch64AsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
2334 bool MatchingInlineAsm) {
2336 unsigned MatchResult;
2337 MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
2340 if (ErrorInfo != ~0U && ErrorInfo >= Operands.
size())
2341 return Error(IDLoc,
"too few operands for instruction");
2343 switch (MatchResult) {
2346 if (validateInstruction(Inst, Operands))
2351 case Match_MissingFeature:
2352 Error(IDLoc,
"instruction requires a CPU feature not currently enabled");
2354 case Match_InvalidOperand: {
2355 SMLoc ErrorLoc = IDLoc;
2356 if (ErrorInfo != ~0U) {
2357 ErrorLoc = ((AArch64Operand*)Operands[ErrorInfo])->getStartLoc();
2358 if (ErrorLoc ==
SMLoc()) ErrorLoc = IDLoc;
2361 return Error(ErrorLoc,
"invalid operand for instruction");
2363 case Match_MnemonicFail:
2364 return Error(IDLoc,
"invalid instruction");
2366 case Match_AddSubRegExtendSmall:
2367 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2368 "expected '[su]xt[bhw]' or 'lsl' with optional integer in range [0, 4]");
2369 case Match_AddSubRegExtendLarge:
2370 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2371 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
2372 case Match_AddSubRegShift32:
2373 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2374 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
2375 case Match_AddSubRegShift64:
2376 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2377 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
2378 case Match_AddSubSecondSource:
2379 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2380 "expected compatible register, symbol or integer in range [0, 4095]");
2381 case Match_CVTFixedPos32:
2382 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2383 "expected integer in range [1, 32]");
2384 case Match_CVTFixedPos64:
2385 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2386 "expected integer in range [1, 64]");
2387 case Match_CondCode:
2388 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2389 "expected AArch64 condition code");
2393 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2394 "expected compatible register or floating-point constant");
2396 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2397 "expected floating-point constant #0.0 or invalid register type");
2399 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2400 "expected label or encodable integer pc offset");
2402 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2403 "expected lane specifier '[1]'");
2404 case Match_LoadStoreExtend32_1:
2405 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2406 "expected 'uxtw' or 'sxtw' with optional shift of #0");
2407 case Match_LoadStoreExtend32_2:
2408 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2409 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
2410 case Match_LoadStoreExtend32_4:
2411 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2412 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
2413 case Match_LoadStoreExtend32_8:
2414 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2415 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
2416 case Match_LoadStoreExtend32_16:
2417 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2418 "expected 'lsl' or 'sxtw' with optional shift of #0 or #4");
2419 case Match_LoadStoreExtend64_1:
2420 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2421 "expected 'lsl' or 'sxtx' with optional shift of #0");
2422 case Match_LoadStoreExtend64_2:
2423 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2424 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
2425 case Match_LoadStoreExtend64_4:
2426 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2427 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
2428 case Match_LoadStoreExtend64_8:
2429 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2430 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
2431 case Match_LoadStoreExtend64_16:
2432 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2433 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
2434 case Match_LoadStoreSImm7_4:
2435 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2436 "expected integer multiple of 4 in range [-256, 252]");
2437 case Match_LoadStoreSImm7_8:
2438 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2439 "expected integer multiple of 8 in range [-512, 508]");
2440 case Match_LoadStoreSImm7_16:
2441 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2442 "expected integer multiple of 16 in range [-1024, 1016]");
2443 case Match_LoadStoreSImm9:
2444 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2445 "expected integer in range [-256, 255]");
2446 case Match_LoadStoreUImm12_1:
2447 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2448 "expected symbolic reference or integer in range [0, 4095]");
2449 case Match_LoadStoreUImm12_2:
2450 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2451 "expected symbolic reference or integer in range [0, 8190]");
2452 case Match_LoadStoreUImm12_4:
2453 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2454 "expected symbolic reference or integer in range [0, 16380]");
2455 case Match_LoadStoreUImm12_8:
2456 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2457 "expected symbolic reference or integer in range [0, 32760]");
2458 case Match_LoadStoreUImm12_16:
2459 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2460 "expected symbolic reference or integer in range [0, 65520]");
2461 case Match_LogicalSecondSource:
2462 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2463 "expected compatible register or logical immediate");
2464 case Match_MOVWUImm16:
2465 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2466 "expected relocated symbol or integer in range [0, 65535]");
2468 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2469 "expected readable system register");
2471 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2472 "expected writable system register or pstate");
2473 case Match_NamedImm_at:
2474 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2475 "expected symbolic 'at' operand: s1e[0-3][rw] or s12e[01][rw]");
2476 case Match_NamedImm_dbarrier:
2477 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2478 "expected integer in range [0, 15] or symbolic barrier operand");
2479 case Match_NamedImm_dc:
2480 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2481 "expected symbolic 'dc' operand");
2482 case Match_NamedImm_ic:
2483 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2484 "expected 'ic' operand: 'ialluis', 'iallu' or 'ivau'");
2485 case Match_NamedImm_isb:
2486 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2487 "expected integer in range [0, 15] or 'sy'");
2488 case Match_NamedImm_prefetch:
2489 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2490 "expected prefetch hint: p(ld|st|i)l[123](strm|keep)");
2491 case Match_NamedImm_tlbi:
2492 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2493 "expected translation buffer invalidation operand");
2495 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2496 "expected integer in range [0, 65535]");
2498 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2499 "expected integer in range [0, 7]");
2501 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2502 "expected integer in range [0, 15]");
2504 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2505 "expected integer in range [0, 31]");
2507 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2508 "expected integer in range [0, 63]");
2510 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2511 "expected integer in range [0, 127]");
2513 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2514 "expected integer in range [<lsb>, 31]");
2516 return Error(((AArch64Operand*)Operands[ErrorInfo])->getStartLoc(),
2517 "expected integer in range [<lsb>, 63]");
2519 return Error(((AArch64Operand *)Operands[ErrorInfo])->getStartLoc(),
2520 "expected integer in range [1, 8]");
2521 case Match_ShrImm16:
2522 return Error(((AArch64Operand *)Operands[ErrorInfo])->getStartLoc(),
2523 "expected integer in range [1, 16]");
2524 case Match_ShrImm32:
2525 return Error(((AArch64Operand *)Operands[ErrorInfo])->getStartLoc(),
2526 "expected integer in range [1, 32]");
2527 case Match_ShrImm64:
2528 return Error(((AArch64Operand *)Operands[ErrorInfo])->getStartLoc(),
2529 "expected integer in range [1, 64]");
2531 return Error(((AArch64Operand *)Operands[ErrorInfo])->getStartLoc(),
2532 "expected integer in range [0, 7]");
2533 case Match_ShlImm16:
2534 return Error(((AArch64Operand *)Operands[ErrorInfo])->getStartLoc(),
2535 "expected integer in range [0, 15]");
2536 case Match_ShlImm32:
2537 return Error(((AArch64Operand *)Operands[ErrorInfo])->getStartLoc(),
2538 "expected integer in range [0, 31]");
2539 case Match_ShlImm64:
2540 return Error(((AArch64Operand *)Operands[ErrorInfo])->getStartLoc(),
2541 "expected integer in range [0, 63]");
2548 void AArch64Operand::print(
raw_ostream &OS)
const {
2551 OS <<
"<CondCode: " << CondCode.Code <<
">";
2554 OS <<
"<fpimm: " << FPImm.Val <<
">";
2557 OS <<
"<immwithlsl: imm=" << ImmWithLSL.Val
2558 <<
", shift=" << ImmWithLSL.ShiftAmount <<
">";
2561 getImm()->print(OS);
2564 OS <<
"<register " <<
getReg() <<
'>';
2570 OS <<
"<shift: type=" << ShiftExtend.ShiftType
2571 <<
", amount=" << ShiftExtend.Amount <<
">";
2575 OS <<
"<sysreg: " << Name << '>
';
2579 llvm_unreachable("No idea how to print this kind of operand");
2584 void AArch64Operand::dump() const {
2590 extern "C" void LLVMInitializeAArch64AsmParser() {
2591 RegisterMCAsmParser<AArch64AsmParser> X(TheAArch64Target);
2594 #define GET_REGISTER_MATCHER
2595 #define GET_MATCHER_IMPLEMENTATION
2596 #include "AArch64GenAsmMatcher.inc"
static bool isReg(const MCInst &MI, unsigned OpNo)
void push_back(const T &Elt)
bool isMOVNImm(int RegWidth, uint64_t Value, int &UImm16, int &Shift)
const char * getPointer() const
size_t size() const
size - Get the string size.
static A64Layout::VectorLayout A64StringToVectorLayout(StringRef LayoutStr)
static unsigned MatchRegisterName(StringRef Name)
static MCOperand CreateReg(unsigned Reg)
static const fltSemantics IEEEdouble
static const MCConstantExpr * Create(int64_t Value, MCContext &Ctx)
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser. The extension should use the AsmParser i...
MCTargetAsmParser - Generic interface to target specific assembly parsers.
enable_if_c<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
size_t find(char C, size_t From=0) const
bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)
Helper functions for StringRef::getAsInteger.
static A64CC::CondCodes A64StringToCondCode(StringRef CondStr)
StringRef getString() const
static MCOperand CreateExpr(const MCExpr *Val)
StringRef substr(size_t Start, size_t N=npos) const
bool isNot(TokenKind K) const
virtual void EmitInstruction(const MCInst &Inst)=0
bool isLogicalImm(unsigned RegWidth, uint64_t Imm, uint32_t &Bits)
StringSwitch & Case(const char(&S)[N], const T &Value)
static bool NeedsRegister(ICValues Val)
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
#define llvm_unreachable(msg)
bool isMOVZImm(int RegWidth, uint64_t Value, int &UImm16, int &Shift)
AsmToken - Target independent representation for an assembler token.
static bool isShift(MachineInstr *MI, int Opcode, int64_t Imm)
This file implements a class to represent arbitrary precision integral constant values and operations...
size_t array_lengthof(T(&)[N])
Find the length of an array.
const char * data() const
static const MCSymbolRefExpr * Create(const MCSymbol *Symbol, MCContext &Ctx)
A self-contained host- and target-independent arbitrary-precision floating-point software implementat...
A switch()-like statement whose cases are string literals.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
char back() const
back - Get the last character in the string.
This file declares a class to represent arbitrary precision floating point values and provide a varie...
enable_if_c< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
bool validImm(uint32_t Value) const
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...
void setOpcode(unsigned Op)
StringRef drop_front(size_t N=1) const
static const AArch64MCExpr * Create(VariantKind Kind, const MCExpr *Expr, MCContext &Ctx)
static bool NeedsRegister(TLBIValues Val)
bool is(TokenKind K) const
R Default(const T &Value) const
unsigned Log2_32(uint32_t Value)
unsigned getOpcode() const
static SMLoc getFromPointer(const char *Ptr)
StringRef getIdentifier() const
static MCOperand CreateImm(int64_t Val)
unsigned getNumOperands() const
uint32_t fromString(StringRef Name, bool &Valid) const
static A64CC::CondCodes A64InvertCondCode(A64CC::CondCodes CC)
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
static bool isMem(const MachineInstr *MI, unsigned Op)
LLVM Value Representation.
uint32_t fromString(StringRef Name, bool &Valid) const
bool isFPImm(const APFloat &Val, uint32_t &Imm8Bits)
void addOperand(const MCOperand &Op)
const MCRegisterInfo & MRI
Represents a location in source code.
std::string lower() const
const MCOperand & getOperand(unsigned i) const