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;
73 bool MatchingInlineAsm)
override;
87 SMLoc &EndLoc)
override;
97 "do not have a target streamer");
103#define GET_ASSEMBLER_HEADER
104#include "CSKYGenAsmMatcher.inc"
118 bool parseDirectiveAttribute();
121 enum CSKYMatchResultTy {
123 Match_RequiresSameSrcAndDst,
124 Match_InvalidRegOutOfRange,
125#define GET_OPERAND_DIAGNOSTIC_TYPES
126#include "CSKYGenAsmMatcher.inc"
127#undef GET_OPERAND_DIAGNOSTIC_TYPES
140 getTargetStreamer().emitTargetAttributes(STI);
174 unsigned List1From = 0;
175 unsigned List1To = 0;
176 unsigned List2From = 0;
177 unsigned List2To = 0;
178 unsigned List3From = 0;
179 unsigned List3To = 0;
180 unsigned List4From = 0;
181 unsigned List4To = 0;
184 SMLoc StartLoc, EndLoc;
199 StartLoc =
o.StartLoc;
223 bool isToken()
const override {
return Kind == Token; }
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) {
233 if (
auto CE = dyn_cast<MCConstantExpr>(Expr)) {
234 Imm =
CE->getValue();
241 template <
unsigned num,
unsigned shift = 0>
bool isUImm()
const {
246 bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
247 return IsConstantImm && isShiftedUInt<num, shift>(Imm);
250 template <
unsigned num>
bool isOImm()
const {
255 bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
256 return IsConstantImm && isUInt<num>(Imm - 1);
259 template <
unsigned num,
unsigned shift = 0>
bool isSImm()
const {
264 bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
265 return IsConstantImm && isShiftedInt<num, shift>(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))
320 return isUInt<5>(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;
395 return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14;
399 SMLoc getStartLoc()
const override {
return StartLoc; }
401 SMLoc getEndLoc()
const override {
return EndLoc; }
408 std::pair<unsigned, unsigned> getRegSeq()
const {
409 assert(Kind == RegisterSeq &&
"Invalid type access!");
410 return std::pair<unsigned, unsigned>(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!");
443 OS << *getConstpoolOp();
448 case KindTy::Register:
452 OS <<
"<register-seq ";
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);
468 OS <<
"'" << getToken() <<
"'";
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(
unsigned RegNo,
SMLoc S,
483 auto Op = std::make_unique<CSKYOperand>(
Register);
484 Op->Reg.RegNum = RegNo;
490 static std::unique_ptr<CSKYOperand> createRegSeq(
unsigned RegNoFrom,
491 unsigned 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);
554 assert(Expr &&
"Expr shouldn't be null!");
555 if (
auto *CE = dyn_cast<MCConstantExpr>(Expr))
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!");
569 addExpr(Inst, getImm());
572 void addConstpoolOperands(
MCInst &Inst,
unsigned N)
const {
573 assert(
N == 1 &&
"Invalid number of operands!");
577 void addRegSeqOperands(
MCInst &Inst,
unsigned N)
const {
578 assert(
N == 2 &&
"Invalid number of operands!");
579 auto regSeq = getRegSeq();
585 static unsigned getListValue(
unsigned ListFrom,
unsigned ListTo) {
586 if (ListFrom == ListTo && ListFrom == CSKY::R15)
588 else if (ListFrom == ListTo && ListFrom == CSKY::R28)
590 else if (ListFrom == CSKY::R4)
591 return ListTo - ListFrom + 1;
592 else if (ListFrom == CSKY::R16)
593 return ((ListTo - ListFrom + 1) << 5);
598 void addRegListOperands(
MCInst &Inst,
unsigned N)
const {
599 assert(
N == 1 &&
"Invalid number of operands!");
600 auto regList = getRegList();
604 unsigned T = getListValue(regList.List1From, regList.List1To);
608 T = getListValue(regList.List2From, regList.List2To);
612 T = getListValue(regList.List3From, regList.List3To);
616 T = getListValue(regList.List4From, regList.List4To);
623 bool isValidForTie(
const CSKYOperand &
Other)
const {
624 if (Kind !=
Other.Kind)
632 return Reg.RegNum ==
Other.Reg.RegNum;
638#define GET_REGISTER_MATCHER
639#define GET_SUBTARGET_FEATURE_NAME
640#define GET_MATCHER_IMPLEMENTATION
641#define GET_MNEMONIC_SPELL_CHECKER
642#include "CSKYGenAsmMatcher.inc"
645 assert(Reg >= CSKY::F0_32 && Reg <= CSKY::F31_32 &&
"Invalid register");
646 return Reg - CSKY::F0_32 + CSKY::F0_64;
650 unsigned VariantID = 0);
652bool CSKYAsmParser::generateImmOutOfRangeError(
654 const Twine &Msg =
"immediate must be an integer in the range") {
659bool CSKYAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
663 bool MatchingInlineAsm) {
673 return processInstruction(Inst, IDLoc,
Operands, Out);
674 case Match_MissingFeature: {
675 assert(MissingFeatures.
any() &&
"Unknown missing features!");
677 std::string Msg =
"instruction requires the following: ";
678 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
679 if (MissingFeatures[i]) {
684 return Error(IDLoc, Msg);
686 case Match_MnemonicFail: {
687 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
688 std::string Suggestion =
690 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
692 case Match_InvalidTiedOperand:
693 case Match_InvalidOperand: {
694 SMLoc ErrorLoc = IDLoc;
697 return Error(ErrorLoc,
"too few operands for instruction");
700 if (ErrorLoc ==
SMLoc())
703 return Error(ErrorLoc,
"invalid operand for instruction");
710 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
711 SMLoc ErrorLoc = IDLoc;
713 return Error(ErrorLoc,
"too few operands for instruction");
719 case Match_InvalidSImm8:
722 case Match_InvalidOImm3:
724 case Match_InvalidOImm4:
726 case Match_InvalidOImm5:
728 case Match_InvalidOImm6:
730 case Match_InvalidOImm8:
732 case Match_InvalidOImm12:
734 case Match_InvalidOImm16:
736 case Match_InvalidUImm1:
738 case Match_InvalidUImm2:
740 case Match_InvalidUImm3:
742 case Match_InvalidUImm4:
744 case Match_InvalidUImm5:
746 case Match_InvalidUImm6:
748 case Match_InvalidUImm7:
750 case Match_InvalidUImm8:
752 case Match_InvalidUImm12:
754 case Match_InvalidUImm16:
756 case Match_InvalidUImm5Shift1:
757 return generateImmOutOfRangeError(
759 "immediate must be a multiple of 2 bytes in the range");
760 case Match_InvalidUImm12Shift1:
761 return generateImmOutOfRangeError(
763 "immediate must be a multiple of 2 bytes in the range");
764 case Match_InvalidUImm5Shift2:
765 return generateImmOutOfRangeError(
767 "immediate must be a multiple of 4 bytes in the range");
768 case Match_InvalidUImm7Shift1:
769 return generateImmOutOfRangeError(
771 "immediate must be a multiple of 2 bytes in the range");
772 case Match_InvalidUImm7Shift2:
773 return generateImmOutOfRangeError(
775 "immediate must be a multiple of 4 bytes in the range");
776 case Match_InvalidUImm8Shift2:
777 return generateImmOutOfRangeError(
779 "immediate must be a multiple of 4 bytes in the range");
780 case Match_InvalidUImm8Shift3:
781 return generateImmOutOfRangeError(
783 "immediate must be a multiple of 8 bytes in the range");
784 case Match_InvalidUImm8Shift8:
785 return generateImmOutOfRangeError(
787 "immediate must be a multiple of 256 bytes in the range");
788 case Match_InvalidUImm12Shift2:
789 return generateImmOutOfRangeError(
791 "immediate must be a multiple of 4 bytes in the range");
792 case Match_InvalidCSKYSymbol: {
794 return Error(ErrorLoc,
"operand must be a symbol name");
796 case Match_InvalidConstpool: {
798 return Error(ErrorLoc,
"operand must be a constpool symbol name");
800 case Match_InvalidPSRFlag: {
802 return Error(ErrorLoc,
"psrset operand is not valid");
804 case Match_InvalidRegSeq: {
806 return Error(ErrorLoc,
"Register sequence is not valid");
808 case Match_InvalidRegOutOfRange: {
810 return Error(ErrorLoc,
"register is out of range");
812 case Match_RequiresSameSrcAndDst: {
814 return Error(ErrorLoc,
"src and dst operand must be same");
816 case Match_InvalidRegList: {
818 return Error(ErrorLoc,
"invalid register list");
830 if (Inst.
getOpcode() == CSKY::PseudoLRW16)
831 Opcode = CSKY::LRW16;
833 Opcode = CSKY::LRW32;
838 Opcode = CSKY::MOVI16;
839 }
else if (getSTI().hasFeature(CSKY::HasE2) &&
841 Opcode = CSKY::MOVI32;
843 auto *Expr = getTargetStreamer().addConstantPoolEntry(
850 const MCExpr *AdjustExpr =
nullptr;
856 MCSymbol *Dot = getContext().createNamedTempSymbol();
861 auto *Expr = getTargetStreamer().addConstantPoolEntry(
877 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
884 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
898 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
905 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
915bool CSKYAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
926 return Error(IDLoc,
"Register sequence is not valid. 'r4-r7' expected");
933 return Error(IDLoc,
"msb must be greater or equal to lsb");
937 return Error(IDLoc,
"msb must be greater or equal to lsb");
941 return Error(IDLoc,
"n must be in range [0,32]");
972 case CSKY::PseudoLRW16:
973 case CSKY::PseudoLRW32:
974 return processLRW(Inst, IDLoc, Out);
975 case CSKY::PseudoJSRI32:
976 return processJSRI(Inst, IDLoc, Out);
977 case CSKY::PseudoJMPI32:
978 return processJMPI(Inst, IDLoc, Out);
989 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
996 emitToStreamer(Out, Inst);
1007 if (Reg == CSKY::NoRegister)
1010 return Reg == CSKY::NoRegister;
1015 const AsmToken &Tok = getParser().getTok();
1032 switch (getLexer().getKind()) {
1043 Operands.push_back(CSKYOperand::createReg(Reg, S, E));
1053 Operands.push_back(CSKYOperand::createToken(
"(", getLoc()));
1055 auto Tok = getParser().Lex();
1057 if (!parseRegister(
Operands).isSuccess()) {
1058 getLexer().UnLex(Tok);
1064 Operands.push_back(CSKYOperand::createToken(
")", getLoc()));
1070 return Error(getLoc(),
"expected ','");
1074 if (parseRegister(
Operands).isSuccess()) {
1076 return Error(getLoc(),
"expected '<<'");
1078 Operands.push_back(CSKYOperand::createToken(
"<<", getLoc()));
1083 return Error(getLoc(),
"expected imm");
1086 return Error(getLoc(),
"expected imm");
1090 return Error(getLoc(),
"expected ')'");
1092 Operands.push_back(CSKYOperand::createToken(
")", getLoc()));
1100 switch (getLexer().getKind()) {
1113 if (getParser().parseExpression(IdVal))
1114 return Error(getLoc(),
"unknown expression");
1117 Operands.push_back(CSKYOperand::createImm(IdVal, S, E));
1128 MatchOperandParserImpl(
Operands, Mnemonic,
true);
1135 auto Res = parseRegister(
Operands);
1136 if (Res.isSuccess())
1138 if (Res.isFailure())
1144 if (Res.isSuccess())
1146 if (Res.isFailure())
1151 if (Res.isSuccess())
1153 if (Res.isFailure())
1157 Error(getLoc(),
"unknown operand");
1170 AsmToken Tok = getLexer().getTok();
1172 if (getParser().parseIdentifier(Identifier))
1173 return Error(getLoc(),
"unknown identifier");
1184 else if (
Identifier.consume_back(
"@TLSGD32"))
1186 else if (
Identifier.consume_back(
"@GOTTPOFF"))
1190 else if (
Identifier.consume_back(
"@TLSLDM32"))
1192 else if (
Identifier.consume_back(
"@TLSLDO32"))
1195 MCSymbol *
Sym = getContext().getInlineAsmLabel(Identifier);
1198 Sym = getContext().getOrCreateSymbol(Identifier);
1200 if (
Sym->isVariable()) {
1201 const MCExpr *
V =
Sym->getVariableValue(
false);
1202 if (!isa<MCSymbolRefExpr>(V)) {
1203 getLexer().UnLex(Tok);
1204 return Error(getLoc(),
"unknown symbol");
1211 switch (getLexer().getKind()) {
1216 Operands.push_back(CSKYOperand::createImm(Res, S, E));
1229 if (getParser().parseExpression(Expr))
1230 return Error(getLoc(),
"unknown expression");
1232 Operands.push_back(CSKYOperand::createImm(Res, S, E));
1245 if (getParser().parseExpression(Expr))
1246 return Error(getLoc(),
"unknown expression");
1251 Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));
1255 AsmToken Tok = getLexer().getTok();
1258 if (getParser().parseIdentifier(Identifier))
1259 return Error(getLoc(),
"unknown identifier " + Identifier);
1267 MCSymbol *
Sym = getContext().getInlineAsmLabel(Identifier);
1270 Sym = getContext().getOrCreateSymbol(Identifier);
1272 if (
Sym->isVariable()) {
1273 const MCExpr *
V =
Sym->getVariableValue(
false);
1274 if (!isa<MCSymbolRefExpr>(V)) {
1275 getLexer().UnLex(Tok);
1276 return Error(getLoc(),
"unknown symbol");
1284 switch (getLexer().getKind()) {
1286 return Error(getLoc(),
"unknown symbol");
1294 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1307 if (getParser().parseExpression(Expr))
1308 return Error(getLoc(),
"unknown expression");
1313 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1327 if (getParser().parseExpression(Expr))
1328 return Error(getLoc(),
"unknown expression");
1332 Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));
1336 AsmToken Tok = getLexer().getTok();
1339 if (getParser().parseIdentifier(Identifier))
1340 return Error(getLoc(),
"unknown identifier");
1342 MCSymbol *
Sym = getContext().getInlineAsmLabel(Identifier);
1345 Sym = getContext().getOrCreateSymbol(Identifier);
1347 if (
Sym->isVariable()) {
1348 const MCExpr *
V =
Sym->getVariableValue(
false);
1349 if (!isa<MCSymbolRefExpr>(V)) {
1350 getLexer().UnLex(Tok);
1351 return Error(getLoc(),
"unknown symbol");
1359 switch (getLexer().getKind()) {
1361 return Error(getLoc(),
"unknown symbol");
1366 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1379 if (getParser().parseExpression(Expr))
1380 return Error(getLoc(),
"unknown expression");
1385 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
1397 if (getParser().parseIdentifier(Identifier))
1398 return Error(getLoc(),
"unknown identifier " + Identifier);
1400 if (Identifier ==
"sie")
1401 Flag = (1 << 4) | Flag;
1402 else if (Identifier ==
"ee")
1403 Flag = (1 << 3) | Flag;
1404 else if (Identifier ==
"ie")
1405 Flag = (1 << 2) | Flag;
1406 else if (Identifier ==
"fe")
1407 Flag = (1 << 1) | Flag;
1408 else if (Identifier ==
"af")
1409 Flag = (1 << 0) | Flag;
1411 return Error(getLoc(),
"expected " + Identifier);
1428 if (!parseRegister(
Operands).isSuccess())
1431 auto Ry =
Operands.back()->getReg();
1436 if (!parseRegister(
Operands).isSuccess())
1437 return Error(getLoc(),
"invalid register");
1439 auto Rz =
Operands.back()->getReg();
1442 Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S));
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));
1491 Operands.push_back(CSKYOperand::createToken(
Name, NameLoc));
1507 SMLoc Loc = getLexer().getLoc();
1508 getParser().eatToEndOfStatement();
1509 return Error(Loc,
"unexpected token");
1518 const AsmToken &Tok = getParser().getTok();
1534 if (IDVal ==
".csky_attribute")
1535 return parseDirectiveAttribute();
1542bool CSKYAsmParser::parseDirectiveAttribute() {
1549 std::optional<unsigned>
Ret =
1552 return Error(TagLoc,
"attribute name not recognised: " +
Name);
1564 return Error(TagLoc,
"expected numeric constant");
1566 Tag =
CE->getValue();
1573 int64_t IntegerValue = 0;
1579 if (IsIntegerValue) {
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);
1620 CSKYOperand &
Op =
static_cast<CSKYOperand &
>(AsmOp);
1623 return Match_InvalidOperand;
1627 if (CSKYMCRegisterClasses[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 (CSKYMCRegisterClasses[CSKY::GPRRegClassID].
contains(Reg)) {
1643 if (Kind == MCK_GPRPair) {
1644 Op.Reg.RegNum =
MRI->getEncodingValue(Reg) + CSKY::R0_R1;
1645 return Match_Success;
1649 return Match_InvalidOperand;
1656 Res = compressInst(CInst, Inst, getSTI());
1658 ++CSKYNumInstrsCompressed;
unsigned const MachineRegisterInfo * MRI
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
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 void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
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
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)
This class represents an Operation in the Expression.
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 ...
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual ParseStatus parseDirective(AsmToken DirectiveID)
Parses a target-specific assembler directive.
@ FIRST_TARGET_MATCH_RESULT_TY
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
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 ...
Target specific streamer interface.
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Wrapper class representing virtual and physical registers.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr 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 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()
DWARFExpression::Operation Op
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...