60#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"),
117 bool ParseDirectiveFalign(
unsigned Size,
SMLoc L);
121 SMLoc &EndLoc)
override;
122 bool ParseDirectiveSubsection(
SMLoc L);
123 bool ParseDirectiveComm(
bool IsLocal,
SMLoc L);
125 bool parseDirectiveAttribute(
SMLoc L);
127 bool RegisterMatchesArch(
unsigned MatchNum)
const;
129 bool matchBundleOptions();
130 bool handleNoncontigiousRegister(
bool Contigious,
SMLoc &Loc);
132 void canonicalizeImmediates(
MCInst &MCI);
135 bool MatchingInlineAsm);
136 void eatToEndOfPacket();
140 bool MatchingInlineAsm)
override;
143 unsigned Kind)
override;
144 bool OutOfRange(
SMLoc IDLoc,
long long Val,
long long Max);
153#define GET_ASSEMBLER_HEADER
154#include "HexagonGenAsmMatcher.inc"
173 getTargetStreamer().emitTargetAttributes(*STI);
181 bool parseExpression(
MCExpr const *&Expr);
200 SMLoc StartLoc, EndLoc;
224 HexagonOperand(
const HexagonOperand &o)
227 StartLoc =
o.StartLoc;
243 SMLoc getStartLoc()
const override {
return StartLoc; }
246 SMLoc getEndLoc()
const override {
return EndLoc; }
253 const MCExpr *getImm()
const {
254 assert(Kind == Immediate &&
"Invalid access!");
258 bool isToken()
const override {
return Kind == Token; }
259 bool isImm()
const override {
return Kind == Immediate; }
263 bool CheckImmRange(
int immBits,
int zeroBits,
bool isSigned,
264 bool isRelocatable,
bool Extendable)
const {
265 if (Kind == Immediate) {
270 if (myMCExpr->evaluateAsAbsolute(Res)) {
271 int bits = immBits + zeroBits;
274 if (Res & ((1 << zeroBits) - 1))
277 if (Res < (1LL << (bits - 1)) && Res >= -(1LL << (bits - 1)))
285 const int64_t high_bit_set = 1ULL << 63;
299 bool isa30_2Imm()
const {
return CheckImmRange(30, 2,
true,
true,
true); }
300 bool isb30_2Imm()
const {
return CheckImmRange(30, 2,
true,
true,
true); }
301 bool isb15_2Imm()
const {
return CheckImmRange(15, 2,
true,
true,
false); }
302 bool isb13_2Imm()
const {
return CheckImmRange(13, 2,
true,
true,
false); }
304 bool ism32_0Imm()
const {
return true; }
306 bool isf32Imm()
const {
return false; }
307 bool isf64Imm()
const {
return false; }
308 bool iss32_0Imm()
const {
return true; }
309 bool iss31_1Imm()
const {
return true; }
310 bool iss30_2Imm()
const {
return true; }
311 bool iss29_3Imm()
const {
return true; }
312 bool iss27_2Imm()
const {
return CheckImmRange(27, 2,
true,
true,
false); }
313 bool iss10_0Imm()
const {
return CheckImmRange(10, 0,
true,
false,
false); }
314 bool iss10_6Imm()
const {
return CheckImmRange(10, 6,
true,
false,
false); }
315 bool iss9_0Imm()
const {
return CheckImmRange(9, 0,
true,
false,
false); }
316 bool iss8_0Imm()
const {
return CheckImmRange(8, 0,
true,
false,
false); }
317 bool iss8_0Imm64()
const {
return CheckImmRange(8, 0,
true,
true,
false); }
318 bool iss7_0Imm()
const {
return CheckImmRange(7, 0,
true,
false,
false); }
319 bool iss6_0Imm()
const {
return CheckImmRange(6, 0,
true,
false,
false); }
320 bool iss6_3Imm()
const {
return CheckImmRange(6, 3,
true,
false,
false); }
321 bool iss4_0Imm()
const {
return CheckImmRange(4, 0,
true,
false,
false); }
322 bool iss4_1Imm()
const {
return CheckImmRange(4, 1,
true,
false,
false); }
323 bool iss4_2Imm()
const {
return CheckImmRange(4, 2,
true,
false,
false); }
324 bool iss4_3Imm()
const {
return CheckImmRange(4, 3,
true,
false,
false); }
325 bool iss3_0Imm()
const {
return CheckImmRange(3, 0,
true,
false,
false); }
327 bool isu64_0Imm()
const {
return CheckImmRange(64, 0,
false,
true,
true); }
328 bool isu32_0Imm()
const {
return true; }
329 bool isu31_1Imm()
const {
return true; }
330 bool isu30_2Imm()
const {
return true; }
331 bool isu29_3Imm()
const {
return true; }
332 bool isu26_6Imm()
const {
return CheckImmRange(26, 6,
false,
true,
false); }
333 bool isu16_0Imm()
const {
return CheckImmRange(16, 0,
false,
true,
false); }
334 bool isu16_1Imm()
const {
return CheckImmRange(16, 1,
false,
true,
false); }
335 bool isu16_2Imm()
const {
return CheckImmRange(16, 2,
false,
true,
false); }
336 bool isu16_3Imm()
const {
return CheckImmRange(16, 3,
false,
true,
false); }
337 bool isu11_3Imm()
const {
return CheckImmRange(11, 3,
false,
false,
false); }
338 bool isu10_0Imm()
const {
return CheckImmRange(10, 0,
false,
false,
false); }
339 bool isu9_0Imm()
const {
return CheckImmRange(9, 0,
false,
false,
false); }
340 bool isu8_0Imm()
const {
return CheckImmRange(8, 0,
false,
false,
false); }
341 bool isu7_0Imm()
const {
return CheckImmRange(7, 0,
false,
false,
false); }
342 bool isu6_0Imm()
const {
return CheckImmRange(6, 0,
false,
false,
false); }
343 bool isu6_1Imm()
const {
return CheckImmRange(6, 1,
false,
false,
false); }
344 bool isu6_2Imm()
const {
return CheckImmRange(6, 2,
false,
false,
false); }
345 bool isu6_3Imm()
const {
return CheckImmRange(6, 3,
false,
false,
false); }
346 bool isu5_0Imm()
const {
return CheckImmRange(5, 0,
false,
false,
false); }
347 bool isu5_2Imm()
const {
return CheckImmRange(5, 2,
false,
false,
false); }
348 bool isu5_3Imm()
const {
return CheckImmRange(5, 3,
false,
false,
false); }
349 bool isu4_0Imm()
const {
return CheckImmRange(4, 0,
false,
false,
false); }
350 bool isu4_2Imm()
const {
return CheckImmRange(4, 2,
false,
false,
false); }
351 bool isu3_0Imm()
const {
return CheckImmRange(3, 0,
false,
false,
false); }
352 bool isu3_1Imm()
const {
return CheckImmRange(3, 1,
false,
false,
false); }
353 bool isu2_0Imm()
const {
return CheckImmRange(2, 0,
false,
false,
false); }
354 bool isu1_0Imm()
const {
return CheckImmRange(1, 0,
false,
false,
false); }
356 bool isn1Const()
const {
360 if (!getImm()->evaluateAsAbsolute(
Value))
364 bool issgp10Const()
const {
367 return getReg() == Hexagon::SGP1_0;
369 bool iss11_0Imm()
const {
370 return CheckImmRange(11 + 26, 0,
true,
true,
true);
372 bool iss11_1Imm()
const {
373 return CheckImmRange(11 + 26, 1,
true,
true,
true);
375 bool iss11_2Imm()
const {
376 return CheckImmRange(11 + 26, 2,
true,
true,
true);
378 bool iss11_3Imm()
const {
379 return CheckImmRange(11 + 26, 3,
true,
true,
true);
381 bool isu32_0MustExt()
const {
return isImm(); }
383 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
384 assert(
N == 1 &&
"Invalid number of operands!");
388 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
389 assert(
N == 1 &&
"Invalid number of operands!");
393 void addSignedImmOperands(
MCInst &Inst,
unsigned N)
const {
394 assert(
N == 1 &&
"Invalid number of operands!");
405 if ((Extended < 0) != (
Value < 0))
412 void addn1ConstOperands(
MCInst &Inst,
unsigned N)
const {
413 addImmOperands(Inst,
N);
415 void addsgp10ConstOperands(
MCInst &Inst,
unsigned N)
const {
416 addRegOperands(Inst,
N);
420 assert(Kind == Token &&
"Invalid access!");
426 static std::unique_ptr<HexagonOperand> CreateToken(
MCContext &Context,
428 HexagonOperand *
Op =
new HexagonOperand(Token, Context);
429 Op->Tok.Data = Str.data();
430 Op->Tok.Length = Str.size();
433 return std::unique_ptr<HexagonOperand>(
Op);
436 static std::unique_ptr<HexagonOperand>
438 HexagonOperand *
Op =
new HexagonOperand(
Register, Context);
439 Op->Reg.RegNum = RegNum;
442 return std::unique_ptr<HexagonOperand>(
Op);
445 static std::unique_ptr<HexagonOperand>
447 HexagonOperand *
Op =
new HexagonOperand(Immediate, Context);
451 return std::unique_ptr<HexagonOperand>(
Op);
460 getImm()->print(
OS,
nullptr);
467 OS <<
"'" << getToken() <<
"'";
487 MII, STI, getContext(), MCB, &
Check,
true);
506bool HexagonAsmParser::matchBundleOptions() {
512 char const *MemNoShuffMsg =
513 "invalid instruction packet: mem_noshuf specifier not "
514 "supported with this architecture";
517 if (
Option.compare_insensitive(
"endloop01") == 0) {
520 }
else if (
Option.compare_insensitive(
"endloop0") == 0) {
522 }
else if (
Option.compare_insensitive(
"endloop1") == 0) {
524 }
else if (
Option.compare_insensitive(
"mem_noshuf") == 0) {
525 if (getSTI().hasFeature(Hexagon::FeatureMemNoShuf))
528 return getParser().Error(IDLoc, MemNoShuffMsg);
529 }
else if (
Option.compare_insensitive(
"mem_no_order") == 0) {
532 return getParser().Error(IDLoc,
llvm::Twine(
"'") + Option +
533 "' is not a valid bundle option");
541void HexagonAsmParser::canonicalizeImmediates(
MCInst &MCI) {
546 int64_t
Value(
I.getImm());
550 if (
I.isExpr() && cast<HexagonMCExpr>(
I.getExpr())->signMismatch() &&
552 Warning(MCI.getLoc(),
"Signed/Unsigned mismatch");
558bool HexagonAsmParser::matchOneInstruction(
MCInst &MCI,
SMLoc IDLoc,
561 bool MatchingInlineAsm) {
564 MatchInstructionImpl(InstOperands, MCI,
ErrorInfo, MatchingInlineAsm);
565 if (result == Match_Success) {
567 canonicalizeImmediates(MCI);
568 result = processInstruction(MCI, InstOperands, IDLoc);
586 case Match_MissingFeature:
587 return Error(IDLoc,
"invalid instruction");
588 case Match_MnemonicFail:
589 return Error(IDLoc,
"unrecognized instruction");
590 case Match_InvalidOperand:
592 case Match_InvalidTiedOperand:
593 SMLoc ErrorLoc = IDLoc;
596 return Error(IDLoc,
"too few operands for instruction");
598 ErrorLoc = (
static_cast<HexagonOperand *
>(InstOperands[
ErrorInfo].get()))
600 if (ErrorLoc ==
SMLoc())
603 return Error(ErrorLoc,
"invalid operand for instruction");
608void HexagonAsmParser::eatToEndOfPacket() {
617bool HexagonAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
621 bool MatchingInlineAsm) {
626 HexagonOperand &FirstOperand =
static_cast<HexagonOperand &
>(*
Operands[0]);
627 if (FirstOperand.isToken() && FirstOperand.getToken() ==
"{") {
628 assert(
Operands.size() == 1 &&
"Brackets should be by themselves");
630 getParser().Error(IDLoc,
"Already in a packet");
637 if (FirstOperand.isToken() && FirstOperand.getToken() ==
"}") {
638 assert(
Operands.size() == 1 &&
"Brackets should be by themselves");
640 getParser().Error(IDLoc,
"Not in a packet");
644 if (matchBundleOptions())
646 return finishBundle(IDLoc, Out);
648 MCInst *SubInst = getParser().getContext().createMCInst();
650 MatchingInlineAsm)) {
656 getParser().getContext(), MII, MCB, *SubInst);
659 return finishBundle(IDLoc, Out);
665bool HexagonAsmParser::parseDirectiveAttribute(
SMLoc L) {
674 return Error(TagLoc,
"attribute name not recognized: " +
Name);
685 if (
check(!CE, TagLoc,
"expected numeric constant"))
688 Tag =
CE->getValue();
695 int64_t IntegerValue = 0;
703 return Error(ValueExprLoc,
"expected numeric constant");
704 IntegerValue =
CE->getValue();
709 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
714bool HexagonAsmParser::ParseDirective(
AsmToken DirectiveID) {
716 if (IDVal.
lower() ==
".falign")
717 return ParseDirectiveFalign(256, DirectiveID.
getLoc());
718 if ((IDVal.
lower() ==
".lcomm") || (IDVal.
lower() ==
".lcommon"))
719 return ParseDirectiveComm(
true, DirectiveID.
getLoc());
720 if ((IDVal.
lower() ==
".comm") || (IDVal.
lower() ==
".common"))
721 return ParseDirectiveComm(
false, DirectiveID.
getLoc());
722 if (IDVal.
lower() ==
".subsection")
723 return ParseDirectiveSubsection(DirectiveID.
getLoc());
724 if (IDVal ==
".attribute")
725 return parseDirectiveAttribute(DirectiveID.
getLoc());
729bool HexagonAsmParser::ParseDirectiveSubsection(
SMLoc L) {
730 const MCExpr *Subsection =
nullptr;
734 "Invalid subsection directive");
735 getParser().parseExpression(Subsection);
737 if (!Subsection->evaluateAsAbsolute(Res))
738 return Error(L,
"Cannot evaluate subsection number");
741 return TokError(
"unexpected token in directive");
747 if ((Res < 0) && (Res > -8193))
751 getStreamer().subSection(Subsection);
756bool HexagonAsmParser::ParseDirectiveFalign(
unsigned Size,
SMLoc L) {
758 int64_t MaxBytesToFill = 15;
766 if (!getParser().parseExpression(
Value)) {
768 auto *MCE = cast<MCConstantExpr>(
Value);
769 uint64_t IntValue = MCE->getValue();
771 return Error(ExprLoc,
"literal value out of range (256) for falign");
772 MaxBytesToFill = IntValue;
775 return Error(ExprLoc,
"not a valid expression for falign directive");
779 getTargetStreamer().emitFAlign(16, MaxBytesToFill);
791bool HexagonAsmParser::ParseDirectiveComm(
bool IsLocal,
SMLoc Loc) {
794 if (getStreamer().hasRawTextSupport())
798 if (getParser().parseIdentifier(
Name))
799 return TokError(
"expected identifier in directive");
804 return TokError(
"unexpected token in directive");
808 SMLoc SizeLoc = getLexer().getLoc();
809 if (getParser().parseAbsoluteExpression(
Size))
813 SMLoc ByteAlignmentLoc;
816 ByteAlignmentLoc = getLexer().getLoc();
817 if (getParser().parseAbsoluteExpression(ByteAlignment))
820 return Error(ByteAlignmentLoc,
"alignment must be a power of 2");
823 int64_t AccessAlignment = 0;
827 SMLoc AccessAlignmentLoc;
829 AccessAlignmentLoc = getLexer().getLoc();
830 if (getParser().parseAbsoluteExpression(AccessAlignment))
834 return Error(AccessAlignmentLoc,
"access alignment must be a power of 2");
838 return TokError(
"unexpected token in '.comm' or '.lcomm' directive");
845 return Error(SizeLoc,
"invalid '.comm' or '.lcomm' directive size, can't "
846 "be less than zero");
851 if (ByteAlignment < 0)
852 return Error(ByteAlignmentLoc,
"invalid '.comm' or '.lcomm' directive "
853 "alignment, can't be less than zero");
855 if (!
Sym->isUndefined())
856 return Error(Loc,
"invalid symbol redefinition");
872bool HexagonAsmParser::RegisterMatchesArch(
unsigned MatchNum)
const {
873 if (HexagonMCRegisterClasses[Hexagon::V62RegsRegClassID].
contains(MatchNum))
874 if (!getSTI().hasFeature(Hexagon::ArchV62))
886#define GET_MATCHER_IMPLEMENTATION
887#define GET_REGISTER_MATCHER
888#include "HexagonGenAsmMatcher.inc"
897 return static_cast<HexagonOperand &
>(Operand).getToken().equals_insensitive(
910 AsmToken const &Token = getParser().getTok();
915 std::pair<StringRef, StringRef> HeadTail =
String.split(
'.');
916 if (!HeadTail.first.empty())
918 HexagonOperand::CreateToken(getContext(), HeadTail.first, Loc));
919 if (!HeadTail.second.empty())
920 Operands.push_back(HexagonOperand::CreateToken(
921 getContext(),
String.substr(HeadTail.first.size(), 1), Loc));
923 }
while (!
String.empty());
943 Warning(Begin,
"Missing parenthesis around predicate register");
944 static char const *LParen =
"(";
945 static char const *RParen =
")";
947 HexagonOperand::CreateToken(getContext(), LParen, Begin));
949 HexagonOperand::CreateReg(getContext(),
Register, Begin,
End));
951 if (MaybeDotNew.
is(AsmToken::TokenKind::Identifier) &&
955 HexagonOperand::CreateToken(getContext(), RParen, Begin));
961 Warning(Begin,
"Missing parenthesis around predicate register");
962 static char const *LParen =
"(";
963 static char const *RParen =
")";
965 getContext(), LParen, Begin));
967 HexagonOperand::CreateReg(getContext(),
Register, Begin,
End));
969 if (MaybeDotNew.
is(AsmToken::TokenKind::Identifier) &&
973 HexagonOperand::CreateToken(getContext(), RParen, Begin));
979 HexagonOperand::CreateReg(getContext(),
Register, Begin,
End));
985bool HexagonAsmParser::isLabel(
AsmToken &Token) {
990 if (Token.
is(AsmToken::TokenKind::LCurly) ||
991 Token.
is(AsmToken::TokenKind::RCurly))
997 if (!Token.
is(AsmToken::TokenKind::Identifier))
999 if (!matchRegister(
String.lower()))
1004 std::string Collapsed = std::string(Raw);
1007 std::pair<StringRef, StringRef> DotSplit = Whole.
split(
'.');
1008 if (!matchRegister(DotSplit.first.lower()))
1013bool HexagonAsmParser::handleNoncontigiousRegister(
bool Contigious,
1016 Error(Loc,
"Register name is not contigious");
1020 Warning(Loc,
"Register name is not contigious");
1026 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
1032 StartLoc = getLexer().getLoc();
1036 bool NeededWorkaround =
false;
1045 Lookahead.
back().getString().data() +
1046 Lookahead.
back().getString().size();
1052 Again = (Contigious &&
Type) || (Workaround &&
Type);
1053 NeededWorkaround = NeededWorkaround || (Again && !(Contigious &&
Type));
1055 std::string Collapsed = std::string(RawString);
1058 std::pair<StringRef, StringRef> DotSplit = FullString.
split(
'.');
1059 unsigned DotReg = matchRegister(DotSplit.first.lower());
1060 if (DotReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1061 if (DotSplit.second.empty()) {
1064 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1069 size_t First = RawString.find(
'.');
1073 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1078 std::pair<StringRef, StringRef> ColonSplit =
StringRef(FullString).
split(
':');
1079 unsigned ColonReg = matchRegister(ColonSplit.first.lower());
1080 if (ColonReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1086 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1090 while (!Lookahead.
empty()) {
1110bool HexagonAsmParser::parseExpression(
MCExpr const *&Expr) {
1114 static char const *
Comma =
",";
1118 switch (Tokens.
back().getKind()) {
1119 case AsmToken::TokenKind::Hash:
1120 if (Tokens.
size() > 1)
1121 if ((Tokens.
end() - 2)->getKind() == AsmToken::TokenKind::Plus) {
1123 AsmToken(AsmToken::TokenKind::Comma, Comma));
1127 case AsmToken::TokenKind::RCurly:
1128 case AsmToken::TokenKind::EndOfStatement:
1129 case AsmToken::TokenKind::Eof:
1136 while (!Tokens.
empty()) {
1141 return getParser().parseExpression(Expr, Loc);
1145 if (implicitExpressionLocation(
Operands)) {
1148 MCExpr const *Expr =
nullptr;
1149 bool Error = parseExpression(Expr);
1153 HexagonOperand::CreateImm(getContext(), Expr, Loc, Loc));
1174 Operands.push_back(HexagonOperand::CreateToken(
1181 Operands.push_back(HexagonOperand::CreateToken(
1197 Operands.push_back(HexagonOperand::CreateToken(
1199 Operands.push_back(HexagonOperand::CreateToken(
1205 bool MustNotExtend =
false;
1206 bool ImplicitExpression = implicitExpressionLocation(
Operands);
1208 if (!ImplicitExpression)
1209 Operands.push_back(HexagonOperand::CreateToken(
1212 bool MustExtend =
false;
1213 bool HiOnly =
false;
1214 bool LoOnly =
false;
1218 }
else if (ImplicitExpression)
1219 MustNotExtend =
true;
1223 if (
String.lower() ==
"hi") {
1225 }
else if (
String.lower() ==
"lo") {
1228 if (HiOnly || LoOnly) {
1238 MCExpr const *Expr =
nullptr;
1239 if (parseExpression(Expr))
1244 if (Expr->evaluateAsAbsolute(
Value)) {
1248 if (HiOnly || LoOnly)
1254 if (!
Value.isAbsolute()) {
1255 switch (
Value.getAccessVariant()) {
1256 case MCSymbolRefExpr::VariantKind::VK_TPREL:
1257 case MCSymbolRefExpr::VariantKind::VK_DTPREL:
1259 MustNotExtend = !MustExtend;
1270 std::unique_ptr<HexagonOperand> Operand =
1271 HexagonOperand::CreateImm(getContext(), Expr, ExprLoc, ExprLoc);
1272 Operands.push_back(std::move(Operand));
1278 if (parseExpressionOrOperand(
Operands))
1286 getLexer().UnLex(
ID);
1305 HexagonOperand *
Op =
static_cast<HexagonOperand *
>(&AsmOp);
1310 return Op->isImm() &&
Op->Imm.Val->evaluateAsAbsolute(
Value) &&
Value == 0
1312 : Match_InvalidOperand;
1316 return Op->isImm() &&
Op->Imm.Val->evaluateAsAbsolute(
Value) &&
Value == 1
1318 : Match_InvalidOperand;
1321 if (
Op->Kind == HexagonOperand::Token && Kind != InvalidMatchClass) {
1323 if (matchTokenString(myStringRef.
lower()) == (MatchClassKind)Kind)
1324 return Match_Success;
1325 if (matchTokenString(myStringRef.
upper()) == (MatchClassKind)Kind)
1326 return Match_Success;
1333 return Match_InvalidOperand;
1337bool HexagonAsmParser::OutOfRange(
SMLoc IDLoc,
long long Val,
long long Max) {
1340 ES <<
"value " << Val <<
"(" <<
format_hex(Val, 0) <<
") out of range: ";
1344 ES <<
Max <<
"-" << (-
Max - 1);
1348int HexagonAsmParser::processInstruction(
MCInst &Inst,
1353 const std::string r =
"r";
1354 const std::string
v =
"v";
1355 const std::string Colon =
":";
1356 using RegPairVals = std::pair<unsigned, unsigned>;
1357 auto GetRegPair = [
this, r](RegPairVals RegPair) {
1358 const std::string R1 = r + utostr(RegPair.first);
1359 const std::string
R2 = r + utostr(RegPair.second);
1361 return std::make_pair(matchRegister(R1), matchRegister(
R2));
1363 auto GetScalarRegs = [RI, GetRegPair](
unsigned RegPair) {
1365 const RegPairVals RegPair_ = std::make_pair(
Lower + 1,
Lower);
1367 return GetRegPair(RegPair_);
1369 auto GetVecRegs = [GetRegPair](
unsigned VecRegPair) {
1370 const RegPairVals RegPair =
1373 return GetRegPair(RegPair);
1376 bool is32bit =
false;
1382 "Found pseudo instruction with no expansion");
1388 case Hexagon::J2_trap1:
1389 if (!getSTI().hasFeature(Hexagon::ArchV65)) {
1392 if (Rx.
getReg() != Hexagon::R0 || Ry.
getReg() != Hexagon::R0) {
1393 Error(IDLoc,
"trap1 can only have register r0 as operand");
1394 return Match_InvalidOperand;
1399 case Hexagon::A2_iconst: {
1411 case Hexagon::M4_mpyrr_addr:
1412 case Hexagon::S4_addi_asl_ri:
1413 case Hexagon::S4_addi_lsr_ri:
1414 case Hexagon::S4_andi_asl_ri:
1415 case Hexagon::S4_andi_lsr_ri:
1416 case Hexagon::S4_ori_asl_ri:
1417 case Hexagon::S4_ori_lsr_ri:
1418 case Hexagon::S4_or_andix:
1419 case Hexagon::S4_subi_asl_ri:
1420 case Hexagon::S4_subi_lsr_ri: {
1424 return Match_InvalidOperand;
1428 case Hexagon::C2_cmpgei: {
1438 case Hexagon::C2_cmpgeui: {
1464 case Hexagon::A2_tfrp: {
1466 const std::pair<unsigned, unsigned> RegPair = GetScalarRegs(MO.
getReg());
1467 MO.
setReg(RegPair.first);
1473 case Hexagon::A2_tfrpt:
1474 case Hexagon::A2_tfrpf: {
1476 const std::pair<unsigned, unsigned> RegPair = GetScalarRegs(MO.
getReg());
1477 MO.
setReg(RegPair.first);
1480 ? Hexagon::C2_ccombinewt
1481 : Hexagon::C2_ccombinewf);
1484 case Hexagon::A2_tfrptnew:
1485 case Hexagon::A2_tfrpfnew: {
1487 const std::pair<unsigned, unsigned> RegPair = GetScalarRegs(MO.
getReg());
1488 MO.
setReg(RegPair.first);
1491 ? Hexagon::C2_ccombinewnewt
1492 : Hexagon::C2_ccombinewnewf);
1497 case Hexagon::V6_vassignp: {
1499 const std::pair<unsigned, unsigned> RegPair = GetVecRegs(MO.
getReg());
1500 MO.
setReg(RegPair.first);
1507 case Hexagon::CONST32:
1511 case Hexagon::CONST64:
1521 std::string myCharStr;
1531 std::string myImmStr = utohexstr(
static_cast<uint32_t>(
Value));
1532 myCharStr =
StringRef(
".gnu.linkonce.l4.CONST_00000000")
1537 std::string myImmStr = utohexstr(
Value);
1538 myCharStr =
StringRef(
".gnu.linkonce.l8.CONST_0000000000000000")
1546 }
else if (MO_1.
isExpr()) {
1548 myCharStr =
".lita";
1555 unsigned byteSize = is32bit ? 4 : 8;
1564 Sym = getContext().getOrCreateSymbol(
StringRef(myCharStr.c_str() + 16));
1565 if (
Sym->isUndefined()) {
1566 getStreamer().emitLabel(
Sym);
1570 }
else if (MO_1.
isExpr()) {
1571 const char *StringStart =
nullptr;
1572 const char *StringEnd =
nullptr;
1573 if (*
Operands[4]->getStartLoc().getPointer() ==
'#') {
1574 StringStart =
Operands[5]->getStartLoc().getPointer();
1575 StringEnd =
Operands[6]->getStartLoc().getPointer();
1577 StringStart =
Operands[4]->getStartLoc().getPointer();
1578 StringEnd =
Operands[5]->getStartLoc().getPointer();
1581 unsigned size = StringEnd - StringStart;
1582 std::string DotConst =
".CONST_";
1583 Sym = getContext().getOrCreateSymbol(DotConst +
1586 if (
Sym->isUndefined()) {
1588 getStreamer().emitLabel(
Sym);
1590 getStreamer().emitValue(MO_1.
getExpr(), 4);
1600 TmpInst.
setOpcode(Hexagon::L2_loadrigp);
1602 TmpInst.
setOpcode(Hexagon::L2_loadrdgp);
1613 case Hexagon::A2_tfrpi: {
1625 case Hexagon::TFRI64_V4: {
1632 OutOfRange(IDLoc, s8, -128);
1650 case Hexagon::TFRI64_V2_ext: {
1657 if (s8 < -128 || s8 > 127)
1658 OutOfRange(IDLoc, s8, -128);
1665 case Hexagon::A4_combineii: {
1671 if (s8 < -128 || s8 > 127)
1672 OutOfRange(IDLoc, s8, -128);
1679 case Hexagon::S2_tableidxb_goodsyntax:
1683 case Hexagon::S2_tableidxh_goodsyntax: {
1693 TmpInst.
setOpcode(Hexagon::S2_tableidxh);
1703 case Hexagon::S2_tableidxw_goodsyntax: {
1713 TmpInst.
setOpcode(Hexagon::S2_tableidxw);
1723 case Hexagon::S2_tableidxd_goodsyntax: {
1733 TmpInst.
setOpcode(Hexagon::S2_tableidxd);
1743 case Hexagon::M2_mpyui:
1746 case Hexagon::M2_mpysmi: {
1755 return Match_InvalidOperand;
1758 return Match_InvalidOperand;
1759 if (Value < 0 && Value > -256) {
1772 case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
1778 return Match_InvalidOperand;
1790 TmpInst.
setOpcode(Hexagon::S2_asr_i_r_rnd);
1801 case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
1808 return Match_InvalidOperand;
1812 std::string R1 = r + utostr(RegPairNum + 1);
1814 Rss.
setReg(matchRegister(Reg1));
1816 std::string
R2 = r + utostr(RegPairNum);
1818 TmpInst.
setOpcode(Hexagon::A2_combinew);
1828 Inst.
setOpcode(Hexagon::S2_asr_i_p_rnd);
1833 case Hexagon::A4_boundscheck: {
1837 Inst.
setOpcode(Hexagon::A4_boundscheck_hi);
1838 std::string
Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1840 Rs.
setReg(matchRegister(RegPair));
1842 Inst.
setOpcode(Hexagon::A4_boundscheck_lo);
1843 std::string
Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1845 Rs.
setReg(matchRegister(RegPair));
1850 case Hexagon::A2_addsp: {
1855 std::string
Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1857 Rs.
setReg(matchRegister(RegPair));
1860 std::string
Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1862 Rs.
setReg(matchRegister(RegPair));
1867 case Hexagon::M2_vrcmpys_s1: {
1871 Inst.
setOpcode(Hexagon::M2_vrcmpys_s1_h);
1872 std::string
Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1874 Rt.
setReg(matchRegister(RegPair));
1876 Inst.
setOpcode(Hexagon::M2_vrcmpys_s1_l);
1877 std::string
Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1879 Rt.
setReg(matchRegister(RegPair));
1884 case Hexagon::M2_vrcmpys_acc_s1: {
1891 TmpInst.
setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
1892 std::string
Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1894 Rt.
setReg(matchRegister(RegPair));
1896 TmpInst.
setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
1897 std::string
Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1899 Rt.
setReg(matchRegister(RegPair));
1910 case Hexagon::M2_vrcmpys_s1rp: {
1914 Inst.
setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
1915 std::string
Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
1917 Rt.
setReg(matchRegister(RegPair));
1919 Inst.
setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
1920 std::string
Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
1922 Rt.
setReg(matchRegister(RegPair));
1927 case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
1932 return Match_InvalidOperand;
1940 Inst.
setOpcode(Hexagon::S5_asrhub_rnd_sat);
1945 case Hexagon::S5_vasrhrnd_goodsyntax: {
1952 return Match_InvalidOperand;
1956 std::string R1 = r + utostr(RegPairNum + 1);
1958 Rss.
setReg(matchRegister(Reg1));
1960 std::string
R2 = r + utostr(RegPairNum);
1962 TmpInst.
setOpcode(Hexagon::A2_combinew);
1977 case Hexagon::A2_not: {
1989 case Hexagon::PS_loadrubabs:
1993 case Hexagon::PS_loadrbabs:
1997 case Hexagon::PS_loadruhabs:
2001 case Hexagon::PS_loadrhabs:
2005 case Hexagon::PS_loadriabs:
2009 case Hexagon::PS_loadrdabs:
2013 case Hexagon::PS_storerbabs:
2017 case Hexagon::PS_storerhabs:
2021 case Hexagon::PS_storerfabs:
2025 case Hexagon::PS_storeriabs:
2029 case Hexagon::PS_storerdabs:
2033 case Hexagon::PS_storerbnewabs:
2035 Inst.
setOpcode(Hexagon::S2_storerbnewgp);
2037 case Hexagon::PS_storerhnewabs:
2039 Inst.
setOpcode(Hexagon::S2_storerhnewgp);
2041 case Hexagon::PS_storerinewabs:
2043 Inst.
setOpcode(Hexagon::S2_storerinewgp);
2045 case Hexagon::A2_zxtb: {
2053 return Match_Success;
static MCRegister MatchRegisterName(StringRef Name)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static MCRegister 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))
static cl::opt< bool > AddBuildAttributes("hexagon-add-build-attributes")
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)
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.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
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.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
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.
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.
std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
const TagNameMap & getHexagonAttributeTags()
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)
@ CE
Windows NT (Windows on ARM)
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,...