39#define DEBUG_TYPE "csky-asm-parser"
42#define GEN_COMPRESS_INSTR
43#include "CSKYGenCompressInstEmitter.inc"
46 "Number of C-SKY Compressed instructions emitted");
51 cl::desc(
"Enable C-SKY asm compressed instruction"));
61 unsigned Kind)
override;
71 bool MatchingInlineAsm)
override;
74 SMLoc &EndLoc)
override;
86 SMLoc &EndLoc)
override;
96 "do not have a target streamer");
102#define GET_ASSEMBLER_HEADER
103#include "CSKYGenAsmMatcher.inc"
117 bool parseDirectiveAttribute();
120 enum CSKYMatchResultTy {
122 Match_RequiresSameSrcAndDst,
123 Match_InvalidRegOutOfRange,
124#define GET_OPERAND_DIAGNOSTIC_TYPES
125#include "CSKYGenAsmMatcher.inc"
126#undef GET_OPERAND_DIAGNOSTIC_TYPES
139 getTargetStreamer().emitTargetAttributes(STI);
173 unsigned List1From = 0;
174 unsigned List1To = 0;
175 unsigned List2From = 0;
176 unsigned List2To = 0;
177 unsigned List3From = 0;
178 unsigned List3To = 0;
179 unsigned List4From = 0;
180 unsigned List4To = 0;
183 SMLoc StartLoc, EndLoc;
198 StartLoc =
o.StartLoc;
222 bool isToken()
const override {
return Kind == Token; }
224 bool isImm()
const override {
return Kind == Immediate; }
225 bool isRegisterSeq()
const {
return Kind == RegisterSeq; }
226 bool isRegisterList()
const {
return Kind == RegisterList; }
227 bool isConstPoolOp()
const {
return Kind == CPOP; }
229 bool isMem()
const override {
return false; }
231 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm) {
232 if (
auto CE = dyn_cast<MCConstantExpr>(Expr)) {
233 Imm =
CE->getValue();
240 template <
unsigned num,
unsigned shift = 0>
bool isUImm()
const {
245 bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
246 return IsConstantImm && isShiftedUInt<num, shift>(Imm);
249 template <
unsigned num>
bool isOImm()
const {
254 bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
255 return IsConstantImm && isUInt<num>(Imm - 1);
258 template <
unsigned num,
unsigned shift = 0>
bool isSImm()
const {
263 bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
264 return IsConstantImm && isShiftedInt<num, shift>(Imm);
267 bool isUImm1()
const {
return isUImm<1>(); }
268 bool isUImm2()
const {
return isUImm<2>(); }
269 bool isUImm3()
const {
return isUImm<3>(); }
270 bool isUImm4()
const {
return isUImm<4>(); }
271 bool isUImm5()
const {
return isUImm<5>(); }
272 bool isUImm6()
const {
return isUImm<6>(); }
273 bool isUImm7()
const {
return isUImm<7>(); }
274 bool isUImm8()
const {
return isUImm<8>(); }
275 bool isUImm12()
const {
return isUImm<12>(); }
276 bool isUImm16()
const {
return isUImm<16>(); }
277 bool isUImm20()
const {
return isUImm<20>(); }
278 bool isUImm24()
const {
return isUImm<24>(); }
280 bool isOImm3()
const {
return isOImm<3>(); }
281 bool isOImm4()
const {
return isOImm<4>(); }
282 bool isOImm5()
const {
return isOImm<5>(); }
283 bool isOImm6()
const {
return isOImm<6>(); }
284 bool isOImm8()
const {
return isOImm<8>(); }
285 bool isOImm12()
const {
return isOImm<12>(); }
286 bool isOImm16()
const {
return isOImm<16>(); }
288 bool isSImm8()
const {
return isSImm<8>(); }
290 bool isUImm5Shift1() {
return isUImm<5, 1>(); }
291 bool isUImm5Shift2() {
return isUImm<5, 2>(); }
292 bool isUImm7Shift1() {
return isUImm<7, 1>(); }
293 bool isUImm7Shift2() {
return isUImm<7, 2>(); }
294 bool isUImm7Shift3() {
return isUImm<7, 3>(); }
295 bool isUImm8Shift2() {
return isUImm<8, 2>(); }
296 bool isUImm8Shift3() {
return isUImm<8, 3>(); }
297 bool isUImm8Shift8() {
return isUImm<8, 8>(); }
298 bool isUImm8Shift16() {
return isUImm<8, 16>(); }
299 bool isUImm8Shift24() {
return isUImm<8, 24>(); }
300 bool isUImm12Shift1() {
return isUImm<12, 1>(); }
301 bool isUImm12Shift2() {
return isUImm<12, 2>(); }
302 bool isUImm16Shift8() {
return isUImm<16, 8>(); }
303 bool isUImm16Shift16() {
return isUImm<16, 16>(); }
304 bool isUImm24Shift8() {
return isUImm<24, 8>(); }
306 bool isSImm16Shift1() {
return isSImm<16, 1>(); }
308 bool isCSKYSymbol()
const {
return isImm(); }
310 bool isConstpool()
const {
return isConstPoolOp(); }
311 bool isDataSymbol()
const {
return isConstPoolOp(); }
313 bool isPSRFlag()
const {
316 if (!
isImm() || !evaluateConstantImm(getImm(), Imm))
319 return isUInt<5>(Imm);
322 template <
unsigned MIN,
unsigned MAX>
bool isRegSeqTemplate()
const {
323 if (!isRegisterSeq())
326 std::pair<unsigned, unsigned> regSeq = getRegSeq();
328 return MIN <= regSeq.first && regSeq.first <= regSeq.second &&
329 regSeq.second <=
MAX;
332 bool isRegSeq()
const {
return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); }
334 bool isRegSeqV1()
const {
335 return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>();
338 bool isRegSeqV2()
const {
339 return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>();
342 static bool isLegalRegList(
unsigned from,
unsigned to) {
343 if (from == 0 && to == 0)
347 if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 &&
353 if (from != CSKY::R4 && from != CSKY::R16)
356 if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12)
358 else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18)
365 bool isRegList()
const {
366 if (!isRegisterList())
369 auto regList = getRegList();
371 if (!isLegalRegList(regList.List1From, regList.List1To))
373 if (!isLegalRegList(regList.List2From, regList.List2To))
375 if (!isLegalRegList(regList.List3From, regList.List3To))
377 if (!isLegalRegList(regList.List4From, regList.List4To))
388 bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
392 int uimm4 =
Imm & 0xf;
394 return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14;
398 SMLoc getStartLoc()
const override {
return StartLoc; }
400 SMLoc getEndLoc()
const override {
return EndLoc; }
402 unsigned getReg()
const override {
407 std::pair<unsigned, unsigned> getRegSeq()
const {
408 assert(Kind == RegisterSeq &&
"Invalid type access!");
409 return std::pair<unsigned, unsigned>(RegSeq.RegNumFrom, RegSeq.RegNumTo);
412 RegListOp getRegList()
const {
413 assert(Kind == RegisterList &&
"Invalid type access!");
417 const MCExpr *getImm()
const {
418 assert(Kind == Immediate &&
"Invalid type access!");
422 const MCExpr *getConstpoolOp()
const {
423 assert(Kind == CPOP &&
"Invalid type access!");
428 assert(Kind == Token &&
"Invalid type access!");
442 OS << *getConstpoolOp();
447 case KindTy::Register:
451 OS <<
"<register-seq ";
456 OS <<
"<register-list ";
457 OS <<
RegName(getRegList().List1From) <<
"-"
458 <<
RegName(getRegList().List1To) <<
",";
459 OS <<
RegName(getRegList().List2From) <<
"-"
460 <<
RegName(getRegList().List2To) <<
",";
461 OS <<
RegName(getRegList().List3From) <<
"-"
462 <<
RegName(getRegList().List3To) <<
",";
463 OS <<
RegName(getRegList().List4From) <<
"-"
464 <<
RegName(getRegList().List4To);
467 OS <<
"'" << getToken() <<
"'";
472 static std::unique_ptr<CSKYOperand> createToken(
StringRef Str,
SMLoc S) {
473 auto Op = std::make_unique<CSKYOperand>(Token);
480 static std::unique_ptr<CSKYOperand> createReg(
unsigned RegNo,
SMLoc S,
482 auto Op = std::make_unique<CSKYOperand>(
Register);
483 Op->Reg.RegNum = RegNo;
489 static std::unique_ptr<CSKYOperand> createRegSeq(
unsigned RegNoFrom,
490 unsigned RegNoTo,
SMLoc S) {
491 auto Op = std::make_unique<CSKYOperand>(RegisterSeq);
492 Op->RegSeq.RegNumFrom = RegNoFrom;
493 Op->RegSeq.RegNumTo = RegNoTo;
499 static std::unique_ptr<CSKYOperand>
501 auto Op = std::make_unique<CSKYOperand>(RegisterList);
502 Op->RegList.List1From = 0;
503 Op->RegList.List1To = 0;
504 Op->RegList.List2From = 0;
505 Op->RegList.List2To = 0;
506 Op->RegList.List3From = 0;
507 Op->RegList.List3To = 0;
508 Op->RegList.List4From = 0;
509 Op->RegList.List4To = 0;
511 for (
unsigned i = 0; i < reglist.
size(); i += 2) {
512 if (
Op->RegList.List1From == 0) {
513 Op->RegList.List1From = reglist[i];
514 Op->RegList.List1To = reglist[i + 1];
515 }
else if (
Op->RegList.List2From == 0) {
516 Op->RegList.List2From = reglist[i];
517 Op->RegList.List2To = reglist[i + 1];
518 }
else if (
Op->RegList.List3From == 0) {
519 Op->RegList.List3From = reglist[i];
520 Op->RegList.List3To = reglist[i + 1];
521 }
else if (
Op->RegList.List4From == 0) {
522 Op->RegList.List4From = reglist[i];
523 Op->RegList.List4To = reglist[i + 1];
534 static std::unique_ptr<CSKYOperand> createImm(
const MCExpr *Val,
SMLoc S,
536 auto Op = std::make_unique<CSKYOperand>(Immediate);
543 static std::unique_ptr<CSKYOperand> createConstpoolOp(
const MCExpr *Val,
545 auto Op = std::make_unique<CSKYOperand>(CPOP);
553 assert(Expr &&
"Expr shouldn't be null!");
554 if (
auto *CE = dyn_cast<MCConstantExpr>(Expr))
561 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
562 assert(
N == 1 &&
"Invalid number of operands!");
566 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
567 assert(
N == 1 &&
"Invalid number of operands!");
568 addExpr(Inst, getImm());
571 void addConstpoolOperands(
MCInst &Inst,
unsigned N)
const {
572 assert(
N == 1 &&
"Invalid number of operands!");
576 void addRegSeqOperands(
MCInst &Inst,
unsigned N)
const {
577 assert(
N == 2 &&
"Invalid number of operands!");
578 auto regSeq = getRegSeq();
584 static unsigned getListValue(
unsigned ListFrom,
unsigned ListTo) {
585 if (ListFrom == ListTo && ListFrom == CSKY::R15)
587 else if (ListFrom == ListTo && ListFrom == CSKY::R28)
589 else if (ListFrom == CSKY::R4)
590 return ListTo - ListFrom + 1;
591 else if (ListFrom == CSKY::R16)
592 return ((ListTo - ListFrom + 1) << 5);
597 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
598 assert(
N == 1 &&
"Invalid number of operands!");
599 auto regList = getRegList();
603 unsigned T = getListValue(regList.List1From, regList.List1To);
607 T = getListValue(regList.List2From, regList.List2To);
611 T = getListValue(regList.List3From, regList.List3To);
615 T = getListValue(regList.List4From, regList.List4To);
622 bool isValidForTie(
const CSKYOperand &
Other)
const {
623 if (Kind !=
Other.Kind)
631 return Reg.RegNum ==
Other.Reg.RegNum;
637#define GET_REGISTER_MATCHER
638#define GET_SUBTARGET_FEATURE_NAME
639#define GET_MATCHER_IMPLEMENTATION
640#define GET_MNEMONIC_SPELL_CHECKER
641#include "CSKYGenAsmMatcher.inc"
644 assert(Reg >= CSKY::F0_32 && Reg <= CSKY::F31_32 &&
"Invalid register");
645 return Reg - CSKY::F0_32 + CSKY::F0_64;
649 unsigned VariantID = 0);
651bool CSKYAsmParser::generateImmOutOfRangeError(
653 Twine Msg =
"immediate must be an integer in the range") {
658bool CSKYAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
662 bool MatchingInlineAsm) {
672 return processInstruction(Inst, IDLoc,
Operands, Out);
673 case Match_MissingFeature: {
674 assert(MissingFeatures.
any() &&
"Unknown missing features!");
676 std::string
Msg =
"instruction requires the following: ";
677 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
678 if (MissingFeatures[i]) {
683 return Error(IDLoc, Msg);
685 case Match_MnemonicFail: {
686 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
687 std::string Suggestion =
689 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
691 case Match_InvalidTiedOperand:
692 case Match_InvalidOperand: {
693 SMLoc ErrorLoc = IDLoc;
696 return Error(ErrorLoc,
"too few operands for instruction");
699 if (ErrorLoc ==
SMLoc())
702 return Error(ErrorLoc,
"invalid operand for instruction");
709 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
710 SMLoc ErrorLoc = IDLoc;
712 return Error(ErrorLoc,
"too few operands for instruction");
718 case Match_InvalidSImm8:
721 case Match_InvalidOImm3:
723 case Match_InvalidOImm4:
725 case Match_InvalidOImm5:
727 case Match_InvalidOImm6:
729 case Match_InvalidOImm8:
731 case Match_InvalidOImm12:
733 case Match_InvalidOImm16:
735 case Match_InvalidUImm1:
737 case Match_InvalidUImm2:
739 case Match_InvalidUImm3:
741 case Match_InvalidUImm4:
743 case Match_InvalidUImm5:
745 case Match_InvalidUImm6:
747 case Match_InvalidUImm7:
749 case Match_InvalidUImm8:
751 case Match_InvalidUImm12:
753 case Match_InvalidUImm16:
755 case Match_InvalidUImm5Shift1:
756 return generateImmOutOfRangeError(
758 "immediate must be a multiple of 2 bytes in the range");
759 case Match_InvalidUImm12Shift1:
760 return generateImmOutOfRangeError(
762 "immediate must be a multiple of 2 bytes in the range");
763 case Match_InvalidUImm5Shift2:
764 return generateImmOutOfRangeError(
766 "immediate must be a multiple of 4 bytes in the range");
767 case Match_InvalidUImm7Shift1:
768 return generateImmOutOfRangeError(
770 "immediate must be a multiple of 2 bytes in the range");
771 case Match_InvalidUImm7Shift2:
772 return generateImmOutOfRangeError(
774 "immediate must be a multiple of 4 bytes in the range");
775 case Match_InvalidUImm8Shift2:
776 return generateImmOutOfRangeError(
778 "immediate must be a multiple of 4 bytes in the range");
779 case Match_InvalidUImm8Shift3:
780 return generateImmOutOfRangeError(
782 "immediate must be a multiple of 8 bytes in the range");
783 case Match_InvalidUImm8Shift8:
784 return generateImmOutOfRangeError(
786 "immediate must be a multiple of 256 bytes in the range");
787 case Match_InvalidUImm12Shift2:
788 return generateImmOutOfRangeError(
790 "immediate must be a multiple of 4 bytes in the range");
791 case Match_InvalidCSKYSymbol: {
793 return Error(ErrorLoc,
"operand must be a symbol name");
795 case Match_InvalidConstpool: {
797 return Error(ErrorLoc,
"operand must be a constpool symbol name");
799 case Match_InvalidPSRFlag: {
801 return Error(ErrorLoc,
"psrset operand is not valid");
803 case Match_InvalidRegSeq: {
805 return Error(ErrorLoc,
"Register sequence is not valid");
807 case Match_InvalidRegOutOfRange: {
809 return Error(ErrorLoc,
"register is out of range");
811 case Match_RequiresSameSrcAndDst: {
813 return Error(ErrorLoc,
"src and dst operand must be same");
815 case Match_InvalidRegList: {
817 return Error(ErrorLoc,
"invalid register list");
829 if (Inst.
getOpcode() == CSKY::PseudoLRW16)
830 Opcode = CSKY::LRW16;
832 Opcode = CSKY::LRW32;
837 Opcode = CSKY::MOVI16;
838 }
else if (getSTI().hasFeature(CSKY::HasE2) &&
840 Opcode = CSKY::MOVI32;
842 auto *Expr = getTargetStreamer().addConstantPoolEntry(
849 const MCExpr *AdjustExpr =
nullptr;
855 MCSymbol *Dot = getContext().createNamedTempSymbol();
860 auto *Expr = getTargetStreamer().addConstantPoolEntry(
876 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
883 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
897 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
904 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
914bool CSKYAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
925 return Error(IDLoc,
"Register sequence is not valid. 'r4-r7' expected");
932 return Error(IDLoc,
"msb must be greater or equal to lsb");
936 return Error(IDLoc,
"msb must be greater or equal to lsb");
940 return Error(IDLoc,
"n must be in range [0,32]");
971 case CSKY::PseudoLRW16:
972 case CSKY::PseudoLRW32:
973 return processLRW(Inst, IDLoc, Out);
974 case CSKY::PseudoJSRI32:
975 return processJSRI(Inst, IDLoc, Out);
976 case CSKY::PseudoJMPI32:
977 return processJMPI(Inst, IDLoc, Out);
988 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
995 emitToStreamer(Out, Inst);
1006 if (RegNo == CSKY::NoRegister)
1009 return RegNo == CSKY::NoRegister;
1014 const AsmToken &Tok = getParser().getTok();
1031 switch (getLexer().getKind()) {
1042 Operands.push_back(CSKYOperand::createReg(RegNo, S,
E));
1052 Operands.push_back(CSKYOperand::createToken(
"(", getLoc()));
1054 auto Tok = getParser().Lex();
1057 getLexer().UnLex(Tok);
1063 Operands.push_back(CSKYOperand::createToken(
")", getLoc()));
1069 Error(getLoc(),
"expected ','");
1077 Error(getLoc(),
"expected '<<'");
1081 Operands.push_back(CSKYOperand::createToken(
"<<", getLoc()));
1086 Error(getLoc(),
"expected imm");
1091 Error(getLoc(),
"expected imm");
1096 Error(getLoc(),
"expected ')'");
1100 Operands.push_back(CSKYOperand::createToken(
")", getLoc()));
1108 switch (getLexer().getKind()) {
1121 if (getParser().parseExpression(IdVal)) {
1122 Error(getLoc(),
"unknown expression");
1127 Operands.push_back(CSKYOperand::createImm(IdVal, S,
E));
1138 MatchOperandParserImpl(
Operands, Mnemonic,
true);
1145 auto Res = parseRegister(
Operands);
1167 Error(getLoc(),
"unknown operand");
1180 AsmToken Tok = getLexer().getTok();
1182 if (getParser().parseIdentifier(Identifier)) {
1183 Error(getLoc(),
"unknown identifier");
1196 else if (
Identifier.consume_back(
"@TLSGD32"))
1198 else if (
Identifier.consume_back(
"@GOTTPOFF"))
1202 else if (
Identifier.consume_back(
"@TLSLDM32"))
1204 else if (
Identifier.consume_back(
"@TLSLDO32"))
1207 MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1210 Sym = getContext().getOrCreateSymbol(Identifier);
1214 if (!isa<MCSymbolRefExpr>(V)) {
1215 getLexer().UnLex(Tok);
1216 Error(getLoc(),
"unknown symbol");
1224 switch (getLexer().getKind()) {
1229 Operands.push_back(CSKYOperand::createImm(Res, S,
E));
1242 if (getParser().parseExpression(Expr)) {
1243 Error(getLoc(),
"unknown expression");
1247 Operands.push_back(CSKYOperand::createImm(Res, S,
E));
1263 if (getParser().parseExpression(Expr)) {
1264 Error(getLoc(),
"unknown expression");
1269 Error(getLoc(),
"expected ]");
1275 Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S,
E));
1279 AsmToken Tok = getLexer().getTok();
1282 if (getParser().parseIdentifier(Identifier)) {
1283 Error(getLoc(),
"unknown identifier " + Identifier);
1293 MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1296 Sym = getContext().getOrCreateSymbol(Identifier);
1300 if (!isa<MCSymbolRefExpr>(V)) {
1301 getLexer().UnLex(Tok);
1302 Error(getLoc(),
"unknown symbol");
1311 switch (getLexer().getKind()) {
1313 Error(getLoc(),
"unknown symbol");
1322 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1335 if (getParser().parseExpression(Expr)) {
1336 Error(getLoc(),
"unknown expression");
1341 Error(getLoc(),
"expected ']'");
1348 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1365 if (getParser().parseExpression(Expr)) {
1366 Error(getLoc(),
"unknown expression");
1371 Error(getLoc(),
"expected ']'");
1377 Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S,
E));
1381 AsmToken Tok = getLexer().getTok();
1384 if (getParser().parseIdentifier(Identifier)) {
1385 Error(getLoc(),
"unknown identifier");
1389 MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1392 Sym = getContext().getOrCreateSymbol(Identifier);
1396 if (!isa<MCSymbolRefExpr>(V)) {
1397 getLexer().UnLex(Tok);
1398 Error(getLoc(),
"unknown symbol");
1407 switch (getLexer().getKind()) {
1409 Error(getLoc(),
"unknown symbol");
1415 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1428 if (getParser().parseExpression(Expr)) {
1429 Error(getLoc(),
"unknown expression");
1434 Error(getLoc(),
"expected ']'");
1441 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S,
E));
1453 if (getParser().parseIdentifier(Identifier)) {
1454 Error(getLoc(),
"unknown identifier " + Identifier);
1458 if (Identifier ==
"sie")
1459 Flag = (1 << 4) | Flag;
1460 else if (Identifier ==
"ee")
1461 Flag = (1 << 3) | Flag;
1462 else if (Identifier ==
"ie")
1463 Flag = (1 << 2) | Flag;
1464 else if (Identifier ==
"fe")
1465 Flag = (1 << 1) | Flag;
1466 else if (Identifier ==
"af")
1467 Flag = (1 << 0) | Flag;
1469 Error(getLoc(),
"expected " + Identifier);
1479 Error(getLoc(),
"expected ,");
1495 auto Ry =
Operands.back()->getReg();
1499 Error(getLoc(),
"expected '-'");
1506 Error(getLoc(),
"invalid register");
1510 auto Rz =
Operands.back()->getReg();
1513 Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S));
1525 Error(getLoc(),
"invalid register");
1529 auto Ry =
Operands.back()->getReg();
1536 Error(getLoc(),
"invalid register");
1540 auto Rz =
Operands.back()->getReg();
1561 Error(getLoc(),
"invalid register list");
1566 Operands.push_back(CSKYOperand::createRegList(reglist, S));
1573 Operands.push_back(CSKYOperand::createToken(
Name, NameLoc));
1594 SMLoc Loc = getLexer().getLoc();
1595 getParser().eatToEndOfStatement();
1596 return Error(Loc,
"unexpected token");
1606 const AsmToken &Tok = getParser().getTok();
1619bool CSKYAsmParser::ParseDirective(
AsmToken DirectiveID) {
1626 if (IDVal ==
".csky_attribute")
1627 return parseDirectiveAttribute();
1634bool CSKYAsmParser::parseDirectiveAttribute() {
1641 std::optional<unsigned>
Ret =
1644 Error(TagLoc,
"attribute name not recognised: " +
Name);
1657 if (
check(!CE, TagLoc,
"expected numeric constant"))
1660 Tag =
CE->getValue();
1667 int64_t IntegerValue = 0;
1673 if (IsIntegerValue) {
1680 return Error(ValueExprLoc,
"expected numeric constant");
1681 IntegerValue =
CE->getValue();
1694 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
1696 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
1701 if (
ID == CSKY::ArchKind::INVALID)
1703 ?
"unknown arch name"
1704 :
"unknown cpu name");
1706 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
1714 CSKYOperand &
Op =
static_cast<CSKYOperand &
>(AsmOp);
1717 return Match_InvalidOperand;
1721 if (CSKYMCRegisterClasses[CSKY::FPR32RegClassID].
contains(Reg)) {
1724 if (Kind == MCK_FPR64 || Kind == MCK_sFPR64) {
1726 if (Kind == MCK_sFPR64 &&
1727 (
Op.Reg.RegNum < CSKY::F0_64 ||
Op.Reg.RegNum > CSKY::F15_64))
1728 return Match_InvalidRegOutOfRange;
1729 if (Kind == MCK_FPR64 &&
1730 (
Op.Reg.RegNum < CSKY::F0_64 ||
Op.Reg.RegNum > CSKY::F31_64))
1731 return Match_InvalidRegOutOfRange;
1732 return Match_Success;
1736 if (CSKYMCRegisterClasses[CSKY::GPRRegClassID].
contains(Reg)) {
1737 if (Kind == MCK_GPRPair) {
1738 Op.Reg.RegNum =
MRI->getEncodingValue(Reg) + CSKY::R0_R1;
1739 return Match_Success;
1743 return Match_InvalidOperand;
1750 Res = compressInst(CInst, Inst, getSTI());
1752 ++CSKYNumInstrsCompressed;
unsigned const MachineRegisterInfo * MRI
static const char * getSubtargetFeatureName(uint64_t Val)
static unsigned MatchRegisterName(StringRef Name)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static unsigned MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &RegNo, 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
std::optional< std::vector< StOtherPiece > > Other
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
mir Rename Register Operands
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
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 bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)
Target independent representation for an assembler token.
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
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)
static const CSKYMCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Container class for subtarget features.
constexpr size_t size() const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCStreamer & getStreamer()
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
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 const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
const MCRegisterInfo * getRegisterInfo() const
Base class for the full range of assembler expressions which are needed for parsing.
Instances of this class represent a single low-level machine instruction.
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
Interface to description of machine instruction set.
Instances of this class represent operands of the MCInst class.
static MCOperand createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
unsigned 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.
Streaming machine code generation interface.
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.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
const FeatureBitset & getFeatureBits() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
bool isVariable() const
isVariable - Check if this is a variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool ParseDirective(AsmToken DirectiveID)=0
ParseDirective - Parse a target specific assembler directive.
@ FIRST_TARGET_MATCH_RESULT_TY
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
void setAvailableFeatures(const FeatureBitset &Value)
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
virtual OperandMatchResultTy tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
Target specific streamer interface.
Wrapper class representing virtual and physical registers.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
const char * getPointer() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const CustomOperand< const MCSubtargetInfo & > Msg[]
const TagNameMap & getCSKYAttributeTags()
ArchKind parseCPUArch(StringRef CPU)
ArchKind parseArch(StringRef Arch)
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)
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
static bool isMem(const MachineInstr &MI, unsigned Op)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Target & getTheCSKYTarget()
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...