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"));
65 unsigned Kind)
override;
71 SMLoc getLoc()
const {
return getParser().getTok().getLoc(); }
73 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
76 bool MatchingInlineAsm)
override;
78 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
80 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
83 ParseStatus parseDirective(AsmToken DirectiveID)
override;
87 void emitToStreamer(MCStreamer &S,
const MCInst &Inst);
89 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
90 SMLoc &EndLoc)
override;
92 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
OperandVector &Operands,
94 bool processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
95 bool processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
96 bool processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
98 CSKYTargetStreamer &getTargetStreamer() {
99 assert(getParser().getStreamer().getTargetStreamer() &&
100 "do not have a target streamer");
101 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
102 return static_cast<CSKYTargetStreamer &
>(TS);
106#define GET_ASSEMBLER_HEADER
107#include "CSKYGenAsmMatcher.inc"
121 bool parseDirectiveAttribute();
124 enum CSKYMatchResultTy {
125 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
126 Match_RequiresSameSrcAndDst,
127 Match_InvalidRegOutOfRange,
128#define GET_OPERAND_DIAGNOSTIC_TYPES
129#include "CSKYGenAsmMatcher.inc"
130#undef GET_OPERAND_DIAGNOSTIC_TYPES
133 CSKYAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
134 const MCInstrInfo &MII)
135 : MCTargetAsmParser(STI, MII) {
142 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
144 getTargetStreamer().emitTargetAttributes(STI,
false);
173 MCRegister RegNumFrom;
178 MCRegister List1From;
180 MCRegister List2From;
182 MCRegister List3From;
184 MCRegister List4From;
188 SMLoc StartLoc, EndLoc;
198 CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(
K) {}
201 CSKYOperand(
const CSKYOperand &o) : MCParsedAsmOperand() {
203 StartLoc =
o.StartLoc;
227 bool isToken()
const override {
return Kind == Token; }
228 bool isReg()
const override {
return Kind == Register; }
229 bool isImm()
const override {
return Kind == Immediate; }
230 bool isRegisterSeq()
const {
return Kind == RegisterSeq; }
231 bool isRegisterList()
const {
return Kind == RegisterList; }
232 bool isConstPoolOp()
const {
return Kind == CPOP; }
234 bool isMem()
const override {
return false; }
236 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm) {
238 Imm =
CE->getValue();
245 template <
unsigned num,
unsigned shift = 0>
bool isUImm()
const {
250 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
254 template <
unsigned num>
bool isOImm()
const {
259 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
263 template <
unsigned num,
unsigned shift = 0>
bool isSImm()
const {
268 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
272 bool isUImm1()
const {
return isUImm<1>(); }
273 bool isUImm2()
const {
return isUImm<2>(); }
274 bool isUImm3()
const {
return isUImm<3>(); }
275 bool isUImm4()
const {
return isUImm<4>(); }
276 bool isUImm5()
const {
return isUImm<5>(); }
277 bool isUImm6()
const {
return isUImm<6>(); }
278 bool isUImm7()
const {
return isUImm<7>(); }
279 bool isUImm8()
const {
return isUImm<8>(); }
280 bool isUImm12()
const {
return isUImm<12>(); }
281 bool isUImm16()
const {
return isUImm<16>(); }
282 bool isUImm20()
const {
return isUImm<20>(); }
283 bool isUImm24()
const {
return isUImm<24>(); }
285 bool isOImm3()
const {
return isOImm<3>(); }
286 bool isOImm4()
const {
return isOImm<4>(); }
287 bool isOImm5()
const {
return isOImm<5>(); }
288 bool isOImm6()
const {
return isOImm<6>(); }
289 bool isOImm8()
const {
return isOImm<8>(); }
290 bool isOImm12()
const {
return isOImm<12>(); }
291 bool isOImm16()
const {
return isOImm<16>(); }
293 bool isSImm8()
const {
return isSImm<8>(); }
295 bool isUImm5Shift1() {
return isUImm<5, 1>(); }
296 bool isUImm5Shift2() {
return isUImm<5, 2>(); }
297 bool isUImm7Shift1() {
return isUImm<7, 1>(); }
298 bool isUImm7Shift2() {
return isUImm<7, 2>(); }
299 bool isUImm7Shift3() {
return isUImm<7, 3>(); }
300 bool isUImm8Shift2() {
return isUImm<8, 2>(); }
301 bool isUImm8Shift3() {
return isUImm<8, 3>(); }
302 bool isUImm8Shift8() {
return isUImm<8, 8>(); }
303 bool isUImm8Shift16() {
return isUImm<8, 16>(); }
304 bool isUImm8Shift24() {
return isUImm<8, 24>(); }
305 bool isUImm12Shift1() {
return isUImm<12, 1>(); }
306 bool isUImm12Shift2() {
return isUImm<12, 2>(); }
307 bool isUImm16Shift8() {
return isUImm<16, 8>(); }
308 bool isUImm16Shift16() {
return isUImm<16, 16>(); }
309 bool isUImm24Shift8() {
return isUImm<24, 8>(); }
311 bool isSImm16Shift1() {
return isSImm<16, 1>(); }
313 bool isCSKYSymbol()
const {
return isImm(); }
315 bool isConstpool()
const {
return isConstPoolOp(); }
316 bool isDataSymbol()
const {
return isConstPoolOp(); }
318 bool isPSRFlag()
const {
321 if (!isImm() || !evaluateConstantImm(
getImm(), Imm))
327 template <
unsigned MIN,
unsigned MAX>
bool isRegSeqTemplate()
const {
328 if (!isRegisterSeq())
331 std::pair<unsigned, unsigned> regSeq = getRegSeq();
333 return MIN <= regSeq.first && regSeq.first <= regSeq.second &&
334 regSeq.second <=
MAX;
337 bool isRegSeq()
const {
return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); }
339 bool isRegSeqV1()
const {
340 return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>();
343 bool isRegSeqV2()
const {
344 return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>();
347 static bool isLegalRegList(
unsigned from,
unsigned to) {
348 if (from == 0 && to == 0)
352 if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 &&
358 if (from != CSKY::R4 && from != CSKY::R16)
361 if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12)
363 else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18)
370 bool isRegList()
const {
371 if (!isRegisterList())
374 auto regList = getRegList();
376 if (!isLegalRegList(regList.List1From, regList.List1To))
378 if (!isLegalRegList(regList.List2From, regList.List2To))
380 if (!isLegalRegList(regList.List3From, regList.List3To))
382 if (!isLegalRegList(regList.List4From, regList.List4To))
393 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
397 int uimm4 =
Imm & 0xf;
403 SMLoc getStartLoc()
const override {
return StartLoc; }
405 SMLoc getEndLoc()
const override {
return EndLoc; }
407 MCRegister
getReg()
const override {
408 assert(Kind == Register &&
"Invalid type access!");
412 std::pair<MCRegister, MCRegister> getRegSeq()
const {
413 assert(Kind == RegisterSeq &&
"Invalid type access!");
414 return {RegSeq.RegNumFrom, RegSeq.RegNumTo};
417 RegListOp getRegList()
const {
418 assert(Kind == RegisterList &&
"Invalid type access!");
422 const MCExpr *
getImm()
const {
423 assert(Kind == Immediate &&
"Invalid type access!");
427 const MCExpr *getConstpoolOp()
const {
428 assert(Kind == CPOP &&
"Invalid type access!");
433 assert(Kind == Token &&
"Invalid type access!");
437 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
452 case KindTy::Register:
456 OS <<
"<register-seq ";
457 OS <<
RegName(getRegSeq().first) <<
"-" <<
RegName(getRegSeq().second)
461 OS <<
"<register-list ";
462 OS <<
RegName(getRegList().List1From) <<
"-"
463 <<
RegName(getRegList().List1To) <<
",";
464 OS <<
RegName(getRegList().List2From) <<
"-"
465 <<
RegName(getRegList().List2To) <<
",";
466 OS <<
RegName(getRegList().List3From) <<
"-"
467 <<
RegName(getRegList().List3To) <<
",";
468 OS <<
RegName(getRegList().List4From) <<
"-"
469 <<
RegName(getRegList().List4To);
477 static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) {
478 auto Op = std::make_unique<CSKYOperand>(Token);
485 static std::unique_ptr<CSKYOperand> createReg(MCRegister RegNo, SMLoc S,
487 auto Op = std::make_unique<CSKYOperand>(Register);
488 Op->Reg.RegNum = RegNo;
494 static std::unique_ptr<CSKYOperand>
495 createRegSeq(MCRegister RegNoFrom, MCRegister RegNoTo, SMLoc S) {
496 auto Op = std::make_unique<CSKYOperand>(RegisterSeq);
497 Op->RegSeq.RegNumFrom = RegNoFrom;
498 Op->RegSeq.RegNumTo = RegNoTo;
504 static std::unique_ptr<CSKYOperand>
506 auto Op = std::make_unique<CSKYOperand>(RegisterList);
507 Op->RegList.List1From = 0;
508 Op->RegList.List1To = 0;
509 Op->RegList.List2From = 0;
510 Op->RegList.List2To = 0;
511 Op->RegList.List3From = 0;
512 Op->RegList.List3To = 0;
513 Op->RegList.List4From = 0;
514 Op->RegList.List4To = 0;
516 for (
unsigned i = 0; i < reglist.
size(); i += 2) {
517 if (
Op->RegList.List1From == 0) {
518 Op->RegList.List1From = reglist[i];
519 Op->RegList.List1To = reglist[i + 1];
520 }
else if (
Op->RegList.List2From == 0) {
521 Op->RegList.List2From = reglist[i];
522 Op->RegList.List2To = reglist[i + 1];
523 }
else if (
Op->RegList.List3From == 0) {
524 Op->RegList.List3From = reglist[i];
525 Op->RegList.List3To = reglist[i + 1];
526 }
else if (
Op->RegList.List4From == 0) {
527 Op->RegList.List4From = reglist[i];
528 Op->RegList.List4To = reglist[i + 1];
539 static std::unique_ptr<CSKYOperand> createImm(
const MCExpr *Val, SMLoc S,
541 auto Op = std::make_unique<CSKYOperand>(Immediate);
548 static std::unique_ptr<CSKYOperand> createConstpoolOp(
const MCExpr *Val,
550 auto Op = std::make_unique<CSKYOperand>(CPOP);
557 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
558 assert(Expr &&
"Expr shouldn't be null!");
566 void addRegOperands(MCInst &Inst,
unsigned N)
const {
567 assert(
N == 1 &&
"Invalid number of operands!");
571 void addImmOperands(MCInst &Inst,
unsigned N)
const {
572 assert(
N == 1 &&
"Invalid number of operands!");
576 void addConstpoolOperands(MCInst &Inst,
unsigned N)
const {
577 assert(
N == 1 &&
"Invalid number of operands!");
581 void addRegSeqOperands(MCInst &Inst,
unsigned N)
const {
582 assert(
N == 2 &&
"Invalid number of operands!");
583 auto regSeq = getRegSeq();
589 static unsigned getListValue(
unsigned ListFrom,
unsigned ListTo) {
590 if (ListFrom == ListTo && ListFrom == CSKY::R15)
592 else if (ListFrom == ListTo && ListFrom == CSKY::R28)
594 else if (ListFrom == CSKY::R4)
595 return ListTo - ListFrom + 1;
596 else if (ListFrom == CSKY::R16)
597 return ((ListTo - ListFrom + 1) << 5);
602 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
603 assert(
N == 1 &&
"Invalid number of operands!");
604 auto regList = getRegList();
608 unsigned T = getListValue(regList.List1From, regList.List1To);
612 T = getListValue(regList.List2From, regList.List2To);
616 T = getListValue(regList.List3From, regList.List3To);
620 T = getListValue(regList.List4From, regList.List4To);
627 bool isValidForTie(
const CSKYOperand &
Other)
const {
628 if (Kind !=
Other.Kind)
636 return Reg.RegNum ==
Other.Reg.RegNum;
642#define GET_REGISTER_MATCHER
643#define GET_SUBTARGET_FEATURE_NAME
644#define GET_MATCHER_IMPLEMENTATION
645#define GET_MNEMONIC_SPELL_CHECKER
646#include "CSKYGenAsmMatcher.inc"
649 assert(
Reg >= CSKY::F0_32 &&
Reg <= CSKY::F31_32 &&
"Invalid register");
650 return Reg - CSKY::F0_32 + CSKY::F0_64;
654 unsigned VariantID = 0);
656bool CSKYAsmParser::generateImmOutOfRangeError(
658 const Twine &
Msg =
"immediate must be an integer in the range") {
659 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[
ErrorInfo]).getStartLoc();
663bool CSKYAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
667 bool MatchingInlineAsm) {
669 FeatureBitset MissingFeatures;
671 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
677 return processInstruction(Inst, IDLoc, Operands, Out);
678 case Match_MissingFeature: {
679 assert(MissingFeatures.
any() &&
"Unknown missing features!");
681 std::string
Msg =
"instruction requires the following: ";
682 for (
unsigned Feature : MissingFeatures) {
688 case Match_MnemonicFail: {
689 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
690 std::string Suggestion =
692 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
694 case Match_InvalidTiedOperand:
695 case Match_InvalidOperand: {
696 SMLoc ErrorLoc = IDLoc;
697 if (ErrorInfo != ~0U) {
698 if (ErrorInfo >= Operands.
size())
699 return Error(ErrorLoc,
"too few operands for instruction");
701 ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
702 if (ErrorLoc == SMLoc())
705 return Error(ErrorLoc,
"invalid operand for instruction");
712 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
713 SMLoc ErrorLoc = IDLoc;
714 if (ErrorInfo != ~0U && ErrorInfo >= Operands.
size())
715 return Error(ErrorLoc,
"too few operands for instruction");
721 case Match_InvalidSImm8:
722 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
724 case Match_InvalidOImm3:
725 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3));
726 case Match_InvalidOImm4:
727 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
728 case Match_InvalidOImm5:
729 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
730 case Match_InvalidOImm6:
731 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
732 case Match_InvalidOImm8:
733 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8));
734 case Match_InvalidOImm12:
735 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12));
736 case Match_InvalidOImm16:
737 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16));
738 case Match_InvalidUImm1:
739 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
740 case Match_InvalidUImm2:
741 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
742 case Match_InvalidUImm3:
743 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
744 case Match_InvalidUImm4:
745 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
746 case Match_InvalidUImm5:
747 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
748 case Match_InvalidUImm6:
749 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
750 case Match_InvalidUImm7:
751 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
752 case Match_InvalidUImm8:
753 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
754 case Match_InvalidUImm12:
755 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);
756 case Match_InvalidUImm16:
757 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1);
758 case Match_InvalidUImm5Shift1:
759 return generateImmOutOfRangeError(
760 Operands, ErrorInfo, 0, (1 << 5) - 2,
761 "immediate must be a multiple of 2 bytes in the range");
762 case Match_InvalidUImm12Shift1:
763 return generateImmOutOfRangeError(
764 Operands, ErrorInfo, 0, (1 << 12) - 2,
765 "immediate must be a multiple of 2 bytes in the range");
766 case Match_InvalidUImm5Shift2:
767 return generateImmOutOfRangeError(
768 Operands, ErrorInfo, 0, (1 << 5) - 4,
769 "immediate must be a multiple of 4 bytes in the range");
770 case Match_InvalidUImm7Shift1:
771 return generateImmOutOfRangeError(
772 Operands, ErrorInfo, 0, (1 << 7) - 2,
773 "immediate must be a multiple of 2 bytes in the range");
774 case Match_InvalidUImm7Shift2:
775 return generateImmOutOfRangeError(
776 Operands, ErrorInfo, 0, (1 << 7) - 4,
777 "immediate must be a multiple of 4 bytes in the range");
778 case Match_InvalidUImm8Shift2:
779 return generateImmOutOfRangeError(
780 Operands, ErrorInfo, 0, (1 << 8) - 4,
781 "immediate must be a multiple of 4 bytes in the range");
782 case Match_InvalidUImm8Shift3:
783 return generateImmOutOfRangeError(
784 Operands, ErrorInfo, 0, (1 << 8) - 8,
785 "immediate must be a multiple of 8 bytes in the range");
786 case Match_InvalidUImm8Shift8:
787 return generateImmOutOfRangeError(
788 Operands, ErrorInfo, 0, (1 << 8) - 256,
789 "immediate must be a multiple of 256 bytes in the range");
790 case Match_InvalidUImm12Shift2:
791 return generateImmOutOfRangeError(
792 Operands, ErrorInfo, 0, (1 << 12) - 4,
793 "immediate must be a multiple of 4 bytes in the range");
794 case Match_InvalidCSKYSymbol: {
795 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
796 return Error(ErrorLoc,
"operand must be a symbol name");
798 case Match_InvalidConstpool: {
799 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
800 return Error(ErrorLoc,
"operand must be a constpool symbol name");
802 case Match_InvalidPSRFlag: {
803 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
804 return Error(ErrorLoc,
"psrset operand is not valid");
806 case Match_InvalidRegSeq: {
807 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
808 return Error(ErrorLoc,
"Register sequence is not valid");
810 case Match_InvalidRegOutOfRange: {
811 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
812 return Error(ErrorLoc,
"register is out of range");
814 case Match_RequiresSameSrcAndDst: {
815 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
816 return Error(ErrorLoc,
"src and dst operand must be same");
818 case Match_InvalidRegList: {
819 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
820 return Error(ErrorLoc,
"invalid register list");
827bool CSKYAsmParser::processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
832 if (Inst.
getOpcode() == CSKY::PseudoLRW16)
833 Opcode = CSKY::LRW16;
835 Opcode = CSKY::LRW32;
840 Opcode = CSKY::MOVI16;
841 }
else if (getSTI().
hasFeature(CSKY::HasE2) &&
843 Opcode = CSKY::MOVI32;
845 auto *Expr = getTargetStreamer().addConstantPoolEntry(
852 const MCExpr *AdjustExpr =
nullptr;
853 if (
const auto *CSKYExpr =
863 auto *Expr = getTargetStreamer().addConstantPoolEntry(
875bool CSKYAsmParser::processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
879 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
886 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
896bool CSKYAsmParser::processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
900 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
907 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
917bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
928 return Error(IDLoc,
"Register sequence is not valid. 'r4-r7' expected");
935 return Error(IDLoc,
"msb must be greater or equal to lsb");
939 return Error(IDLoc,
"msb must be greater or equal to lsb");
943 return Error(IDLoc,
"n must be in range [0,32]");
974 case CSKY::PseudoLRW16:
975 case CSKY::PseudoLRW32:
976 return processLRW(Inst, IDLoc, Out);
977 case CSKY::PseudoJSRI32:
978 return processJSRI(Inst, IDLoc, Out);
979 case CSKY::PseudoJMPI32:
980 return processJMPI(Inst, IDLoc, Out);
991 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
998 emitToStreamer(Out, Inst);
1009 if (
Reg == CSKY::NoRegister)
1012 return Reg == CSKY::NoRegister;
1015bool CSKYAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1017 const AsmToken &Tok = getParser().getTok();
1020 StringRef
Name = getLexer().getTok().getIdentifier();
1030ParseStatus CSKYAsmParser::parseRegister(
OperandVector &Operands) {
1034 switch (getLexer().getKind()) {
1038 StringRef
Name = getLexer().getTok().getIdentifier();
1052ParseStatus CSKYAsmParser::parseBaseRegImm(
OperandVector &Operands) {
1055 Operands.
push_back(CSKYOperand::createToken(
"(", getLoc()));
1057 auto Tok = getParser().Lex();
1059 if (!parseRegister(Operands).isSuccess()) {
1060 getLexer().UnLex(Tok);
1066 Operands.
push_back(CSKYOperand::createToken(
")", getLoc()));
1072 return Error(getLoc(),
"expected ','");
1076 if (parseRegister(Operands).isSuccess()) {
1078 return Error(getLoc(),
"expected '<<'");
1080 Operands.
push_back(CSKYOperand::createToken(
"<<", getLoc()));
1085 return Error(getLoc(),
"expected imm");
1088 return Error(getLoc(),
"expected imm");
1092 return Error(getLoc(),
"expected ')'");
1094 Operands.
push_back(CSKYOperand::createToken(
")", getLoc()));
1101ParseStatus CSKYAsmParser::parseImmediate(
OperandVector &Operands) {
1102 switch (getLexer().getKind()) {
1113 const MCExpr *IdVal;
1115 if (getParser().parseExpression(IdVal))
1116 return Error(getLoc(),
"unknown expression");
1119 Operands.
push_back(CSKYOperand::createImm(IdVal, S,
E));
1126bool CSKYAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
1130 MatchOperandParserImpl(Operands, Mnemonic,
true);
1137 auto Res = parseRegister(Operands);
1138 if (Res.isSuccess())
1140 if (Res.isFailure())
1145 Res = parseBaseRegImm(Operands);
1146 if (Res.isSuccess())
1148 if (Res.isFailure())
1153 if (Res.isSuccess())
1155 if (Res.isFailure())
1159 Error(getLoc(),
"unknown operand");
1163ParseStatus CSKYAsmParser::parseCSKYSymbol(
OperandVector &Operands) {
1172 AsmToken Tok = getLexer().getTok();
1174 if (getParser().parseIdentifier(Identifier))
1175 return Error(getLoc(),
"unknown identifier");
1186 else if (
Identifier.consume_back(
"@TLSGD32"))
1188 else if (
Identifier.consume_back(
"@GOTTPOFF"))
1192 else if (
Identifier.consume_back(
"@TLSLDM32"))
1194 else if (
Identifier.consume_back(
"@TLSLDO32"))
1200 Sym =
getContext().getOrCreateSymbol(Identifier);
1205 getLexer().UnLex(Tok);
1206 return Error(getLoc(),
"unknown symbol");
1213 switch (getLexer().getKind()) {
1218 Operands.
push_back(CSKYOperand::createImm(Res, S,
E));
1231 if (getParser().parseExpression(Expr))
1232 return Error(getLoc(),
"unknown expression");
1234 Operands.
push_back(CSKYOperand::createImm(Res, S,
E));
1238ParseStatus CSKYAsmParser::parseDataSymbol(
OperandVector &Operands) {
1247 if (getParser().parseExpression(Expr))
1248 return Error(getLoc(),
"unknown expression");
1253 Operands.
push_back(CSKYOperand::createConstpoolOp(Expr, S,
E));
1257 AsmToken Tok = getLexer().getTok();
1260 if (getParser().parseIdentifier(Identifier))
1261 return Error(getLoc(),
"unknown identifier " + Identifier);
1272 Sym =
getContext().getOrCreateSymbol(Identifier);
1277 getLexer().UnLex(Tok);
1278 return Error(getLoc(),
"unknown symbol");
1286 switch (getLexer().getKind()) {
1288 return Error(getLoc(),
"unknown symbol");
1296 Operands.
push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1309 if (getParser().parseExpression(Expr))
1310 return Error(getLoc(),
"unknown expression");
1315 Operands.
push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1319ParseStatus CSKYAsmParser::parseConstpoolSymbol(
OperandVector &Operands) {
1329 if (getParser().parseExpression(Expr))
1330 return Error(getLoc(),
"unknown expression");
1334 Operands.
push_back(CSKYOperand::createConstpoolOp(Expr, S,
E));
1338 AsmToken Tok = getLexer().getTok();
1341 if (getParser().parseIdentifier(Identifier))
1342 return Error(getLoc(),
"unknown identifier");
1347 Sym =
getContext().getOrCreateSymbol(Identifier);
1352 getLexer().UnLex(Tok);
1353 return Error(getLoc(),
"unknown symbol");
1361 switch (getLexer().getKind()) {
1363 return Error(getLoc(),
"unknown symbol");
1368 Operands.
push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1381 if (getParser().parseExpression(Expr))
1382 return Error(getLoc(),
"unknown expression");
1387 Operands.
push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1391ParseStatus CSKYAsmParser::parsePSRFlag(
OperandVector &Operands) {
1399 if (getParser().parseIdentifier(Identifier))
1400 return Error(getLoc(),
"unknown identifier " + Identifier);
1402 if (Identifier ==
"sie")
1403 Flag = (1 << 4) | Flag;
1404 else if (Identifier ==
"ee")
1405 Flag = (1 << 3) | Flag;
1406 else if (Identifier ==
"ie")
1407 Flag = (1 << 2) | Flag;
1408 else if (Identifier ==
"fe")
1409 Flag = (1 << 1) | Flag;
1410 else if (Identifier ==
"af")
1411 Flag = (1 << 0) | Flag;
1413 return Error(getLoc(),
"expected " + Identifier);
1427ParseStatus CSKYAsmParser::parseRegSeq(
OperandVector &Operands) {
1430 if (!parseRegister(Operands).isSuccess())
1433 auto Ry = Operands.
back()->getReg();
1438 if (!parseRegister(Operands).isSuccess())
1439 return Error(getLoc(),
"invalid register");
1441 auto Rz = Operands.
back()->getReg();
1444 Operands.
push_back(CSKYOperand::createRegSeq(Ry, Rz, S));
1448ParseStatus CSKYAsmParser::parseRegList(
OperandVector &Operands) {
1453 if (!parseRegister(Operands).isSuccess())
1454 return Error(getLoc(),
"invalid register");
1456 auto Ry = Operands.
back()->getReg();
1460 if (!parseRegister(Operands).isSuccess())
1461 return Error(getLoc(),
"invalid register");
1463 auto Rz = Operands.
back()->getReg();
1480 return Error(getLoc(),
"invalid register list");
1484 Operands.
push_back(CSKYOperand::createRegList(reglist, S));
1488bool CSKYAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1491 Operands.
push_back(CSKYOperand::createToken(Name, NameLoc));
1498 if (parseOperand(Operands, Name))
1503 if (parseOperand(Operands, Name))
1507 SMLoc Loc = getLexer().getLoc();
1508 getParser().eatToEndOfStatement();
1509 return Error(Loc,
"unexpected token");
1516ParseStatus CSKYAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1518 const AsmToken &Tok = getParser().getTok();
1522 StringRef
Name = getLexer().getTok().getIdentifier();
1531ParseStatus CSKYAsmParser::parseDirective(AsmToken DirectiveID) {
1532 StringRef IDVal = DirectiveID.
getString();
1534 if (IDVal ==
".csky_attribute")
1535 return parseDirectiveAttribute();
1542bool CSKYAsmParser::parseDirectiveAttribute() {
1543 MCAsmParser &Parser = getParser();
1549 std::optional<unsigned> Ret =
1552 return Error(TagLoc,
"attribute name not recognised: " + Name);
1556 const MCExpr *AttrExpr;
1564 return Error(TagLoc,
"expected numeric constant");
1566 Tag =
CE->getValue();
1572 StringRef StringValue;
1573 int64_t IntegerValue = 0;
1579 if (IsIntegerValue) {
1580 const MCExpr *ValueExpr;
1586 return Error(ValueExprLoc,
"expected numeric constant");
1587 IntegerValue =
CE->getValue();
1600 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
1602 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
1607 if (ID == CSKY::ArchKind::INVALID)
1609 ?
"unknown arch name"
1610 :
"unknown cpu name");
1612 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
1618unsigned CSKYAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1620 CSKYOperand &
Op =
static_cast<CSKYOperand &
>(AsmOp);
1623 return Match_InvalidOperand;
1625 MCRegister
Reg =
Op.getReg();
1627 if (getCSKYMCRegisterClass(CSKY::FPR32RegClassID).
contains(
Reg)) {
1630 if (Kind == MCK_FPR64 || Kind == MCK_sFPR64) {
1632 if (Kind == MCK_sFPR64 &&
1633 (
Op.Reg.RegNum < CSKY::F0_64 ||
Op.Reg.RegNum > CSKY::F15_64))
1634 return Match_InvalidRegOutOfRange;
1635 if (Kind == MCK_FPR64 &&
1636 (
Op.Reg.RegNum < CSKY::F0_64 ||
Op.Reg.RegNum > CSKY::F31_64))
1637 return Match_InvalidRegOutOfRange;
1638 return Match_Success;
1642 if (getCSKYMCRegisterClass(CSKY::GPRRegClassID).
contains(
Reg)) {
1643 if (Kind == MCK_GPRPair) {
1645 return Match_Success;
1649 return Match_InvalidOperand;
1652void CSKYAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
1656 Res = compressInst(CInst, Inst, getSTI());
1658 ++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)
static cl::opt< bool > AddBuildAttributes("csky-add-build-attributes", cl::init(true))
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
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(MCRegister Reg)
Base class for user error types.
Container class for subtarget features.
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...
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.
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)
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)
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)
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,...