59#define DEBUG_TYPE "mcasmparser"
64 "mwarn-missing-parenthesis",
65 cl::desc(
"Warn for missing parenthesis around predicate registers"),
68 "merror-missing-parenthesis",
69 cl::desc(
"Error for missing parenthesis around predicate registers"),
72 "mwarn-sign-mismatch",
73 cl::desc(
"Warn for mismatching a signed and unsigned value"),
76 "mwarn-noncontigious-register",
79 "merror-noncontigious-register",
80 cl::desc(
"Error for register names that aren't contigious"),
116 bool ParseDirectiveFalign(
unsigned Size,
SMLoc L);
120 SMLoc &EndLoc)
override;
121 bool ParseDirectiveSubsection(
SMLoc L);
122 bool ParseDirectiveComm(
bool IsLocal,
SMLoc L);
123 bool RegisterMatchesArch(
unsigned MatchNum)
const;
125 bool matchBundleOptions();
126 bool handleNoncontigiousRegister(
bool Contigious,
SMLoc &Loc);
128 void canonicalizeImmediates(
MCInst &MCI);
131 bool MatchingInlineAsm);
132 void eatToEndOfPacket();
136 bool MatchingInlineAsm)
override;
139 unsigned Kind)
override;
140 bool OutOfRange(
SMLoc IDLoc,
long long Val,
long long Max);
149#define GET_ASSEMBLER_HEADER
150#include "HexagonGenAsmMatcher.inc"
174 bool parseExpression(
MCExpr const *&Expr);
193 SMLoc StartLoc, EndLoc;
217 HexagonOperand(
const HexagonOperand &o)
220 StartLoc =
o.StartLoc;
236 SMLoc getStartLoc()
const override {
return StartLoc; }
239 SMLoc getEndLoc()
const override {
return EndLoc; }
241 unsigned getReg()
const override {
246 const MCExpr *getImm()
const {
247 assert(Kind == Immediate &&
"Invalid access!");
251 bool isToken()
const override {
return Kind == Token; }
252 bool isImm()
const override {
return Kind == Immediate; }
256 bool CheckImmRange(
int immBits,
int zeroBits,
bool isSigned,
257 bool isRelocatable,
bool Extendable)
const {
258 if (Kind == Immediate) {
263 if (myMCExpr->evaluateAsAbsolute(Res)) {
264 int bits = immBits + zeroBits;
267 if (Res & ((1 << zeroBits) - 1))
270 if (Res < (1LL << (bits - 1)) && Res >= -(1LL << (bits - 1)))
278 const int64_t high_bit_set = 1ULL << 63;
292 bool isa30_2Imm()
const {
return CheckImmRange(30, 2,
true,
true,
true); }
293 bool isb30_2Imm()
const {
return CheckImmRange(30, 2,
true,
true,
true); }
294 bool isb15_2Imm()
const {
return CheckImmRange(15, 2,
true,
true,
false); }
295 bool isb13_2Imm()
const {
return CheckImmRange(13, 2,
true,
true,
false); }
297 bool ism32_0Imm()
const {
return true; }
299 bool isf32Imm()
const {
return false; }
300 bool isf64Imm()
const {
return false; }
301 bool iss32_0Imm()
const {
return true; }
302 bool iss31_1Imm()
const {
return true; }
303 bool iss30_2Imm()
const {
return true; }
304 bool iss29_3Imm()
const {
return true; }
305 bool iss27_2Imm()
const {
return CheckImmRange(27, 2,
true,
true,
false); }
306 bool iss10_0Imm()
const {
return CheckImmRange(10, 0,
true,
false,
false); }
307 bool iss10_6Imm()
const {
return CheckImmRange(10, 6,
true,
false,
false); }
308 bool iss9_0Imm()
const {
return CheckImmRange(9, 0,
true,
false,
false); }
309 bool iss8_0Imm()
const {
return CheckImmRange(8, 0,
true,
false,
false); }
310 bool iss8_0Imm64()
const {
return CheckImmRange(8, 0,
true,
true,
false); }
311 bool iss7_0Imm()
const {
return CheckImmRange(7, 0,
true,
false,
false); }
312 bool iss6_0Imm()
const {
return CheckImmRange(6, 0,
true,
false,
false); }
313 bool iss6_3Imm()
const {
return CheckImmRange(6, 3,
true,
false,
false); }
314 bool iss4_0Imm()
const {
return CheckImmRange(4, 0,
true,
false,
false); }
315 bool iss4_1Imm()
const {
return CheckImmRange(4, 1,
true,
false,
false); }
316 bool iss4_2Imm()
const {
return CheckImmRange(4, 2,
true,
false,
false); }
317 bool iss4_3Imm()
const {
return CheckImmRange(4, 3,
true,
false,
false); }
318 bool iss3_0Imm()
const {
return CheckImmRange(3, 0,
true,
false,
false); }
320 bool isu64_0Imm()
const {
return CheckImmRange(64, 0,
false,
true,
true); }
321 bool isu32_0Imm()
const {
return true; }
322 bool isu31_1Imm()
const {
return true; }
323 bool isu30_2Imm()
const {
return true; }
324 bool isu29_3Imm()
const {
return true; }
325 bool isu26_6Imm()
const {
return CheckImmRange(26, 6,
false,
true,
false); }
326 bool isu16_0Imm()
const {
return CheckImmRange(16, 0,
false,
true,
false); }
327 bool isu16_1Imm()
const {
return CheckImmRange(16, 1,
false,
true,
false); }
328 bool isu16_2Imm()
const {
return CheckImmRange(16, 2,
false,
true,
false); }
329 bool isu16_3Imm()
const {
return CheckImmRange(16, 3,
false,
true,
false); }
330 bool isu11_3Imm()
const {
return CheckImmRange(11, 3,
false,
false,
false); }
331 bool isu10_0Imm()
const {
return CheckImmRange(10, 0,
false,
false,
false); }
332 bool isu9_0Imm()
const {
return CheckImmRange(9, 0,
false,
false,
false); }
333 bool isu8_0Imm()
const {
return CheckImmRange(8, 0,
false,
false,
false); }
334 bool isu7_0Imm()
const {
return CheckImmRange(7, 0,
false,
false,
false); }
335 bool isu6_0Imm()
const {
return CheckImmRange(6, 0,
false,
false,
false); }
336 bool isu6_1Imm()
const {
return CheckImmRange(6, 1,
false,
false,
false); }
337 bool isu6_2Imm()
const {
return CheckImmRange(6, 2,
false,
false,
false); }
338 bool isu6_3Imm()
const {
return CheckImmRange(6, 3,
false,
false,
false); }
339 bool isu5_0Imm()
const {
return CheckImmRange(5, 0,
false,
false,
false); }
340 bool isu5_2Imm()
const {
return CheckImmRange(5, 2,
false,
false,
false); }
341 bool isu5_3Imm()
const {
return CheckImmRange(5, 3,
false,
false,
false); }
342 bool isu4_0Imm()
const {
return CheckImmRange(4, 0,
false,
false,
false); }
343 bool isu4_2Imm()
const {
return CheckImmRange(4, 2,
false,
false,
false); }
344 bool isu3_0Imm()
const {
return CheckImmRange(3, 0,
false,
false,
false); }
345 bool isu3_1Imm()
const {
return CheckImmRange(3, 1,
false,
false,
false); }
346 bool isu2_0Imm()
const {
return CheckImmRange(2, 0,
false,
false,
false); }
347 bool isu1_0Imm()
const {
return CheckImmRange(1, 0,
false,
false,
false); }
349 bool isn1Const()
const {
353 if (!getImm()->evaluateAsAbsolute(
Value))
357 bool issgp10Const()
const {
360 return getReg() == Hexagon::SGP1_0;
362 bool iss11_0Imm()
const {
363 return CheckImmRange(11 + 26, 0,
true,
true,
true);
365 bool iss11_1Imm()
const {
366 return CheckImmRange(11 + 26, 1,
true,
true,
true);
368 bool iss11_2Imm()
const {
369 return CheckImmRange(11 + 26, 2,
true,
true,
true);
371 bool iss11_3Imm()
const {
372 return CheckImmRange(11 + 26, 3,
true,
true,
true);
374 bool isu32_0MustExt()
const {
return isImm(); }
376 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
377 assert(
N == 1 &&
"Invalid number of operands!");
381 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
382 assert(
N == 1 &&
"Invalid number of operands!");
386 void addSignedImmOperands(
MCInst &Inst,
unsigned N)
const {
387 assert(
N == 1 &&
"Invalid number of operands!");
398 if ((Extended < 0) != (
Value < 0))
405 void addn1ConstOperands(
MCInst &Inst,
unsigned N)
const {
406 addImmOperands(Inst,
N);
408 void addsgp10ConstOperands(
MCInst &Inst,
unsigned N)
const {
409 addRegOperands(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);
460 OS <<
"'" << getToken() <<
"'";
480 MII, STI, getContext(), MCB, &
Check,
true);
499bool HexagonAsmParser::matchBundleOptions() {
505 char const *MemNoShuffMsg =
506 "invalid instruction packet: mem_noshuf specifier not "
507 "supported with this architecture";
510 if (
Option.compare_insensitive(
"endloop01") == 0) {
513 }
else if (
Option.compare_insensitive(
"endloop0") == 0) {
515 }
else if (
Option.compare_insensitive(
"endloop1") == 0) {
517 }
else if (
Option.compare_insensitive(
"mem_noshuf") == 0) {
518 if (getSTI().hasFeature(Hexagon::FeatureMemNoShuf))
521 return getParser().Error(IDLoc, MemNoShuffMsg);
522 }
else if (
Option.compare_insensitive(
"mem_no_order") == 0) {
525 return getParser().Error(IDLoc,
llvm::Twine(
"'") + Option +
526 "' is not a valid bundle option");
534void HexagonAsmParser::canonicalizeImmediates(
MCInst &MCI) {
539 int64_t
Value(
I.getImm());
543 if (
I.isExpr() && cast<HexagonMCExpr>(
I.getExpr())->signMismatch() &&
545 Warning(MCI.getLoc(),
"Signed/Unsigned mismatch");
551bool HexagonAsmParser::matchOneInstruction(
MCInst &MCI,
SMLoc IDLoc,
554 bool MatchingInlineAsm) {
557 MatchInstructionImpl(InstOperands, MCI,
ErrorInfo, MatchingInlineAsm);
558 if (result == Match_Success) {
560 canonicalizeImmediates(MCI);
561 result = processInstruction(MCI, InstOperands, IDLoc);
579 case Match_MissingFeature:
580 return Error(IDLoc,
"invalid instruction");
581 case Match_MnemonicFail:
582 return Error(IDLoc,
"unrecognized instruction");
583 case Match_InvalidOperand:
585 case Match_InvalidTiedOperand:
586 SMLoc ErrorLoc = IDLoc;
589 return Error(IDLoc,
"too few operands for instruction");
591 ErrorLoc = (
static_cast<HexagonOperand *
>(InstOperands[
ErrorInfo].get()))
593 if (ErrorLoc ==
SMLoc())
596 return Error(ErrorLoc,
"invalid operand for instruction");
601void HexagonAsmParser::eatToEndOfPacket() {
610bool HexagonAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &
Opcode,
614 bool MatchingInlineAsm) {
619 HexagonOperand &FirstOperand =
static_cast<HexagonOperand &
>(*
Operands[0]);
620 if (FirstOperand.isToken() && FirstOperand.getToken() ==
"{") {
621 assert(
Operands.size() == 1 &&
"Brackets should be by themselves");
623 getParser().Error(IDLoc,
"Already in a packet");
630 if (FirstOperand.isToken() && FirstOperand.getToken() ==
"}") {
631 assert(
Operands.size() == 1 &&
"Brackets should be by themselves");
633 getParser().Error(IDLoc,
"Not in a packet");
637 if (matchBundleOptions())
639 return finishBundle(IDLoc, Out);
641 MCInst *SubInst = getParser().getContext().createMCInst();
643 MatchingInlineAsm)) {
649 getParser().getContext(), MII, MCB, *SubInst);
652 return finishBundle(IDLoc, Out);
657bool HexagonAsmParser::ParseDirective(
AsmToken DirectiveID) {
659 if (IDVal.
lower() ==
".falign")
660 return ParseDirectiveFalign(256, DirectiveID.
getLoc());
661 if ((IDVal.
lower() ==
".lcomm") || (IDVal.
lower() ==
".lcommon"))
662 return ParseDirectiveComm(
true, DirectiveID.
getLoc());
663 if ((IDVal.
lower() ==
".comm") || (IDVal.
lower() ==
".common"))
664 return ParseDirectiveComm(
false, DirectiveID.
getLoc());
665 if (IDVal.
lower() ==
".subsection")
666 return ParseDirectiveSubsection(DirectiveID.
getLoc());
670bool HexagonAsmParser::ParseDirectiveSubsection(
SMLoc L) {
671 const MCExpr *Subsection =
nullptr;
675 "Invalid subsection directive");
676 getParser().parseExpression(Subsection);
678 if (!Subsection->evaluateAsAbsolute(Res))
679 return Error(L,
"Cannot evaluate subsection number");
682 return TokError(
"unexpected token in directive");
688 if ((Res < 0) && (Res > -8193))
692 getStreamer().subSection(Subsection);
697bool HexagonAsmParser::ParseDirectiveFalign(
unsigned Size,
SMLoc L) {
699 int64_t MaxBytesToFill = 15;
707 if (!getParser().parseExpression(
Value)) {
709 auto *MCE = cast<MCConstantExpr>(
Value);
710 uint64_t IntValue = MCE->getValue();
712 return Error(ExprLoc,
"literal value out of range (256) for falign");
713 MaxBytesToFill = IntValue;
716 return Error(ExprLoc,
"not a valid expression for falign directive");
720 getTargetStreamer().emitFAlign(16, MaxBytesToFill);
732bool HexagonAsmParser::ParseDirectiveComm(
bool IsLocal,
SMLoc Loc) {
735 if (getStreamer().hasRawTextSupport())
739 if (getParser().parseIdentifier(
Name))
740 return TokError(
"expected identifier in directive");
745 return TokError(
"unexpected token in directive");
749 SMLoc SizeLoc = getLexer().getLoc();
750 if (getParser().parseAbsoluteExpression(
Size))
754 SMLoc ByteAlignmentLoc;
757 ByteAlignmentLoc = getLexer().getLoc();
758 if (getParser().parseAbsoluteExpression(ByteAlignment))
761 return Error(ByteAlignmentLoc,
"alignment must be a power of 2");
764 int64_t AccessAlignment = 0;
768 SMLoc AccessAlignmentLoc;
770 AccessAlignmentLoc = getLexer().getLoc();
771 if (getParser().parseAbsoluteExpression(AccessAlignment))
775 return Error(AccessAlignmentLoc,
"access alignment must be a power of 2");
779 return TokError(
"unexpected token in '.comm' or '.lcomm' directive");
786 return Error(SizeLoc,
"invalid '.comm' or '.lcomm' directive size, can't "
787 "be less than zero");
792 if (ByteAlignment < 0)
793 return Error(ByteAlignmentLoc,
"invalid '.comm' or '.lcomm' directive "
794 "alignment, can't be less than zero");
796 if (!
Sym->isUndefined())
797 return Error(Loc,
"invalid symbol redefinition");
813bool HexagonAsmParser::RegisterMatchesArch(
unsigned MatchNum)
const {
814 if (HexagonMCRegisterClasses[Hexagon::V62RegsRegClassID].
contains(MatchNum))
815 if (!getSTI().hasFeature(Hexagon::ArchV62))
827#define GET_MATCHER_IMPLEMENTATION
828#define GET_REGISTER_MATCHER
829#include "HexagonGenAsmMatcher.inc"
838 return static_cast<HexagonOperand &
>(Operand).getToken().equals_insensitive(
851 AsmToken const &Token = getParser().getTok();
856 std::pair<StringRef, StringRef> HeadTail =
String.split(
'.');
857 if (!HeadTail.first.empty())
859 HexagonOperand::CreateToken(getContext(), HeadTail.first, Loc));
860 if (!HeadTail.second.empty())
861 Operands.push_back(HexagonOperand::CreateToken(
862 getContext(),
String.substr(HeadTail.first.size(), 1), Loc));
864 }
while (!
String.empty());
884 Warning(Begin,
"Missing parenthesis around predicate register");
885 static char const *LParen =
"(";
886 static char const *RParen =
")";
888 HexagonOperand::CreateToken(getContext(), LParen, Begin));
890 HexagonOperand::CreateReg(getContext(),
Register, Begin,
End));
892 if (MaybeDotNew.
is(AsmToken::TokenKind::Identifier) &&
896 HexagonOperand::CreateToken(getContext(), RParen, Begin));
902 Warning(Begin,
"Missing parenthesis around predicate register");
903 static char const *LParen =
"(";
904 static char const *RParen =
")";
906 getContext(), LParen, Begin));
908 HexagonOperand::CreateReg(getContext(),
Register, Begin,
End));
910 if (MaybeDotNew.
is(AsmToken::TokenKind::Identifier) &&
914 HexagonOperand::CreateToken(getContext(), RParen, Begin));
920 HexagonOperand::CreateReg(getContext(),
Register, Begin,
End));
926bool HexagonAsmParser::isLabel(
AsmToken &Token) {
931 if (Token.
is(AsmToken::TokenKind::LCurly) ||
932 Token.
is(AsmToken::TokenKind::RCurly))
938 if (!Token.
is(AsmToken::TokenKind::Identifier))
940 if (!matchRegister(
String.lower()))
945 std::string Collapsed = std::string(Raw);
948 std::pair<StringRef, StringRef> DotSplit = Whole.
split(
'.');
949 if (!matchRegister(DotSplit.first.lower()))
954bool HexagonAsmParser::handleNoncontigiousRegister(
bool Contigious,
957 Error(Loc,
"Register name is not contigious");
961 Warning(Loc,
"Register name is not contigious");
967 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
973 StartLoc = getLexer().getLoc();
977 bool NeededWorkaround =
false;
986 Lookahead.
back().getString().data() +
987 Lookahead.
back().getString().size();
993 Again = (Contigious &&
Type) || (Workaround &&
Type);
994 NeededWorkaround = NeededWorkaround || (Again && !(Contigious &&
Type));
996 std::string Collapsed = std::string(RawString);
999 std::pair<StringRef, StringRef> DotSplit = FullString.
split(
'.');
1000 unsigned DotReg = matchRegister(DotSplit.first.lower());
1001 if (DotReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1002 if (DotSplit.second.empty()) {
1005 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1010 size_t First = RawString.find(
'.');
1014 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1019 std::pair<StringRef, StringRef> ColonSplit =
StringRef(FullString).
split(
':');
1020 unsigned ColonReg = matchRegister(ColonSplit.first.lower());
1021 if (ColonReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1027 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1031 while (!Lookahead.
empty()) {
1051bool HexagonAsmParser::parseExpression(
MCExpr const *&Expr) {
1055 static char const *
Comma =
",";
1059 switch (Tokens.
back().getKind()) {
1060 case AsmToken::TokenKind::Hash:
1061 if (Tokens.
size() > 1)
1062 if ((Tokens.
end() - 2)->getKind() == AsmToken::TokenKind::Plus) {
1064 AsmToken(AsmToken::TokenKind::Comma, Comma));
1068 case AsmToken::TokenKind::RCurly:
1069 case AsmToken::TokenKind::EndOfStatement:
1070 case AsmToken::TokenKind::Eof:
1077 while (!Tokens.
empty()) {
1082 return getParser().parseExpression(Expr, Loc);
1086 if (implicitExpressionLocation(
Operands)) {
1089 MCExpr const *Expr =
nullptr;
1090 bool Error = parseExpression(Expr);
1094 HexagonOperand::CreateImm(getContext(), Expr, Loc, Loc));
1115 Operands.push_back(HexagonOperand::CreateToken(
1122 Operands.push_back(HexagonOperand::CreateToken(
1138 Operands.push_back(HexagonOperand::CreateToken(
1140 Operands.push_back(HexagonOperand::CreateToken(
1146 bool MustNotExtend =
false;
1147 bool ImplicitExpression = implicitExpressionLocation(
Operands);
1149 if (!ImplicitExpression)
1150 Operands.push_back(HexagonOperand::CreateToken(
1153 bool MustExtend =
false;
1154 bool HiOnly =
false;
1155 bool LoOnly =
false;
1159 }
else if (ImplicitExpression)
1160 MustNotExtend =
true;
1164 if (
String.lower() ==
"hi") {
1166 }
else if (
String.lower() ==
"lo") {
1169 if (HiOnly || LoOnly) {
1179 MCExpr const *Expr =
nullptr;
1180 if (parseExpression(Expr))
1185 if (Expr->evaluateAsAbsolute(
Value)) {
1189 if (HiOnly || LoOnly)
1195 if (!
Value.isAbsolute()) {
1196 switch (
Value.getAccessVariant()) {
1197 case MCSymbolRefExpr::VariantKind::VK_TPREL:
1198 case MCSymbolRefExpr::VariantKind::VK_DTPREL:
1200 MustNotExtend = !MustExtend;
1211 std::unique_ptr<HexagonOperand> Operand =
1212 HexagonOperand::CreateImm(getContext(), Expr, ExprLoc, ExprLoc);
1213 Operands.push_back(std::move(Operand));
1219 if (parseExpressionOrOperand(
Operands))
1227 getLexer().UnLex(
ID);
1246 HexagonOperand *
Op =
static_cast<HexagonOperand *
>(&AsmOp);
1251 return Op->isImm() &&
Op->Imm.Val->evaluateAsAbsolute(
Value) &&
Value == 0
1253 : Match_InvalidOperand;
1257 return Op->isImm() &&
Op->Imm.Val->evaluateAsAbsolute(
Value) &&
Value == 1
1259 : Match_InvalidOperand;
1262 if (
Op->Kind == HexagonOperand::Token && Kind != InvalidMatchClass) {
1264 if (matchTokenString(myStringRef.
lower()) == (MatchClassKind)Kind)
1265 return Match_Success;
1266 if (matchTokenString(myStringRef.
upper()) == (MatchClassKind)Kind)
1267 return Match_Success;
1274 return Match_InvalidOperand;
1278bool HexagonAsmParser::OutOfRange(
SMLoc IDLoc,
long long Val,
long long Max) {
1281 ES <<
"value " << Val <<
"(" <<
format_hex(Val, 0) <<
") out of range: ";
1285 ES <<
Max <<
"-" << (-
Max - 1);
1289int HexagonAsmParser::processInstruction(
MCInst &Inst,
1294 const std::string r =
"r";
1295 const std::string
v =
"v";
1296 const std::string Colon =
":";
1297 using RegPairVals = std::pair<unsigned, unsigned>;
1298 auto GetRegPair = [
this, r](RegPairVals RegPair) {
1299 const std::string R1 = r + utostr(RegPair.first);
1300 const std::string
R2 = r + utostr(RegPair.second);
1302 return std::make_pair(matchRegister(R1), matchRegister(
R2));
1304 auto GetScalarRegs = [RI, GetRegPair](
unsigned RegPair) {
1306 const RegPairVals RegPair_ = std::make_pair(
Lower + 1,
Lower);
1308 return GetRegPair(RegPair_);
1310 auto GetVecRegs = [GetRegPair](
unsigned VecRegPair) {
1311 const RegPairVals RegPair =
1314 return GetRegPair(RegPair);
1317 bool is32bit =
false;
1323 "Found pseudo instruction with no expansion");
1329 case Hexagon::J2_trap1:
1330 if (!getSTI().hasFeature(Hexagon::ArchV65)) {
1333 if (Rx.
getReg() != Hexagon::R0 || Ry.
getReg() != Hexagon::R0) {
1334 Error(IDLoc,
"trap1 can only have register r0 as operand");
1335 return Match_InvalidOperand;
1340 case Hexagon::A2_iconst: {
1352 case Hexagon::M4_mpyrr_addr:
1353 case Hexagon::S4_addi_asl_ri:
1354 case Hexagon::S4_addi_lsr_ri:
1355 case Hexagon::S4_andi_asl_ri:
1356 case Hexagon::S4_andi_lsr_ri:
1357 case Hexagon::S4_ori_asl_ri:
1358 case Hexagon::S4_ori_lsr_ri:
1359 case Hexagon::S4_or_andix:
1360 case Hexagon::S4_subi_asl_ri:
1361 case Hexagon::S4_subi_lsr_ri: {
1365 return Match_InvalidOperand;
1369 case Hexagon::C2_cmpgei: {
1379 case Hexagon::C2_cmpgeui: {
1405 case Hexagon::A2_tfrp: {
1407 const std::pair<unsigned, unsigned> RegPair = GetScalarRegs(MO.
getReg());
1408 MO.
setReg(RegPair.first);
1414 case Hexagon::A2_tfrpt:
1415 case Hexagon::A2_tfrpf: {
1417 const std::pair<unsigned, unsigned> RegPair = GetScalarRegs(MO.
getReg());
1418 MO.
setReg(RegPair.first);
1421 ? Hexagon::C2_ccombinewt
1422 : Hexagon::C2_ccombinewf);
1425 case Hexagon::A2_tfrptnew:
1426 case Hexagon::A2_tfrpfnew: {
1428 const std::pair<unsigned, unsigned> RegPair = GetScalarRegs(MO.
getReg());
1429 MO.
setReg(RegPair.first);
1432 ? Hexagon::C2_ccombinewnewt
1433 : Hexagon::C2_ccombinewnewf);
1438 case Hexagon::V6_vassignp: {
1440 const std::pair<unsigned, unsigned> RegPair = GetVecRegs(MO.
getReg());
1441 MO.
setReg(RegPair.first);
1448 case Hexagon::CONST32:
1452 case Hexagon::CONST64:
1462 std::string myCharStr;
1472 std::string myImmStr = utohexstr(
static_cast<uint32_t>(
Value));
1473 myCharStr =
StringRef(
".gnu.linkonce.l4.CONST_00000000")
1478 std::string myImmStr = utohexstr(
Value);
1479 myCharStr =
StringRef(
".gnu.linkonce.l8.CONST_0000000000000000")
1487 }
else if (MO_1.
isExpr()) {
1489 myCharStr =
".lita";
1496 unsigned byteSize = is32bit ? 4 : 8;
1505 Sym = getContext().getOrCreateSymbol(
StringRef(myCharStr.c_str() + 16));
1506 if (
Sym->isUndefined()) {
1507 getStreamer().emitLabel(
Sym);
1511 }
else if (MO_1.
isExpr()) {
1512 const char *StringStart =
nullptr;
1513 const char *StringEnd =
nullptr;
1514 if (*
Operands[4]->getStartLoc().getPointer() ==
'#') {
1515 StringStart =
Operands[5]->getStartLoc().getPointer();
1516 StringEnd =
Operands[6]->getStartLoc().getPointer();
1518 StringStart =
Operands[4]->getStartLoc().getPointer();
1519 StringEnd =
Operands[5]->getStartLoc().getPointer();
1522 unsigned size = StringEnd - StringStart;
1523 std::string DotConst =
".CONST_";
1524 Sym = getContext().getOrCreateSymbol(DotConst +
1527 if (
Sym->isUndefined()) {
1529 getStreamer().emitLabel(
Sym);
1531 getStreamer().emitValue(MO_1.
getExpr(), 4);
1541 TmpInst.
setOpcode(Hexagon::L2_loadrigp);
1543 TmpInst.
setOpcode(Hexagon::L2_loadrdgp);
1554 case Hexagon::A2_tfrpi: {
1566 case Hexagon::TFRI64_V4: {
1573 OutOfRange(IDLoc, s8, -128);
1591 case Hexagon::TFRI64_V2_ext: {
1598 if (s8 < -128 || s8 > 127)
1599 OutOfRange(IDLoc, s8, -128);
1606 case Hexagon::A4_combineii: {
1612 if (s8 < -128 || s8 > 127)
1613 OutOfRange(IDLoc, s8, -128);
1620 case Hexagon::S2_tableidxb_goodsyntax:
1624 case Hexagon::S2_tableidxh_goodsyntax: {
1634 TmpInst.
setOpcode(Hexagon::S2_tableidxh);
1644 case Hexagon::S2_tableidxw_goodsyntax: {
1654 TmpInst.
setOpcode(Hexagon::S2_tableidxw);
1664 case Hexagon::S2_tableidxd_goodsyntax: {
1674 TmpInst.
setOpcode(Hexagon::S2_tableidxd);
1684 case Hexagon::M2_mpyui:
1687 case Hexagon::M2_mpysmi: {
1696 return Match_InvalidOperand;
1699 return Match_InvalidOperand;
1700 if (Value < 0 && Value > -256) {
1713 case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
1719 return Match_InvalidOperand;
1731 TmpInst.
setOpcode(Hexagon::S2_asr_i_r_rnd);
1742 case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
1749 return Match_InvalidOperand;
1753 std::string R1 = r + utostr(RegPairNum + 1);
1755 Rss.
setReg(matchRegister(Reg1));
1757 std::string
R2 = r + utostr(RegPairNum);
1759 TmpInst.
setOpcode(Hexagon::A2_combinew);
1769 Inst.
setOpcode(Hexagon::S2_asr_i_p_rnd);
1774 case Hexagon::A4_boundscheck: {
1778 Inst.
setOpcode(Hexagon::A4_boundscheck_hi);
1779 std::string
Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1781 Rs.
setReg(matchRegister(RegPair));
1783 Inst.
setOpcode(Hexagon::A4_boundscheck_lo);
1784 std::string
Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1786 Rs.
setReg(matchRegister(RegPair));
1791 case Hexagon::A2_addsp: {
1796 std::string
Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1798 Rs.
setReg(matchRegister(RegPair));
1801 std::string
Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1803 Rs.
setReg(matchRegister(RegPair));
1808 case Hexagon::M2_vrcmpys_s1: {
1812 Inst.
setOpcode(Hexagon::M2_vrcmpys_s1_h);
1813 std::string
Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1815 Rt.
setReg(matchRegister(RegPair));
1817 Inst.
setOpcode(Hexagon::M2_vrcmpys_s1_l);
1818 std::string
Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1820 Rt.
setReg(matchRegister(RegPair));
1825 case Hexagon::M2_vrcmpys_acc_s1: {
1832 TmpInst.
setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
1833 std::string
Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1835 Rt.
setReg(matchRegister(RegPair));
1837 TmpInst.
setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
1838 std::string
Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1840 Rt.
setReg(matchRegister(RegPair));
1851 case Hexagon::M2_vrcmpys_s1rp: {
1855 Inst.
setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
1856 std::string
Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1858 Rt.
setReg(matchRegister(RegPair));
1860 Inst.
setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
1861 std::string
Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1863 Rt.
setReg(matchRegister(RegPair));
1868 case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
1873 return Match_InvalidOperand;
1881 Inst.
setOpcode(Hexagon::S5_asrhub_rnd_sat);
1886 case Hexagon::S5_vasrhrnd_goodsyntax: {
1893 return Match_InvalidOperand;
1897 std::string R1 = r + utostr(RegPairNum + 1);
1899 Rss.
setReg(matchRegister(Reg1));
1901 std::string
R2 = r + utostr(RegPairNum);
1903 TmpInst.
setOpcode(Hexagon::A2_combinew);
1918 case Hexagon::A2_not: {
1930 case Hexagon::PS_loadrubabs:
1934 case Hexagon::PS_loadrbabs:
1938 case Hexagon::PS_loadruhabs:
1942 case Hexagon::PS_loadrhabs:
1946 case Hexagon::PS_loadriabs:
1950 case Hexagon::PS_loadrdabs:
1954 case Hexagon::PS_storerbabs:
1958 case Hexagon::PS_storerhabs:
1962 case Hexagon::PS_storerfabs:
1966 case Hexagon::PS_storeriabs:
1970 case Hexagon::PS_storerdabs:
1974 case Hexagon::PS_storerbnewabs:
1976 Inst.
setOpcode(Hexagon::S2_storerbnewgp);
1978 case Hexagon::PS_storerhnewabs:
1980 Inst.
setOpcode(Hexagon::S2_storerhnewgp);
1982 case Hexagon::PS_storerinewabs:
1984 Inst.
setOpcode(Hexagon::S2_storerinewgp);
1986 case Hexagon::A2_zxtb: {
1994 return Match_Success;
static unsigned MatchRegisterName(StringRef Name)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static unsigned MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static size_t byteSize(BTF::CommonType *Type)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static bool isSigned(unsigned int Opcode)
static cl::opt< bool > WarnSignedMismatch("mwarn-sign-mismatch", cl::desc("Warn for mismatching a signed and unsigned value"), cl::init(false))
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))
static cl::opt< bool > ErrorNoncontigiousRegister("merror-noncontigious-register", cl::desc("Error for register names that aren't contigious"), cl::init(false))
static bool previousEqual(OperandVector &Operands, size_t Index, StringRef String)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeHexagonAsmParser()
Force static initialization.
static MCInst makeCombineInst(int opCode, MCOperand &Rdd, MCOperand &MO1, MCOperand &MO2)
static bool previousIsLoop(OperandVector &Operands, size_t Index)
static cl::opt< bool > WarnMissingParenthesis("mwarn-missing-parenthesis", cl::desc("Warn for missing parenthesis around predicate registers"), cl::init(true))
mir Rename Register Operands
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
This file defines the SmallVector class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static constexpr uint32_t Opcode
Target independent representation for an assembler token.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Check for a valid bundle.
void HexagonMCEmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment, unsigned AccessSize)
void HexagonMCEmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, Align ByteAlignment, unsigned AccessSize)
bool mustNotExtend() const
static HexagonMCExpr * create(MCExpr const *Expr, MCContext &Ctx)
Generic assembler lexer interface, for use by target specific assembly lexers.
void UnLex(AsmToken const &Token)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
SMLoc getLoc() const
Get the current source location.
const AsmToken & getTok() const
Get the current (last) lexed token.
const AsmToken & Lex()
Consume the next token from the input stream and return it.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual bool printError(SMLoc L, const Twine &Msg, SMRange Range=std::nullopt)=0
Emit an error at the location L, with the message Msg.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual MCAsmLexer & getLexer()=0
virtual bool Warning(SMLoc L, const Twine &Msg, SMRange Range=std::nullopt)=0
Emit a warning at the location L, with the message Msg.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual MCContext & getContext()=0
bool Error(SMLoc L, const Twine &Msg, SMRange Range=std::nullopt)
Return an error at the location L, with the message Msg.
static const MCBinaryExpr * createLShr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, const SectionAddrMap &Addrs) const
Try to evaluate the expression to an absolute value.
@ Unary
Unary expressions.
@ SymbolRef
References to labels and assigned expressions.
@ Binary
Binary expressions.
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Instances of this class represent a single low-level machine instruction.
void dump_pretty(raw_ostream &OS, const MCInstPrinter *Printer=nullptr, StringRef Separator=" ", const MCRegisterInfo *RegInfo=nullptr) const
Dump the MCInst as prettily as possible using the additional MC structures, if given.
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Interface to description of machine instruction set.
MCAssembler & getAssembler()
Instances of this class represent operands of the MCInst class.
static MCOperand createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
void setReg(unsigned Reg)
Set the register number.
void setExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
unsigned getReg() const
Returns the register number.
const MCExpr * getExpr() const
static MCOperand createInst(const MCInst *Val)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual bool isToken() const =0
isToken - Is this a token operand?
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
uint16_t getEncodingValue(MCRegister RegNo) const
Returns the encoding for RegNo.
Wrapper class representing physical registers. Should be passed by value.
This represents a section on linux, lots of unix variants and some bare metal systems.
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual bool hasRawTextSupport() const
Return true if this asm streamer supports emitting unformatted text to the .s file with EmitRawText.
bool popSection()
Restore the current and previous section from the section stack.
MCTargetStreamer * getTargetStreamer()
void pushSection()
Save the current and previous section on the section stack.
virtual void switchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
Generic base class for all target subtargets.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool equalIsAsmAssignment()
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual bool ParseDirective(AsmToken DirectiveID)
ParseDirective - Parse a target specific assembler directive This method is deprecated,...
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
virtual bool isLabel(AsmToken &Token)
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
Target specific streamer interface.
MCStreamer & getStreamer()
This represents an "assembler immediate".
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Wrapper class representing virtual and physical registers.
Instances of this class encapsulate one diagnostic report, allowing printing to a raw_ostream as a ca...
void print(const char *ProgName, raw_ostream &S, bool ShowColors=true, bool ShowKindLabel=true) const
Represents a location in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
std::string str() const
str - Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
std::string upper() const
Convert the given ASCII string to uppercase.
constexpr size_t size() const
size - Get the string size.
std::string lower() const
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setOuterLoop(MCInst &MCI)
bool isOuterLoop(MCInst const &MCI)
size_t bundleSize(MCInst const &MCI)
void setS27_2_reloc(MCExpr const &Expr, bool Val=true)
void setInnerLoop(MCInst &MCI)
std::pair< unsigned, unsigned > GetVecRegPairIndices(unsigned VecRegPair)
Returns an ordered pair of the constituent register ordinals for each of the elements of VecRegPair.
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
void setMemReorderDisabled(MCInst &MCI)
bool isBundle(MCInst const &MCI)
MCExpr const & getExpr(MCExpr const &Expr)
bool isInnerLoop(MCInst const &MCI)
bool canonicalizePacket(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCContext &Context, MCInst &MCB, HexagonMCChecker *Checker, bool AttemptCompatibility=false)
void setMustNotExtend(MCExpr const &Expr, bool Val=true)
void extendIfNeeded(MCContext &Context, MCInstrInfo const &MCII, MCInst &MCB, MCInst const &MCI)
bool mustExtend(MCExpr const &Expr)
void setMustExtend(MCExpr const &Expr, bool Val=true)
bool isPseudo(uint64_t TSFlags)
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Target & getTheHexagonTarget()
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
@ MCSA_Global
.type _foo, @gnu_unique_object
auto mask(ShuffFunc S, unsigned Length, OptArgs... args) -> MaskT
This struct is a compact representation of a valid (non-zero power of two) alignment.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...