1663 lines · cpp
1//===---- CSKYAsmParser.cpp - Parse CSKY assembly to MCInst instructions --===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "MCTargetDesc/CSKYInstPrinter.h"10#include "MCTargetDesc/CSKYMCAsmInfo.h"11#include "MCTargetDesc/CSKYMCTargetDesc.h"12#include "MCTargetDesc/CSKYTargetStreamer.h"13#include "TargetInfo/CSKYTargetInfo.h"14#include "llvm/ADT/STLExtras.h"15#include "llvm/ADT/Statistic.h"16#include "llvm/ADT/StringExtras.h"17#include "llvm/ADT/StringSwitch.h"18#include "llvm/BinaryFormat/ELF.h"19#include "llvm/CodeGen/Register.h"20#include "llvm/MC/MCContext.h"21#include "llvm/MC/MCExpr.h"22#include "llvm/MC/MCInst.h"23#include "llvm/MC/MCInstrInfo.h"24#include "llvm/MC/MCParser/AsmLexer.h"25#include "llvm/MC/MCParser/MCParsedAsmOperand.h"26#include "llvm/MC/MCParser/MCTargetAsmParser.h"27#include "llvm/MC/MCRegisterInfo.h"28#include "llvm/MC/MCSectionELF.h"29#include "llvm/MC/MCStreamer.h"30#include "llvm/MC/MCSubtargetInfo.h"31#include "llvm/MC/TargetRegistry.h"32#include "llvm/Support/CSKYAttributes.h"33#include "llvm/Support/Casting.h"34#include "llvm/Support/CommandLine.h"35#include "llvm/Support/Debug.h"36#include "llvm/TargetParser/CSKYTargetParser.h"37 38using namespace llvm;39 40#define DEBUG_TYPE "csky-asm-parser"41 42// Include the auto-generated portion of the compress emitter.43#define GEN_COMPRESS_INSTR44#include "CSKYGenCompressInstEmitter.inc"45 46STATISTIC(CSKYNumInstrsCompressed,47 "Number of C-SKY Compressed instructions emitted");48 49static cl::opt<bool>50 EnableCompressedInst("enable-csky-asm-compressed-inst", cl::Hidden,51 cl::init(false),52 cl::desc("Enable C-SKY asm compressed instruction"));53 54namespace {55struct CSKYOperand;56 57class CSKYAsmParser : public MCTargetAsmParser {58 59 const MCRegisterInfo *MRI;60 61 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,62 unsigned Kind) override;63 64 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,65 int64_t Lower, int64_t Upper,66 const Twine &Msg);67 68 SMLoc getLoc() const { return getParser().getTok().getLoc(); }69 70 bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,71 OperandVector &Operands, MCStreamer &Out,72 uint64_t &ErrorInfo,73 bool MatchingInlineAsm) override;74 75 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;76 77 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,78 SMLoc NameLoc, OperandVector &Operands) override;79 80 ParseStatus parseDirective(AsmToken DirectiveID) override;81 82 // Helper to actually emit an instruction to the MCStreamer. Also, when83 // possible, compression of the instruction is performed.84 void emitToStreamer(MCStreamer &S, const MCInst &Inst);85 86 ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,87 SMLoc &EndLoc) override;88 89 bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,90 MCStreamer &Out);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);94 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);100 }101 102// Auto-generated instruction matching functions103#define GET_ASSEMBLER_HEADER104#include "CSKYGenAsmMatcher.inc"105 106 ParseStatus parseImmediate(OperandVector &Operands);107 ParseStatus parseRegister(OperandVector &Operands);108 ParseStatus parseBaseRegImm(OperandVector &Operands);109 ParseStatus parseCSKYSymbol(OperandVector &Operands);110 ParseStatus parseConstpoolSymbol(OperandVector &Operands);111 ParseStatus parseDataSymbol(OperandVector &Operands);112 ParseStatus parsePSRFlag(OperandVector &Operands);113 ParseStatus parseRegSeq(OperandVector &Operands);114 ParseStatus parseRegList(OperandVector &Operands);115 116 bool parseOperand(OperandVector &Operands, StringRef Mnemonic);117 118 bool parseDirectiveAttribute();119 120public:121 enum CSKYMatchResultTy {122 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,123 Match_RequiresSameSrcAndDst,124 Match_InvalidRegOutOfRange,125#define GET_OPERAND_DIAGNOSTIC_TYPES126#include "CSKYGenAsmMatcher.inc"127#undef GET_OPERAND_DIAGNOSTIC_TYPES128 };129 130 CSKYAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,131 const MCInstrInfo &MII, const MCTargetOptions &Options)132 : MCTargetAsmParser(Options, STI, MII) {133 134 MCAsmParserExtension::Initialize(Parser);135 136 // Cache the MCRegisterInfo.137 MRI = getContext().getRegisterInfo();138 139 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));140 getTargetStreamer().emitTargetAttributes(STI);141 }142};143 144/// Instances of this class represent a parsed machine instruction.145struct CSKYOperand : public MCParsedAsmOperand {146 147 enum KindTy {148 Token,149 Register,150 Immediate,151 RegisterSeq,152 CPOP,153 RegisterList154 } Kind;155 156 struct RegOp {157 MCRegister RegNum;158 };159 160 struct ImmOp {161 const MCExpr *Val;162 };163 164 struct ConstpoolOp {165 const MCExpr *Val;166 };167 168 struct RegSeqOp {169 MCRegister RegNumFrom;170 MCRegister RegNumTo;171 };172 173 struct RegListOp {174 MCRegister List1From;175 MCRegister List1To;176 MCRegister List2From;177 MCRegister List2To;178 MCRegister List3From;179 MCRegister List3To;180 MCRegister List4From;181 MCRegister List4To;182 };183 184 SMLoc StartLoc, EndLoc;185 union {186 StringRef Tok;187 RegOp Reg;188 ImmOp Imm;189 ConstpoolOp CPool;190 RegSeqOp RegSeq;191 RegListOp RegList;192 };193 194 CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}195 196public:197 CSKYOperand(const CSKYOperand &o) : MCParsedAsmOperand() {198 Kind = o.Kind;199 StartLoc = o.StartLoc;200 EndLoc = o.EndLoc;201 switch (Kind) {202 case Register:203 Reg = o.Reg;204 break;205 case RegisterSeq:206 RegSeq = o.RegSeq;207 break;208 case CPOP:209 CPool = o.CPool;210 break;211 case Immediate:212 Imm = o.Imm;213 break;214 case Token:215 Tok = o.Tok;216 break;217 case RegisterList:218 RegList = o.RegList;219 break;220 }221 }222 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; }229 230 bool isMem() const override { return false; }231 232 static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) {233 if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {234 Imm = CE->getValue();235 return true;236 }237 238 return false;239 }240 241 template <unsigned num, unsigned shift = 0> bool isUImm() const {242 if (!isImm())243 return false;244 245 int64_t Imm;246 bool IsConstantImm = evaluateConstantImm(getImm(), Imm);247 return IsConstantImm && isShiftedUInt<num, shift>(Imm);248 }249 250 template <unsigned num> bool isOImm() const {251 if (!isImm())252 return false;253 254 int64_t Imm;255 bool IsConstantImm = evaluateConstantImm(getImm(), Imm);256 return IsConstantImm && isUInt<num>(Imm - 1);257 }258 259 template <unsigned num, unsigned shift = 0> bool isSImm() const {260 if (!isImm())261 return false;262 263 int64_t Imm;264 bool IsConstantImm = evaluateConstantImm(getImm(), Imm);265 return IsConstantImm && isShiftedInt<num, shift>(Imm);266 }267 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>(); }280 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>(); }288 289 bool isSImm8() const { return isSImm<8>(); }290 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>(); }306 307 bool isSImm16Shift1() { return isSImm<16, 1>(); }308 309 bool isCSKYSymbol() const { return isImm(); }310 311 bool isConstpool() const { return isConstPoolOp(); }312 bool isDataSymbol() const { return isConstPoolOp(); }313 314 bool isPSRFlag() const {315 int64_t Imm;316 // Must be of 'immediate' type and a constant.317 if (!isImm() || !evaluateConstantImm(getImm(), Imm))318 return false;319 320 return isUInt<5>(Imm);321 }322 323 template <unsigned MIN, unsigned MAX> bool isRegSeqTemplate() const {324 if (!isRegisterSeq())325 return false;326 327 std::pair<unsigned, unsigned> regSeq = getRegSeq();328 329 return MIN <= regSeq.first && regSeq.first <= regSeq.second &&330 regSeq.second <= MAX;331 }332 333 bool isRegSeq() const { return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); }334 335 bool isRegSeqV1() const {336 return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>();337 }338 339 bool isRegSeqV2() const {340 return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>();341 }342 343 static bool isLegalRegList(unsigned from, unsigned to) {344 if (from == 0 && to == 0)345 return true;346 347 if (from == to) {348 if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 &&349 from != CSKY::R28)350 return false;351 352 return true;353 } else {354 if (from != CSKY::R4 && from != CSKY::R16)355 return false;356 357 if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12)358 return true;359 else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18)360 return true;361 else362 return false;363 }364 }365 366 bool isRegList() const {367 if (!isRegisterList())368 return false;369 370 auto regList = getRegList();371 372 if (!isLegalRegList(regList.List1From, regList.List1To))373 return false;374 if (!isLegalRegList(regList.List2From, regList.List2To))375 return false;376 if (!isLegalRegList(regList.List3From, regList.List3To))377 return false;378 if (!isLegalRegList(regList.List4From, regList.List4To))379 return false;380 381 return true;382 }383 384 bool isExtImm6() {385 if (!isImm())386 return false;387 388 int64_t Imm;389 bool IsConstantImm = evaluateConstantImm(getImm(), Imm);390 if (!IsConstantImm)391 return false;392 393 int uimm4 = Imm & 0xf;394 395 return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14;396 }397 398 /// Gets location of the first token of this operand.399 SMLoc getStartLoc() const override { return StartLoc; }400 /// Gets location of the last token of this operand.401 SMLoc getEndLoc() const override { return EndLoc; }402 403 MCRegister getReg() const override {404 assert(Kind == Register && "Invalid type access!");405 return Reg.RegNum;406 }407 408 std::pair<MCRegister, MCRegister> getRegSeq() const {409 assert(Kind == RegisterSeq && "Invalid type access!");410 return {RegSeq.RegNumFrom, RegSeq.RegNumTo};411 }412 413 RegListOp getRegList() const {414 assert(Kind == RegisterList && "Invalid type access!");415 return RegList;416 }417 418 const MCExpr *getImm() const {419 assert(Kind == Immediate && "Invalid type access!");420 return Imm.Val;421 }422 423 const MCExpr *getConstpoolOp() const {424 assert(Kind == CPOP && "Invalid type access!");425 return CPool.Val;426 }427 428 StringRef getToken() const {429 assert(Kind == Token && "Invalid type access!");430 return Tok;431 }432 433 void print(raw_ostream &OS, const MCAsmInfo &MAI) const override {434 auto RegName = [](MCRegister Reg) {435 if (Reg)436 return CSKYInstPrinter::getRegisterName(Reg);437 else438 return "noreg";439 };440 441 switch (Kind) {442 case CPOP:443 MAI.printExpr(OS, *getConstpoolOp());444 break;445 case Immediate:446 MAI.printExpr(OS, *getImm());447 break;448 case KindTy::Register:449 OS << "<register " << RegName(getReg()) << ">";450 break;451 case RegisterSeq:452 OS << "<register-seq ";453 OS << RegName(getRegSeq().first) << "-" << RegName(getRegSeq().second)454 << ">";455 break;456 case RegisterList: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);466 break;467 case Token:468 OS << "'" << getToken() << "'";469 break;470 }471 }472 473 static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) {474 auto Op = std::make_unique<CSKYOperand>(Token);475 Op->Tok = Str;476 Op->StartLoc = S;477 Op->EndLoc = S;478 return Op;479 }480 481 static std::unique_ptr<CSKYOperand> createReg(MCRegister RegNo, SMLoc S,482 SMLoc E) {483 auto Op = std::make_unique<CSKYOperand>(Register);484 Op->Reg.RegNum = RegNo;485 Op->StartLoc = S;486 Op->EndLoc = E;487 return Op;488 }489 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;495 Op->StartLoc = S;496 Op->EndLoc = S;497 return Op;498 }499 500 static std::unique_ptr<CSKYOperand>501 createRegList(const SmallVector<MCRegister, 4> ®list, SMLoc S) {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;511 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];525 } else {526 assert(0);527 }528 }529 530 Op->StartLoc = S;531 Op->EndLoc = S;532 return Op;533 }534 535 static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S,536 SMLoc E) {537 auto Op = std::make_unique<CSKYOperand>(Immediate);538 Op->Imm.Val = Val;539 Op->StartLoc = S;540 Op->EndLoc = E;541 return Op;542 }543 544 static std::unique_ptr<CSKYOperand> createConstpoolOp(const MCExpr *Val,545 SMLoc S, SMLoc E) {546 auto Op = std::make_unique<CSKYOperand>(CPOP);547 Op->CPool.Val = Val;548 Op->StartLoc = S;549 Op->EndLoc = E;550 return Op;551 }552 553 void addExpr(MCInst &Inst, const MCExpr *Expr) const {554 assert(Expr && "Expr shouldn't be null!");555 if (auto *CE = dyn_cast<MCConstantExpr>(Expr))556 Inst.addOperand(MCOperand::createImm(CE->getValue()));557 else558 Inst.addOperand(MCOperand::createExpr(Expr));559 }560 561 // Used by the TableGen Code.562 void addRegOperands(MCInst &Inst, unsigned N) const {563 assert(N == 1 && "Invalid number of operands!");564 Inst.addOperand(MCOperand::createReg(getReg()));565 }566 567 void addImmOperands(MCInst &Inst, unsigned N) const {568 assert(N == 1 && "Invalid number of operands!");569 addExpr(Inst, getImm());570 }571 572 void addConstpoolOperands(MCInst &Inst, unsigned N) const {573 assert(N == 1 && "Invalid number of operands!");574 Inst.addOperand(MCOperand::createExpr(getConstpoolOp()));575 }576 577 void addRegSeqOperands(MCInst &Inst, unsigned N) const {578 assert(N == 2 && "Invalid number of operands!");579 auto regSeq = getRegSeq();580 581 Inst.addOperand(MCOperand::createReg(regSeq.first));582 Inst.addOperand(MCOperand::createReg(regSeq.second));583 }584 585 static unsigned getListValue(unsigned ListFrom, unsigned ListTo) {586 if (ListFrom == ListTo && ListFrom == CSKY::R15)587 return (1 << 4);588 else if (ListFrom == ListTo && ListFrom == CSKY::R28)589 return (1 << 8);590 else if (ListFrom == CSKY::R4)591 return ListTo - ListFrom + 1;592 else if (ListFrom == CSKY::R16)593 return ((ListTo - ListFrom + 1) << 5);594 else595 return 0;596 }597 598 void addRegListOperands(MCInst &Inst, unsigned N) const {599 assert(N == 1 && "Invalid number of operands!");600 auto regList = getRegList();601 602 unsigned V = 0;603 604 unsigned T = getListValue(regList.List1From, regList.List1To);605 if (T != 0)606 V = V | T;607 608 T = getListValue(regList.List2From, regList.List2To);609 if (T != 0)610 V = V | T;611 612 T = getListValue(regList.List3From, regList.List3To);613 if (T != 0)614 V = V | T;615 616 T = getListValue(regList.List4From, regList.List4To);617 if (T != 0)618 V = V | T;619 620 Inst.addOperand(MCOperand::createImm(V));621 }622 623 bool isValidForTie(const CSKYOperand &Other) const {624 if (Kind != Other.Kind)625 return false;626 627 switch (Kind) {628 default:629 llvm_unreachable("Unexpected kind");630 return false;631 case Register:632 return Reg.RegNum == Other.Reg.RegNum;633 }634 }635};636} // end anonymous namespace.637 638#define GET_REGISTER_MATCHER639#define GET_SUBTARGET_FEATURE_NAME640#define GET_MATCHER_IMPLEMENTATION641#define GET_MNEMONIC_SPELL_CHECKER642#include "CSKYGenAsmMatcher.inc"643 644static MCRegister convertFPR32ToFPR64(MCRegister Reg) {645 assert(Reg >= CSKY::F0_32 && Reg <= CSKY::F31_32 && "Invalid register");646 return Reg - CSKY::F0_32 + CSKY::F0_64;647}648 649static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,650 unsigned VariantID = 0);651 652bool CSKYAsmParser::generateImmOutOfRangeError(653 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,654 const Twine &Msg = "immediate must be an integer in the range") {655 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();656 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");657}658 659bool CSKYAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,660 OperandVector &Operands,661 MCStreamer &Out,662 uint64_t &ErrorInfo,663 bool MatchingInlineAsm) {664 MCInst Inst;665 FeatureBitset MissingFeatures;666 667 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,668 MatchingInlineAsm);669 switch (Result) {670 default:671 break;672 case Match_Success:673 return processInstruction(Inst, IDLoc, Operands, Out);674 case Match_MissingFeature: {675 assert(MissingFeatures.any() && "Unknown missing features!");676 ListSeparator LS;677 std::string Msg = "instruction requires the following: ";678 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {679 if (MissingFeatures[i]) {680 Msg += LS;681 Msg += getSubtargetFeatureName(i);682 }683 }684 return Error(IDLoc, Msg);685 }686 case Match_MnemonicFail: {687 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());688 std::string Suggestion =689 CSKYMnemonicSpellCheck(((CSKYOperand &)*Operands[0]).getToken(), FBS);690 return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);691 }692 case Match_InvalidTiedOperand:693 case Match_InvalidOperand: {694 SMLoc ErrorLoc = IDLoc;695 if (ErrorInfo != ~0U) {696 if (ErrorInfo >= Operands.size())697 return Error(ErrorLoc, "too few operands for instruction");698 699 ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();700 if (ErrorLoc == SMLoc())701 ErrorLoc = IDLoc;702 }703 return Error(ErrorLoc, "invalid operand for instruction");704 }705 }706 707 // Handle the case when the error message is of specific type708 // other than the generic Match_InvalidOperand, and the709 // corresponding operand is missing.710 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {711 SMLoc ErrorLoc = IDLoc;712 if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())713 return Error(ErrorLoc, "too few operands for instruction");714 }715 716 switch (Result) {717 default:718 break;719 case Match_InvalidSImm8:720 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),721 (1 << 7) - 1);722 case Match_InvalidOImm3:723 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3));724 case Match_InvalidOImm4:725 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));726 case Match_InvalidOImm5:727 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));728 case Match_InvalidOImm6:729 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));730 case Match_InvalidOImm8:731 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8));732 case Match_InvalidOImm12:733 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12));734 case Match_InvalidOImm16:735 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16));736 case Match_InvalidUImm1:737 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);738 case Match_InvalidUImm2:739 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);740 case Match_InvalidUImm3:741 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);742 case Match_InvalidUImm4:743 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);744 case Match_InvalidUImm5:745 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);746 case Match_InvalidUImm6:747 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);748 case Match_InvalidUImm7:749 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);750 case Match_InvalidUImm8:751 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);752 case Match_InvalidUImm12:753 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);754 case Match_InvalidUImm16:755 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1);756 case Match_InvalidUImm5Shift1:757 return generateImmOutOfRangeError(758 Operands, ErrorInfo, 0, (1 << 5) - 2,759 "immediate must be a multiple of 2 bytes in the range");760 case Match_InvalidUImm12Shift1:761 return generateImmOutOfRangeError(762 Operands, ErrorInfo, 0, (1 << 12) - 2,763 "immediate must be a multiple of 2 bytes in the range");764 case Match_InvalidUImm5Shift2:765 return generateImmOutOfRangeError(766 Operands, ErrorInfo, 0, (1 << 5) - 4,767 "immediate must be a multiple of 4 bytes in the range");768 case Match_InvalidUImm7Shift1:769 return generateImmOutOfRangeError(770 Operands, ErrorInfo, 0, (1 << 7) - 2,771 "immediate must be a multiple of 2 bytes in the range");772 case Match_InvalidUImm7Shift2:773 return generateImmOutOfRangeError(774 Operands, ErrorInfo, 0, (1 << 7) - 4,775 "immediate must be a multiple of 4 bytes in the range");776 case Match_InvalidUImm8Shift2:777 return generateImmOutOfRangeError(778 Operands, ErrorInfo, 0, (1 << 8) - 4,779 "immediate must be a multiple of 4 bytes in the range");780 case Match_InvalidUImm8Shift3:781 return generateImmOutOfRangeError(782 Operands, ErrorInfo, 0, (1 << 8) - 8,783 "immediate must be a multiple of 8 bytes in the range");784 case Match_InvalidUImm8Shift8:785 return generateImmOutOfRangeError(786 Operands, ErrorInfo, 0, (1 << 8) - 256,787 "immediate must be a multiple of 256 bytes in the range");788 case Match_InvalidUImm12Shift2:789 return generateImmOutOfRangeError(790 Operands, ErrorInfo, 0, (1 << 12) - 4,791 "immediate must be a multiple of 4 bytes in the range");792 case Match_InvalidCSKYSymbol: {793 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();794 return Error(ErrorLoc, "operand must be a symbol name");795 }796 case Match_InvalidConstpool: {797 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();798 return Error(ErrorLoc, "operand must be a constpool symbol name");799 }800 case Match_InvalidPSRFlag: {801 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();802 return Error(ErrorLoc, "psrset operand is not valid");803 }804 case Match_InvalidRegSeq: {805 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();806 return Error(ErrorLoc, "Register sequence is not valid");807 }808 case Match_InvalidRegOutOfRange: {809 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();810 return Error(ErrorLoc, "register is out of range");811 }812 case Match_RequiresSameSrcAndDst: {813 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();814 return Error(ErrorLoc, "src and dst operand must be same");815 }816 case Match_InvalidRegList: {817 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();818 return Error(ErrorLoc, "invalid register list");819 }820 }821 LLVM_DEBUG(dbgs() << "Result = " << Result);822 llvm_unreachable("Unknown match type detected!");823}824 825bool CSKYAsmParser::processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {826 Inst.setLoc(IDLoc);827 828 unsigned Opcode;829 MCOperand Op;830 if (Inst.getOpcode() == CSKY::PseudoLRW16)831 Opcode = CSKY::LRW16;832 else833 Opcode = CSKY::LRW32;834 835 if (Inst.getOperand(1).isImm()) {836 if (isUInt<8>(Inst.getOperand(1).getImm()) &&837 Inst.getOperand(0).getReg() <= CSKY::R7) {838 Opcode = CSKY::MOVI16;839 } else if (getSTI().hasFeature(CSKY::HasE2) &&840 isUInt<16>(Inst.getOperand(1).getImm())) {841 Opcode = CSKY::MOVI32;842 } else {843 auto *Expr = getTargetStreamer().addConstantPoolEntry(844 MCConstantExpr::create(Inst.getOperand(1).getImm(), getContext()),845 Inst.getLoc());846 Inst.erase(std::prev(Inst.end()));847 Inst.addOperand(MCOperand::createExpr(Expr));848 }849 } else {850 const MCExpr *AdjustExpr = nullptr;851 if (const auto *CSKYExpr =852 dyn_cast<MCSpecifierExpr>(Inst.getOperand(1).getExpr())) {853 if (CSKYExpr->getSpecifier() == CSKY::S_TLSGD ||854 CSKYExpr->getSpecifier() == CSKY::S_TLSIE ||855 CSKYExpr->getSpecifier() == CSKY::S_TLSLDM) {856 MCSymbol *Dot = getContext().createNamedTempSymbol();857 Out.emitLabel(Dot);858 AdjustExpr = MCSymbolRefExpr::create(Dot, getContext());859 }860 }861 auto *Expr = getTargetStreamer().addConstantPoolEntry(862 Inst.getOperand(1).getExpr(), Inst.getLoc(), AdjustExpr);863 Inst.erase(std::prev(Inst.end()));864 Inst.addOperand(MCOperand::createExpr(Expr));865 }866 867 Inst.setOpcode(Opcode);868 869 Out.emitInstruction(Inst, getSTI());870 return false;871}872 873bool CSKYAsmParser::processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {874 Inst.setLoc(IDLoc);875 876 if (Inst.getOperand(0).isImm()) {877 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(878 MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()),879 Inst.getLoc());880 Inst.setOpcode(CSKY::JSRI32);881 Inst.erase(std::prev(Inst.end()));882 Inst.addOperand(MCOperand::createExpr(Expr));883 } else {884 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(885 Inst.getOperand(0).getExpr(), Inst.getLoc());886 Inst.setOpcode(CSKY::JBSR32);887 Inst.addOperand(MCOperand::createExpr(Expr));888 }889 890 Out.emitInstruction(Inst, getSTI());891 return false;892}893 894bool CSKYAsmParser::processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {895 Inst.setLoc(IDLoc);896 897 if (Inst.getOperand(0).isImm()) {898 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(899 MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()),900 Inst.getLoc());901 Inst.setOpcode(CSKY::JMPI32);902 Inst.erase(std::prev(Inst.end()));903 Inst.addOperand(MCOperand::createExpr(Expr));904 } else {905 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(906 Inst.getOperand(0).getExpr(), Inst.getLoc());907 Inst.setOpcode(CSKY::JBR32);908 Inst.addOperand(MCOperand::createExpr(Expr));909 }910 911 Out.emitInstruction(Inst, getSTI());912 return false;913}914 915bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,916 OperandVector &Operands,917 MCStreamer &Out) {918 919 switch (Inst.getOpcode()) {920 default:921 break;922 case CSKY::LDQ32:923 case CSKY::STQ32:924 if (Inst.getOperand(1).getReg() != CSKY::R4 ||925 Inst.getOperand(2).getReg() != CSKY::R7) {926 return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected");927 }928 Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32);929 break;930 case CSKY::SEXT32:931 case CSKY::ZEXT32:932 if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm())933 return Error(IDLoc, "msb must be greater or equal to lsb");934 break;935 case CSKY::INS32:936 if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm())937 return Error(IDLoc, "msb must be greater or equal to lsb");938 break;939 case CSKY::IDLY32:940 if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0)941 return Error(IDLoc, "n must be in range [0,32]");942 break;943 case CSKY::ADDC32:944 case CSKY::SUBC32:945 case CSKY::ADDC16:946 case CSKY::SUBC16:947 Inst.erase(std::next(Inst.begin()));948 Inst.erase(std::prev(Inst.end()));949 Inst.insert(std::next(Inst.begin()), MCOperand::createReg(CSKY::C));950 Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));951 break;952 case CSKY::CMPNEI32:953 case CSKY::CMPNEI16:954 case CSKY::CMPNE32:955 case CSKY::CMPNE16:956 case CSKY::CMPHSI32:957 case CSKY::CMPHSI16:958 case CSKY::CMPHS32:959 case CSKY::CMPHS16:960 case CSKY::CMPLTI32:961 case CSKY::CMPLTI16:962 case CSKY::CMPLT32:963 case CSKY::CMPLT16:964 case CSKY::BTSTI32:965 Inst.erase(Inst.begin());966 Inst.insert(Inst.begin(), MCOperand::createReg(CSKY::C));967 break;968 case CSKY::MVCV32:969 Inst.erase(std::next(Inst.begin()));970 Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));971 break;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);979 case CSKY::JBSR32:980 case CSKY::JBR16:981 case CSKY::JBT16:982 case CSKY::JBF16:983 case CSKY::JBR32:984 case CSKY::JBT32:985 case CSKY::JBF32:986 unsigned Num = Inst.getNumOperands() - 1;987 assert(Inst.getOperand(Num).isExpr());988 989 const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(990 Inst.getOperand(Num).getExpr(), Inst.getLoc());991 992 Inst.addOperand(MCOperand::createExpr(Expr));993 break;994 }995 996 emitToStreamer(Out, Inst);997 return false;998}999 1000// Attempts to match Name as a register (either using the default name or1001// alternative ABI names), setting RegNo to the matching register. Upon1002// failure, returns true and sets RegNo to 0.1003static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg,1004 StringRef Name) {1005 Reg = MatchRegisterName(Name);1006 1007 if (Reg == CSKY::NoRegister)1008 Reg = MatchRegisterAltName(Name);1009 1010 return Reg == CSKY::NoRegister;1011}1012 1013bool CSKYAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,1014 SMLoc &EndLoc) {1015 const AsmToken &Tok = getParser().getTok();1016 StartLoc = Tok.getLoc();1017 EndLoc = Tok.getEndLoc();1018 StringRef Name = getLexer().getTok().getIdentifier();1019 1020 if (!matchRegisterNameHelper(getSTI(), Reg, Name)) {1021 getParser().Lex(); // Eat identifier token.1022 return false;1023 }1024 1025 return true;1026}1027 1028ParseStatus CSKYAsmParser::parseRegister(OperandVector &Operands) {1029 SMLoc S = getLoc();1030 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);1031 1032 switch (getLexer().getKind()) {1033 default:1034 return ParseStatus::NoMatch;1035 case AsmToken::Identifier: {1036 StringRef Name = getLexer().getTok().getIdentifier();1037 MCRegister Reg;1038 1039 if (matchRegisterNameHelper(getSTI(), Reg, Name))1040 return ParseStatus::NoMatch;1041 1042 getLexer().Lex();1043 Operands.push_back(CSKYOperand::createReg(Reg, S, E));1044 1045 return ParseStatus::Success;1046 }1047 }1048}1049 1050ParseStatus CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) {1051 assert(getLexer().is(AsmToken::LParen));1052 1053 Operands.push_back(CSKYOperand::createToken("(", getLoc()));1054 1055 auto Tok = getParser().Lex(); // Eat '('1056 1057 if (!parseRegister(Operands).isSuccess()) {1058 getLexer().UnLex(Tok);1059 Operands.pop_back();1060 return ParseStatus::NoMatch;1061 }1062 1063 if (getLexer().is(AsmToken::RParen)) {1064 Operands.push_back(CSKYOperand::createToken(")", getLoc()));1065 getParser().Lex(); // Eat ')'1066 return ParseStatus::Success;1067 }1068 1069 if (getLexer().isNot(AsmToken::Comma))1070 return Error(getLoc(), "expected ','");1071 1072 getParser().Lex(); // Eat ','1073 1074 if (parseRegister(Operands).isSuccess()) {1075 if (getLexer().isNot(AsmToken::LessLess))1076 return Error(getLoc(), "expected '<<'");1077 1078 Operands.push_back(CSKYOperand::createToken("<<", getLoc()));1079 1080 getParser().Lex(); // Eat '<<'1081 1082 if (!parseImmediate(Operands).isSuccess())1083 return Error(getLoc(), "expected imm");1084 1085 } else if (!parseImmediate(Operands).isSuccess()) {1086 return Error(getLoc(), "expected imm");1087 }1088 1089 if (getLexer().isNot(AsmToken::RParen))1090 return Error(getLoc(), "expected ')'");1091 1092 Operands.push_back(CSKYOperand::createToken(")", getLoc()));1093 1094 getParser().Lex(); // Eat ')'1095 1096 return ParseStatus::Success;1097}1098 1099ParseStatus CSKYAsmParser::parseImmediate(OperandVector &Operands) {1100 switch (getLexer().getKind()) {1101 default:1102 return ParseStatus::NoMatch;1103 case AsmToken::LParen:1104 case AsmToken::Minus:1105 case AsmToken::Plus:1106 case AsmToken::Integer:1107 case AsmToken::String:1108 break;1109 }1110 1111 const MCExpr *IdVal;1112 SMLoc S = getLoc();1113 if (getParser().parseExpression(IdVal))1114 return Error(getLoc(), "unknown expression");1115 1116 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);1117 Operands.push_back(CSKYOperand::createImm(IdVal, S, E));1118 return ParseStatus::Success;1119}1120 1121/// Looks at a token type and creates the relevant operand from this1122/// information, adding to Operands. If operand was parsed, returns false, else1123/// true.1124bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {1125 // Check if the current operand has a custom associated parser, if so, try to1126 // custom parse the operand, or fallback to the general approach.1127 ParseStatus Result =1128 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);1129 if (Result.isSuccess())1130 return false;1131 if (Result.isFailure())1132 return true;1133 1134 // Attempt to parse token as register1135 auto Res = parseRegister(Operands);1136 if (Res.isSuccess())1137 return false;1138 if (Res.isFailure())1139 return true;1140 1141 // Attempt to parse token as (register, imm)1142 if (getLexer().is(AsmToken::LParen)) {1143 Res = parseBaseRegImm(Operands);1144 if (Res.isSuccess())1145 return false;1146 if (Res.isFailure())1147 return true;1148 }1149 1150 Res = parseImmediate(Operands);1151 if (Res.isSuccess())1152 return false;1153 if (Res.isFailure())1154 return true;1155 1156 // Finally we have exhausted all options and must declare defeat.1157 Error(getLoc(), "unknown operand");1158 return true;1159}1160 1161ParseStatus CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) {1162 SMLoc S = getLoc();1163 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);1164 const MCExpr *Res;1165 1166 if (getLexer().getKind() != AsmToken::Identifier)1167 return ParseStatus::NoMatch;1168 1169 StringRef Identifier;1170 AsmToken Tok = getLexer().getTok();1171 1172 if (getParser().parseIdentifier(Identifier))1173 return Error(getLoc(), "unknown identifier");1174 1175 CSKY::Specifier Kind = CSKY::S_None;1176 if (Identifier.consume_back("@GOT"))1177 Kind = CSKY::S_GOT;1178 else if (Identifier.consume_back("@GOTOFF"))1179 Kind = CSKY::S_GOTOFF;1180 else if (Identifier.consume_back("@PLT"))1181 Kind = CSKY::S_PLT;1182 else if (Identifier.consume_back("@GOTPC"))1183 Kind = CSKY::S_GOTPC;1184 else if (Identifier.consume_back("@TLSGD32"))1185 Kind = CSKY::S_TLSGD;1186 else if (Identifier.consume_back("@GOTTPOFF"))1187 Kind = CSKY::S_TLSIE;1188 else if (Identifier.consume_back("@TPOFF"))1189 Kind = CSKY::S_TLSLE;1190 else if (Identifier.consume_back("@TLSLDM32"))1191 Kind = CSKY::S_TLSLDM;1192 else if (Identifier.consume_back("@TLSLDO32"))1193 Kind = CSKY::S_TLSLDO;1194 1195 MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);1196 1197 if (!Sym)1198 Sym = getContext().getOrCreateSymbol(Identifier);1199 1200 if (Sym->isVariable()) {1201 const MCExpr *V = Sym->getVariableValue();1202 if (!isa<MCSymbolRefExpr>(V)) {1203 getLexer().UnLex(Tok); // Put back if it's not a bare symbol.1204 return Error(getLoc(), "unknown symbol");1205 }1206 Res = V;1207 } else1208 Res = MCSymbolRefExpr::create(Sym, getContext());1209 1210 MCBinaryExpr::Opcode Opcode;1211 switch (getLexer().getKind()) {1212 default:1213 if (Kind != CSKY::S_None)1214 Res = MCSpecifierExpr::create(Res, Kind, getContext());1215 1216 Operands.push_back(CSKYOperand::createImm(Res, S, E));1217 return ParseStatus::Success;1218 case AsmToken::Plus:1219 Opcode = MCBinaryExpr::Add;1220 break;1221 case AsmToken::Minus:1222 Opcode = MCBinaryExpr::Sub;1223 break;1224 }1225 1226 getLexer().Lex(); // eat + or -1227 1228 const MCExpr *Expr;1229 if (getParser().parseExpression(Expr))1230 return Error(getLoc(), "unknown expression");1231 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());1232 Operands.push_back(CSKYOperand::createImm(Res, S, E));1233 return ParseStatus::Success;1234}1235 1236ParseStatus CSKYAsmParser::parseDataSymbol(OperandVector &Operands) {1237 SMLoc S = getLoc();1238 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);1239 const MCExpr *Res;1240 1241 if (!parseOptionalToken(AsmToken::LBrac))1242 return ParseStatus::NoMatch;1243 if (getLexer().getKind() != AsmToken::Identifier) {1244 const MCExpr *Expr;1245 if (getParser().parseExpression(Expr))1246 return Error(getLoc(), "unknown expression");1247 1248 if (parseToken(AsmToken::RBrac, "expected ']'"))1249 return ParseStatus::Failure;1250 1251 Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));1252 return ParseStatus::Success;1253 }1254 1255 AsmToken Tok = getLexer().getTok();1256 StringRef Identifier;1257 1258 if (getParser().parseIdentifier(Identifier))1259 return Error(getLoc(), "unknown identifier " + Identifier);1260 1261 CSKY::Specifier Kind = CSKY::S_None;1262 if (Identifier.consume_back("@GOT"))1263 Kind = CSKY::S_GOT_IMM18_BY4;1264 else if (Identifier.consume_back("@PLT"))1265 Kind = CSKY::S_PLT_IMM18_BY4;1266 1267 MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);1268 1269 if (!Sym)1270 Sym = getContext().getOrCreateSymbol(Identifier);1271 1272 if (Sym->isVariable()) {1273 const MCExpr *V = Sym->getVariableValue();1274 if (!isa<MCSymbolRefExpr>(V)) {1275 getLexer().UnLex(Tok); // Put back if it's not a bare symbol.1276 return Error(getLoc(), "unknown symbol");1277 }1278 Res = V;1279 } else {1280 Res = MCSymbolRefExpr::create(Sym, getContext());1281 }1282 1283 MCBinaryExpr::Opcode Opcode;1284 switch (getLexer().getKind()) {1285 default:1286 return Error(getLoc(), "unknown symbol");1287 case AsmToken::RBrac:1288 1289 getLexer().Lex(); // Eat ']'.1290 1291 if (Kind != CSKY::S_None)1292 Res = MCSpecifierExpr::create(Res, Kind, getContext());1293 1294 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));1295 return ParseStatus::Success;1296 case AsmToken::Plus:1297 Opcode = MCBinaryExpr::Add;1298 break;1299 case AsmToken::Minus:1300 Opcode = MCBinaryExpr::Sub;1301 break;1302 }1303 1304 getLexer().Lex(); // eat + or -1305 1306 const MCExpr *Expr;1307 if (getParser().parseExpression(Expr))1308 return Error(getLoc(), "unknown expression");1309 if (parseToken(AsmToken::RBrac, "expected ']'"))1310 return ParseStatus::Failure;1311 1312 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());1313 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));1314 return ParseStatus::Success;1315}1316 1317ParseStatus CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) {1318 SMLoc S = getLoc();1319 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);1320 const MCExpr *Res;1321 1322 if (!parseOptionalToken(AsmToken::LBrac))1323 return ParseStatus::NoMatch;1324 1325 if (getLexer().getKind() != AsmToken::Identifier) {1326 const MCExpr *Expr;1327 if (getParser().parseExpression(Expr))1328 return Error(getLoc(), "unknown expression");1329 if (parseToken(AsmToken::RBrac))1330 return ParseStatus::Failure;1331 1332 Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));1333 return ParseStatus::Success;1334 }1335 1336 AsmToken Tok = getLexer().getTok();1337 StringRef Identifier;1338 1339 if (getParser().parseIdentifier(Identifier))1340 return Error(getLoc(), "unknown identifier");1341 1342 MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);1343 1344 if (!Sym)1345 Sym = getContext().getOrCreateSymbol(Identifier);1346 1347 if (Sym->isVariable()) {1348 const MCExpr *V = Sym->getVariableValue();1349 if (!isa<MCSymbolRefExpr>(V)) {1350 getLexer().UnLex(Tok); // Put back if it's not a bare symbol.1351 return Error(getLoc(), "unknown symbol");1352 }1353 Res = V;1354 } else {1355 Res = MCSymbolRefExpr::create(Sym, getContext());1356 }1357 1358 MCBinaryExpr::Opcode Opcode;1359 switch (getLexer().getKind()) {1360 default:1361 return Error(getLoc(), "unknown symbol");1362 case AsmToken::RBrac:1363 1364 getLexer().Lex(); // Eat ']'.1365 1366 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));1367 return ParseStatus::Success;1368 case AsmToken::Plus:1369 Opcode = MCBinaryExpr::Add;1370 break;1371 case AsmToken::Minus:1372 Opcode = MCBinaryExpr::Sub;1373 break;1374 }1375 1376 getLexer().Lex(); // eat + or -1377 1378 const MCExpr *Expr;1379 if (getParser().parseExpression(Expr))1380 return Error(getLoc(), "unknown expression");1381 if (parseToken(AsmToken::RBrac, "expected ']'"))1382 return ParseStatus::Failure;1383 1384 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());1385 Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));1386 return ParseStatus::Success;1387}1388 1389ParseStatus CSKYAsmParser::parsePSRFlag(OperandVector &Operands) {1390 SMLoc S = getLoc();1391 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);1392 1393 unsigned Flag = 0;1394 1395 while (getLexer().isNot(AsmToken::EndOfStatement)) {1396 StringRef Identifier;1397 if (getParser().parseIdentifier(Identifier))1398 return Error(getLoc(), "unknown identifier " + Identifier);1399 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;1410 else1411 return Error(getLoc(), "expected " + Identifier);1412 1413 if (getLexer().is(AsmToken::EndOfStatement))1414 break;1415 1416 if (parseToken(AsmToken::Comma, "expected ','"))1417 return ParseStatus::Failure;1418 }1419 1420 Operands.push_back(1421 CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E));1422 return ParseStatus::Success;1423}1424 1425ParseStatus CSKYAsmParser::parseRegSeq(OperandVector &Operands) {1426 SMLoc S = getLoc();1427 1428 if (!parseRegister(Operands).isSuccess())1429 return ParseStatus::NoMatch;1430 1431 auto Ry = Operands.back()->getReg();1432 Operands.pop_back();1433 1434 if (parseToken(AsmToken::Minus, "expected '-'"))1435 return ParseStatus::Failure;1436 if (!parseRegister(Operands).isSuccess())1437 return Error(getLoc(), "invalid register");1438 1439 auto Rz = Operands.back()->getReg();1440 Operands.pop_back();1441 1442 Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S));1443 return ParseStatus::Success;1444}1445 1446ParseStatus CSKYAsmParser::parseRegList(OperandVector &Operands) {1447 SMLoc S = getLoc();1448 SmallVector<MCRegister, 4> reglist;1449 while (true) {1450 1451 if (!parseRegister(Operands).isSuccess())1452 return Error(getLoc(), "invalid register");1453 1454 auto Ry = Operands.back()->getReg();1455 Operands.pop_back();1456 1457 if (parseOptionalToken(AsmToken::Minus)) {1458 if (!parseRegister(Operands).isSuccess())1459 return Error(getLoc(), "invalid register");1460 1461 auto Rz = Operands.back()->getReg();1462 Operands.pop_back();1463 1464 reglist.push_back(Ry);1465 reglist.push_back(Rz);1466 1467 if (getLexer().is(AsmToken::EndOfStatement))1468 break;1469 (void)parseOptionalToken(AsmToken::Comma);1470 } else if (parseOptionalToken(AsmToken::Comma)) {1471 reglist.push_back(Ry);1472 reglist.push_back(Ry);1473 } else if (getLexer().is(AsmToken::EndOfStatement)) {1474 reglist.push_back(Ry);1475 reglist.push_back(Ry);1476 break;1477 } else {1478 return Error(getLoc(), "invalid register list");1479 }1480 }1481 1482 Operands.push_back(CSKYOperand::createRegList(reglist, S));1483 return ParseStatus::Success;1484}1485 1486bool CSKYAsmParser::parseInstruction(ParseInstructionInfo &Info, StringRef Name,1487 SMLoc NameLoc, OperandVector &Operands) {1488 // First operand is token for instruction.1489 Operands.push_back(CSKYOperand::createToken(Name, NameLoc));1490 1491 // If there are no more operands, then finish.1492 if (getLexer().is(AsmToken::EndOfStatement))1493 return false;1494 1495 // Parse first operand.1496 if (parseOperand(Operands, Name))1497 return true;1498 1499 // Parse until end of statement, consuming commas between operands.1500 while (parseOptionalToken(AsmToken::Comma))1501 if (parseOperand(Operands, Name))1502 return true;1503 1504 if (getLexer().isNot(AsmToken::EndOfStatement)) {1505 SMLoc Loc = getLexer().getLoc();1506 getParser().eatToEndOfStatement();1507 return Error(Loc, "unexpected token");1508 }1509 1510 getParser().Lex(); // Consume the EndOfStatement.1511 return false;1512}1513 1514ParseStatus CSKYAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,1515 SMLoc &EndLoc) {1516 const AsmToken &Tok = getParser().getTok();1517 StartLoc = Tok.getLoc();1518 EndLoc = Tok.getEndLoc();1519 1520 StringRef Name = getLexer().getTok().getIdentifier();1521 1522 if (matchRegisterNameHelper(getSTI(), Reg, Name))1523 return ParseStatus::NoMatch;1524 1525 getParser().Lex(); // Eat identifier token.1526 return ParseStatus::Success;1527}1528 1529ParseStatus CSKYAsmParser::parseDirective(AsmToken DirectiveID) {1530 StringRef IDVal = DirectiveID.getString();1531 1532 if (IDVal == ".csky_attribute")1533 return parseDirectiveAttribute();1534 1535 return ParseStatus::NoMatch;1536}1537 1538/// parseDirectiveAttribute1539/// ::= .attribute expression ',' ( expression | "string" )1540bool CSKYAsmParser::parseDirectiveAttribute() {1541 MCAsmParser &Parser = getParser();1542 int64_t Tag;1543 SMLoc TagLoc;1544 TagLoc = Parser.getTok().getLoc();1545 if (Parser.getTok().is(AsmToken::Identifier)) {1546 StringRef Name = Parser.getTok().getIdentifier();1547 std::optional<unsigned> Ret =1548 ELFAttrs::attrTypeFromString(Name, CSKYAttrs::getCSKYAttributeTags());1549 if (!Ret)1550 return Error(TagLoc, "attribute name not recognised: " + Name);1551 Tag = *Ret;1552 Parser.Lex();1553 } else {1554 const MCExpr *AttrExpr;1555 1556 TagLoc = Parser.getTok().getLoc();1557 if (Parser.parseExpression(AttrExpr))1558 return true;1559 1560 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);1561 if (!CE)1562 return Error(TagLoc, "expected numeric constant");1563 1564 Tag = CE->getValue();1565 }1566 1567 if (Parser.parseComma())1568 return true;1569 1570 StringRef StringValue;1571 int64_t IntegerValue = 0;1572 bool IsIntegerValue = ((Tag != CSKYAttrs::CSKY_ARCH_NAME) &&1573 (Tag != CSKYAttrs::CSKY_CPU_NAME) &&1574 (Tag != CSKYAttrs::CSKY_FPU_NUMBER_MODULE));1575 1576 SMLoc ValueExprLoc = Parser.getTok().getLoc();1577 if (IsIntegerValue) {1578 const MCExpr *ValueExpr;1579 if (Parser.parseExpression(ValueExpr))1580 return true;1581 1582 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);1583 if (!CE)1584 return Error(ValueExprLoc, "expected numeric constant");1585 IntegerValue = CE->getValue();1586 } else {1587 if (Parser.getTok().isNot(AsmToken::String))1588 return Error(Parser.getTok().getLoc(), "expected string constant");1589 1590 StringValue = Parser.getTok().getStringContents();1591 Parser.Lex();1592 }1593 1594 if (Parser.parseEOL())1595 return true;1596 1597 if (IsIntegerValue)1598 getTargetStreamer().emitAttribute(Tag, IntegerValue);1599 else if (Tag != CSKYAttrs::CSKY_ARCH_NAME && Tag != CSKYAttrs::CSKY_CPU_NAME)1600 getTargetStreamer().emitTextAttribute(Tag, StringValue);1601 else {1602 CSKY::ArchKind ID = (Tag == CSKYAttrs::CSKY_ARCH_NAME)1603 ? CSKY::parseArch(StringValue)1604 : CSKY::parseCPUArch(StringValue);1605 if (ID == CSKY::ArchKind::INVALID)1606 return Error(ValueExprLoc, (Tag == CSKYAttrs::CSKY_ARCH_NAME)1607 ? "unknown arch name"1608 : "unknown cpu name");1609 1610 getTargetStreamer().emitTextAttribute(Tag, StringValue);1611 }1612 1613 return false;1614}1615 1616unsigned CSKYAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,1617 unsigned Kind) {1618 CSKYOperand &Op = static_cast<CSKYOperand &>(AsmOp);1619 1620 if (!Op.isReg())1621 return Match_InvalidOperand;1622 1623 MCRegister Reg = Op.getReg();1624 1625 if (CSKYMCRegisterClasses[CSKY::FPR32RegClassID].contains(Reg)) {1626 // As the parser couldn't differentiate an FPR64 from an FPR32, coerce the1627 // register from FPR32 to FPR64 if necessary.1628 if (Kind == MCK_FPR64 || Kind == MCK_sFPR64) {1629 Op.Reg.RegNum = convertFPR32ToFPR64(Reg);1630 if (Kind == MCK_sFPR64 &&1631 (Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F15_64))1632 return Match_InvalidRegOutOfRange;1633 if (Kind == MCK_FPR64 &&1634 (Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F31_64))1635 return Match_InvalidRegOutOfRange;1636 return Match_Success;1637 }1638 }1639 1640 if (CSKYMCRegisterClasses[CSKY::GPRRegClassID].contains(Reg)) {1641 if (Kind == MCK_GPRPair) {1642 Op.Reg.RegNum = MRI->getEncodingValue(Reg) + CSKY::R0_R1;1643 return Match_Success;1644 }1645 }1646 1647 return Match_InvalidOperand;1648}1649 1650void CSKYAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {1651 MCInst CInst;1652 bool Res = false;1653 if (EnableCompressedInst)1654 Res = compressInst(CInst, Inst, getSTI());1655 if (Res)1656 ++CSKYNumInstrsCompressed;1657 S.emitInstruction((Res ? CInst : Inst), getSTI());1658}1659 1660extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser() {1661 RegisterMCAsmParser<CSKYAsmParser> X(getTheCSKYTarget());1662}1663