40#define DEBUG_TYPE "csky-asm-parser"
43#define GEN_COMPRESS_INSTR
44#include "CSKYGenCompressInstEmitter.inc"
47 "Number of C-SKY Compressed instructions emitted");
53 const CSKYMCOptions &CLOpts;
57 unsigned Kind)
override;
63 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
65 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
68 bool MatchingInlineAsm)
override;
70 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
72 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
75 ParseStatus parseDirective(AsmToken DirectiveID)
override;
79 void emitToStreamer(MCStreamer &S,
const MCInst &Inst);
81 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
82 SMLoc &EndLoc)
override;
86 bool processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
87 bool processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
88 bool processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
90 CSKYTargetStreamer &getTargetStreamer() {
91 assert(getParser().getStreamer().getTargetStreamer() &&
92 "do not have a target streamer");
93 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
94 return static_cast<CSKYTargetStreamer &
>(TS);
98#define GET_ASSEMBLER_HEADER
99#include "CSKYGenAsmMatcher.inc"
113 bool parseDirectiveAttribute();
116 enum CSKYMatchResultTy {
117 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
118 Match_RequiresSameSrcAndDst,
119 Match_InvalidRegOutOfRange,
120#define GET_OPERAND_DIAGNOSTIC_TYPES
121#include "CSKYGenAsmMatcher.inc"
122#undef GET_OPERAND_DIAGNOSTIC_TYPES
125 CSKYAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
126 const MCInstrInfo &MII)
127 : MCTargetAsmParser(STI, MII),
135 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
136 if (CLOpts.add_build_attributes)
137 getTargetStreamer().emitTargetAttributes(STI,
false);
166 MCRegister RegNumFrom;
171 MCRegister List1From;
173 MCRegister List2From;
175 MCRegister List3From;
177 MCRegister List4From;
181 SMLoc StartLoc, EndLoc;
191 CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(
K) {}
194 CSKYOperand(
const CSKYOperand &o) : MCParsedAsmOperand() {
196 StartLoc =
o.StartLoc;
220 bool isToken()
const override {
return Kind == Token; }
221 bool isReg()
const override {
return Kind == Register; }
222 bool isImm()
const override {
return Kind == Immediate; }
223 bool isRegisterSeq()
const {
return Kind == RegisterSeq; }
224 bool isRegisterList()
const {
return Kind == RegisterList; }
225 bool isConstPoolOp()
const {
return Kind == CPOP; }
227 bool isMem()
const override {
return false; }
229 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &
Imm) {
231 Imm =
CE->getValue();
238 template <
unsigned num,
unsigned shift = 0>
bool isUImm()
const {
243 bool IsConstantImm = evaluateConstantImm(
getImm(),
Imm);
247 template <
unsigned num>
bool isOImm()
const {
252 bool IsConstantImm = evaluateConstantImm(
getImm(),
Imm);
256 template <
unsigned num,
unsigned shift = 0>
bool isSImm()
const {
261 bool IsConstantImm = evaluateConstantImm(
getImm(),
Imm);
265 bool isUImm1()
const {
return isUImm<1>(); }
266 bool isUImm2()
const {
return isUImm<2>(); }
267 bool isUImm3()
const {
return isUImm<3>(); }
268 bool isUImm4()
const {
return isUImm<4>(); }
269 bool isUImm5()
const {
return isUImm<5>(); }
270 bool isUImm6()
const {
return isUImm<6>(); }
271 bool isUImm7()
const {
return isUImm<7>(); }
272 bool isUImm8()
const {
return isUImm<8>(); }
273 bool isUImm12()
const {
return isUImm<12>(); }
274 bool isUImm16()
const {
return isUImm<16>(); }
275 bool isUImm20()
const {
return isUImm<20>(); }
276 bool isUImm24()
const {
return isUImm<24>(); }
278 bool isOImm3()
const {
return isOImm<3>(); }
279 bool isOImm4()
const {
return isOImm<4>(); }
280 bool isOImm5()
const {
return isOImm<5>(); }
281 bool isOImm6()
const {
return isOImm<6>(); }
282 bool isOImm8()
const {
return isOImm<8>(); }
283 bool isOImm12()
const {
return isOImm<12>(); }
284 bool isOImm16()
const {
return isOImm<16>(); }
286 bool isSImm8()
const {
return isSImm<8>(); }
288 bool isUImm5Shift1() {
return isUImm<5, 1>(); }
289 bool isUImm5Shift2() {
return isUImm<5, 2>(); }
290 bool isUImm7Shift1() {
return isUImm<7, 1>(); }
291 bool isUImm7Shift2() {
return isUImm<7, 2>(); }
292 bool isUImm7Shift3() {
return isUImm<7, 3>(); }
293 bool isUImm8Shift2() {
return isUImm<8, 2>(); }
294 bool isUImm8Shift3() {
return isUImm<8, 3>(); }
295 bool isUImm8Shift8() {
return isUImm<8, 8>(); }
296 bool isUImm8Shift16() {
return isUImm<8, 16>(); }
297 bool isUImm8Shift24() {
return isUImm<8, 24>(); }
298 bool isUImm12Shift1() {
return isUImm<12, 1>(); }
299 bool isUImm12Shift2() {
return isUImm<12, 2>(); }
300 bool isUImm16Shift8() {
return isUImm<16, 8>(); }
301 bool isUImm16Shift16() {
return isUImm<16, 16>(); }
302 bool isUImm24Shift8() {
return isUImm<24, 8>(); }
304 bool isSImm16Shift1() {
return isSImm<16, 1>(); }
306 bool isCSKYSymbol()
const {
return isImm(); }
308 bool isConstpool()
const {
return isConstPoolOp(); }
309 bool isDataSymbol()
const {
return isConstPoolOp(); }
311 bool isPSRFlag()
const {
314 if (!isImm() || !evaluateConstantImm(
getImm(),
Imm))
320 template <
unsigned MIN,
unsigned MAX>
bool isRegSeqTemplate()
const {
321 if (!isRegisterSeq())
324 std::pair<unsigned, unsigned> regSeq = getRegSeq();
326 return MIN <= regSeq.first && regSeq.first <= regSeq.second &&
327 regSeq.second <=
MAX;
330 bool isRegSeq()
const {
return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); }
332 bool isRegSeqV1()
const {
333 return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>();
336 bool isRegSeqV2()
const {
337 return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>();
340 static bool isLegalRegList(
unsigned from,
unsigned to) {
341 if (from == 0 && to == 0)
345 if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 &&
351 if (from != CSKY::R4 && from != CSKY::R16)
354 if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12)
356 else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18)
363 bool isRegList()
const {
364 if (!isRegisterList())
367 auto regList = getRegList();
369 if (!isLegalRegList(regList.List1From, regList.List1To))
371 if (!isLegalRegList(regList.List2From, regList.List2To))
373 if (!isLegalRegList(regList.List3From, regList.List3To))
375 if (!isLegalRegList(regList.List4From, regList.List4To))
386 bool IsConstantImm = evaluateConstantImm(
getImm(),
Imm);
390 int uimm4 =
Imm & 0xf;
396 SMLoc getStartLoc()
const override {
return StartLoc; }
398 SMLoc getEndLoc()
const override {
return EndLoc; }
400 MCRegister
getReg()
const override {
401 assert(Kind == Register &&
"Invalid type access!");
405 std::pair<MCRegister, MCRegister> getRegSeq()
const {
406 assert(Kind == RegisterSeq &&
"Invalid type access!");
407 return {RegSeq.RegNumFrom, RegSeq.RegNumTo};
410 RegListOp getRegList()
const {
411 assert(Kind == RegisterList &&
"Invalid type access!");
415 const MCExpr *
getImm()
const {
416 assert(Kind == Immediate &&
"Invalid type access!");
420 const MCExpr *getConstpoolOp()
const {
421 assert(Kind == CPOP &&
"Invalid type access!");
426 assert(Kind == Token &&
"Invalid type access!");
430 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
446 case KindTy::Register:
450 OS <<
"<register-seq ";
451 OS <<
RegName(getRegSeq().first) <<
"-" <<
RegName(getRegSeq().second)
455 OS <<
"<register-list ";
456 OS <<
RegName(getRegList().List1From) <<
"-"
457 <<
RegName(getRegList().List1To) <<
",";
458 OS <<
RegName(getRegList().List2From) <<
"-"
459 <<
RegName(getRegList().List2To) <<
",";
460 OS <<
RegName(getRegList().List3From) <<
"-"
461 <<
RegName(getRegList().List3To) <<
",";
462 OS <<
RegName(getRegList().List4From) <<
"-"
463 <<
RegName(getRegList().List4To);
471 static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) {
472 auto Op = std::make_unique<CSKYOperand>(Token);
479 static std::unique_ptr<CSKYOperand> createReg(MCRegister RegNo, SMLoc S,
481 auto Op = std::make_unique<CSKYOperand>(Register);
482 Op->Reg.RegNum = RegNo;
488 static std::unique_ptr<CSKYOperand>
489 createRegSeq(MCRegister RegNoFrom, MCRegister RegNoTo, SMLoc S) {
490 auto Op = std::make_unique<CSKYOperand>(RegisterSeq);
491 Op->RegSeq.RegNumFrom = RegNoFrom;
492 Op->RegSeq.RegNumTo = RegNoTo;
498 static std::unique_ptr<CSKYOperand>
500 auto Op = std::make_unique<CSKYOperand>(RegisterList);
501 Op->RegList.List1From = 0;
502 Op->RegList.List1To = 0;
503 Op->RegList.List2From = 0;
504 Op->RegList.List2To = 0;
505 Op->RegList.List3From = 0;
506 Op->RegList.List3To = 0;
507 Op->RegList.List4From = 0;
508 Op->RegList.List4To = 0;
510 for (
unsigned i = 0; i < reglist.
size(); i += 2) {
511 if (
Op->RegList.List1From == 0) {
512 Op->RegList.List1From = reglist[i];
513 Op->RegList.List1To = reglist[i + 1];
514 }
else if (
Op->RegList.List2From == 0) {
515 Op->RegList.List2From = reglist[i];
516 Op->RegList.List2To = reglist[i + 1];
517 }
else if (
Op->RegList.List3From == 0) {
518 Op->RegList.List3From = reglist[i];
519 Op->RegList.List3To = reglist[i + 1];
520 }
else if (
Op->RegList.List4From == 0) {
521 Op->RegList.List4From = reglist[i];
522 Op->RegList.List4To = reglist[i + 1];
533 static std::unique_ptr<CSKYOperand> createImm(
const MCExpr *Val, SMLoc S,
535 auto Op = std::make_unique<CSKYOperand>(Immediate);
542 static std::unique_ptr<CSKYOperand> createConstpoolOp(
const MCExpr *Val,
544 auto Op = std::make_unique<CSKYOperand>(CPOP);
551 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
552 assert(Expr &&
"Expr shouldn't be null!");
560 void addRegOperands(MCInst &Inst,
unsigned N)
const {
561 assert(
N == 1 &&
"Invalid number of operands!");
565 void addImmOperands(MCInst &Inst,
unsigned N)
const {
566 assert(
N == 1 &&
"Invalid number of operands!");
570 void addConstpoolOperands(MCInst &Inst,
unsigned N)
const {
571 assert(
N == 1 &&
"Invalid number of operands!");
575 void addRegSeqOperands(MCInst &Inst,
unsigned N)
const {
576 assert(
N == 2 &&
"Invalid number of operands!");
577 auto regSeq = getRegSeq();
583 static unsigned getListValue(
unsigned ListFrom,
unsigned ListTo) {
584 if (ListFrom == ListTo && ListFrom == CSKY::R15)
586 else if (ListFrom == ListTo && ListFrom == CSKY::R28)
588 else if (ListFrom == CSKY::R4)
589 return ListTo - ListFrom + 1;
590 else if (ListFrom == CSKY::R16)
591 return ((ListTo - ListFrom + 1) << 5);
596 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
597 assert(
N == 1 &&
"Invalid number of operands!");
598 auto regList = getRegList();
602 unsigned T = getListValue(regList.List1From, regList.List1To);
606 T = getListValue(regList.List2From, regList.List2To);
610 T = getListValue(regList.List3From, regList.List3To);
614 T = getListValue(regList.List4From, regList.List4To);
621 bool isValidForTie(
const CSKYOperand &
Other)
const {
622 if (Kind !=
Other.Kind)
630 return Reg.RegNum ==
Other.Reg.RegNum;
636#define GET_REGISTER_MATCHER
637#define GET_SUBTARGET_FEATURE_NAME
638#define GET_MATCHER_IMPLEMENTATION
639#define GET_MNEMONIC_SPELL_CHECKER
640#include "CSKYGenAsmMatcher.inc"
643 assert(
Reg >= CSKY::F0_32 &&
Reg <= CSKY::F31_32 &&
"Invalid register");
644 return Reg - CSKY::F0_32 + CSKY::F0_64;
648 unsigned VariantID = 0);
650bool CSKYAsmParser::generateImmOutOfRangeError(
652 const Twine &
Msg =
"immediate must be an integer in the range") {
657bool CSKYAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
661 bool MatchingInlineAsm) {
663 FeatureBitset MissingFeatures;
665 auto Result = MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
671 return processInstruction(Inst, IDLoc,
Operands, Out);
672 case Match_MissingFeature: {
673 assert(MissingFeatures.
any() &&
"Unknown missing features!");
675 std::string
Msg =
"instruction requires the following: ";
676 for (
unsigned Feature : MissingFeatures) {
682 case Match_MnemonicFail: {
683 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
684 std::string Suggestion =
686 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
688 case Match_InvalidTiedOperand:
689 case Match_InvalidOperand: {
690 SMLoc ErrorLoc = IDLoc;
691 if (ErrorInfo != ~0U) {
693 return Error(ErrorLoc,
"too few operands for instruction");
695 ErrorLoc = ((CSKYOperand &)*
Operands[ErrorInfo]).getStartLoc();
696 if (ErrorLoc == SMLoc())
699 return Error(ErrorLoc,
"invalid operand for instruction");
706 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
707 SMLoc ErrorLoc = IDLoc;
708 if (ErrorInfo != ~0U && ErrorInfo >=
Operands.size())
709 return Error(ErrorLoc,
"too few operands for instruction");
715 case Match_InvalidSImm8:
716 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 7),
718 case Match_InvalidOImm3:
719 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 3));
720 case Match_InvalidOImm4:
721 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 4));
722 case Match_InvalidOImm5:
723 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 5));
724 case Match_InvalidOImm6:
725 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 6));
726 case Match_InvalidOImm8:
727 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 8));
728 case Match_InvalidOImm12:
729 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 12));
730 case Match_InvalidOImm16:
731 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 16));
732 case Match_InvalidUImm1:
733 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 1) - 1);
734 case Match_InvalidUImm2:
735 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 2) - 1);
736 case Match_InvalidUImm3:
737 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 3) - 1);
738 case Match_InvalidUImm4:
739 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 4) - 1);
740 case Match_InvalidUImm5:
741 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 5) - 1);
742 case Match_InvalidUImm6:
743 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 6) - 1);
744 case Match_InvalidUImm7:
745 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 7) - 1);
746 case Match_InvalidUImm8:
747 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 8) - 1);
748 case Match_InvalidUImm12:
749 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 12) - 1);
750 case Match_InvalidUImm16:
751 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 16) - 1);
752 case Match_InvalidUImm5Shift1:
753 return generateImmOutOfRangeError(
754 Operands, ErrorInfo, 0, (1 << 5) - 2,
755 "immediate must be a multiple of 2 bytes in the range");
756 case Match_InvalidUImm12Shift1:
757 return generateImmOutOfRangeError(
758 Operands, ErrorInfo, 0, (1 << 12) - 2,
759 "immediate must be a multiple of 2 bytes in the range");
760 case Match_InvalidUImm5Shift2:
761 return generateImmOutOfRangeError(
762 Operands, ErrorInfo, 0, (1 << 5) - 4,
763 "immediate must be a multiple of 4 bytes in the range");
764 case Match_InvalidUImm7Shift1:
765 return generateImmOutOfRangeError(
766 Operands, ErrorInfo, 0, (1 << 7) - 2,
767 "immediate must be a multiple of 2 bytes in the range");
768 case Match_InvalidUImm7Shift2:
769 return generateImmOutOfRangeError(
770 Operands, ErrorInfo, 0, (1 << 7) - 4,
771 "immediate must be a multiple of 4 bytes in the range");
772 case Match_InvalidUImm8Shift2:
773 return generateImmOutOfRangeError(
774 Operands, ErrorInfo, 0, (1 << 8) - 4,
775 "immediate must be a multiple of 4 bytes in the range");
776 case Match_InvalidUImm8Shift3:
777 return generateImmOutOfRangeError(
778 Operands, ErrorInfo, 0, (1 << 8) - 8,
779 "immediate must be a multiple of 8 bytes in the range");
780 case Match_InvalidUImm8Shift8:
781 return generateImmOutOfRangeError(
782 Operands, ErrorInfo, 0, (1 << 8) - 256,
783 "immediate must be a multiple of 256 bytes in the range");
784 case Match_InvalidUImm12Shift2:
785 return generateImmOutOfRangeError(
786 Operands, ErrorInfo, 0, (1 << 12) - 4,
787 "immediate must be a multiple of 4 bytes in the range");
788 case Match_InvalidCSKYSymbol: {
789 SMLoc ErrorLoc = ((CSKYOperand &)*
Operands[ErrorInfo]).getStartLoc();
790 return Error(ErrorLoc,
"operand must be a symbol name");
792 case Match_InvalidConstpool: {
793 SMLoc ErrorLoc = ((CSKYOperand &)*
Operands[ErrorInfo]).getStartLoc();
794 return Error(ErrorLoc,
"operand must be a constpool symbol name");
796 case Match_InvalidPSRFlag: {
797 SMLoc ErrorLoc = ((CSKYOperand &)*
Operands[ErrorInfo]).getStartLoc();
798 return Error(ErrorLoc,
"psrset operand is not valid");
800 case Match_InvalidRegSeq: {
801 SMLoc ErrorLoc = ((CSKYOperand &)*
Operands[ErrorInfo]).getStartLoc();
802 return Error(ErrorLoc,
"Register sequence is not valid");
804 case Match_InvalidRegOutOfRange: {
805 SMLoc ErrorLoc = ((CSKYOperand &)*
Operands[ErrorInfo]).getStartLoc();
806 return Error(ErrorLoc,
"register is out of range");
808 case Match_RequiresSameSrcAndDst: {
809 SMLoc ErrorLoc = ((CSKYOperand &)*
Operands[ErrorInfo]).getStartLoc();
810 return Error(ErrorLoc,
"src and dst operand must be same");
812 case Match_InvalidRegList: {
813 SMLoc ErrorLoc = ((CSKYOperand &)*
Operands[ErrorInfo]).getStartLoc();
814 return Error(ErrorLoc,
"invalid register list");
821bool CSKYAsmParser::processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
826 if (Inst.
getOpcode() == CSKY::PseudoLRW16)
827 Opcode = CSKY::LRW16;
829 Opcode = CSKY::LRW32;
834 Opcode = CSKY::MOVI16;
835 }
else if (getSTI().
hasFeature(CSKY::HasE2) &&
837 Opcode = CSKY::MOVI32;
839 auto *Expr = getTargetStreamer().addConstantPoolEntry(
846 const MCExpr *AdjustExpr =
nullptr;
847 if (
const auto *CSKYExpr =
857 auto *Expr = getTargetStreamer().addConstantPoolEntry(
865 Out.emitInstruction(Inst, getSTI());
869bool CSKYAsmParser::processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
873 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
880 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
886 Out.emitInstruction(Inst, getSTI());
890bool CSKYAsmParser::processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
894 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
901 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
907 Out.emitInstruction(Inst, getSTI());
911bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
922 return Error(IDLoc,
"Register sequence is not valid. 'r4-r7' expected");
929 return Error(IDLoc,
"msb must be greater or equal to lsb");
933 return Error(IDLoc,
"msb must be greater or equal to lsb");
937 return Error(IDLoc,
"n must be in range [0,32]");
968 case CSKY::PseudoLRW16:
969 case CSKY::PseudoLRW32:
970 return processLRW(Inst, IDLoc, Out);
971 case CSKY::PseudoJSRI32:
972 return processJSRI(Inst, IDLoc, Out);
973 case CSKY::PseudoJMPI32:
974 return processJMPI(Inst, IDLoc, Out);
985 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
992 emitToStreamer(Out, Inst);
1003 if (
Reg == CSKY::NoRegister)
1006 return Reg == CSKY::NoRegister;
1009bool CSKYAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1011 const AsmToken &Tok = getParser().getTok();
1014 StringRef
Name = getLexer().getTok().getIdentifier();
1028 switch (getLexer().getKind()) {
1032 StringRef
Name = getLexer().getTok().getIdentifier();
1049 Operands.push_back(CSKYOperand::createToken(
"(", getLoc()));
1051 auto Tok = getParser().Lex();
1053 if (!parseRegister(
Operands).isSuccess()) {
1054 getLexer().UnLex(Tok);
1060 Operands.push_back(CSKYOperand::createToken(
")", getLoc()));
1066 return Error(getLoc(),
"expected ','");
1070 if (parseRegister(
Operands).isSuccess()) {
1072 return Error(getLoc(),
"expected '<<'");
1074 Operands.push_back(CSKYOperand::createToken(
"<<", getLoc()));
1079 return Error(getLoc(),
"expected imm");
1082 return Error(getLoc(),
"expected imm");
1086 return Error(getLoc(),
"expected ')'");
1088 Operands.push_back(CSKYOperand::createToken(
")", getLoc()));
1096 switch (getLexer().getKind()) {
1107 const MCExpr *IdVal;
1109 if (getParser().parseExpression(IdVal))
1110 return Error(getLoc(),
"unknown expression");
1113 Operands.push_back(CSKYOperand::createImm(IdVal, S,
E));
1124 MatchOperandParserImpl(
Operands, Mnemonic,
true);
1131 auto Res = parseRegister(
Operands);
1132 if (Res.isSuccess())
1134 if (Res.isFailure())
1140 if (Res.isSuccess())
1142 if (Res.isFailure())
1147 if (Res.isSuccess())
1149 if (Res.isFailure())
1153 Error(getLoc(),
"unknown operand");
1166 AsmToken Tok = getLexer().getTok();
1168 if (getParser().parseIdentifier(Identifier))
1169 return Error(getLoc(),
"unknown identifier");
1180 else if (
Identifier.consume_back(
"@TLSGD32"))
1182 else if (
Identifier.consume_back(
"@GOTTPOFF"))
1186 else if (
Identifier.consume_back(
"@TLSLDM32"))
1188 else if (
Identifier.consume_back(
"@TLSLDO32"))
1194 Sym =
getContext().getOrCreateSymbol(Identifier);
1199 getLexer().UnLex(Tok);
1200 return Error(getLoc(),
"unknown symbol");
1207 switch (getLexer().getKind()) {
1212 Operands.push_back(CSKYOperand::createImm(Res, S,
E));
1225 if (getParser().parseExpression(Expr))
1226 return Error(getLoc(),
"unknown expression");
1228 Operands.push_back(CSKYOperand::createImm(Res, S,
E));
1241 if (getParser().parseExpression(Expr))
1242 return Error(getLoc(),
"unknown expression");
1247 Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S,
E));
1251 AsmToken Tok = getLexer().getTok();
1254 if (getParser().parseIdentifier(Identifier))
1255 return Error(getLoc(),
"unknown identifier " + Identifier);
1266 Sym =
getContext().getOrCreateSymbol(Identifier);
1271 getLexer().UnLex(Tok);
1272 return Error(getLoc(),
"unknown symbol");
1280 switch (getLexer().getKind()) {
1282 return Error(getLoc(),
"unknown symbol");
1290 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1303 if (getParser().parseExpression(Expr))
1304 return Error(getLoc(),
"unknown expression");
1309 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1323 if (getParser().parseExpression(Expr))
1324 return Error(getLoc(),
"unknown expression");
1328 Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S,
E));
1332 AsmToken Tok = getLexer().getTok();
1335 if (getParser().parseIdentifier(Identifier))
1336 return Error(getLoc(),
"unknown identifier");
1341 Sym =
getContext().getOrCreateSymbol(Identifier);
1346 getLexer().UnLex(Tok);
1347 return Error(getLoc(),
"unknown symbol");
1355 switch (getLexer().getKind()) {
1357 return Error(getLoc(),
"unknown symbol");
1362 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1375 if (getParser().parseExpression(Expr))
1376 return Error(getLoc(),
"unknown expression");
1381 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1393 if (getParser().parseIdentifier(Identifier))
1394 return Error(getLoc(),
"unknown identifier " + Identifier);
1396 if (Identifier ==
"sie")
1397 Flag = (1 << 4) | Flag;
1398 else if (Identifier ==
"ee")
1399 Flag = (1 << 3) | Flag;
1400 else if (Identifier ==
"ie")
1401 Flag = (1 << 2) | Flag;
1402 else if (Identifier ==
"fe")
1403 Flag = (1 << 1) | Flag;
1404 else if (Identifier ==
"af")
1405 Flag = (1 << 0) | Flag;
1407 return Error(getLoc(),
"expected " + Identifier);
1424 if (!parseRegister(
Operands).isSuccess())
1427 auto Ry =
Operands.back()->getReg();
1432 if (!parseRegister(
Operands).isSuccess())
1433 return Error(getLoc(),
"invalid register");
1435 auto Rz =
Operands.back()->getReg();
1438 Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S));
1447 if (!parseRegister(
Operands).isSuccess())
1448 return Error(getLoc(),
"invalid register");
1450 auto Ry =
Operands.back()->getReg();
1454 if (!parseRegister(
Operands).isSuccess())
1455 return Error(getLoc(),
"invalid register");
1457 auto Rz =
Operands.back()->getReg();
1474 return Error(getLoc(),
"invalid register list");
1482bool CSKYAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1485 Operands.push_back(CSKYOperand::createToken(Name, NameLoc));
1501 SMLoc Loc = getLexer().getLoc();
1502 getParser().eatToEndOfStatement();
1503 return Error(Loc,
"unexpected token");
1510ParseStatus CSKYAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1512 const AsmToken &Tok = getParser().getTok();
1516 StringRef
Name = getLexer().getTok().getIdentifier();
1525ParseStatus CSKYAsmParser::parseDirective(AsmToken DirectiveID) {
1526 StringRef IDVal = DirectiveID.
getString();
1528 if (IDVal ==
".csky_attribute")
1529 return parseDirectiveAttribute();
1536bool CSKYAsmParser::parseDirectiveAttribute() {
1537 MCAsmParser &Parser = getParser();
1543 std::optional<unsigned> Ret =
1546 return Error(TagLoc,
"attribute name not recognised: " + Name);
1550 const MCExpr *AttrExpr;
1558 return Error(TagLoc,
"expected numeric constant");
1560 Tag =
CE->getValue();
1566 StringRef StringValue;
1567 int64_t IntegerValue = 0;
1573 if (IsIntegerValue) {
1574 const MCExpr *ValueExpr;
1580 return Error(ValueExprLoc,
"expected numeric constant");
1581 IntegerValue =
CE->getValue();
1594 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
1596 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
1601 if (ID == CSKY::ArchKind::INVALID)
1603 ?
"unknown arch name"
1604 :
"unknown cpu name");
1606 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
1612unsigned CSKYAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1614 CSKYOperand &
Op =
static_cast<CSKYOperand &
>(AsmOp);
1617 return Match_InvalidOperand;
1619 MCRegister
Reg =
Op.getReg();
1621 if (getCSKYMCRegisterClass(CSKY::FPR32RegClassID).
contains(
Reg)) {
1624 if (Kind == MCK_FPR64 || Kind == MCK_sFPR64) {
1626 if (Kind == MCK_sFPR64 &&
1627 (
Op.Reg.RegNum < CSKY::F0_64 ||
Op.Reg.RegNum > CSKY::F15_64))
1628 return Match_InvalidRegOutOfRange;
1629 if (Kind == MCK_FPR64 &&
1630 (
Op.Reg.RegNum < CSKY::F0_64 ||
Op.Reg.RegNum > CSKY::F31_64))
1631 return Match_InvalidRegOutOfRange;
1632 return Match_Success;
1636 if (getCSKYMCRegisterClass(CSKY::GPRRegClassID).
contains(
Reg)) {
1637 if (Kind == MCK_GPRPair) {
1639 return Match_Success;
1643 return Match_InvalidOperand;
1646void CSKYAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
1649 if (CLOpts.asm_compressed_inst)
1650 Res = compressInst(CInst, Inst, getSTI());
1652 ++CSKYNumInstrsCompressed;
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg, StringRef Name)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser()
static MCRegister convertFPR32ToFPR64(MCRegister Reg)
static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
#define LLVM_EXTERNAL_VISIBILITY
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
static bool isUImm2(const MachineOperand &MO)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)
LLVM_ABI SMLoc getLoc() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getStringContents() const
Get the contents of a string token (without quotes).
bool is(TokenKind K) const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
static const char * getRegisterName(const CSKYMCOptions &CLOpts, MCRegister Reg)
Base class for user error types.
Container class for subtarget features.
void printExpr(raw_ostream &, const MCExpr &) const
const MCTargetOptions & getTargetOptions() const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
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.
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
unsigned getNumOperands() const
unsigned getOpcode() const
iterator insert(iterator I, const MCOperand &Op)
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
Wrapper class representing physical registers. Should be passed by value.
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const AArch64MCOptions & getCLOpts(const MCTargetOptions &Options)
LLVM_ABI const TagNameMap & getCSKYAttributeTags()
const CSKYMCOptions & getCLOpts(const MCTargetOptions &Options)
LLVM_ABI ArchKind parseCPUArch(StringRef CPU)
LLVM_ABI ArchKind parseArch(StringRef Arch)
LLVM_ABI std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
Flag
These should be considered private to the implementation of the MCInstrDesc class.
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI 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 ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Target & getTheCSKYTarget()
DWARFExpression::Operation Op
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...