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;
89 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
OperandVector &Operands,
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)
132 : MCTargetAsmParser(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") {
655 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[
ErrorInfo]).getStartLoc();
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 Feature : MissingFeatures) {
682 return Error(IDLoc, Msg);
684 case Match_MnemonicFail: {
685 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
686 std::string Suggestion =
688 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
690 case Match_InvalidTiedOperand:
691 case Match_InvalidOperand: {
692 SMLoc ErrorLoc = IDLoc;
693 if (ErrorInfo != ~0U) {
694 if (ErrorInfo >= Operands.
size())
695 return Error(ErrorLoc,
"too few operands for instruction");
697 ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
698 if (ErrorLoc == SMLoc())
701 return Error(ErrorLoc,
"invalid operand for instruction");
708 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
709 SMLoc ErrorLoc = IDLoc;
710 if (ErrorInfo != ~0U && ErrorInfo >= Operands.
size())
711 return Error(ErrorLoc,
"too few operands for instruction");
717 case Match_InvalidSImm8:
718 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
720 case Match_InvalidOImm3:
721 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3));
722 case Match_InvalidOImm4:
723 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
724 case Match_InvalidOImm5:
725 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
726 case Match_InvalidOImm6:
727 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
728 case Match_InvalidOImm8:
729 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8));
730 case Match_InvalidOImm12:
731 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12));
732 case Match_InvalidOImm16:
733 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16));
734 case Match_InvalidUImm1:
735 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
736 case Match_InvalidUImm2:
737 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
738 case Match_InvalidUImm3:
739 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
740 case Match_InvalidUImm4:
741 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
742 case Match_InvalidUImm5:
743 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
744 case Match_InvalidUImm6:
745 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
746 case Match_InvalidUImm7:
747 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
748 case Match_InvalidUImm8:
749 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
750 case Match_InvalidUImm12:
751 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);
752 case Match_InvalidUImm16:
753 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1);
754 case Match_InvalidUImm5Shift1:
755 return generateImmOutOfRangeError(
756 Operands, ErrorInfo, 0, (1 << 5) - 2,
757 "immediate must be a multiple of 2 bytes in the range");
758 case Match_InvalidUImm12Shift1:
759 return generateImmOutOfRangeError(
760 Operands, ErrorInfo, 0, (1 << 12) - 2,
761 "immediate must be a multiple of 2 bytes in the range");
762 case Match_InvalidUImm5Shift2:
763 return generateImmOutOfRangeError(
764 Operands, ErrorInfo, 0, (1 << 5) - 4,
765 "immediate must be a multiple of 4 bytes in the range");
766 case Match_InvalidUImm7Shift1:
767 return generateImmOutOfRangeError(
768 Operands, ErrorInfo, 0, (1 << 7) - 2,
769 "immediate must be a multiple of 2 bytes in the range");
770 case Match_InvalidUImm7Shift2:
771 return generateImmOutOfRangeError(
772 Operands, ErrorInfo, 0, (1 << 7) - 4,
773 "immediate must be a multiple of 4 bytes in the range");
774 case Match_InvalidUImm8Shift2:
775 return generateImmOutOfRangeError(
776 Operands, ErrorInfo, 0, (1 << 8) - 4,
777 "immediate must be a multiple of 4 bytes in the range");
778 case Match_InvalidUImm8Shift3:
779 return generateImmOutOfRangeError(
780 Operands, ErrorInfo, 0, (1 << 8) - 8,
781 "immediate must be a multiple of 8 bytes in the range");
782 case Match_InvalidUImm8Shift8:
783 return generateImmOutOfRangeError(
784 Operands, ErrorInfo, 0, (1 << 8) - 256,
785 "immediate must be a multiple of 256 bytes in the range");
786 case Match_InvalidUImm12Shift2:
787 return generateImmOutOfRangeError(
788 Operands, ErrorInfo, 0, (1 << 12) - 4,
789 "immediate must be a multiple of 4 bytes in the range");
790 case Match_InvalidCSKYSymbol: {
791 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
792 return Error(ErrorLoc,
"operand must be a symbol name");
794 case Match_InvalidConstpool: {
795 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
796 return Error(ErrorLoc,
"operand must be a constpool symbol name");
798 case Match_InvalidPSRFlag: {
799 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
800 return Error(ErrorLoc,
"psrset operand is not valid");
802 case Match_InvalidRegSeq: {
803 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
804 return Error(ErrorLoc,
"Register sequence is not valid");
806 case Match_InvalidRegOutOfRange: {
807 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
808 return Error(ErrorLoc,
"register is out of range");
810 case Match_RequiresSameSrcAndDst: {
811 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
812 return Error(ErrorLoc,
"src and dst operand must be same");
814 case Match_InvalidRegList: {
815 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
816 return Error(ErrorLoc,
"invalid register list");
823bool CSKYAsmParser::processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
828 if (Inst.
getOpcode() == CSKY::PseudoLRW16)
829 Opcode = CSKY::LRW16;
831 Opcode = CSKY::LRW32;
836 Opcode = CSKY::MOVI16;
837 }
else if (getSTI().
hasFeature(CSKY::HasE2) &&
839 Opcode = CSKY::MOVI32;
841 auto *Expr = getTargetStreamer().addConstantPoolEntry(
848 const MCExpr *AdjustExpr =
nullptr;
849 if (
const auto *CSKYExpr =
859 auto *Expr = getTargetStreamer().addConstantPoolEntry(
871bool CSKYAsmParser::processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
875 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
882 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
892bool CSKYAsmParser::processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
896 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
903 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
913bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
924 return Error(IDLoc,
"Register sequence is not valid. 'r4-r7' expected");
931 return Error(IDLoc,
"msb must be greater or equal to lsb");
935 return Error(IDLoc,
"msb must be greater or equal to lsb");
939 return Error(IDLoc,
"n must be in range [0,32]");
970 case CSKY::PseudoLRW16:
971 case CSKY::PseudoLRW32:
972 return processLRW(Inst, IDLoc, Out);
973 case CSKY::PseudoJSRI32:
974 return processJSRI(Inst, IDLoc, Out);
975 case CSKY::PseudoJMPI32:
976 return processJMPI(Inst, IDLoc, Out);
987 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
994 emitToStreamer(Out, Inst);
1005 if (
Reg == CSKY::NoRegister)
1008 return Reg == CSKY::NoRegister;
1011bool CSKYAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1013 const AsmToken &Tok = getParser().getTok();
1016 StringRef
Name = getLexer().getTok().getIdentifier();
1026ParseStatus CSKYAsmParser::parseRegister(
OperandVector &Operands) {
1030 switch (getLexer().getKind()) {
1034 StringRef
Name = getLexer().getTok().getIdentifier();
1048ParseStatus CSKYAsmParser::parseBaseRegImm(
OperandVector &Operands) {
1051 Operands.
push_back(CSKYOperand::createToken(
"(", getLoc()));
1053 auto Tok = getParser().Lex();
1055 if (!parseRegister(Operands).isSuccess()) {
1056 getLexer().UnLex(Tok);
1062 Operands.
push_back(CSKYOperand::createToken(
")", getLoc()));
1068 return Error(getLoc(),
"expected ','");
1072 if (parseRegister(Operands).isSuccess()) {
1074 return Error(getLoc(),
"expected '<<'");
1076 Operands.
push_back(CSKYOperand::createToken(
"<<", getLoc()));
1081 return Error(getLoc(),
"expected imm");
1084 return Error(getLoc(),
"expected imm");
1088 return Error(getLoc(),
"expected ')'");
1090 Operands.
push_back(CSKYOperand::createToken(
")", getLoc()));
1097ParseStatus CSKYAsmParser::parseImmediate(
OperandVector &Operands) {
1098 switch (getLexer().getKind()) {
1109 const MCExpr *IdVal;
1111 if (getParser().parseExpression(IdVal))
1112 return Error(getLoc(),
"unknown expression");
1115 Operands.
push_back(CSKYOperand::createImm(IdVal, S,
E));
1122bool CSKYAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
1126 MatchOperandParserImpl(Operands, Mnemonic,
true);
1133 auto Res = parseRegister(Operands);
1134 if (Res.isSuccess())
1136 if (Res.isFailure())
1141 Res = parseBaseRegImm(Operands);
1142 if (Res.isSuccess())
1144 if (Res.isFailure())
1149 if (Res.isSuccess())
1151 if (Res.isFailure())
1155 Error(getLoc(),
"unknown operand");
1159ParseStatus CSKYAsmParser::parseCSKYSymbol(
OperandVector &Operands) {
1168 AsmToken Tok = getLexer().getTok();
1170 if (getParser().parseIdentifier(Identifier))
1171 return Error(getLoc(),
"unknown identifier");
1182 else if (
Identifier.consume_back(
"@TLSGD32"))
1184 else if (
Identifier.consume_back(
"@GOTTPOFF"))
1188 else if (
Identifier.consume_back(
"@TLSLDM32"))
1190 else if (
Identifier.consume_back(
"@TLSLDO32"))
1196 Sym =
getContext().getOrCreateSymbol(Identifier);
1201 getLexer().UnLex(Tok);
1202 return Error(getLoc(),
"unknown symbol");
1209 switch (getLexer().getKind()) {
1214 Operands.
push_back(CSKYOperand::createImm(Res, S,
E));
1227 if (getParser().parseExpression(Expr))
1228 return Error(getLoc(),
"unknown expression");
1230 Operands.
push_back(CSKYOperand::createImm(Res, S,
E));
1234ParseStatus CSKYAsmParser::parseDataSymbol(
OperandVector &Operands) {
1243 if (getParser().parseExpression(Expr))
1244 return Error(getLoc(),
"unknown expression");
1249 Operands.
push_back(CSKYOperand::createConstpoolOp(Expr, S,
E));
1253 AsmToken Tok = getLexer().getTok();
1256 if (getParser().parseIdentifier(Identifier))
1257 return Error(getLoc(),
"unknown identifier " + Identifier);
1268 Sym =
getContext().getOrCreateSymbol(Identifier);
1273 getLexer().UnLex(Tok);
1274 return Error(getLoc(),
"unknown symbol");
1282 switch (getLexer().getKind()) {
1284 return Error(getLoc(),
"unknown symbol");
1292 Operands.
push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1305 if (getParser().parseExpression(Expr))
1306 return Error(getLoc(),
"unknown expression");
1311 Operands.
push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1315ParseStatus CSKYAsmParser::parseConstpoolSymbol(
OperandVector &Operands) {
1325 if (getParser().parseExpression(Expr))
1326 return Error(getLoc(),
"unknown expression");
1330 Operands.
push_back(CSKYOperand::createConstpoolOp(Expr, S,
E));
1334 AsmToken Tok = getLexer().getTok();
1337 if (getParser().parseIdentifier(Identifier))
1338 return Error(getLoc(),
"unknown identifier");
1343 Sym =
getContext().getOrCreateSymbol(Identifier);
1348 getLexer().UnLex(Tok);
1349 return Error(getLoc(),
"unknown symbol");
1357 switch (getLexer().getKind()) {
1359 return Error(getLoc(),
"unknown symbol");
1364 Operands.
push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1377 if (getParser().parseExpression(Expr))
1378 return Error(getLoc(),
"unknown expression");
1383 Operands.
push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1387ParseStatus CSKYAsmParser::parsePSRFlag(
OperandVector &Operands) {
1395 if (getParser().parseIdentifier(Identifier))
1396 return Error(getLoc(),
"unknown identifier " + Identifier);
1398 if (Identifier ==
"sie")
1399 Flag = (1 << 4) | Flag;
1400 else if (Identifier ==
"ee")
1401 Flag = (1 << 3) | Flag;
1402 else if (Identifier ==
"ie")
1403 Flag = (1 << 2) | Flag;
1404 else if (Identifier ==
"fe")
1405 Flag = (1 << 1) | Flag;
1406 else if (Identifier ==
"af")
1407 Flag = (1 << 0) | Flag;
1409 return Error(getLoc(),
"expected " + Identifier);
1423ParseStatus CSKYAsmParser::parseRegSeq(
OperandVector &Operands) {
1426 if (!parseRegister(Operands).isSuccess())
1429 auto Ry = Operands.
back()->getReg();
1434 if (!parseRegister(Operands).isSuccess())
1435 return Error(getLoc(),
"invalid register");
1437 auto Rz = Operands.
back()->getReg();
1440 Operands.
push_back(CSKYOperand::createRegSeq(Ry, Rz, S));
1444ParseStatus CSKYAsmParser::parseRegList(
OperandVector &Operands) {
1449 if (!parseRegister(Operands).isSuccess())
1450 return Error(getLoc(),
"invalid register");
1452 auto Ry = Operands.
back()->getReg();
1456 if (!parseRegister(Operands).isSuccess())
1457 return Error(getLoc(),
"invalid register");
1459 auto Rz = Operands.
back()->getReg();
1476 return Error(getLoc(),
"invalid register list");
1480 Operands.
push_back(CSKYOperand::createRegList(reglist, S));
1484bool CSKYAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,
1487 Operands.
push_back(CSKYOperand::createToken(Name, NameLoc));
1494 if (parseOperand(Operands, Name))
1499 if (parseOperand(Operands, Name))
1503 SMLoc Loc = getLexer().getLoc();
1504 getParser().eatToEndOfStatement();
1505 return Error(Loc,
"unexpected token");
1512ParseStatus CSKYAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1514 const AsmToken &Tok = getParser().getTok();
1518 StringRef
Name = getLexer().getTok().getIdentifier();
1527ParseStatus CSKYAsmParser::parseDirective(AsmToken DirectiveID) {
1528 StringRef IDVal = DirectiveID.
getString();
1530 if (IDVal ==
".csky_attribute")
1531 return parseDirectiveAttribute();
1538bool CSKYAsmParser::parseDirectiveAttribute() {
1539 MCAsmParser &Parser = getParser();
1545 std::optional<unsigned> Ret =
1548 return Error(TagLoc,
"attribute name not recognised: " + Name);
1552 const MCExpr *AttrExpr;
1560 return Error(TagLoc,
"expected numeric constant");
1562 Tag =
CE->getValue();
1568 StringRef StringValue;
1569 int64_t IntegerValue = 0;
1575 if (IsIntegerValue) {
1576 const MCExpr *ValueExpr;
1582 return Error(ValueExprLoc,
"expected numeric constant");
1583 IntegerValue =
CE->getValue();
1596 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
1598 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
1603 if (
ID == CSKY::ArchKind::INVALID)
1605 ?
"unknown arch name"
1606 :
"unknown cpu name");
1608 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
1614unsigned CSKYAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1616 CSKYOperand &
Op =
static_cast<CSKYOperand &
>(AsmOp);
1619 return Match_InvalidOperand;
1621 MCRegister
Reg =
Op.getReg();
1623 if (CSKYMCRegisterClasses[CSKY::FPR32RegClassID].
contains(
Reg)) {
1626 if (Kind == MCK_FPR64 || Kind == MCK_sFPR64) {
1628 if (Kind == MCK_sFPR64 &&
1629 (
Op.Reg.RegNum < CSKY::F0_64 ||
Op.Reg.RegNum > CSKY::F15_64))
1630 return Match_InvalidRegOutOfRange;
1631 if (Kind == MCK_FPR64 &&
1632 (
Op.Reg.RegNum < CSKY::F0_64 ||
Op.Reg.RegNum > CSKY::F31_64))
1633 return Match_InvalidRegOutOfRange;
1634 return Match_Success;
1638 if (CSKYMCRegisterClasses[CSKY::GPRRegClassID].
contains(
Reg)) {
1639 if (Kind == MCK_GPRPair) {
1641 return Match_Success;
1645 return Match_InvalidOperand;
1648void CSKYAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
1652 Res = compressInst(CInst, Inst, getSTI());
1654 ++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)
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)
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)
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,...