40#define DEBUG_TYPE "csky-asm-parser"
43#define GEN_COMPRESS_INSTR
44#include "CSKYGenCompressInstEmitter.inc"
47 "Number of C-SKY Compressed instructions emitted");
52 cl::desc(
"Enable C-SKY asm compressed instruction"));
62 unsigned Kind)
override;
68 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
70 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
73 bool MatchingInlineAsm)
override;
75 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
77 bool parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
80 ParseStatus parseDirective(AsmToken DirectiveID)
override;
84 void emitToStreamer(MCStreamer &S,
const MCInst &Inst);
86 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
87 SMLoc &EndLoc)
override;
91 bool processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
92 bool processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
93 bool processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
95 CSKYTargetStreamer &getTargetStreamer() {
96 assert(getParser().getStreamer().getTargetStreamer() &&
97 "do not have a target streamer");
98 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
99 return static_cast<CSKYTargetStreamer &
>(TS);
103#define GET_ASSEMBLER_HEADER
104#include "CSKYGenAsmMatcher.inc"
118 bool parseDirectiveAttribute();
121 enum CSKYMatchResultTy {
122 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
123 Match_RequiresSameSrcAndDst,
124 Match_InvalidRegOutOfRange,
125#define GET_OPERAND_DIAGNOSTIC_TYPES
126#include "CSKYGenAsmMatcher.inc"
127#undef GET_OPERAND_DIAGNOSTIC_TYPES
130 CSKYAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
131 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
132 : MCTargetAsmParser(
Options, STI, MII) {
139 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
140 getTargetStreamer().emitTargetAttributes(STI);
169 MCRegister RegNumFrom;
174 MCRegister List1From;
176 MCRegister List2From;
178 MCRegister List3From;
180 MCRegister List4From;
184 SMLoc StartLoc, EndLoc;
194 CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(
K) {}
197 CSKYOperand(
const CSKYOperand &o) : MCParsedAsmOperand() {
199 StartLoc =
o.StartLoc;
223 bool isToken()
const override {
return Kind == Token; }
224 bool isReg()
const override {
return Kind == Register; }
225 bool isImm()
const override {
return Kind == Immediate; }
226 bool isRegisterSeq()
const {
return Kind == RegisterSeq; }
227 bool isRegisterList()
const {
return Kind == RegisterList; }
228 bool isConstPoolOp()
const {
return Kind == CPOP; }
230 bool isMem()
const override {
return false; }
232 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm) {
234 Imm =
CE->getValue();
241 template <
unsigned num,
unsigned shift = 0>
bool isUImm()
const {
246 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
250 template <
unsigned num>
bool isOImm()
const {
255 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
259 template <
unsigned num,
unsigned shift = 0>
bool isSImm()
const {
264 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
268 bool isUImm1()
const {
return isUImm<1>(); }
269 bool isUImm2()
const {
return isUImm<2>(); }
270 bool isUImm3()
const {
return isUImm<3>(); }
271 bool isUImm4()
const {
return isUImm<4>(); }
272 bool isUImm5()
const {
return isUImm<5>(); }
273 bool isUImm6()
const {
return isUImm<6>(); }
274 bool isUImm7()
const {
return isUImm<7>(); }
275 bool isUImm8()
const {
return isUImm<8>(); }
276 bool isUImm12()
const {
return isUImm<12>(); }
277 bool isUImm16()
const {
return isUImm<16>(); }
278 bool isUImm20()
const {
return isUImm<20>(); }
279 bool isUImm24()
const {
return isUImm<24>(); }
281 bool isOImm3()
const {
return isOImm<3>(); }
282 bool isOImm4()
const {
return isOImm<4>(); }
283 bool isOImm5()
const {
return isOImm<5>(); }
284 bool isOImm6()
const {
return isOImm<6>(); }
285 bool isOImm8()
const {
return isOImm<8>(); }
286 bool isOImm12()
const {
return isOImm<12>(); }
287 bool isOImm16()
const {
return isOImm<16>(); }
289 bool isSImm8()
const {
return isSImm<8>(); }
291 bool isUImm5Shift1() {
return isUImm<5, 1>(); }
292 bool isUImm5Shift2() {
return isUImm<5, 2>(); }
293 bool isUImm7Shift1() {
return isUImm<7, 1>(); }
294 bool isUImm7Shift2() {
return isUImm<7, 2>(); }
295 bool isUImm7Shift3() {
return isUImm<7, 3>(); }
296 bool isUImm8Shift2() {
return isUImm<8, 2>(); }
297 bool isUImm8Shift3() {
return isUImm<8, 3>(); }
298 bool isUImm8Shift8() {
return isUImm<8, 8>(); }
299 bool isUImm8Shift16() {
return isUImm<8, 16>(); }
300 bool isUImm8Shift24() {
return isUImm<8, 24>(); }
301 bool isUImm12Shift1() {
return isUImm<12, 1>(); }
302 bool isUImm12Shift2() {
return isUImm<12, 2>(); }
303 bool isUImm16Shift8() {
return isUImm<16, 8>(); }
304 bool isUImm16Shift16() {
return isUImm<16, 16>(); }
305 bool isUImm24Shift8() {
return isUImm<24, 8>(); }
307 bool isSImm16Shift1() {
return isSImm<16, 1>(); }
309 bool isCSKYSymbol()
const {
return isImm(); }
311 bool isConstpool()
const {
return isConstPoolOp(); }
312 bool isDataSymbol()
const {
return isConstPoolOp(); }
314 bool isPSRFlag()
const {
317 if (!isImm() || !evaluateConstantImm(
getImm(), Imm))
323 template <
unsigned MIN,
unsigned MAX>
bool isRegSeqTemplate()
const {
324 if (!isRegisterSeq())
327 std::pair<unsigned, unsigned> regSeq = getRegSeq();
329 return MIN <= regSeq.first && regSeq.first <= regSeq.second &&
330 regSeq.second <=
MAX;
333 bool isRegSeq()
const {
return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); }
335 bool isRegSeqV1()
const {
336 return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>();
339 bool isRegSeqV2()
const {
340 return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>();
343 static bool isLegalRegList(
unsigned from,
unsigned to) {
344 if (from == 0 && to == 0)
348 if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 &&
354 if (from != CSKY::R4 && from != CSKY::R16)
357 if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12)
359 else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18)
366 bool isRegList()
const {
367 if (!isRegisterList())
370 auto regList = getRegList();
372 if (!isLegalRegList(regList.List1From, regList.List1To))
374 if (!isLegalRegList(regList.List2From, regList.List2To))
376 if (!isLegalRegList(regList.List3From, regList.List3To))
378 if (!isLegalRegList(regList.List4From, regList.List4To))
389 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
393 int uimm4 =
Imm & 0xf;
399 SMLoc getStartLoc()
const override {
return StartLoc; }
401 SMLoc getEndLoc()
const override {
return EndLoc; }
403 MCRegister
getReg()
const override {
404 assert(Kind == Register &&
"Invalid type access!");
408 std::pair<MCRegister, MCRegister> getRegSeq()
const {
409 assert(Kind == RegisterSeq &&
"Invalid type access!");
410 return {RegSeq.RegNumFrom, RegSeq.RegNumTo};
413 RegListOp getRegList()
const {
414 assert(Kind == RegisterList &&
"Invalid type access!");
418 const MCExpr *
getImm()
const {
419 assert(Kind == Immediate &&
"Invalid type access!");
423 const MCExpr *getConstpoolOp()
const {
424 assert(Kind == CPOP &&
"Invalid type access!");
429 assert(Kind == Token &&
"Invalid type access!");
433 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
448 case KindTy::Register:
452 OS <<
"<register-seq ";
453 OS <<
RegName(getRegSeq().first) <<
"-" <<
RegName(getRegSeq().second)
457 OS <<
"<register-list ";
458 OS <<
RegName(getRegList().List1From) <<
"-"
459 <<
RegName(getRegList().List1To) <<
",";
460 OS <<
RegName(getRegList().List2From) <<
"-"
461 <<
RegName(getRegList().List2To) <<
",";
462 OS <<
RegName(getRegList().List3From) <<
"-"
463 <<
RegName(getRegList().List3To) <<
",";
464 OS <<
RegName(getRegList().List4From) <<
"-"
465 <<
RegName(getRegList().List4To);
473 static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) {
474 auto Op = std::make_unique<CSKYOperand>(Token);
481 static std::unique_ptr<CSKYOperand> createReg(MCRegister RegNo, SMLoc S,
483 auto Op = std::make_unique<CSKYOperand>(Register);
484 Op->Reg.RegNum = RegNo;
490 static std::unique_ptr<CSKYOperand>
491 createRegSeq(MCRegister RegNoFrom, MCRegister RegNoTo, SMLoc S) {
492 auto Op = std::make_unique<CSKYOperand>(RegisterSeq);
493 Op->RegSeq.RegNumFrom = RegNoFrom;
494 Op->RegSeq.RegNumTo = RegNoTo;
500 static std::unique_ptr<CSKYOperand>
502 auto Op = std::make_unique<CSKYOperand>(RegisterList);
503 Op->RegList.List1From = 0;
504 Op->RegList.List1To = 0;
505 Op->RegList.List2From = 0;
506 Op->RegList.List2To = 0;
507 Op->RegList.List3From = 0;
508 Op->RegList.List3To = 0;
509 Op->RegList.List4From = 0;
510 Op->RegList.List4To = 0;
512 for (
unsigned i = 0; i < reglist.
size(); i += 2) {
513 if (
Op->RegList.List1From == 0) {
514 Op->RegList.List1From = reglist[i];
515 Op->RegList.List1To = reglist[i + 1];
516 }
else if (
Op->RegList.List2From == 0) {
517 Op->RegList.List2From = reglist[i];
518 Op->RegList.List2To = reglist[i + 1];
519 }
else if (
Op->RegList.List3From == 0) {
520 Op->RegList.List3From = reglist[i];
521 Op->RegList.List3To = reglist[i + 1];
522 }
else if (
Op->RegList.List4From == 0) {
523 Op->RegList.List4From = reglist[i];
524 Op->RegList.List4To = reglist[i + 1];
535 static std::unique_ptr<CSKYOperand> createImm(
const MCExpr *Val, SMLoc S,
537 auto Op = std::make_unique<CSKYOperand>(Immediate);
544 static std::unique_ptr<CSKYOperand> createConstpoolOp(
const MCExpr *Val,
546 auto Op = std::make_unique<CSKYOperand>(CPOP);
553 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
554 assert(Expr &&
"Expr shouldn't be null!");
562 void addRegOperands(MCInst &Inst,
unsigned N)
const {
563 assert(
N == 1 &&
"Invalid number of operands!");
567 void addImmOperands(MCInst &Inst,
unsigned N)
const {
568 assert(
N == 1 &&
"Invalid number of operands!");
572 void addConstpoolOperands(MCInst &Inst,
unsigned N)
const {
573 assert(
N == 1 &&
"Invalid number of operands!");
577 void addRegSeqOperands(MCInst &Inst,
unsigned N)
const {
578 assert(
N == 2 &&
"Invalid number of operands!");
579 auto regSeq = getRegSeq();
585 static unsigned getListValue(
unsigned ListFrom,
unsigned ListTo) {
586 if (ListFrom == ListTo && ListFrom == CSKY::R15)
588 else if (ListFrom == ListTo && ListFrom == CSKY::R28)
590 else if (ListFrom == CSKY::R4)
591 return ListTo - ListFrom + 1;
592 else if (ListFrom == CSKY::R16)
593 return ((ListTo - ListFrom + 1) << 5);
598 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
599 assert(
N == 1 &&
"Invalid number of operands!");
600 auto regList = getRegList();
604 unsigned T = getListValue(regList.List1From, regList.List1To);
608 T = getListValue(regList.List2From, regList.List2To);
612 T = getListValue(regList.List3From, regList.List3To);
616 T = getListValue(regList.List4From, regList.List4To);
623 bool isValidForTie(
const CSKYOperand &
Other)
const {
624 if (Kind !=
Other.Kind)
632 return Reg.RegNum ==
Other.Reg.RegNum;
638#define GET_REGISTER_MATCHER
639#define GET_SUBTARGET_FEATURE_NAME
640#define GET_MATCHER_IMPLEMENTATION
641#define GET_MNEMONIC_SPELL_CHECKER
642#include "CSKYGenAsmMatcher.inc"
645 assert(
Reg >= CSKY::F0_32 &&
Reg <= CSKY::F31_32 &&
"Invalid register");
646 return Reg - CSKY::F0_32 + CSKY::F0_64;
650 unsigned VariantID = 0);
652bool CSKYAsmParser::generateImmOutOfRangeError(
654 const Twine &Msg =
"immediate must be an integer in the range") {
659bool CSKYAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
663 bool MatchingInlineAsm) {
665 FeatureBitset MissingFeatures;
667 auto Result = MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
673 return processInstruction(Inst, IDLoc,
Operands, Out);
674 case Match_MissingFeature: {
675 assert(MissingFeatures.
any() &&
"Unknown missing features!");
677 std::string Msg =
"instruction requires the following: ";
678 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
679 if (MissingFeatures[i]) {
684 return Error(IDLoc, Msg);
686 case Match_MnemonicFail: {
687 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
688 std::string Suggestion =
690 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
692 case Match_InvalidTiedOperand:
693 case Match_InvalidOperand: {
694 SMLoc ErrorLoc = IDLoc;
695 if (ErrorInfo != ~0U) {
697 return Error(ErrorLoc,
"too few operands for instruction");
699 ErrorLoc = ((CSKYOperand &)*
Operands[ErrorInfo]).getStartLoc();
700 if (ErrorLoc == SMLoc())
703 return Error(ErrorLoc,
"invalid operand for instruction");
710 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
711 SMLoc ErrorLoc = IDLoc;
712 if (ErrorInfo != ~0U && ErrorInfo >=
Operands.size())
713 return Error(ErrorLoc,
"too few operands for instruction");
719 case Match_InvalidSImm8:
720 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 7),
722 case Match_InvalidOImm3:
723 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 3));
724 case Match_InvalidOImm4:
725 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 4));
726 case Match_InvalidOImm5:
727 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 5));
728 case Match_InvalidOImm6:
729 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 6));
730 case Match_InvalidOImm8:
731 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 8));
732 case Match_InvalidOImm12:
733 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 12));
734 case Match_InvalidOImm16:
735 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 16));
736 case Match_InvalidUImm1:
737 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 1) - 1);
738 case Match_InvalidUImm2:
739 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 2) - 1);
740 case Match_InvalidUImm3:
741 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 3) - 1);
742 case Match_InvalidUImm4:
743 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 4) - 1);
744 case Match_InvalidUImm5:
745 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 5) - 1);
746 case Match_InvalidUImm6:
747 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 6) - 1);
748 case Match_InvalidUImm7:
749 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 7) - 1);
750 case Match_InvalidUImm8:
751 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 8) - 1);
752 case Match_InvalidUImm12:
753 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 12) - 1);
754 case Match_InvalidUImm16:
755 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 16) - 1);
756 case Match_InvalidUImm5Shift1:
757 return generateImmOutOfRangeError(
758 Operands, ErrorInfo, 0, (1 << 5) - 2,
759 "immediate must be a multiple of 2 bytes in the range");
760 case Match_InvalidUImm12Shift1:
761 return generateImmOutOfRangeError(
762 Operands, ErrorInfo, 0, (1 << 12) - 2,
763 "immediate must be a multiple of 2 bytes in the range");
764 case Match_InvalidUImm5Shift2:
765 return generateImmOutOfRangeError(
766 Operands, ErrorInfo, 0, (1 << 5) - 4,
767 "immediate must be a multiple of 4 bytes in the range");
768 case Match_InvalidUImm7Shift1:
769 return generateImmOutOfRangeError(
770 Operands, ErrorInfo, 0, (1 << 7) - 2,
771 "immediate must be a multiple of 2 bytes in the range");
772 case Match_InvalidUImm7Shift2:
773 return generateImmOutOfRangeError(
774 Operands, ErrorInfo, 0, (1 << 7) - 4,
775 "immediate must be a multiple of 4 bytes in the range");
776 case Match_InvalidUImm8Shift2:
777 return generateImmOutOfRangeError(
778 Operands, ErrorInfo, 0, (1 << 8) - 4,
779 "immediate must be a multiple of 4 bytes in the range");
780 case Match_InvalidUImm8Shift3:
781 return generateImmOutOfRangeError(
782 Operands, ErrorInfo, 0, (1 << 8) - 8,
783 "immediate must be a multiple of 8 bytes in the range");
784 case Match_InvalidUImm8Shift8:
785 return generateImmOutOfRangeError(
786 Operands, ErrorInfo, 0, (1 << 8) - 256,
787 "immediate must be a multiple of 256 bytes in the range");
788 case Match_InvalidUImm12Shift2:
789 return generateImmOutOfRangeError(
790 Operands, ErrorInfo, 0, (1 << 12) - 4,
791 "immediate must be a multiple of 4 bytes in the range");
792 case Match_InvalidCSKYSymbol: {
793 SMLoc ErrorLoc = ((CSKYOperand &)*
Operands[ErrorInfo]).getStartLoc();
794 return Error(ErrorLoc,
"operand must be a symbol name");
796 case Match_InvalidConstpool: {
797 SMLoc ErrorLoc = ((CSKYOperand &)*
Operands[ErrorInfo]).getStartLoc();
798 return Error(ErrorLoc,
"operand must be a constpool symbol name");
800 case Match_InvalidPSRFlag: {
801 SMLoc ErrorLoc = ((CSKYOperand &)*
Operands[ErrorInfo]).getStartLoc();
802 return Error(ErrorLoc,
"psrset operand is not valid");
804 case Match_InvalidRegSeq: {
805 SMLoc ErrorLoc = ((CSKYOperand &)*
Operands[ErrorInfo]).getStartLoc();
806 return Error(ErrorLoc,
"Register sequence is not valid");
808 case Match_InvalidRegOutOfRange: {
809 SMLoc ErrorLoc = ((CSKYOperand &)*
Operands[ErrorInfo]).getStartLoc();
810 return Error(ErrorLoc,
"register is out of range");
812 case Match_RequiresSameSrcAndDst: {
813 SMLoc ErrorLoc = ((CSKYOperand &)*
Operands[ErrorInfo]).getStartLoc();
814 return Error(ErrorLoc,
"src and dst operand must be same");
816 case Match_InvalidRegList: {
817 SMLoc ErrorLoc = ((CSKYOperand &)*
Operands[ErrorInfo]).getStartLoc();
818 return Error(ErrorLoc,
"invalid register list");
825bool CSKYAsmParser::processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
830 if (Inst.
getOpcode() == CSKY::PseudoLRW16)
831 Opcode = CSKY::LRW16;
833 Opcode = CSKY::LRW32;
838 Opcode = CSKY::MOVI16;
839 }
else if (getSTI().hasFeature(CSKY::HasE2) &&
841 Opcode = CSKY::MOVI32;
843 auto *Expr = getTargetStreamer().addConstantPoolEntry(
850 const MCExpr *AdjustExpr =
nullptr;
851 if (
const auto *CSKYExpr =
861 auto *Expr = getTargetStreamer().addConstantPoolEntry(
873bool CSKYAsmParser::processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
877 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
884 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
894bool CSKYAsmParser::processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
898 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
905 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
915bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
926 return Error(IDLoc,
"Register sequence is not valid. 'r4-r7' expected");
933 return Error(IDLoc,
"msb must be greater or equal to lsb");
937 return Error(IDLoc,
"msb must be greater or equal to lsb");
941 return Error(IDLoc,
"n must be in range [0,32]");
972 case CSKY::PseudoLRW16:
973 case CSKY::PseudoLRW32:
974 return processLRW(Inst, IDLoc, Out);
975 case CSKY::PseudoJSRI32:
976 return processJSRI(Inst, IDLoc, Out);
977 case CSKY::PseudoJMPI32:
978 return processJMPI(Inst, IDLoc, Out);
989 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
996 emitToStreamer(Out, Inst);
1007 if (
Reg == CSKY::NoRegister)
1010 return Reg == CSKY::NoRegister;
1013bool CSKYAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1015 const AsmToken &Tok = getParser().getTok();
1018 StringRef
Name = getLexer().getTok().getIdentifier();
1032 switch (getLexer().getKind()) {
1036 StringRef
Name = getLexer().getTok().getIdentifier();
1053 Operands.push_back(CSKYOperand::createToken(
"(", getLoc()));
1055 auto Tok = getParser().Lex();
1057 if (!parseRegister(
Operands).isSuccess()) {
1058 getLexer().UnLex(Tok);
1064 Operands.push_back(CSKYOperand::createToken(
")", getLoc()));
1070 return Error(getLoc(),
"expected ','");
1074 if (parseRegister(
Operands).isSuccess()) {
1076 return Error(getLoc(),
"expected '<<'");
1078 Operands.push_back(CSKYOperand::createToken(
"<<", getLoc()));
1083 return Error(getLoc(),
"expected imm");
1086 return Error(getLoc(),
"expected imm");
1090 return Error(getLoc(),
"expected ')'");
1092 Operands.push_back(CSKYOperand::createToken(
")", getLoc()));
1100 switch (getLexer().getKind()) {
1111 const MCExpr *IdVal;
1113 if (getParser().parseExpression(IdVal))
1114 return Error(getLoc(),
"unknown expression");
1117 Operands.push_back(CSKYOperand::createImm(IdVal, S,
E));
1128 MatchOperandParserImpl(
Operands, Mnemonic,
true);
1135 auto Res = parseRegister(
Operands);
1136 if (Res.isSuccess())
1138 if (Res.isFailure())
1144 if (Res.isSuccess())
1146 if (Res.isFailure())
1151 if (Res.isSuccess())
1153 if (Res.isFailure())
1157 Error(getLoc(),
"unknown operand");
1170 AsmToken Tok = getLexer().getTok();
1172 if (getParser().parseIdentifier(Identifier))
1173 return Error(getLoc(),
"unknown identifier");
1184 else if (
Identifier.consume_back(
"@TLSGD32"))
1186 else if (
Identifier.consume_back(
"@GOTTPOFF"))
1190 else if (
Identifier.consume_back(
"@TLSLDM32"))
1192 else if (
Identifier.consume_back(
"@TLSLDO32"))
1198 Sym =
getContext().getOrCreateSymbol(Identifier);
1203 getLexer().UnLex(Tok);
1204 return Error(getLoc(),
"unknown symbol");
1211 switch (getLexer().getKind()) {
1216 Operands.push_back(CSKYOperand::createImm(Res, S,
E));
1229 if (getParser().parseExpression(Expr))
1230 return Error(getLoc(),
"unknown expression");
1232 Operands.push_back(CSKYOperand::createImm(Res, S,
E));
1245 if (getParser().parseExpression(Expr))
1246 return Error(getLoc(),
"unknown expression");
1251 Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S,
E));
1255 AsmToken Tok = getLexer().getTok();
1258 if (getParser().parseIdentifier(Identifier))
1259 return Error(getLoc(),
"unknown identifier " + Identifier);
1270 Sym =
getContext().getOrCreateSymbol(Identifier);
1275 getLexer().UnLex(Tok);
1276 return Error(getLoc(),
"unknown symbol");
1284 switch (getLexer().getKind()) {
1286 return Error(getLoc(),
"unknown symbol");
1294 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1307 if (getParser().parseExpression(Expr))
1308 return Error(getLoc(),
"unknown expression");
1313 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1327 if (getParser().parseExpression(Expr))
1328 return Error(getLoc(),
"unknown expression");
1332 Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S,
E));
1336 AsmToken Tok = getLexer().getTok();
1339 if (getParser().parseIdentifier(Identifier))
1340 return Error(getLoc(),
"unknown identifier");
1345 Sym =
getContext().getOrCreateSymbol(Identifier);
1350 getLexer().UnLex(Tok);
1351 return Error(getLoc(),
"unknown symbol");
1359 switch (getLexer().getKind()) {
1361 return Error(getLoc(),
"unknown symbol");
1366 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1379 if (getParser().parseExpression(Expr))
1380 return Error(getLoc(),
"unknown expression");
1385 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1397 if (getParser().parseIdentifier(Identifier))
1398 return Error(getLoc(),
"unknown identifier " + Identifier);
1400 if (Identifier ==
"sie")
1401 Flag = (1 << 4) | Flag;
1402 else if (Identifier ==
"ee")
1403 Flag = (1 << 3) | Flag;
1404 else if (Identifier ==
"ie")
1405 Flag = (1 << 2) | Flag;
1406 else if (Identifier ==
"fe")
1407 Flag = (1 << 1) | Flag;
1408 else if (Identifier ==
"af")
1409 Flag = (1 << 0) | Flag;
1411 return Error(getLoc(),
"expected " + Identifier);
1428 if (!parseRegister(
Operands).isSuccess())
1431 auto Ry =
Operands.back()->getReg();
1436 if (!parseRegister(
Operands).isSuccess())
1437 return Error(getLoc(),
"invalid register");
1439 auto Rz =
Operands.back()->getReg();
1442 Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S));
1451 if (!parseRegister(
Operands).isSuccess())
1452 return Error(getLoc(),
"invalid register");
1454 auto Ry =
Operands.back()->getReg();
1458 if (!parseRegister(
Operands).isSuccess())
1459 return Error(getLoc(),
"invalid register");
1461 auto Rz =
Operands.back()->getReg();
1478 return Error(getLoc(),
"invalid register list");
1482 Operands.push_back(CSKYOperand::createRegList(reglist, S));
1486bool CSKYAsmParser::parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
1489 Operands.push_back(CSKYOperand::createToken(Name, NameLoc));
1505 SMLoc Loc = getLexer().getLoc();
1506 getParser().eatToEndOfStatement();
1507 return Error(Loc,
"unexpected token");
1514ParseStatus CSKYAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1516 const AsmToken &Tok = getParser().getTok();
1520 StringRef
Name = getLexer().getTok().getIdentifier();
1529ParseStatus CSKYAsmParser::parseDirective(AsmToken DirectiveID) {
1530 StringRef IDVal = DirectiveID.
getString();
1532 if (IDVal ==
".csky_attribute")
1533 return parseDirectiveAttribute();
1540bool CSKYAsmParser::parseDirectiveAttribute() {
1541 MCAsmParser &Parser = getParser();
1547 std::optional<unsigned>
Ret =
1550 return Error(TagLoc,
"attribute name not recognised: " + Name);
1554 const MCExpr *AttrExpr;
1562 return Error(TagLoc,
"expected numeric constant");
1564 Tag =
CE->getValue();
1570 StringRef StringValue;
1571 int64_t IntegerValue = 0;
1577 if (IsIntegerValue) {
1578 const MCExpr *ValueExpr;
1584 return Error(ValueExprLoc,
"expected numeric constant");
1585 IntegerValue =
CE->getValue();
1598 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
1600 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
1605 if (
ID == CSKY::ArchKind::INVALID)
1607 ?
"unknown arch name"
1608 :
"unknown cpu name");
1610 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
1616unsigned CSKYAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1618 CSKYOperand &
Op =
static_cast<CSKYOperand &
>(AsmOp);
1621 return Match_InvalidOperand;
1623 MCRegister
Reg =
Op.getReg();
1625 if (CSKYMCRegisterClasses[CSKY::FPR32RegClassID].
contains(
Reg)) {
1628 if (Kind == MCK_FPR64 || Kind == MCK_sFPR64) {
1630 if (Kind == MCK_sFPR64 &&
1631 (
Op.Reg.RegNum < CSKY::F0_64 ||
Op.Reg.RegNum > CSKY::F15_64))
1632 return Match_InvalidRegOutOfRange;
1633 if (Kind == MCK_FPR64 &&
1634 (
Op.Reg.RegNum < CSKY::F0_64 ||
Op.Reg.RegNum > CSKY::F31_64))
1635 return Match_InvalidRegOutOfRange;
1636 return Match_Success;
1640 if (CSKYMCRegisterClasses[CSKY::GPRRegClassID].
contains(
Reg)) {
1641 if (Kind == MCK_GPRPair) {
1642 Op.Reg.RegNum =
MRI->getEncodingValue(
Reg) + CSKY::R0_R1;
1643 return Match_Success;
1647 return Match_InvalidOperand;
1650void CSKYAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
1654 Res = compressInst(CInst, Inst, getSTI());
1656 ++CSKYNumInstrsCompressed;
unsigned const MachineRegisterInfo * MRI
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")
Analysis containing CSE Info
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)
static cl::opt< bool > EnableCompressedInst("enable-csky-asm-compressed-inst", cl::Hidden, cl::init(false), cl::desc("Enable C-SKY asm compressed instruction"))
#define LLVM_EXTERNAL_VISIBILITY
mir Rename Register Operands
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
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...
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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(MCRegister Reg)
Base class for user error types.
Container class for subtarget features.
constexpr size_t size() const
void printExpr(raw_ostream &, const MCExpr &) 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...
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.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol 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)
StringRef - 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.
LLVM_ABI const TagNameMap & getCSKYAttributeTags()
LLVM_ABI ArchKind parseCPUArch(StringRef CPU)
LLVM_ABI ArchKind parseArch(StringRef Arch)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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)
initializer< Ty > init(const Ty &Val)
Context & getContext() const
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,...