10 #define DEBUG_TYPE "mcasmparser" 65 "mwarn-missing-parenthesis",
66 cl::desc(
"Warn for missing parenthesis around predicate registers"),
69 "merror-missing-parenthesis",
70 cl::desc(
"Error for missing parenthesis around predicate registers"),
73 "mwarn-sign-mismatch",
74 cl::desc(
"Warn for mismatching a signed and unsigned value"),
77 "mwarn-noncontigious-register",
80 "merror-noncontigious-register",
81 cl::desc(
"Error for register names that aren't contigious"),
86 struct HexagonOperand;
112 bool equalIsAsmAssignment()
override {
return false; }
113 bool isLabel(
AsmToken &Token)
override;
117 bool ParseDirectiveFalign(
unsigned Size,
SMLoc L);
119 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
120 bool ParseDirectiveSubsection(
SMLoc L);
121 bool ParseDirectiveComm(
bool IsLocal,
SMLoc L);
122 bool RegisterMatchesArch(
unsigned MatchNum)
const;
124 bool matchBundleOptions();
125 bool handleNoncontigiousRegister(
bool Contigious,
SMLoc &Loc);
127 void canonicalizeImmediates(
MCInst &MCI);
130 bool MatchingInlineAsm);
131 void eatToEndOfPacket();
132 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
135 bool MatchingInlineAsm)
override;
138 unsigned Kind)
override;
139 bool OutOfRange(
SMLoc IDLoc,
long long Val,
long long Max);
144 void chksetELFHeaderEFlags(
unsigned flags) {
146 getAssembler()->setELFHeaderEFlags(flags);
154 #define GET_ASSEMBLER_HEADER 155 #include "HexagonGenAsmMatcher.inc" 165 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
179 bool parseExpression(
MCExpr const *&Expr);
189 bool ParseDirective(
AsmToken DirectiveID)
override;
198 SMLoc StartLoc, EndLoc;
223 HexagonOperand(KindTy K,
MCContext &Context)
227 HexagonOperand(
const HexagonOperand &o)
230 StartLoc = o.StartLoc;
246 SMLoc getStartLoc()
const override {
return StartLoc; }
249 SMLoc getEndLoc()
const override {
return EndLoc; }
251 unsigned getReg()
const override {
256 const MCExpr *getImm()
const {
257 assert(Kind == Immediate &&
"Invalid access!");
261 bool isToken()
const override {
return Kind == Token; }
262 bool isImm()
const override {
return Kind == Immediate; }
266 bool CheckImmRange(
int immBits,
int zeroBits,
bool isSigned,
267 bool isRelocatable,
bool Extendable)
const {
268 if (Kind == Immediate) {
273 if (myMCExpr->evaluateAsAbsolute(Res)) {
274 int bits = immBits + zeroBits;
277 if (Res & ((1 << zeroBits) - 1))
280 if (Res < (1LL << (bits - 1)) && Res >= -(1LL << (bits - 1)))
286 return ((uint64_t)Res < (uint64_t)(1ULL << bits));
288 const int64_t high_bit_set = 1ULL << 63;
289 const uint64_t mask = (high_bit_set >> (63 -
bits));
290 return (((uint64_t)Res & mask) == mask);
302 bool isa30_2Imm()
const {
return CheckImmRange(30, 2,
true,
true,
true); }
303 bool isb30_2Imm()
const {
return CheckImmRange(30, 2,
true,
true,
true); }
304 bool isb15_2Imm()
const {
return CheckImmRange(15, 2,
true,
true,
false); }
305 bool isb13_2Imm()
const {
return CheckImmRange(13, 2,
true,
true,
false); }
307 bool ism32_0Imm()
const {
return true; }
309 bool isf32Imm()
const {
return false; }
310 bool isf64Imm()
const {
return false; }
311 bool iss32_0Imm()
const {
return true; }
312 bool iss31_1Imm()
const {
return true; }
313 bool iss30_2Imm()
const {
return true; }
314 bool iss29_3Imm()
const {
return true; }
315 bool iss27_2Imm()
const {
return CheckImmRange(27, 2,
true,
true,
false); }
316 bool iss9_0Imm()
const {
return CheckImmRange(9, 0,
true,
false,
false); }
317 bool iss8_0Imm()
const {
return CheckImmRange(8, 0,
true,
false,
false); }
318 bool iss8_0Imm64()
const {
return CheckImmRange(8, 0,
true,
true,
false); }
319 bool iss7_0Imm()
const {
return CheckImmRange(7, 0,
true,
false,
false); }
320 bool iss6_0Imm()
const {
return CheckImmRange(6, 0,
true,
false,
false); }
321 bool iss6_3Imm()
const {
return CheckImmRange(6, 3,
true,
false,
false); }
322 bool iss4_0Imm()
const {
return CheckImmRange(4, 0,
true,
false,
false); }
323 bool iss4_1Imm()
const {
return CheckImmRange(4, 1,
true,
false,
false); }
324 bool iss4_2Imm()
const {
return CheckImmRange(4, 2,
true,
false,
false); }
325 bool iss4_3Imm()
const {
return CheckImmRange(4, 3,
true,
false,
false); }
326 bool iss3_0Imm()
const {
return CheckImmRange(3, 0,
true,
false,
false); }
328 bool isu64_0Imm()
const {
return CheckImmRange(64, 0,
false,
true,
true); }
329 bool isu32_0Imm()
const {
return true; }
330 bool isu31_1Imm()
const {
return true; }
331 bool isu30_2Imm()
const {
return true; }
332 bool isu29_3Imm()
const {
return true; }
333 bool isu26_6Imm()
const {
return CheckImmRange(26, 6,
false,
true,
false); }
334 bool isu16_0Imm()
const {
return CheckImmRange(16, 0,
false,
true,
false); }
335 bool isu16_1Imm()
const {
return CheckImmRange(16, 1,
false,
true,
false); }
336 bool isu16_2Imm()
const {
return CheckImmRange(16, 2,
false,
true,
false); }
337 bool isu16_3Imm()
const {
return CheckImmRange(16, 3,
false,
true,
false); }
338 bool isu11_3Imm()
const {
return CheckImmRange(11, 3,
false,
false,
false); }
339 bool isu10_0Imm()
const {
return CheckImmRange(10, 0,
false,
false,
false); }
340 bool isu9_0Imm()
const {
return CheckImmRange(9, 0,
false,
false,
false); }
341 bool isu8_0Imm()
const {
return CheckImmRange(8, 0,
false,
false,
false); }
342 bool isu7_0Imm()
const {
return CheckImmRange(7, 0,
false,
false,
false); }
343 bool isu6_0Imm()
const {
return CheckImmRange(6, 0,
false,
false,
false); }
344 bool isu6_1Imm()
const {
return CheckImmRange(6, 1,
false,
false,
false); }
345 bool isu6_2Imm()
const {
return CheckImmRange(6, 2,
false,
false,
false); }
346 bool isu6_3Imm()
const {
return CheckImmRange(6, 3,
false,
false,
false); }
347 bool isu5_0Imm()
const {
return CheckImmRange(5, 0,
false,
false,
false); }
348 bool isu5_2Imm()
const {
return CheckImmRange(5, 2,
false,
false,
false); }
349 bool isu5_3Imm()
const {
return CheckImmRange(5, 3,
false,
false,
false); }
350 bool isu4_0Imm()
const {
return CheckImmRange(4, 0,
false,
false,
false); }
351 bool isu4_2Imm()
const {
return CheckImmRange(4, 2,
false,
false,
false); }
352 bool isu3_0Imm()
const {
return CheckImmRange(3, 0,
false,
false,
false); }
353 bool isu3_1Imm()
const {
return CheckImmRange(3, 1,
false,
false,
false); }
354 bool isu2_0Imm()
const {
return CheckImmRange(2, 0,
false,
false,
false); }
355 bool isu1_0Imm()
const {
return CheckImmRange(1, 0,
false,
false,
false); }
357 bool isn1Const()
const {
361 if (!getImm()->evaluateAsAbsolute(Value))
365 bool iss11_0Imm()
const {
366 return CheckImmRange(11 + 26, 0,
true,
true,
true);
368 bool iss11_1Imm()
const {
369 return CheckImmRange(11 + 26, 1,
true,
true,
true);
371 bool iss11_2Imm()
const {
372 return CheckImmRange(11 + 26, 2,
true,
true,
true);
374 bool iss11_3Imm()
const {
375 return CheckImmRange(11 + 26, 3,
true,
true,
true);
377 bool isu32_0MustExt()
const {
return isImm(); }
379 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
380 assert(N == 1 &&
"Invalid number of operands!");
384 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
385 assert(N == 1 &&
"Invalid number of operands!");
389 void addSignedImmOperands(
MCInst &Inst,
unsigned N)
const {
390 assert(N == 1 &&
"Invalid number of operands!");
401 if ((Extended < 0) != (Value < 0))
408 void addn1ConstOperands(
MCInst &Inst,
unsigned N)
const {
409 addImmOperands(Inst, N);
413 assert(Kind == Token &&
"Invalid access!");
419 static std::unique_ptr<HexagonOperand> CreateToken(
MCContext &Context,
421 HexagonOperand *
Op =
new HexagonOperand(Token, Context);
422 Op->Tok.Data = Str.
data();
423 Op->Tok.Length = Str.
size();
426 return std::unique_ptr<HexagonOperand>(
Op);
429 static std::unique_ptr<HexagonOperand>
431 HexagonOperand *
Op =
new HexagonOperand(
Register, Context);
432 Op->Reg.RegNum = RegNum;
435 return std::unique_ptr<HexagonOperand>(
Op);
438 static std::unique_ptr<HexagonOperand>
440 HexagonOperand *
Op =
new HexagonOperand(Immediate, Context);
444 return std::unique_ptr<HexagonOperand>(
Op);
453 getImm()->print(OS,
nullptr);
491 Error(IDLoc,
"invalid instruction packet: out of slots");
499 bool HexagonAsmParser::matchBundleOptions() {
505 char const *MemNoShuffMsg =
506 "invalid instruction packet: mem_noshuf specifier not " 507 "supported with this architecture";
518 if (getSTI().getFeatureBits()[Hexagon::FeatureMemNoShuf])
521 return getParser().Error(IDLoc, MemNoShuffMsg);
523 return getParser().Error(IDLoc,
llvm::Twine(
"'") + Option +
524 "' is not a valid bundle option");
532 void HexagonAsmParser::canonicalizeImmediates(
MCInst &MCI) {
537 int64_t
Value(
I.getImm());
541 if (
I.isExpr() && cast<HexagonMCExpr>(
I.getExpr())->signMismatch() &&
543 Warning(MCI.getLoc(),
"Signed/Unsigned mismatch");
549 bool HexagonAsmParser::matchOneInstruction(
MCInst &MCI,
SMLoc IDLoc,
552 bool MatchingInlineAsm) {
555 MatchInstructionImpl(InstOperands, MCI, ErrorInfo, MatchingInlineAsm);
556 if (result == Match_Success) {
558 canonicalizeImmediates(MCI);
559 result = processInstruction(MCI, InstOperands, IDLoc);
577 case Match_MissingFeature:
578 return Error(IDLoc,
"invalid instruction");
579 case Match_MnemonicFail:
580 return Error(IDLoc,
"unrecognized instruction");
581 case Match_InvalidOperand:
582 case Match_InvalidTiedOperand:
583 SMLoc ErrorLoc = IDLoc;
584 if (ErrorInfo != ~0U) {
585 if (ErrorInfo >= InstOperands.
size())
586 return Error(IDLoc,
"too few operands for instruction");
588 ErrorLoc = (
static_cast<HexagonOperand *
>(InstOperands[ErrorInfo].get()))
590 if (ErrorLoc ==
SMLoc())
593 return Error(ErrorLoc,
"invalid operand for instruction");
598 void HexagonAsmParser::eatToEndOfPacket() {
607 bool HexagonAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
611 bool MatchingInlineAsm) {
616 HexagonOperand &FirstOperand =
static_cast<HexagonOperand &
>(*Operands[0]);
617 if (FirstOperand.isToken() && FirstOperand.getToken() ==
"{") {
618 assert(Operands.
size() == 1 &&
"Brackets should be by themselves");
620 getParser().Error(IDLoc,
"Already in a packet");
627 if (FirstOperand.isToken() && FirstOperand.getToken() ==
"}") {
628 assert(Operands.
size() == 1 &&
"Brackets should be by themselves");
630 getParser().Error(IDLoc,
"Not in a packet");
634 if (matchBundleOptions())
636 return finishBundle(IDLoc, Out);
638 MCInst *SubInst =
new (getParser().getContext())
MCInst;
639 if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
640 MatchingInlineAsm)) {
646 getParser().getContext(), MII, MCB, *SubInst);
649 return finishBundle(IDLoc, Out);
654 bool HexagonAsmParser::ParseDirective(
AsmToken DirectiveID) {
656 if (IDVal.
lower() ==
".falign")
657 return ParseDirectiveFalign(256, DirectiveID.
getLoc());
658 if ((IDVal.
lower() ==
".lcomm") || (IDVal.
lower() ==
".lcommon"))
659 return ParseDirectiveComm(
true, DirectiveID.
getLoc());
660 if ((IDVal.
lower() ==
".comm") || (IDVal.
lower() ==
".common"))
661 return ParseDirectiveComm(
false, DirectiveID.
getLoc());
662 if (IDVal.
lower() ==
".subsection")
663 return ParseDirectiveSubsection(DirectiveID.
getLoc());
667 bool HexagonAsmParser::ParseDirectiveSubsection(
SMLoc L) {
668 const MCExpr *Subsection =
nullptr;
672 "Invalid subsection directive");
673 getParser().parseExpression(Subsection);
675 if (!Subsection->evaluateAsAbsolute(Res))
676 return Error(L,
"Cannot evaluate subsection number");
679 return TokError(
"unexpected token in directive");
685 if ((Res < 0) && (Res > -8193))
689 getStreamer().SubSection(Subsection);
694 bool HexagonAsmParser::ParseDirectiveFalign(
unsigned Size,
SMLoc L) {
696 int64_t MaxBytesToFill = 15;
704 if (!getParser().parseExpression(Value)) {
707 uint64_t IntValue = MCE->
getValue();
709 return Error(ExprLoc,
"literal value out of range (256) for falign");
710 MaxBytesToFill = IntValue;
713 return Error(ExprLoc,
"not a valid expression for falign directive");
717 getTargetStreamer().emitFAlign(16, MaxBytesToFill);
729 bool HexagonAsmParser::ParseDirectiveComm(
bool IsLocal,
SMLoc Loc) {
732 if (getStreamer().hasRawTextSupport())
736 if (getParser().parseIdentifier(Name))
737 return TokError(
"expected identifier in directive");
739 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
742 return TokError(
"unexpected token in directive");
746 SMLoc SizeLoc = getLexer().getLoc();
747 if (getParser().parseAbsoluteExpression(Size))
751 SMLoc ByteAlignmentLoc;
754 ByteAlignmentLoc = getLexer().getLoc();
755 if (getParser().parseAbsoluteExpression(ByteAlignment))
758 return Error(ByteAlignmentLoc,
"alignment must be a power of 2");
761 int64_t AccessAlignment = 0;
765 SMLoc AccessAlignmentLoc;
767 AccessAlignmentLoc = getLexer().getLoc();
768 if (getParser().parseAbsoluteExpression(AccessAlignment))
772 return Error(AccessAlignmentLoc,
"access alignment must be a power of 2");
776 return TokError(
"unexpected token in '.comm' or '.lcomm' directive");
783 return Error(SizeLoc,
"invalid '.comm' or '.lcomm' directive size, can't " 784 "be less than zero");
789 if (ByteAlignment < 0)
790 return Error(ByteAlignmentLoc,
"invalid '.comm' or '.lcomm' directive " 791 "alignment, can't be less than zero");
794 return Error(Loc,
"invalid symbol redefinition");
810 bool HexagonAsmParser::RegisterMatchesArch(
unsigned MatchNum)
const {
811 if (HexagonMCRegisterClasses[Hexagon::V62RegsRegClassID].
contains(MatchNum))
812 if (!getSTI().getFeatureBits()[Hexagon::ArchV62])
824 #define GET_MATCHER_IMPLEMENTATION 825 #define GET_REGISTER_MATCHER 826 #include "HexagonGenAsmMatcher.inc" 830 if (Index >= Operands.
size())
835 return static_cast<HexagonOperand &
>(Operand).
getToken().equals_lower(String);
846 bool HexagonAsmParser::splitIdentifier(
OperandVector &Operands) {
847 AsmToken const &Token = getParser().getTok();
852 std::pair<StringRef, StringRef> HeadTail = String.
split(
'.');
853 if (!HeadTail.first.empty())
855 HexagonOperand::CreateToken(getContext(), HeadTail.first, Loc));
856 if (!HeadTail.second.empty())
857 Operands.
push_back(HexagonOperand::CreateToken(
858 getContext(), String.
substr(HeadTail.first.size(), 1), Loc));
859 String = HeadTail.second;
860 }
while (!String.
empty());
864 bool HexagonAsmParser::parseOperand(
OperandVector &Operands) {
869 if (!ParseRegister(Register, Begin, End)) {
880 Warning(Begin,
"Missing parenthesis around predicate register");
881 static char const *LParen =
"(";
882 static char const *RParen =
")";
884 HexagonOperand::CreateToken(getContext(), LParen, Begin));
886 HexagonOperand::CreateReg(getContext(), Register, Begin, End));
890 splitIdentifier(Operands);
892 HexagonOperand::CreateToken(getContext(), RParen, Begin));
898 Warning(Begin,
"Missing parenthesis around predicate register");
899 static char const *LParen =
"(";
900 static char const *RParen =
")";
901 Operands.
insert(Operands.
end() - 1, HexagonOperand::CreateToken(
902 getContext(), LParen, Begin));
904 HexagonOperand::CreateReg(getContext(), Register, Begin, End));
908 splitIdentifier(Operands);
910 HexagonOperand::CreateToken(getContext(), RParen, Begin));
916 HexagonOperand::CreateReg(getContext(), Register, Begin, End));
919 return splitIdentifier(Operands);
922 bool HexagonAsmParser::isLabel(
AsmToken &Token) {
927 if (Token.
is(AsmToken::TokenKind::LCurly) ||
928 Token.
is(AsmToken::TokenKind::RCurly))
936 if (!matchRegister(String.
lower()))
941 std::string Collapsed = Raw;
944 std::pair<StringRef, StringRef> DotSplit = Whole.
split(
'.');
945 if (!matchRegister(DotSplit.first.lower()))
950 bool HexagonAsmParser::handleNoncontigiousRegister(
bool Contigious,
953 Error(Loc,
"Register name is not contigious");
957 Warning(Loc,
"Register name is not contigious");
961 bool HexagonAsmParser::ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
964 StartLoc = getLexer().getLoc();
968 bool NeededWorkaround =
false;
984 Again = (Contigious &&
Type) || (Workaround && Type);
985 NeededWorkaround = NeededWorkaround || (Again && !(Contigious &&
Type));
987 std::string Collapsed = RawString;
990 std::pair<StringRef, StringRef> DotSplit = FullString.
split(
'.');
991 unsigned DotReg = matchRegister(DotSplit.first.lower());
992 if (DotReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
993 if (DotSplit.second.empty()) {
996 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1001 size_t First = RawString.find(
'.');
1002 StringRef DotString (RawString.data() + First, RawString.size() - First);
1005 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1010 std::pair<StringRef, StringRef> ColonSplit =
StringRef(FullString).
split(
':');
1011 unsigned ColonReg = matchRegister(ColonSplit.first.lower());
1012 if (ColonReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1019 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1023 while (!Lookahead.
empty()) {
1030 bool HexagonAsmParser::implicitExpressionLocation(
OperandVector &Operands) {
1044 bool HexagonAsmParser::parseExpression(
MCExpr const *&Expr) {
1048 static char const *
Comma =
",";
1053 case AsmToken::TokenKind::Hash:
1054 if (Tokens.
size() > 1)
1055 if ((Tokens.
end() - 2)->getKind() == AsmToken::TokenKind::Plus) {
1061 case AsmToken::TokenKind::RCurly:
1062 case AsmToken::TokenKind::EndOfStatement:
1070 while (!Tokens.
empty()) {
1075 return getParser().parseExpression(Expr, Loc);
1078 bool HexagonAsmParser::parseExpressionOrOperand(
OperandVector &Operands) {
1079 if (implicitExpressionLocation(Operands)) {
1082 MCExpr const *Expr =
nullptr;
1083 bool Error = parseExpression(Expr);
1087 HexagonOperand::CreateImm(getContext(), Expr, Loc, Loc));
1090 return parseOperand(Operands);
1094 bool HexagonAsmParser::parseInstruction(
OperandVector &Operands) {
1106 if (!Operands.
empty())
1108 Operands.
push_back(HexagonOperand::CreateToken(
1114 if (Operands.
empty()) {
1115 Operands.
push_back(HexagonOperand::CreateToken(
1131 Operands.
push_back(HexagonOperand::CreateToken(
1133 Operands.
push_back(HexagonOperand::CreateToken(
1139 bool MustNotExtend =
false;
1140 bool ImplicitExpression = implicitExpressionLocation(Operands);
1142 if (!ImplicitExpression)
1143 Operands.
push_back(HexagonOperand::CreateToken(
1146 bool MustExtend =
false;
1147 bool HiOnly =
false;
1148 bool LoOnly =
false;
1152 }
else if (ImplicitExpression)
1153 MustNotExtend =
true;
1157 if (String.
lower() ==
"hi") {
1159 }
else if (String.
lower() ==
"lo") {
1162 if (HiOnly || LoOnly) {
1172 MCExpr const *Expr =
nullptr;
1173 if (parseExpression(Expr))
1178 if (Expr->evaluateAsAbsolute(Value)) {
1182 if (HiOnly || LoOnly)
1190 case MCSymbolRefExpr::VariantKind::VK_TPREL:
1191 case MCSymbolRefExpr::VariantKind::VK_DTPREL:
1193 MustNotExtend = !MustExtend;
1204 std::unique_ptr<HexagonOperand> Operand =
1205 HexagonOperand::CreateImm(getContext(), Expr, ExprLoc, ExprLoc);
1212 if (parseExpressionOrOperand(Operands))
1220 getLexer().UnLex(ID);
1221 return parseInstruction(Operands);
1239 HexagonOperand *
Op =
static_cast<HexagonOperand *
>(&AsmOp);
1244 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 0
1246 : Match_InvalidOperand;
1250 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 1
1252 : Match_InvalidOperand;
1255 if (Op->Kind == HexagonOperand::Token && Kind != InvalidMatchClass) {
1257 if (matchTokenString(myStringRef.
lower()) == (MatchClassKind)
Kind)
1258 return Match_Success;
1259 if (matchTokenString(myStringRef.
upper()) == (MatchClassKind)
Kind)
1260 return Match_Success;
1267 return Match_InvalidOperand;
1271 bool HexagonAsmParser::OutOfRange(
SMLoc IDLoc,
long long Val,
long long Max) {
1274 ES <<
"value " << Val <<
"(" <<
format_hex(Val, 0) <<
") out of range: ";
1278 ES << Max <<
"-" << (-Max - 1);
1282 int HexagonAsmParser::processInstruction(
MCInst &Inst,
1287 std::string r =
"r";
1288 std::string v =
"v";
1289 std::string Colon =
":";
1297 "Found pseudo instruction with no expansion");
1303 case Hexagon::J2_trap1:
1304 if (!getSTI().getFeatureBits()[Hexagon::ArchV65]) {
1307 if (Rx.
getReg() != Hexagon::R0 || Ry.
getReg() != Hexagon::R0) {
1308 Error(IDLoc,
"trap1 can only have register r0 as operand");
1309 return Match_InvalidOperand;
1314 case Hexagon::A2_iconst: {
1326 case Hexagon::M4_mpyrr_addr:
1327 case Hexagon::S4_addi_asl_ri:
1328 case Hexagon::S4_addi_lsr_ri:
1329 case Hexagon::S4_andi_asl_ri:
1330 case Hexagon::S4_andi_lsr_ri:
1331 case Hexagon::S4_ori_asl_ri:
1332 case Hexagon::S4_ori_lsr_ri:
1333 case Hexagon::S4_or_andix:
1334 case Hexagon::S4_subi_asl_ri:
1335 case Hexagon::S4_subi_lsr_ri: {
1339 return Match_InvalidOperand;
1343 case Hexagon::C2_cmpgei: {
1353 case Hexagon::C2_cmpgeui: {
1358 assert(Success &&
"Assured by matcher");
1379 case Hexagon::A2_tfrp: {
1382 std::string R1 = r +
utostr(RegPairNum + 1);
1384 MO.
setReg(matchRegister(Reg1));
1386 std::string
R2 = r +
utostr(RegPairNum);
1393 case Hexagon::A2_tfrpt:
1394 case Hexagon::A2_tfrpf: {
1397 std::string R1 = r +
utostr(RegPairNum + 1);
1399 MO.
setReg(matchRegister(Reg1));
1401 std::string
R2 = r +
utostr(RegPairNum);
1405 ? Hexagon::C2_ccombinewt
1406 : Hexagon::C2_ccombinewf);
1409 case Hexagon::A2_tfrptnew:
1410 case Hexagon::A2_tfrpfnew: {
1413 std::string R1 = r +
utostr(RegPairNum + 1);
1415 MO.
setReg(matchRegister(Reg1));
1417 std::string
R2 = r +
utostr(RegPairNum);
1421 ? Hexagon::C2_ccombinewnewt
1422 : Hexagon::C2_ccombinewnewf);
1427 case Hexagon::V6_vassignp: {
1430 std::string R1 = v +
utostr(RegPairNum + 1);
1433 std::string
R2 = v +
utostr(RegPairNum);
1444 case Hexagon::CONST64:
1454 std::string myCharStr;
1464 std::string myImmStr =
utohexstr(static_cast<uint32_t>(Value));
1465 myCharStr =
StringRef(
".gnu.linkonce.l4.CONST_00000000")
1470 std::string myImmStr =
utohexstr(Value);
1471 myCharStr =
StringRef(
".gnu.linkonce.l8.CONST_0000000000000000")
1479 }
else if (MO_1.
isExpr()) {
1481 myCharStr =
".lita";
1488 unsigned byteSize = is32bit ? 4 : 8;
1489 getStreamer().EmitCodeAlignment(byteSize, byteSize);
1497 Sym = getContext().getOrCreateSymbol(
StringRef(myCharStr.c_str() + 16));
1499 getStreamer().EmitLabel(Sym);
1500 getStreamer().EmitSymbolAttribute(Sym,
MCSA_Global);
1501 getStreamer().EmitIntValue(Value, byteSize);
1503 }
else if (MO_1.
isExpr()) {
1504 const char *StringStart =
nullptr;
1505 const char *StringEnd =
nullptr;
1506 if (*Operands[4]->getStartLoc().getPointer() ==
'#') {
1507 StringStart = Operands[5]->getStartLoc().getPointer();
1508 StringEnd = Operands[6]->getStartLoc().getPointer();
1510 StringStart = Operands[4]->getStartLoc().getPointer();
1511 StringEnd = Operands[5]->getStartLoc().getPointer();
1514 unsigned size = StringEnd - StringStart;
1515 std::string DotConst =
".CONST_";
1516 Sym = getContext().getOrCreateSymbol(DotConst +
1521 getStreamer().EmitLabel(Sym);
1522 getStreamer().EmitSymbolAttribute(Sym,
MCSA_Local);
1523 getStreamer().EmitValue(MO_1.
getExpr(), 4);
1533 TmpInst.
setOpcode(Hexagon::L2_loadrigp);
1535 TmpInst.
setOpcode(Hexagon::L2_loadrdgp);
1546 case Hexagon::A2_tfrpi: {
1550 int sVal = (MO.
getExpr()->evaluateAsAbsolute(Value) && Value < 0) ? -1 : 0;
1558 case Hexagon::TFRI64_V4: {
1562 if (MO.
getExpr()->evaluateAsAbsolute(Value)) {
1563 int s8 =
Hi_32(Value);
1565 OutOfRange(IDLoc, s8, -128);
1583 case Hexagon::TFRI64_V2_ext: {
1588 if (MO2.
getExpr()->evaluateAsAbsolute(Value)) {
1590 if (s8 < -128 || s8 > 127)
1591 OutOfRange(IDLoc, s8, -128);
1598 case Hexagon::A4_combineii: {
1602 if (MO1.
getExpr()->evaluateAsAbsolute(Value)) {
1604 if (s8 < -128 || s8 > 127)
1605 OutOfRange(IDLoc, s8, -128);
1612 case Hexagon::S2_tableidxb_goodsyntax:
1616 case Hexagon::S2_tableidxh_goodsyntax: {
1626 TmpInst.
setOpcode(Hexagon::S2_tableidxh);
1636 case Hexagon::S2_tableidxw_goodsyntax: {
1646 TmpInst.
setOpcode(Hexagon::S2_tableidxw);
1656 case Hexagon::S2_tableidxd_goodsyntax: {
1666 TmpInst.
setOpcode(Hexagon::S2_tableidxd);
1676 case Hexagon::M2_mpyui:
1679 case Hexagon::M2_mpysmi: {
1686 bool Absolute = Expr.evaluateAsAbsolute(Value);
1690 ((Value <= -256) || Value >= 256))
1691 return Match_InvalidOperand;
1705 case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
1723 TmpInst.
setOpcode(Hexagon::S2_asr_i_r_rnd);
1734 case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
1745 std::string R1 = r +
utostr(RegPairNum + 1);
1747 Rss.
setReg(matchRegister(Reg1));
1749 std::string
R2 = r +
utostr(RegPairNum);
1751 TmpInst.
setOpcode(Hexagon::A2_combinew);
1761 Inst.
setOpcode(Hexagon::S2_asr_i_p_rnd);
1766 case Hexagon::A4_boundscheck: {
1770 Inst.
setOpcode(Hexagon::A4_boundscheck_hi);
1771 std::string Name = r +
utostr(RegNum) + Colon +
utostr(RegNum - 1);
1773 Rs.
setReg(matchRegister(RegPair));
1775 Inst.
setOpcode(Hexagon::A4_boundscheck_lo);
1776 std::string Name = r +
utostr(RegNum + 1) + Colon +
utostr(RegNum);
1778 Rs.
setReg(matchRegister(RegPair));
1783 case Hexagon::A2_addsp: {
1788 std::string Name = r +
utostr(RegNum) + Colon +
utostr(RegNum - 1);
1790 Rs.
setReg(matchRegister(RegPair));
1793 std::string Name = r +
utostr(RegNum + 1) + Colon +
utostr(RegNum);
1795 Rs.
setReg(matchRegister(RegPair));
1800 case Hexagon::M2_vrcmpys_s1: {
1804 Inst.
setOpcode(Hexagon::M2_vrcmpys_s1_h);
1805 std::string Name = r +
utostr(RegNum) + Colon +
utostr(RegNum - 1);
1807 Rt.
setReg(matchRegister(RegPair));
1809 Inst.
setOpcode(Hexagon::M2_vrcmpys_s1_l);
1810 std::string Name = r +
utostr(RegNum + 1) + Colon +
utostr(RegNum);
1812 Rt.
setReg(matchRegister(RegPair));
1817 case Hexagon::M2_vrcmpys_acc_s1: {
1824 TmpInst.
setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
1825 std::string Name = r +
utostr(RegNum) + Colon +
utostr(RegNum - 1);
1827 Rt.
setReg(matchRegister(RegPair));
1829 TmpInst.
setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
1830 std::string Name = r +
utostr(RegNum + 1) + Colon +
utostr(RegNum);
1832 Rt.
setReg(matchRegister(RegPair));
1843 case Hexagon::M2_vrcmpys_s1rp: {
1847 Inst.
setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
1848 std::string Name = r +
utostr(RegNum) + Colon +
utostr(RegNum - 1);
1850 Rt.
setReg(matchRegister(RegPair));
1852 Inst.
setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
1853 std::string Name = r +
utostr(RegNum + 1) + Colon +
utostr(RegNum);
1855 Rt.
setReg(matchRegister(RegPair));
1860 case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
1873 Inst.
setOpcode(Hexagon::S5_asrhub_rnd_sat);
1878 case Hexagon::S5_vasrhrnd_goodsyntax: {
1889 std::string R1 = r +
utostr(RegPairNum + 1);
1891 Rss.
setReg(matchRegister(Reg1));
1893 std::string
R2 = r +
utostr(RegPairNum);
1895 TmpInst.
setOpcode(Hexagon::A2_combinew);
1910 case Hexagon::A2_not: {
1922 case Hexagon::PS_loadrubabs:
1926 case Hexagon::PS_loadrbabs:
1930 case Hexagon::PS_loadruhabs:
1934 case Hexagon::PS_loadrhabs:
1938 case Hexagon::PS_loadriabs:
1942 case Hexagon::PS_loadrdabs:
1946 case Hexagon::PS_storerbabs:
1950 case Hexagon::PS_storerhabs:
1954 case Hexagon::PS_storerfabs:
1958 case Hexagon::PS_storeriabs:
1962 case Hexagon::PS_storerdabs:
1966 case Hexagon::PS_storerbnewabs:
1968 Inst.
setOpcode(Hexagon::S2_storerbnewgp);
1970 case Hexagon::PS_storerhnewabs:
1972 Inst.
setOpcode(Hexagon::S2_storerhnewgp);
1974 case Hexagon::PS_storerinewabs:
1976 Inst.
setOpcode(Hexagon::S2_storerinewgp);
1978 case Hexagon::A2_zxtb: {
1986 return Match_Success;
1989 unsigned HexagonAsmParser::matchRegister(
StringRef Name) {
static bool isReg(const MCInst &MI, unsigned OpNo)
static bool Check(DecodeStatus &Out, DecodeStatus In)
const AsmToken & getTok() const
Get the current (last) lexed token.
Type
MessagePack types as defined in the standard, with the exception of Integer being divided into a sign...
void setMustExtend(bool Val=true)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
static unsigned MatchRegisterName(StringRef Name)
void print(const char *ProgName, raw_ostream &S, bool ShowColors=true, bool ShowKindLabel=true) const
This represents an "assembler immediate".
virtual bool Warning(SMLoc L, const Twine &Msg, SMRange Range=None)=0
Emit a warning at the location L, with the message Msg.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
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.
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
static MCOperand createExpr(const MCExpr *Val)
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
void setMustNotExtend(bool Val=true)
void push_back(const T &Elt)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
virtual bool isToken() const =0
isToken - Is this a token operand?
void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ") const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
Target specific streamer interface.
constexpr bool isInt< 8 >(int64_t x)
bool isAbsolute() const
Is this an absolute (as opposed to relocatable) value.
void PushSection()
Save the current and previous section on the section stack.
static const MCBinaryExpr * createAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
bool isPseudo() const
Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction...
void LLVMInitializeHexagonAsmParser()
Force static initialization.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
static cl::opt< bool > WarnSignedMismatch("mwarn-sign-mismatch", cl::desc("Warn for mismatching a signed and unsigned value"), cl::init(true))
bool isOuterLoop(MCInst const &MCI)
static bool is32bit(MachineTypes Machine)
MCSymbolRefExpr::VariantKind getAccessVariant() const
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).
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, bool PrintSchedInfo=false)
Emit the given Instruction into the current section.
return AArch64::GPR64RegClass contains(Reg)
void setInnerLoop(MCInst &MCI)
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string...
SMLoc getLoc() const
Get the current source location.
amdgpu Simplify well known AMD library false Value Value const Twine & Name
static MCOperand createReg(unsigned Reg)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Generic assembler lexer interface, for use by target specific assembly lexers.
static cl::opt< bool > WarnNoncontigiousRegister("mwarn-noncontigious-register", cl::desc("Warn for register names that arent contigious"), cl::init(true))
static cl::opt< bool > ErrorMissingParenthesis("merror-missing-parenthesis", cl::desc("Error for missing parenthesis around predicate registers"), cl::init(false))
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
virtual bool printError(SMLoc L, const Twine &Msg, SMRange Range=None)=0
Emit an error at the location L, with the message Msg.
Base class for the full range of assembler expressions which are needed for parsing.
Target independent representation for an assembler token.
static bool isMem(const MachineInstr &MI, unsigned Op)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
unsigned getReg() const
Returns the register number.
void setMemReorderDisabled(MCInst &MCI)
Context object for machine code objects.
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \\\)
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
bool canonicalizePacket(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCContext &Context, MCInst &MCB, HexagonMCChecker *Checker)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
void extendIfNeeded(MCContext &Context, MCInstrInfo const &MCII, MCInst &MCB, MCInst const &MCI)
void setMustExtend(MCExpr const &Expr, bool Val=true)
const MCExpr * getExpr() const
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).
LLVM_NODISCARD std::string upper() const
Convert the given ASCII string to uppercase.
Analysis containing CSE Info
Instances of this class represent a single low-level machine instruction.
virtual bool hasRawTextSupport() const
Return true if this asm streamer supports emitting unformatted text to the .s file with EmitRawText...
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual MCContext & getContext()=0
initializer< Ty > init(const Ty &Val)
Streaming machine code generation interface.
static HexagonMCExpr * create(MCExpr const *Expr, MCContext &Ctx)
MCTargetStreamer * getTargetStreamer()
The instances of the Type class are immutable: once they are created, they are never changed...
bool mustExtend(MCExpr const &Expr)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
virtual void SwitchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
void setSignMismatch(bool Val=true)
MCAssembler & getAssembler()
Interface to description of machine instruction set.
virtual MCAsmLexer & getLexer()=0
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
static cl::opt< bool > ErrorNoncontigiousRegister("merror-noncontigious-register", cl::desc("Error for register names that aren't contigious"), cl::init(false))
void setOuterLoop(MCInst &MCI)
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
bool Error(SMLoc L, const Twine &Msg, SMRange Range=None)
Return an error at the location L, with the message Msg.
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
bool mustNotExtend() const
std::string & str()
Flushes the stream contents to the target string and returns the string's reference.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static const MCBinaryExpr * createLShr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static unsigned MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
LLVM_NODISCARD int compare_lower(StringRef RHS) const
compare_lower - Compare two strings, ignoring case.
void HexagonMCEmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, unsigned AccessSize)
MCStreamer & getStreamer()
void setOpcode(unsigned Op)
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
void UnLex(AsmToken const &Token)
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
const MCOperand & getOperand(unsigned i) const
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Promote Memory to Register
static bool previousIsLoop(OperandVector &Operands, size_t Index)
static bool previousEqual(OperandVector &Operands, size_t Index, StringRef String)
std::string utostr(uint64_t X, bool isNeg=false)
const AsmToken & Lex()
Consume the next token from the input stream and return it.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool is(TokenKind K) const
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, const SectionAddrMap &Addrs) const
Try to evaluate the expression to an absolute value.
Base class for user error types.
iterator insert(iterator I, T &&Elt)
static MCOperand createInst(const MCInst *Val)
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
void emplace_back(ArgTypes &&... Args)
MCExpr const & getExpr(MCExpr const &Expr)
LLVM_NODISCARD bool empty() const
static MCInst makeCombineInst(int opCode, MCOperand &Rdd, MCOperand &MO1, MCOperand &MO2)
Generic base class for all target subtargets.
This represents a section on linux, lots of unix variants and some bare metal systems.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
References to labels and assigned expressions.
void setMustNotExtend(MCExpr const &Expr, bool Val=true)
size_t bundleSize(MCInst const &MCI)
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
void setReg(unsigned Reg)
Set the register number.
LLVM_NODISCARD std::string lower() const
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isInnerLoop(MCInst const &MCI)
A raw_ostream that writes to an std::string.
bool PopSection()
Restore the current and previous section from the section stack.
#define HEXAGON_PACKET_SIZE
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM Value Representation.
Lightweight error class with error context and mandatory checking.
Check for a valid bundle.
This class implements an extremely fast bulk output stream that can only output to a stream...
void addOperand(const MCOperand &Op)
StringRef - Represent a constant reference to a string, i.e.
static cl::opt< bool > WarnMissingParenthesis("mwarn-missing-parenthesis", cl::desc("Warn for missing parenthesis around predicate registers"), cl::init(true))
Represents a location in source code.
void setS27_2_reloc(MCExpr const &Expr, bool Val=true)
unsigned getOpcode() const
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Instances of this class represent operands of the MCInst class.
static MCOperand createImm(int64_t Val)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
Target & getTheHexagonTarget()
void HexagonMCEmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, unsigned AccessSize)
std::string utohexstr(uint64_t X, bool LowerCase=false)
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
TokenKind getKind() const
void setExpr(const MCExpr *Val)