10 #define DEBUG_TYPE "mcasmparser"
64 cl::desc(
"Enable future registers"));
67 cl::desc(
"Warn for missing parenthesis around predicate registers"),
70 cl::desc(
"Error for missing parenthesis around predicate registers"),
73 cl::desc(
"Warn for mismatching a signed and unsigned value"),
76 cl::desc(
"Warn for register names that arent contigious"),
79 cl::desc(
"Error for register names that aren't contigious"),
84 struct HexagonOperand;
100 MCAssembler *getAssembler()
const {
return Assembler; }
101 MCAsmLexer &getLexer()
const {
return Parser.getLexer(); }
103 bool equalIsAsmAssignment()
override {
return false; }
106 void Warning(
SMLoc L,
const Twine &Msg) { Parser.Warning(L, Msg); }
108 bool ParseDirectiveFalign(
unsigned Size,
SMLoc L);
110 bool ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc)
override;
111 bool ParseDirectiveSubsection(
SMLoc L);
112 bool ParseDirectiveValue(
unsigned Size,
SMLoc L);
113 bool ParseDirectiveComm(
bool IsLocal,
SMLoc L);
114 bool RegisterMatchesArch(
unsigned MatchNum)
const;
116 bool matchBundleOptions();
117 bool handleNoncontigiousRegister(
bool Contigious,
SMLoc &Loc);
119 void canonicalizeImmediates(
MCInst &MCI);
122 bool MatchingInlineAsm);
124 bool MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
126 uint64_t &
ErrorInfo,
bool MatchingInlineAsm)
override;
129 bool OutOfRange(
SMLoc IDLoc,
long long Val,
long long Max);
134 void chksetELFHeaderEFlags(
unsigned flags) {
136 getAssembler()->setELFHeaderEFlags(flags);
144 #define GET_ASSEMBLER_HEADER
145 #include "HexagonGenAsmMatcher.inc"
154 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
160 if (!Parser.getStreamer().hasRawTextSupport()) {
171 bool parseExpression(
MCExpr const *& Expr);
182 bool ParseDirective(
AsmToken DirectiveID)
override;
190 SMLoc StartLoc, EndLoc;
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)))
276 return ((uint64_t)Res < (uint64_t)(1ULL << bits));
278 const int64_t high_bit_set = 1ULL << 63;
279 const uint64_t mask = (high_bit_set >> (63 -
bits));
280 return (((uint64_t)Res & mask) == mask);
292 bool isf32Ext()
const {
return false; }
293 bool iss32_0Imm()
const {
return CheckImmRange(32, 0,
true,
true,
false); }
294 bool iss23_2Imm()
const {
return CheckImmRange(23, 2,
true,
true,
false); }
295 bool iss8_0Imm()
const {
return CheckImmRange(8, 0,
true,
false,
false); }
296 bool iss8_0Imm64()
const {
return CheckImmRange(8, 0,
true,
true,
false); }
297 bool iss7_0Imm()
const {
return CheckImmRange(7, 0,
true,
false,
false); }
298 bool iss6_0Imm()
const {
return CheckImmRange(6, 0,
true,
false,
false); }
299 bool iss4_0Imm()
const {
return CheckImmRange(4, 0,
true,
false,
false); }
300 bool iss4_1Imm()
const {
return CheckImmRange(4, 1,
true,
false,
false); }
301 bool iss4_2Imm()
const {
return CheckImmRange(4, 2,
true,
false,
false); }
302 bool iss4_3Imm()
const {
return CheckImmRange(4, 3,
true,
false,
false); }
303 bool iss4_6Imm()
const {
return CheckImmRange(4, 0,
true,
false,
false); }
304 bool iss3_6Imm()
const {
return CheckImmRange(3, 0,
true,
false,
false); }
305 bool iss3_0Imm()
const {
return CheckImmRange(3, 0,
true,
false,
false); }
307 bool isu64_0Imm()
const {
return CheckImmRange(64, 0,
false,
true,
true); }
308 bool isu32_0Imm()
const {
return CheckImmRange(32, 0,
false,
true,
false); }
309 bool isu26_6Imm()
const {
return CheckImmRange(26, 6,
false,
true,
false); }
310 bool isu16_0Imm()
const {
return CheckImmRange(16, 0,
false,
true,
false); }
311 bool isu16_1Imm()
const {
return CheckImmRange(16, 1,
false,
true,
false); }
312 bool isu16_2Imm()
const {
return CheckImmRange(16, 2,
false,
true,
false); }
313 bool isu16_3Imm()
const {
return CheckImmRange(16, 3,
false,
true,
false); }
314 bool isu11_3Imm()
const {
return CheckImmRange(11, 3,
false,
false,
false); }
315 bool isu6_1Imm()
const {
return CheckImmRange(6, 1,
false,
false,
false); }
316 bool isu6_2Imm()
const {
return CheckImmRange(6, 2,
false,
false,
false); }
317 bool isu6_3Imm()
const {
return CheckImmRange(6, 3,
false,
false,
false); }
318 bool isu10_0Imm()
const {
return CheckImmRange(10, 0,
false,
false,
false); }
319 bool isu9_0Imm()
const {
return CheckImmRange(9, 0,
false,
false,
false); }
320 bool isu8_0Imm()
const {
return CheckImmRange(8, 0,
false,
false,
false); }
321 bool isu7_0Imm()
const {
return CheckImmRange(7, 0,
false,
false,
false); }
322 bool isu6_0Imm()
const {
return CheckImmRange(6, 0,
false,
false,
false); }
323 bool isu5_0Imm()
const {
return CheckImmRange(5, 0,
false,
false,
false); }
324 bool isu4_0Imm()
const {
return CheckImmRange(4, 0,
false,
false,
false); }
325 bool isu3_0Imm()
const {
return CheckImmRange(3, 0,
false,
false,
false); }
326 bool isu2_0Imm()
const {
return CheckImmRange(2, 0,
false,
false,
false); }
327 bool isu1_0Imm()
const {
return CheckImmRange(1, 0,
false,
false,
false); }
329 bool ism6_0Imm()
const {
return CheckImmRange(6, 0,
false,
false,
false); }
330 bool isn8_0Imm()
const {
return CheckImmRange(8, 0,
false,
false,
false); }
331 bool isn1Const()
const {
335 if (!getImm()->evaluateAsAbsolute(Value))
340 bool iss16_0Ext()
const {
return CheckImmRange(16 + 26, 0,
true,
true,
true); }
341 bool iss12_0Ext()
const {
return CheckImmRange(12 + 26, 0,
true,
true,
true); }
342 bool iss10_0Ext()
const {
return CheckImmRange(10 + 26, 0,
true,
true,
true); }
343 bool iss9_0Ext()
const {
return CheckImmRange(9 + 26, 0,
true,
true,
true); }
344 bool iss8_0Ext()
const {
return CheckImmRange(8 + 26, 0,
true,
true,
true); }
345 bool iss7_0Ext()
const {
return CheckImmRange(7 + 26, 0,
true,
true,
true); }
346 bool iss6_0Ext()
const {
return CheckImmRange(6 + 26, 0,
true,
true,
true); }
347 bool iss11_0Ext()
const {
348 return CheckImmRange(11 + 26, 0,
true,
true,
true);
350 bool iss11_1Ext()
const {
351 return CheckImmRange(11 + 26, 1,
true,
true,
true);
353 bool iss11_2Ext()
const {
354 return CheckImmRange(11 + 26, 2,
true,
true,
true);
356 bool iss11_3Ext()
const {
357 return CheckImmRange(11 + 26, 3,
true,
true,
true);
360 bool isu7_0Ext()
const {
return CheckImmRange(7 + 26, 0,
false,
true,
true); }
361 bool isu8_0Ext()
const {
return CheckImmRange(8 + 26, 0,
false,
true,
true); }
362 bool isu9_0Ext()
const {
return CheckImmRange(9 + 26, 0,
false,
true,
true); }
363 bool isu10_0Ext()
const {
return CheckImmRange(10 + 26, 0,
false,
true,
true); }
364 bool isu6_0Ext()
const {
return CheckImmRange(6 + 26, 0,
false,
true,
true); }
365 bool isu6_1Ext()
const {
return CheckImmRange(6 + 26, 1,
false,
true,
true); }
366 bool isu6_2Ext()
const {
return CheckImmRange(6 + 26, 2,
false,
true,
true); }
367 bool isu6_3Ext()
const {
return CheckImmRange(6 + 26, 3,
false,
true,
true); }
368 bool isu32_0MustExt()
const {
return isImm(); }
370 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
371 assert(N == 1 &&
"Invalid number of operands!");
375 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
376 assert(N == 1 &&
"Invalid number of operands!");
380 void addSignedImmOperands(
MCInst &Inst,
unsigned N)
const {
381 assert(N == 1 &&
"Invalid number of operands!");
390 if ((Extended < 0) != (Value < 0))
395 void addf32ExtOperands(
MCInst &Inst,
unsigned N)
const {
396 addImmOperands(Inst, N);
399 void adds32_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
400 addSignedImmOperands(Inst, N);
402 void adds23_2ImmOperands(
MCInst &Inst,
unsigned N)
const {
403 addSignedImmOperands(Inst, N);
405 void adds8_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
406 addSignedImmOperands(Inst, N);
408 void adds8_0Imm64Operands(
MCInst &Inst,
unsigned N)
const {
409 addSignedImmOperands(Inst, N);
411 void adds6_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
412 addSignedImmOperands(Inst, N);
414 void adds4_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
415 addSignedImmOperands(Inst, N);
417 void adds4_1ImmOperands(
MCInst &Inst,
unsigned N)
const {
418 addSignedImmOperands(Inst, N);
420 void adds4_2ImmOperands(
MCInst &Inst,
unsigned N)
const {
421 addSignedImmOperands(Inst, N);
423 void adds4_3ImmOperands(
MCInst &Inst,
unsigned N)
const {
424 addSignedImmOperands(Inst, N);
426 void adds3_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
427 addSignedImmOperands(Inst, N);
430 void addu64_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
431 addImmOperands(Inst, N);
433 void addu32_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
434 addImmOperands(Inst, N);
436 void addu26_6ImmOperands(
MCInst &Inst,
unsigned N)
const {
437 addImmOperands(Inst, N);
439 void addu16_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
440 addImmOperands(Inst, N);
442 void addu16_1ImmOperands(
MCInst &Inst,
unsigned N)
const {
443 addImmOperands(Inst, N);
445 void addu16_2ImmOperands(
MCInst &Inst,
unsigned N)
const {
446 addImmOperands(Inst, N);
448 void addu16_3ImmOperands(
MCInst &Inst,
unsigned N)
const {
449 addImmOperands(Inst, N);
451 void addu11_3ImmOperands(
MCInst &Inst,
unsigned N)
const {
452 addImmOperands(Inst, N);
454 void addu10_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
455 addImmOperands(Inst, N);
457 void addu9_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
458 addImmOperands(Inst, N);
460 void addu8_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
461 addImmOperands(Inst, N);
463 void addu7_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
464 addImmOperands(Inst, N);
466 void addu6_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
467 addImmOperands(Inst, N);
469 void addu6_1ImmOperands(
MCInst &Inst,
unsigned N)
const {
470 addImmOperands(Inst, N);
472 void addu6_2ImmOperands(
MCInst &Inst,
unsigned N)
const {
473 addImmOperands(Inst, N);
475 void addu6_3ImmOperands(
MCInst &Inst,
unsigned N)
const {
476 addImmOperands(Inst, N);
478 void addu5_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
479 addImmOperands(Inst, N);
481 void addu4_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
482 addImmOperands(Inst, N);
484 void addu3_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
485 addImmOperands(Inst, N);
487 void addu2_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
488 addImmOperands(Inst, N);
490 void addu1_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
491 addImmOperands(Inst, N);
494 void addm6_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
495 addImmOperands(Inst, N);
497 void addn8_0ImmOperands(
MCInst &Inst,
unsigned N)
const {
498 addImmOperands(Inst, N);
501 void adds16_0ExtOperands(
MCInst &Inst,
unsigned N)
const {
502 addSignedImmOperands(Inst, N);
504 void adds12_0ExtOperands(
MCInst &Inst,
unsigned N)
const {
505 addSignedImmOperands(Inst, N);
507 void adds10_0ExtOperands(
MCInst &Inst,
unsigned N)
const {
508 addSignedImmOperands(Inst, N);
510 void adds9_0ExtOperands(
MCInst &Inst,
unsigned N)
const {
511 addSignedImmOperands(Inst, N);
513 void adds8_0ExtOperands(
MCInst &Inst,
unsigned N)
const {
514 addSignedImmOperands(Inst, N);
516 void adds6_0ExtOperands(
MCInst &Inst,
unsigned N)
const {
517 addSignedImmOperands(Inst, N);
519 void adds11_0ExtOperands(
MCInst &Inst,
unsigned N)
const {
520 addSignedImmOperands(Inst, N);
522 void adds11_1ExtOperands(
MCInst &Inst,
unsigned N)
const {
523 addSignedImmOperands(Inst, N);
525 void adds11_2ExtOperands(
MCInst &Inst,
unsigned N)
const {
526 addSignedImmOperands(Inst, N);
528 void adds11_3ExtOperands(
MCInst &Inst,
unsigned N)
const {
529 addSignedImmOperands(Inst, N);
531 void addn1ConstOperands(
MCInst &Inst,
unsigned N)
const {
532 addImmOperands(Inst, N);
535 void addu7_0ExtOperands(
MCInst &Inst,
unsigned N)
const {
536 addImmOperands(Inst, N);
538 void addu8_0ExtOperands(
MCInst &Inst,
unsigned N)
const {
539 addImmOperands(Inst, N);
541 void addu9_0ExtOperands(
MCInst &Inst,
unsigned N)
const {
542 addImmOperands(Inst, N);
544 void addu10_0ExtOperands(
MCInst &Inst,
unsigned N)
const {
545 addImmOperands(Inst, N);
547 void addu6_0ExtOperands(
MCInst &Inst,
unsigned N)
const {
548 addImmOperands(Inst, N);
550 void addu6_1ExtOperands(
MCInst &Inst,
unsigned N)
const {
551 addImmOperands(Inst, N);
553 void addu6_2ExtOperands(
MCInst &Inst,
unsigned N)
const {
554 addImmOperands(Inst, N);
556 void addu6_3ExtOperands(
MCInst &Inst,
unsigned N)
const {
557 addImmOperands(Inst, N);
559 void addu32_0MustExtOperands(
MCInst &Inst,
unsigned N)
const {
560 addImmOperands(Inst, N);
563 void adds4_6ImmOperands(
MCInst &Inst,
unsigned N)
const {
564 assert(N == 1 &&
"Invalid number of operands!");
570 void adds3_6ImmOperands(
MCInst &Inst,
unsigned N)
const {
571 assert(N == 1 &&
"Invalid number of operands!");
584 static std::unique_ptr<HexagonOperand> CreateToken(
StringRef Str,
SMLoc S) {
585 HexagonOperand *
Op =
new HexagonOperand(
Token);
586 Op->Tok.Data = Str.
data();
587 Op->Tok.Length = Str.
size();
590 return std::unique_ptr<HexagonOperand>(
Op);
593 static std::unique_ptr<HexagonOperand> CreateReg(
unsigned RegNum,
SMLoc S,
595 HexagonOperand *Op =
new HexagonOperand(
Register);
596 Op->Reg.RegNum = RegNum;
599 return std::unique_ptr<HexagonOperand>(
Op);
602 static std::unique_ptr<HexagonOperand> CreateImm(
const MCExpr *Val,
SMLoc S,
604 HexagonOperand *Op =
new HexagonOperand(Immediate);
608 return std::unique_ptr<HexagonOperand>(
Op);
614 void HexagonOperand::print(
raw_ostream &OS)
const {
617 getImm()->print(OS,
nullptr);
642 while (
Check.getNextErrInfo()) {
643 unsigned Reg =
Check.getErrRegister();
646 uint64_t Err =
Check.getError();
651 "unconditional branch cannot precede another branch in packet");
655 return Error(IDLoc,
"register `" + R +
656 "' used with `.new' "
657 "but not validly modified in the same packet");
660 return Error(IDLoc,
"register `" + R +
"' modified more than once");
663 return Error(IDLoc,
"cannot write to read-only register `" + R +
"'");
666 return Error(IDLoc,
"loop-setup and some branch instructions "
667 "cannot be in the same packet");
672 "packet marked with `:endloop" + N +
"' " +
673 "cannot contain instructions that modify register " +
680 "instruction cannot appear in packet with other instructions");
683 return Error(IDLoc,
"too many slots used in packet");
686 uint64_t Erm =
Check.getShuffleError();
689 return Error(IDLoc,
"invalid instruction packet");
691 return Error(IDLoc,
"invalid instruction packet: too many stores");
693 return Error(IDLoc,
"invalid instruction packet: too many loads");
695 return Error(IDLoc,
"too many branches in packet");
697 return Error(IDLoc,
"invalid instruction packet: out of slots");
699 return Error(IDLoc,
"invalid instruction packet: slot error");
701 return Error(IDLoc,
"v60 packet violation");
703 return Error(IDLoc,
"slot 0 instruction does not allow slot 1 store");
705 return Error(IDLoc,
"unknown error in instruction packet");
709 unsigned Warn =
Check.getWarning();
712 Warning(IDLoc,
"register `" + R +
"' used with `.cur' "
713 "but not used in the same packet");
715 Warning(IDLoc,
"register `" + R +
"' used with `.tmp' "
716 "but not used in the same packet");
733 Error(IDLoc,
"invalid instruction packet: out of slots");
741 bool HexagonAsmParser::matchBundleOptions() {
765 void HexagonAsmParser::canonicalizeImmediates(
MCInst &MCI) {
770 int64_t Value (
I.getImm());
775 if (
I.isExpr() && cast<HexagonMCExpr>(
I.getExpr())->signMismatch() &&
777 Warning (MCI.getLoc(),
"Signed/Unsigned mismatch");
783 bool HexagonAsmParser::matchOneInstruction(
MCInst &MCI,
SMLoc IDLoc,
786 bool MatchingInlineAsm) {
789 MatchInstructionImpl(InstOperands, MCI, ErrorInfo, MatchingInlineAsm);
790 if (result == Match_Success) {
792 canonicalizeImmediates(MCI);
793 result = processInstruction(MCI, InstOperands, IDLoc);
811 case Match_MissingFeature:
812 return Error(IDLoc,
"invalid instruction");
813 case Match_MnemonicFail:
814 return Error(IDLoc,
"unrecognized instruction");
815 case Match_InvalidOperand:
816 SMLoc ErrorLoc = IDLoc;
817 if (ErrorInfo != ~0U) {
818 if (ErrorInfo >= InstOperands.
size())
819 return Error(IDLoc,
"too few operands for instruction");
821 ErrorLoc = (
static_cast<HexagonOperand *
>(InstOperands[ErrorInfo].get()))
823 if (ErrorLoc ==
SMLoc())
826 return Error(ErrorLoc,
"invalid operand for instruction");
831 bool HexagonAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
835 bool MatchingInlineAsm) {
840 HexagonOperand &FirstOperand =
static_cast<HexagonOperand &
>(*Operands[0]);
841 if (FirstOperand.isToken() && FirstOperand.getToken() ==
"{") {
842 assert(Operands.
size() == 1 &&
"Brackets should be by themselves");
844 getParser().Error(IDLoc,
"Already in a packet");
850 if (FirstOperand.isToken() && FirstOperand.getToken() ==
"}") {
851 assert(Operands.
size() == 1 &&
"Brackets should be by themselves");
853 getParser().Error(IDLoc,
"Not in a packet");
857 if (matchBundleOptions())
859 return finishBundle(IDLoc, Out);
861 MCInst *SubInst =
new (getParser().getContext())
MCInst;
862 if (matchOneInstruction(*SubInst, IDLoc, Operands, ErrorInfo,
866 getParser().getContext(), MCII, MCB, *SubInst);
869 return finishBundle(IDLoc, Out);
874 bool HexagonAsmParser::ParseDirective(
AsmToken DirectiveID) {
876 if ((IDVal.
lower() ==
".word") || (IDVal.
lower() ==
".4byte"))
877 return ParseDirectiveValue(4, DirectiveID.
getLoc());
878 if (IDVal.
lower() ==
".short" || IDVal.
lower() ==
".hword" ||
879 IDVal.
lower() ==
".half")
880 return ParseDirectiveValue(2, DirectiveID.
getLoc());
881 if (IDVal.
lower() ==
".falign")
882 return ParseDirectiveFalign(256, DirectiveID.
getLoc());
883 if ((IDVal.
lower() ==
".lcomm") || (IDVal.
lower() ==
".lcommon"))
884 return ParseDirectiveComm(
true, DirectiveID.
getLoc());
885 if ((IDVal.
lower() ==
".comm") || (IDVal.
lower() ==
".common"))
886 return ParseDirectiveComm(
false, DirectiveID.
getLoc());
887 if (IDVal.
lower() ==
".subsection")
888 return ParseDirectiveSubsection(DirectiveID.
getLoc());
892 bool HexagonAsmParser::ParseDirectiveSubsection(
SMLoc L) {
893 const MCExpr *Subsection =
nullptr;
897 "Invalid subsection directive");
898 getParser().parseExpression(Subsection);
900 if (!Subsection->evaluateAsAbsolute(Res))
901 return Error(L,
"Cannot evaluate subsection number");
904 return TokError(
"unexpected token in directive");
910 if ((Res < 0) && (Res > -8193))
914 getStreamer().SubSection(Subsection);
919 bool HexagonAsmParser::ParseDirectiveFalign(
unsigned Size,
SMLoc L) {
921 int64_t MaxBytesToFill = 15;
929 if (!getParser().parseExpression(Value)) {
932 uint64_t IntValue = MCE->
getValue();
934 return Error(ExprLoc,
"literal value out of range (256) for falign");
935 MaxBytesToFill = IntValue;
938 return Error(ExprLoc,
"not a valid expression for falign directive");
942 getTargetStreamer().emitFAlign(16, MaxBytesToFill);
949 bool HexagonAsmParser::ParseDirectiveValue(
unsigned Size,
SMLoc L) {
954 if (getParser().parseExpression(Value))
958 if (
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value)) {
959 assert(Size <= 8 &&
"Invalid size");
960 uint64_t IntValue = MCE->
getValue();
961 if (!
isUIntN(8 * Size, IntValue) && !
isIntN(8 * Size, IntValue))
962 return Error(ExprLoc,
"literal value out of range for directive");
963 getStreamer().EmitIntValue(IntValue, Size);
965 getStreamer().EmitValue(Value, Size);
972 return TokError(
"unexpected token in directive");
987 bool HexagonAsmParser::ParseDirectiveComm(
bool IsLocal,
SMLoc Loc) {
990 if (getStreamer().hasRawTextSupport())
994 if (getParser().parseIdentifier(Name))
995 return TokError(
"expected identifier in directive");
997 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
1000 return TokError(
"unexpected token in directive");
1004 SMLoc SizeLoc = getLexer().getLoc();
1005 if (getParser().parseAbsoluteExpression(Size))
1009 SMLoc ByteAlignmentLoc;
1012 ByteAlignmentLoc = getLexer().getLoc();
1013 if (getParser().parseAbsoluteExpression(ByteAlignment))
1016 return Error(ByteAlignmentLoc,
"alignment must be a power of 2");
1019 int64_t AccessAlignment = 0;
1023 SMLoc AccessAlignmentLoc;
1025 AccessAlignmentLoc = getLexer().getLoc();
1026 if (getParser().parseAbsoluteExpression(AccessAlignment))
1030 return Error(AccessAlignmentLoc,
"access alignment must be a power of 2");
1034 return TokError(
"unexpected token in '.comm' or '.lcomm' directive");
1041 return Error(SizeLoc,
"invalid '.comm' or '.lcomm' directive size, can't "
1042 "be less than zero");
1047 if (ByteAlignment < 0)
1048 return Error(ByteAlignmentLoc,
"invalid '.comm' or '.lcomm' directive "
1049 "alignment, can't be less than zero");
1052 return Error(Loc,
"invalid symbol redefinition");
1068 bool HexagonAsmParser::RegisterMatchesArch(
unsigned MatchNum)
const {
1079 #define GET_MATCHER_IMPLEMENTATION
1080 #define GET_REGISTER_MATCHER
1081 #include "HexagonGenAsmMatcher.inc"
1085 if (Index >= Operands.
size())
1090 return static_cast<HexagonOperand &
>(Operand).
getToken().equals_lower(String);
1101 bool HexagonAsmParser::splitIdentifier(
OperandVector &Operands) {
1107 std::pair<StringRef, StringRef> HeadTail = String.
split(
'.');
1108 if (!HeadTail.first.empty())
1109 Operands.
push_back(HexagonOperand::CreateToken(HeadTail.first, Loc));
1110 if (!HeadTail.second.empty())
1111 Operands.
push_back(HexagonOperand::CreateToken(
1112 String.
substr(HeadTail.first.size(), 1), Loc));
1113 String = HeadTail.second;
1114 }
while (!String.
empty());
1118 bool HexagonAsmParser::parseOperand(
OperandVector &Operands) {
1123 if (!ParseRegister(Register, Begin, End)) {
1134 Warning (Begin,
"Missing parenthesis around predicate register");
1135 static char const *LParen =
"(";
1136 static char const *RParen =
")";
1137 Operands.
push_back(HexagonOperand::CreateToken(LParen, Begin));
1138 Operands.
push_back(HexagonOperand::CreateReg(Register, Begin, End));
1140 if (MaybeDotNew.
is(AsmToken::TokenKind::Identifier) &&
1142 splitIdentifier(Operands);
1143 Operands.
push_back(HexagonOperand::CreateToken(RParen, Begin));
1149 Warning (Begin,
"Missing parenthesis around predicate register");
1150 static char const *LParen =
"(";
1151 static char const *RParen =
")";
1153 HexagonOperand::CreateToken(LParen, Begin));
1154 Operands.
push_back(HexagonOperand::CreateReg(Register, Begin, End));
1156 if (MaybeDotNew.
is(AsmToken::TokenKind::Identifier) &&
1158 splitIdentifier(Operands);
1159 Operands.
push_back(HexagonOperand::CreateToken(RParen, Begin));
1164 Operands.
push_back(HexagonOperand::CreateReg(
1165 Register, Begin, End));
1168 return splitIdentifier(Operands);
1171 bool HexagonAsmParser::isLabel(
AsmToken &Token) {
1176 if (Token.
is(AsmToken::TokenKind::LCurly) ||
1177 Token.
is(AsmToken::TokenKind::RCurly))
1179 if (!Token.
is(AsmToken::TokenKind::Identifier))
1181 if (!matchRegister(String.
lower()))
1187 std::string Collapsed =
Raw;
1188 Collapsed.erase(
llvm::remove_if(Collapsed, isspace), Collapsed.end());
1190 std::pair<StringRef, StringRef> DotSplit = Whole.
split(
'.');
1191 if (!matchRegister(DotSplit.first.lower()))
1196 bool HexagonAsmParser::handleNoncontigiousRegister(
bool Contigious,
SMLoc &Loc) {
1198 Error(Loc,
"Register name is not contigious");
1202 Warning(Loc,
"Register name is not contigious");
1206 bool HexagonAsmParser::ParseRegister(
unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc) {
1208 StartLoc = getLexer().getLoc();
1212 bool NeededWorkaround =
false;
1228 Again = (Contigious &&
Type) || (Workaround && Type);
1229 NeededWorkaround = NeededWorkaround || (Again && !(Contigious &&
Type));
1231 std::string Collapsed = RawString;
1232 Collapsed.erase(
llvm::remove_if(Collapsed, isspace), Collapsed.end());
1234 std::pair<StringRef, StringRef> DotSplit = FullString.
split(
'.');
1235 unsigned DotReg = matchRegister(DotSplit.first.lower());
1236 if (DotReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1237 if (DotSplit.second.empty()) {
1240 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1245 size_t First = RawString.find(
'.');
1246 StringRef DotString (RawString.data() + First, RawString.size() - First);
1249 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1254 std::pair<StringRef, StringRef> ColonSplit =
StringRef(FullString).
split(
':');
1255 unsigned ColonReg = matchRegister(ColonSplit.first.lower());
1256 if (ColonReg != Hexagon::NoRegister && RegisterMatchesArch(DotReg)) {
1263 if (handleNoncontigiousRegister(!NeededWorkaround, StartLoc))
1267 while (!Lookahead.
empty()) {
1274 bool HexagonAsmParser::implicitExpressionLocation(
OperandVector &Operands) {
1288 bool HexagonAsmParser::parseExpression(
MCExpr const *& Expr) {
1292 static char const * Comma =
",";
1299 if (Tokens.
size () > 1)
1300 if ((Tokens.
end () - 2)->getKind() == AsmToken::TokenKind::Plus) {
1302 AsmToken(AsmToken::TokenKind::Comma, Comma));
1306 case AsmToken::TokenKind::RCurly:
1307 case AsmToken::TokenKind::EndOfStatement:
1315 while (!Tokens.
empty()) {
1319 return getParser().parseExpression(Expr);
1322 bool HexagonAsmParser::parseExpressionOrOperand(
OperandVector &Operands) {
1323 if (implicitExpressionLocation(Operands)) {
1326 MCExpr const *Expr =
nullptr;
1327 bool Error = parseExpression(Expr);
1330 Operands.
push_back(HexagonOperand::CreateImm(Expr, Loc, Loc));
1333 return parseOperand(Operands);
1337 bool HexagonAsmParser::parseInstruction(
OperandVector &Operands) {
1348 if (!Operands.
empty())
1356 if (Operands.
empty()) {
1373 Operands.
push_back(HexagonOperand::CreateToken(
1375 Operands.
push_back(HexagonOperand::CreateToken(
1381 bool MustNotExtend =
false;
1382 bool ImplicitExpression = implicitExpressionLocation(Operands);
1384 if (!ImplicitExpression)
1388 bool MustExtend =
false;
1389 bool HiOnly =
false;
1390 bool LoOnly =
false;
1394 }
else if (ImplicitExpression)
1395 MustNotExtend =
true;
1399 if (String.
lower() ==
"hi") {
1401 }
else if (String.
lower() ==
"lo") {
1404 if (HiOnly || LoOnly) {
1414 MCExpr const *Expr =
nullptr;
1415 if (parseExpression(Expr))
1420 if (Expr->evaluateAsAbsolute(Value)) {
1424 if (HiOnly || LoOnly)
1433 case MCSymbolRefExpr::VariantKind::VK_TPREL:
1434 case MCSymbolRefExpr::VariantKind::VK_DTPREL:
1436 MustNotExtend = !MustExtend;
1447 std::unique_ptr<HexagonOperand> Operand =
1448 HexagonOperand::CreateImm(Expr, ExprLoc, ExprLoc);
1455 if (parseExpressionOrOperand(Operands))
1464 getLexer().UnLex(ID);
1465 return parseInstruction(Operands);
1483 HexagonOperand *
Op =
static_cast<HexagonOperand *
>(&AsmOp);
1488 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 0
1490 : Match_InvalidOperand;
1494 return Op->isImm() && Op->Imm.Val->evaluateAsAbsolute(Value) && Value == 1
1496 : Match_InvalidOperand;
1501 if (matchTokenString(myStringRef.
lower()) == (MatchClassKind)
Kind)
1502 return Match_Success;
1503 if (matchTokenString(myStringRef.
upper()) == (MatchClassKind)
Kind)
1504 return Match_Success;
1511 return Match_InvalidOperand;
1515 bool HexagonAsmParser::OutOfRange(
SMLoc IDLoc,
long long Val,
long long Max) {
1518 ES <<
"value " << Val <<
"(" <<
format_hex(Val, 0) <<
") out of range: ";
1522 ES << Max <<
"-" << (-Max - 1);
1526 int HexagonAsmParser::processInstruction(
MCInst &Inst,
1529 MCContext &Context = getParser().getContext();
1531 std::string r =
"r";
1532 std::string v =
"v";
1533 std::string Colon =
":";
1535 bool is32bit =
false;
1540 case Hexagon::A2_iconst: {
1552 case Hexagon::M4_mpyrr_addr:
1553 case Hexagon::S4_addi_asl_ri:
1554 case Hexagon::S4_addi_lsr_ri:
1555 case Hexagon::S4_andi_asl_ri:
1556 case Hexagon::S4_andi_lsr_ri:
1557 case Hexagon::S4_ori_asl_ri:
1558 case Hexagon::S4_ori_lsr_ri:
1559 case Hexagon::S4_or_andix:
1560 case Hexagon::S4_subi_asl_ri:
1561 case Hexagon::S4_subi_lsr_ri: {
1565 return Match_InvalidOperand;
1569 case Hexagon::C2_cmpgei: {
1577 case Hexagon::C2_cmpgeui: {
1582 assert(Success &&
"Assured by matcher");
1601 case Hexagon::A2_tfrp: {
1604 std::string R1 = r +
utostr(RegPairNum + 1);
1606 MO.
setReg(matchRegister(Reg1));
1608 std::string
R2 = r +
utostr(RegPairNum);
1615 case Hexagon::A2_tfrpt:
1616 case Hexagon::A2_tfrpf: {
1619 std::string R1 = r +
utostr(RegPairNum + 1);
1621 MO.
setReg(matchRegister(Reg1));
1623 std::string R2 = r +
utostr(RegPairNum);
1627 ? Hexagon::C2_ccombinewt
1628 : Hexagon::C2_ccombinewf);
1631 case Hexagon::A2_tfrptnew:
1632 case Hexagon::A2_tfrpfnew: {
1635 std::string R1 = r +
utostr(RegPairNum + 1);
1637 MO.
setReg(matchRegister(Reg1));
1639 std::string R2 = r +
utostr(RegPairNum);
1643 ? Hexagon::C2_ccombinewnewt
1644 : Hexagon::C2_ccombinewnewf);
1649 case Hexagon::V6_vassignp: {
1652 std::string R1 = v +
utostr(RegPairNum + 1);
1655 std::string R2 = v +
utostr(RegPairNum);
1665 case Hexagon::CONST64:
1675 std::string myCharStr;
1685 std::string myImmStr =
utohexstr(static_cast<uint32_t>(Value));
1686 myCharStr =
StringRef(
".gnu.linkonce.l4.CONST_00000000")
1691 std::string myImmStr =
utohexstr(Value);
1692 myCharStr =
StringRef(
".gnu.linkonce.l8.CONST_0000000000000000")
1700 }
else if (MO_1.
isExpr()) {
1702 myCharStr =
".lita";
1709 unsigned byteSize = is32bit ? 4 : 8;
1710 getStreamer().EmitCodeAlignment(byteSize, byteSize);
1718 Sym = getContext().getOrCreateSymbol(
StringRef(myCharStr.c_str() + 16));
1720 getStreamer().EmitLabel(Sym);
1721 getStreamer().EmitSymbolAttribute(Sym,
MCSA_Global);
1722 getStreamer().EmitIntValue(Value, byteSize);
1724 }
else if (MO_1.
isExpr()) {
1725 const char *StringStart =
nullptr;
1726 const char *StringEnd =
nullptr;
1727 if (*Operands[4]->getStartLoc().getPointer() ==
'#') {
1728 StringStart = Operands[5]->getStartLoc().getPointer();
1729 StringEnd = Operands[6]->getStartLoc().getPointer();
1731 StringStart = Operands[4]->getStartLoc().getPointer();
1732 StringEnd = Operands[5]->getStartLoc().getPointer();
1735 unsigned size = StringEnd - StringStart;
1736 std::string DotConst =
".CONST_";
1737 Sym = getContext().getOrCreateSymbol(DotConst +
1742 getStreamer().EmitLabel(Sym);
1743 getStreamer().EmitSymbolAttribute(Sym,
MCSA_Local);
1744 getStreamer().EmitValue(MO_1.
getExpr(), 4);
1754 TmpInst.
setOpcode(Hexagon::L2_loadrigp);
1756 TmpInst.
setOpcode(Hexagon::L2_loadrdgp);
1767 case Hexagon::A2_tfrpi: {
1771 int sVal = (MO.
getExpr()->evaluateAsAbsolute(Value) && Value < 0) ? -1 : 0;
1779 case Hexagon::TFRI64_V4: {
1783 if (MO.
getExpr()->evaluateAsAbsolute(Value)) {
1784 int s8 =
Hi_32(Value);
1786 OutOfRange(IDLoc, s8, -128);
1803 case Hexagon::TFRI64_V2_ext: {
1808 if (MO2.
getExpr()->evaluateAsAbsolute(Value)) {
1810 if (s8 < -128 || s8 > 127)
1811 OutOfRange(IDLoc, s8, -128);
1818 case Hexagon::A4_combineii: {
1822 if (MO1.
getExpr()->evaluateAsAbsolute(Value)) {
1824 if (s8 < -128 || s8 > 127)
1825 OutOfRange(IDLoc, s8, -128);
1832 case Hexagon::S2_tableidxb_goodsyntax:
1836 case Hexagon::S2_tableidxh_goodsyntax: {
1845 TmpInst.
setOpcode(Hexagon::S2_tableidxh);
1855 case Hexagon::S2_tableidxw_goodsyntax: {
1864 TmpInst.
setOpcode(Hexagon::S2_tableidxw);
1874 case Hexagon::S2_tableidxd_goodsyntax: {
1883 TmpInst.
setOpcode(Hexagon::S2_tableidxd);
1893 case Hexagon::M2_mpyui:
1896 case Hexagon::M2_mpysmi: {
1903 bool Absolute = Expr.evaluateAsAbsolute(Value);
1914 return Match_InvalidOperand;
1919 return Match_InvalidOperand;
1928 case Hexagon::S2_asr_i_r_rnd_goodsyntax: {
1932 bool Absolute = Imm.
getExpr()->evaluateAsAbsolute(Value);
1946 TmpInst.
setOpcode(Hexagon::S2_asr_i_r_rnd);
1957 case Hexagon::S2_asr_i_p_rnd_goodsyntax: {
1962 bool Absolute = Imm.
getExpr()->evaluateAsAbsolute(Value);
1968 std::string R1 = r +
utostr(RegPairNum + 1);
1970 Rss.
setReg(matchRegister(Reg1));
1972 std::string R2 = r +
utostr(RegPairNum);
1974 TmpInst.
setOpcode(Hexagon::A2_combinew);
1984 Inst.
setOpcode(Hexagon::S2_asr_i_p_rnd);
1989 case Hexagon::A4_boundscheck: {
1993 Inst.
setOpcode(Hexagon::A4_boundscheck_hi);
1994 std::string Name = r +
utostr(RegNum) + Colon +
utostr(RegNum - 1);
1996 Rs.
setReg(matchRegister(RegPair));
1998 Inst.
setOpcode(Hexagon::A4_boundscheck_lo);
1999 std::string Name = r +
utostr(RegNum + 1) + Colon +
utostr(RegNum);
2001 Rs.
setReg(matchRegister(RegPair));
2006 case Hexagon::A2_addsp: {
2011 std::string Name = r +
utostr(RegNum) + Colon +
utostr(RegNum - 1);
2013 Rs.
setReg(matchRegister(RegPair));
2016 std::string Name = r +
utostr(RegNum + 1) + Colon +
utostr(RegNum);
2018 Rs.
setReg(matchRegister(RegPair));
2023 case Hexagon::M2_vrcmpys_s1: {
2027 Inst.
setOpcode(Hexagon::M2_vrcmpys_s1_h);
2028 std::string Name = r +
utostr(RegNum) + Colon +
utostr(RegNum - 1);
2030 Rt.
setReg(matchRegister(RegPair));
2032 Inst.
setOpcode(Hexagon::M2_vrcmpys_s1_l);
2033 std::string Name = r +
utostr(RegNum + 1) + Colon +
utostr(RegNum);
2035 Rt.
setReg(matchRegister(RegPair));
2040 case Hexagon::M2_vrcmpys_acc_s1: {
2047 TmpInst.
setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
2048 std::string Name = r +
utostr(RegNum) + Colon +
utostr(RegNum - 1);
2050 Rt.
setReg(matchRegister(RegPair));
2052 TmpInst.
setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
2053 std::string Name = r +
utostr(RegNum + 1) + Colon +
utostr(RegNum);
2055 Rt.
setReg(matchRegister(RegPair));
2066 case Hexagon::M2_vrcmpys_s1rp: {
2070 Inst.
setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
2071 std::string Name = r +
utostr(RegNum) + Colon +
utostr(RegNum - 1);
2073 Rt.
setReg(matchRegister(RegPair));
2075 Inst.
setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
2076 std::string Name = r +
utostr(RegNum + 1) + Colon +
utostr(RegNum);
2078 Rt.
setReg(matchRegister(RegPair));
2083 case Hexagon::S5_asrhub_rnd_sat_goodsyntax: {
2086 bool Absolute = Imm.
getExpr()->evaluateAsAbsolute(Value);
2096 Inst.
setOpcode(Hexagon::S5_asrhub_rnd_sat);
2101 case Hexagon::S5_vasrhrnd_goodsyntax: {
2106 bool Absolute = Imm.
getExpr()->evaluateAsAbsolute(Value);
2112 std::string R1 = r +
utostr(RegPairNum + 1);
2114 Rss.
setReg(matchRegister(Reg1));
2116 std::string R2 = r +
utostr(RegPairNum);
2118 TmpInst.
setOpcode(Hexagon::A2_combinew);
2133 case Hexagon::A2_not: {
2147 return Match_Success;
2150 unsigned HexagonAsmParser::matchRegister(
StringRef Name) {
static bool isReg(const MCInst &MI, unsigned OpNo)
static bool Check(DecodeStatus &Out, DecodeStatus In)
void push_back(const T &Elt)
LLVM_NODISCARD int compare_lower(StringRef RHS) const
compare_lower - Compare two strings, ignoring case.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
TokenKind getKind() const
This represents an "assembler immediate".
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Generic assembler parser interface, for use by target specific assembly parsers.
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
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)
Lo_32 - This function returns the low 32 bits of a 64 bit value.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool isToken() const =0
isToken - Is this a token operand?
Target specific streamer interface.
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
constexpr bool isInt< 8 >(int64_t x)
virtual bool hasRawTextSupport() const
Return true if this asm streamer supports emitting unformatted text to the .s file with EmitRawText...
void PushSection()
Save the current and previous section on the section stack.
SMLoc getLoc() const
Get the current source location.
static const MCBinaryExpr * createAnd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
void LLVMInitializeHexagonAsmParser()
Force static initialization.
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)
virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
const AsmToken & getTok() const
Get the current (last) lexed token.
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.
void setInnerLoop(MCInst &MCI)
No free slots for store insns.
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.
std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
static unsigned MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
#define HEXAGON_PACKET_SIZE
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.
Reg
All possible values of the reg field in the ModR/M byte.
Target independent representation for an assembler token.
Windows NT (Windows on ARM)
static bool isMem(const MachineInstr &MI, unsigned Op)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand...
LLVM_NODISCARD bool empty() const
void setMemReorderDisabled(MCInst &MCI)
Context object for machine code objects.
No free slots for branch insns.
void setS23_2_reloc(MCExpr const &Expr, bool Val=true)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
unsigned getReg() const
Returns the register number.
bool canonicalizePacket(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCContext &Context, MCInst &MCB, HexagonMCChecker *Checker)
bool isAbsolute() const
Is this an absolute (as opposed to relocatable) value.
Function Alias Analysis false
static std::string utostr(uint64_t X, bool isNeg=false)
void extendIfNeeded(MCContext &Context, MCInstrInfo const &MCII, MCInst &MCB, MCInst const &MCI)
void setMustExtend(MCExpr const &Expr, bool Val=true)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
Instances of this class represent a single low-level machine instruction.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
No free slots for load insns.
const MCExpr * getExpr() const
void setMemStoreReorderEnabled(MCInst &MCI)
virtual MCContext & getContext()=0
initializer< Ty > init(const Ty &Val)
Streaming machine code generation interface.
static HexagonMCExpr * create(MCExpr const *Expr, MCContext &Ctx)
The instances of the Type class are immutable: once they are created, they are never changed...
bool mustExtend(MCExpr const &Expr)
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()
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Interface to description of machine instruction set.
virtual MCAsmLexer & getLexer()=0
MCSymbolRefExpr::VariantKind getAccessVariant() const
constexpr bool isPowerOf2_64(uint64_t Value)
isPowerOf2_64 - This function returns true if the argument is a power of two 0 (64 bit edition...
static cl::opt< bool > ErrorNoncontigiousRegister("merror-noncontigious-register", cl::desc("Error for register names that aren't contigious"), cl::init(false))
static cl::opt< bool > EnableFutureRegs("mfuture-regs", cl::desc("Enable future registers"))
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
void setOuterLoop(MCInst &MCI)
static const unsigned End
MCExpr const & getExpr(MCExpr const &Expr)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
No free slots for other insns.
bool isIntN(unsigned N, int64_t x)
isIntN - Checks if an signed integer fits into the given (dynamic) bit width.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
static const MCBinaryExpr * createLShr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
void HexagonMCEmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, unsigned AccessSize)
void setOpcode(unsigned Op)
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
void UnLex(AsmToken const &Token)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
LLVM_NODISCARD std::string upper() const
Convert the given ASCII string to uppercase.
Promote Memory to Register
static bool previousIsLoop(OperandVector &Operands, size_t Index)
bool is(TokenKind K) const
static bool previousEqual(OperandVector &Operands, size_t Index, StringRef String)
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 evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
unsigned getOpcode() const
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
Base class for user error types.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
iterator insert(iterator I, T &&Elt)
static MCOperand createInst(const MCInst *Val)
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string...
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
RegisterMCAsmParser - Helper template for registering a target specific assembly parser, for use in the target machine initialization function.
void emplace_back(ArgTypes &&...Args)
static MCInst makeCombineInst(int opCode, MCOperand &Rdd, MCOperand &MO1, MCOperand &MO2)
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
MCSubtargetInfo - 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)
bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout, const SectionAddrMap &Addrs) const
Try to evaluate the expression to an absolute value.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
static std::string utohexstr(uint64_t X, bool LowerCase=false)
void setReg(unsigned Reg)
Set the register number.
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.
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
constexpr uint32_t Hi_32(uint64_t Value)
Hi_32 - This function returns the high 32 bits of a 64 bit value.
LLVM Value Representation.
Lightweight error class with error context and mandatory checking.
static unsigned MatchRegisterName(StringRef Name)
Maps from the set of all register names to a register number.
Check for a valid bundle.
This class implements an extremely fast bulk output stream that can only output to a stream...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
std::string Hash(const Unit &U)
const char * getName(unsigned RegNo) const
Return the human-readable symbolic target-specific name for the specified physical register...
void addOperand(const MCOperand &Op)
StringRef - Represent a constant reference to a string, i.e.
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.
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.
bool isUIntN(unsigned N, uint64_t x)
isUIntN - 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)
LLVM_NODISCARD std::string lower() const
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
const MCOperand & getOperand(unsigned i) const
Target & getTheHexagonTarget()
void HexagonMCEmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment, unsigned AccessSize)
bool isUndefined(bool SetUsed=true) const
isUndefined - Check if this symbol undefined (i.e., implicitly defined).
void setExpr(const MCExpr *Val)