Path: blob/main/contrib/llvm-project/llvm/lib/Target/CSKY/AsmParser/CSKYAsmParser.cpp
35293 views
//===---- CSKYAsmParser.cpp - Parse CSKY assembly to MCInst instructions --===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "MCTargetDesc/CSKYInstPrinter.h"9#include "MCTargetDesc/CSKYMCExpr.h"10#include "MCTargetDesc/CSKYMCTargetDesc.h"11#include "MCTargetDesc/CSKYTargetStreamer.h"12#include "TargetInfo/CSKYTargetInfo.h"13#include "llvm/ADT/STLExtras.h"14#include "llvm/ADT/Statistic.h"15#include "llvm/ADT/StringExtras.h"16#include "llvm/ADT/StringSwitch.h"17#include "llvm/BinaryFormat/ELF.h"18#include "llvm/CodeGen/Register.h"19#include "llvm/MC/MCContext.h"20#include "llvm/MC/MCExpr.h"21#include "llvm/MC/MCInst.h"22#include "llvm/MC/MCInstrInfo.h"23#include "llvm/MC/MCParser/MCAsmLexer.h"24#include "llvm/MC/MCParser/MCParsedAsmOperand.h"25#include "llvm/MC/MCParser/MCTargetAsmParser.h"26#include "llvm/MC/MCRegisterInfo.h"27#include "llvm/MC/MCSectionELF.h"28#include "llvm/MC/MCStreamer.h"29#include "llvm/MC/MCSubtargetInfo.h"30#include "llvm/MC/TargetRegistry.h"31#include "llvm/Support/CSKYAttributes.h"32#include "llvm/Support/Casting.h"33#include "llvm/Support/CommandLine.h"34#include "llvm/Support/Debug.h"35#include "llvm/TargetParser/CSKYTargetParser.h"3637using namespace llvm;3839#define DEBUG_TYPE "csky-asm-parser"4041// Include the auto-generated portion of the compress emitter.42#define GEN_COMPRESS_INSTR43#include "CSKYGenCompressInstEmitter.inc"4445STATISTIC(CSKYNumInstrsCompressed,46"Number of C-SKY Compressed instructions emitted");4748static cl::opt<bool>49EnableCompressedInst("enable-csky-asm-compressed-inst", cl::Hidden,50cl::init(false),51cl::desc("Enable C-SKY asm compressed instruction"));5253namespace {54struct CSKYOperand;5556class CSKYAsmParser : public MCTargetAsmParser {5758const MCRegisterInfo *MRI;5960unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,61unsigned Kind) override;6263bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,64int64_t Lower, int64_t Upper,65const Twine &Msg);6667SMLoc getLoc() const { return getParser().getTok().getLoc(); }6869bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,70OperandVector &Operands, MCStreamer &Out,71uint64_t &ErrorInfo,72bool MatchingInlineAsm) override;7374bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;7576bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,77SMLoc NameLoc, OperandVector &Operands) override;7879ParseStatus parseDirective(AsmToken DirectiveID) override;8081// Helper to actually emit an instruction to the MCStreamer. Also, when82// possible, compression of the instruction is performed.83void emitToStreamer(MCStreamer &S, const MCInst &Inst);8485ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,86SMLoc &EndLoc) override;8788bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,89MCStreamer &Out);90bool processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);91bool processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);92bool processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);9394CSKYTargetStreamer &getTargetStreamer() {95assert(getParser().getStreamer().getTargetStreamer() &&96"do not have a target streamer");97MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();98return static_cast<CSKYTargetStreamer &>(TS);99}100101// Auto-generated instruction matching functions102#define GET_ASSEMBLER_HEADER103#include "CSKYGenAsmMatcher.inc"104105ParseStatus parseImmediate(OperandVector &Operands);106ParseStatus parseRegister(OperandVector &Operands);107ParseStatus parseBaseRegImm(OperandVector &Operands);108ParseStatus parseCSKYSymbol(OperandVector &Operands);109ParseStatus parseConstpoolSymbol(OperandVector &Operands);110ParseStatus parseDataSymbol(OperandVector &Operands);111ParseStatus parsePSRFlag(OperandVector &Operands);112ParseStatus parseRegSeq(OperandVector &Operands);113ParseStatus parseRegList(OperandVector &Operands);114115bool parseOperand(OperandVector &Operands, StringRef Mnemonic);116117bool parseDirectiveAttribute();118119public:120enum CSKYMatchResultTy {121Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,122Match_RequiresSameSrcAndDst,123Match_InvalidRegOutOfRange,124#define GET_OPERAND_DIAGNOSTIC_TYPES125#include "CSKYGenAsmMatcher.inc"126#undef GET_OPERAND_DIAGNOSTIC_TYPES127};128129CSKYAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,130const MCInstrInfo &MII, const MCTargetOptions &Options)131: MCTargetAsmParser(Options, STI, MII) {132133MCAsmParserExtension::Initialize(Parser);134135// Cache the MCRegisterInfo.136MRI = getContext().getRegisterInfo();137138setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));139getTargetStreamer().emitTargetAttributes(STI);140}141};142143/// Instances of this class represent a parsed machine instruction.144struct CSKYOperand : public MCParsedAsmOperand {145146enum KindTy {147Token,148Register,149Immediate,150RegisterSeq,151CPOP,152RegisterList153} Kind;154155struct RegOp {156unsigned RegNum;157};158159struct ImmOp {160const MCExpr *Val;161};162163struct ConstpoolOp {164const MCExpr *Val;165};166167struct RegSeqOp {168unsigned RegNumFrom;169unsigned RegNumTo;170};171172struct RegListOp {173unsigned List1From = 0;174unsigned List1To = 0;175unsigned List2From = 0;176unsigned List2To = 0;177unsigned List3From = 0;178unsigned List3To = 0;179unsigned List4From = 0;180unsigned List4To = 0;181};182183SMLoc StartLoc, EndLoc;184union {185StringRef Tok;186RegOp Reg;187ImmOp Imm;188ConstpoolOp CPool;189RegSeqOp RegSeq;190RegListOp RegList;191};192193CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}194195public:196CSKYOperand(const CSKYOperand &o) : MCParsedAsmOperand() {197Kind = o.Kind;198StartLoc = o.StartLoc;199EndLoc = o.EndLoc;200switch (Kind) {201case Register:202Reg = o.Reg;203break;204case RegisterSeq:205RegSeq = o.RegSeq;206break;207case CPOP:208CPool = o.CPool;209break;210case Immediate:211Imm = o.Imm;212break;213case Token:214Tok = o.Tok;215break;216case RegisterList:217RegList = o.RegList;218break;219}220}221222bool isToken() const override { return Kind == Token; }223bool isReg() const override { return Kind == Register; }224bool isImm() const override { return Kind == Immediate; }225bool isRegisterSeq() const { return Kind == RegisterSeq; }226bool isRegisterList() const { return Kind == RegisterList; }227bool isConstPoolOp() const { return Kind == CPOP; }228229bool isMem() const override { return false; }230231static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) {232if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {233Imm = CE->getValue();234return true;235}236237return false;238}239240template <unsigned num, unsigned shift = 0> bool isUImm() const {241if (!isImm())242return false;243244int64_t Imm;245bool IsConstantImm = evaluateConstantImm(getImm(), Imm);246return IsConstantImm && isShiftedUInt<num, shift>(Imm);247}248249template <unsigned num> bool isOImm() const {250if (!isImm())251return false;252253int64_t Imm;254bool IsConstantImm = evaluateConstantImm(getImm(), Imm);255return IsConstantImm && isUInt<num>(Imm - 1);256}257258template <unsigned num, unsigned shift = 0> bool isSImm() const {259if (!isImm())260return false;261262int64_t Imm;263bool IsConstantImm = evaluateConstantImm(getImm(), Imm);264return IsConstantImm && isShiftedInt<num, shift>(Imm);265}266267bool isUImm1() const { return isUImm<1>(); }268bool isUImm2() const { return isUImm<2>(); }269bool isUImm3() const { return isUImm<3>(); }270bool isUImm4() const { return isUImm<4>(); }271bool isUImm5() const { return isUImm<5>(); }272bool isUImm6() const { return isUImm<6>(); }273bool isUImm7() const { return isUImm<7>(); }274bool isUImm8() const { return isUImm<8>(); }275bool isUImm12() const { return isUImm<12>(); }276bool isUImm16() const { return isUImm<16>(); }277bool isUImm20() const { return isUImm<20>(); }278bool isUImm24() const { return isUImm<24>(); }279280bool isOImm3() const { return isOImm<3>(); }281bool isOImm4() const { return isOImm<4>(); }282bool isOImm5() const { return isOImm<5>(); }283bool isOImm6() const { return isOImm<6>(); }284bool isOImm8() const { return isOImm<8>(); }285bool isOImm12() const { return isOImm<12>(); }286bool isOImm16() const { return isOImm<16>(); }287288bool isSImm8() const { return isSImm<8>(); }289290bool isUImm5Shift1() { return isUImm<5, 1>(); }291bool isUImm5Shift2() { return isUImm<5, 2>(); }292bool isUImm7Shift1() { return isUImm<7, 1>(); }293bool isUImm7Shift2() { return isUImm<7, 2>(); }294bool isUImm7Shift3() { return isUImm<7, 3>(); }295bool isUImm8Shift2() { return isUImm<8, 2>(); }296bool isUImm8Shift3() { return isUImm<8, 3>(); }297bool isUImm8Shift8() { return isUImm<8, 8>(); }298bool isUImm8Shift16() { return isUImm<8, 16>(); }299bool isUImm8Shift24() { return isUImm<8, 24>(); }300bool isUImm12Shift1() { return isUImm<12, 1>(); }301bool isUImm12Shift2() { return isUImm<12, 2>(); }302bool isUImm16Shift8() { return isUImm<16, 8>(); }303bool isUImm16Shift16() { return isUImm<16, 16>(); }304bool isUImm24Shift8() { return isUImm<24, 8>(); }305306bool isSImm16Shift1() { return isSImm<16, 1>(); }307308bool isCSKYSymbol() const { return isImm(); }309310bool isConstpool() const { return isConstPoolOp(); }311bool isDataSymbol() const { return isConstPoolOp(); }312313bool isPSRFlag() const {314int64_t Imm;315// Must be of 'immediate' type and a constant.316if (!isImm() || !evaluateConstantImm(getImm(), Imm))317return false;318319return isUInt<5>(Imm);320}321322template <unsigned MIN, unsigned MAX> bool isRegSeqTemplate() const {323if (!isRegisterSeq())324return false;325326std::pair<unsigned, unsigned> regSeq = getRegSeq();327328return MIN <= regSeq.first && regSeq.first <= regSeq.second &&329regSeq.second <= MAX;330}331332bool isRegSeq() const { return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); }333334bool isRegSeqV1() const {335return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>();336}337338bool isRegSeqV2() const {339return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>();340}341342static bool isLegalRegList(unsigned from, unsigned to) {343if (from == 0 && to == 0)344return true;345346if (from == to) {347if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 &&348from != CSKY::R28)349return false;350351return true;352} else {353if (from != CSKY::R4 && from != CSKY::R16)354return false;355356if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12)357return true;358else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18)359return true;360else361return false;362}363}364365bool isRegList() const {366if (!isRegisterList())367return false;368369auto regList = getRegList();370371if (!isLegalRegList(regList.List1From, regList.List1To))372return false;373if (!isLegalRegList(regList.List2From, regList.List2To))374return false;375if (!isLegalRegList(regList.List3From, regList.List3To))376return false;377if (!isLegalRegList(regList.List4From, regList.List4To))378return false;379380return true;381}382383bool isExtImm6() {384if (!isImm())385return false;386387int64_t Imm;388bool IsConstantImm = evaluateConstantImm(getImm(), Imm);389if (!IsConstantImm)390return false;391392int uimm4 = Imm & 0xf;393394return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14;395}396397/// Gets location of the first token of this operand.398SMLoc getStartLoc() const override { return StartLoc; }399/// Gets location of the last token of this operand.400SMLoc getEndLoc() const override { return EndLoc; }401402MCRegister getReg() const override {403assert(Kind == Register && "Invalid type access!");404return Reg.RegNum;405}406407std::pair<unsigned, unsigned> getRegSeq() const {408assert(Kind == RegisterSeq && "Invalid type access!");409return std::pair<unsigned, unsigned>(RegSeq.RegNumFrom, RegSeq.RegNumTo);410}411412RegListOp getRegList() const {413assert(Kind == RegisterList && "Invalid type access!");414return RegList;415}416417const MCExpr *getImm() const {418assert(Kind == Immediate && "Invalid type access!");419return Imm.Val;420}421422const MCExpr *getConstpoolOp() const {423assert(Kind == CPOP && "Invalid type access!");424return CPool.Val;425}426427StringRef getToken() const {428assert(Kind == Token && "Invalid type access!");429return Tok;430}431432void print(raw_ostream &OS) const override {433auto RegName = [](MCRegister Reg) {434if (Reg)435return CSKYInstPrinter::getRegisterName(Reg);436else437return "noreg";438};439440switch (Kind) {441case CPOP:442OS << *getConstpoolOp();443break;444case Immediate:445OS << *getImm();446break;447case KindTy::Register:448OS << "<register " << RegName(getReg()) << ">";449break;450case RegisterSeq:451OS << "<register-seq ";452OS << RegName(getRegSeq().first) << "-" << RegName(getRegSeq().second)453<< ">";454break;455case RegisterList:456OS << "<register-list ";457OS << RegName(getRegList().List1From) << "-"458<< RegName(getRegList().List1To) << ",";459OS << RegName(getRegList().List2From) << "-"460<< RegName(getRegList().List2To) << ",";461OS << RegName(getRegList().List3From) << "-"462<< RegName(getRegList().List3To) << ",";463OS << RegName(getRegList().List4From) << "-"464<< RegName(getRegList().List4To);465break;466case Token:467OS << "'" << getToken() << "'";468break;469}470}471472static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) {473auto Op = std::make_unique<CSKYOperand>(Token);474Op->Tok = Str;475Op->StartLoc = S;476Op->EndLoc = S;477return Op;478}479480static std::unique_ptr<CSKYOperand> createReg(unsigned RegNo, SMLoc S,481SMLoc E) {482auto Op = std::make_unique<CSKYOperand>(Register);483Op->Reg.RegNum = RegNo;484Op->StartLoc = S;485Op->EndLoc = E;486return Op;487}488489static std::unique_ptr<CSKYOperand> createRegSeq(unsigned RegNoFrom,490unsigned RegNoTo, SMLoc S) {491auto Op = std::make_unique<CSKYOperand>(RegisterSeq);492Op->RegSeq.RegNumFrom = RegNoFrom;493Op->RegSeq.RegNumTo = RegNoTo;494Op->StartLoc = S;495Op->EndLoc = S;496return Op;497}498499static std::unique_ptr<CSKYOperand>500createRegList(SmallVector<unsigned, 4> reglist, SMLoc S) {501auto Op = std::make_unique<CSKYOperand>(RegisterList);502Op->RegList.List1From = 0;503Op->RegList.List1To = 0;504Op->RegList.List2From = 0;505Op->RegList.List2To = 0;506Op->RegList.List3From = 0;507Op->RegList.List3To = 0;508Op->RegList.List4From = 0;509Op->RegList.List4To = 0;510511for (unsigned i = 0; i < reglist.size(); i += 2) {512if (Op->RegList.List1From == 0) {513Op->RegList.List1From = reglist[i];514Op->RegList.List1To = reglist[i + 1];515} else if (Op->RegList.List2From == 0) {516Op->RegList.List2From = reglist[i];517Op->RegList.List2To = reglist[i + 1];518} else if (Op->RegList.List3From == 0) {519Op->RegList.List3From = reglist[i];520Op->RegList.List3To = reglist[i + 1];521} else if (Op->RegList.List4From == 0) {522Op->RegList.List4From = reglist[i];523Op->RegList.List4To = reglist[i + 1];524} else {525assert(0);526}527}528529Op->StartLoc = S;530Op->EndLoc = S;531return Op;532}533534static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S,535SMLoc E) {536auto Op = std::make_unique<CSKYOperand>(Immediate);537Op->Imm.Val = Val;538Op->StartLoc = S;539Op->EndLoc = E;540return Op;541}542543static std::unique_ptr<CSKYOperand> createConstpoolOp(const MCExpr *Val,544SMLoc S, SMLoc E) {545auto Op = std::make_unique<CSKYOperand>(CPOP);546Op->CPool.Val = Val;547Op->StartLoc = S;548Op->EndLoc = E;549return Op;550}551552void addExpr(MCInst &Inst, const MCExpr *Expr) const {553assert(Expr && "Expr shouldn't be null!");554if (auto *CE = dyn_cast<MCConstantExpr>(Expr))555Inst.addOperand(MCOperand::createImm(CE->getValue()));556else557Inst.addOperand(MCOperand::createExpr(Expr));558}559560// Used by the TableGen Code.561void addRegOperands(MCInst &Inst, unsigned N) const {562assert(N == 1 && "Invalid number of operands!");563Inst.addOperand(MCOperand::createReg(getReg()));564}565566void addImmOperands(MCInst &Inst, unsigned N) const {567assert(N == 1 && "Invalid number of operands!");568addExpr(Inst, getImm());569}570571void addConstpoolOperands(MCInst &Inst, unsigned N) const {572assert(N == 1 && "Invalid number of operands!");573Inst.addOperand(MCOperand::createExpr(getConstpoolOp()));574}575576void addRegSeqOperands(MCInst &Inst, unsigned N) const {577assert(N == 2 && "Invalid number of operands!");578auto regSeq = getRegSeq();579580Inst.addOperand(MCOperand::createReg(regSeq.first));581Inst.addOperand(MCOperand::createReg(regSeq.second));582}583584static unsigned getListValue(unsigned ListFrom, unsigned ListTo) {585if (ListFrom == ListTo && ListFrom == CSKY::R15)586return (1 << 4);587else if (ListFrom == ListTo && ListFrom == CSKY::R28)588return (1 << 8);589else if (ListFrom == CSKY::R4)590return ListTo - ListFrom + 1;591else if (ListFrom == CSKY::R16)592return ((ListTo - ListFrom + 1) << 5);593else594return 0;595}596597void addRegListOperands(MCInst &Inst, unsigned N) const {598assert(N == 1 && "Invalid number of operands!");599auto regList = getRegList();600601unsigned V = 0;602603unsigned T = getListValue(regList.List1From, regList.List1To);604if (T != 0)605V = V | T;606607T = getListValue(regList.List2From, regList.List2To);608if (T != 0)609V = V | T;610611T = getListValue(regList.List3From, regList.List3To);612if (T != 0)613V = V | T;614615T = getListValue(regList.List4From, regList.List4To);616if (T != 0)617V = V | T;618619Inst.addOperand(MCOperand::createImm(V));620}621622bool isValidForTie(const CSKYOperand &Other) const {623if (Kind != Other.Kind)624return false;625626switch (Kind) {627default:628llvm_unreachable("Unexpected kind");629return false;630case Register:631return Reg.RegNum == Other.Reg.RegNum;632}633}634};635} // end anonymous namespace.636637#define GET_REGISTER_MATCHER638#define GET_SUBTARGET_FEATURE_NAME639#define GET_MATCHER_IMPLEMENTATION640#define GET_MNEMONIC_SPELL_CHECKER641#include "CSKYGenAsmMatcher.inc"642643static MCRegister convertFPR32ToFPR64(MCRegister Reg) {644assert(Reg >= CSKY::F0_32 && Reg <= CSKY::F31_32 && "Invalid register");645return Reg - CSKY::F0_32 + CSKY::F0_64;646}647648static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,649unsigned VariantID = 0);650651bool CSKYAsmParser::generateImmOutOfRangeError(652OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,653const Twine &Msg = "immediate must be an integer in the range") {654SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();655return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");656}657658bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,659OperandVector &Operands,660MCStreamer &Out,661uint64_t &ErrorInfo,662bool MatchingInlineAsm) {663MCInst Inst;664FeatureBitset MissingFeatures;665666auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,667MatchingInlineAsm);668switch (Result) {669default:670break;671case Match_Success:672return processInstruction(Inst, IDLoc, Operands, Out);673case Match_MissingFeature: {674assert(MissingFeatures.any() && "Unknown missing features!");675ListSeparator LS;676std::string Msg = "instruction requires the following: ";677for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {678if (MissingFeatures[i]) {679Msg += LS;680Msg += getSubtargetFeatureName(i);681}682}683return Error(IDLoc, Msg);684}685case Match_MnemonicFail: {686FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());687std::string Suggestion =688CSKYMnemonicSpellCheck(((CSKYOperand &)*Operands[0]).getToken(), FBS);689return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);690}691case Match_InvalidTiedOperand:692case Match_InvalidOperand: {693SMLoc ErrorLoc = IDLoc;694if (ErrorInfo != ~0U) {695if (ErrorInfo >= Operands.size())696return Error(ErrorLoc, "too few operands for instruction");697698ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();699if (ErrorLoc == SMLoc())700ErrorLoc = IDLoc;701}702return Error(ErrorLoc, "invalid operand for instruction");703}704}705706// Handle the case when the error message is of specific type707// other than the generic Match_InvalidOperand, and the708// corresponding operand is missing.709if (Result > FIRST_TARGET_MATCH_RESULT_TY) {710SMLoc ErrorLoc = IDLoc;711if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())712return Error(ErrorLoc, "too few operands for instruction");713}714715switch (Result) {716default:717break;718case Match_InvalidSImm8:719return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),720(1 << 7) - 1);721case Match_InvalidOImm3:722return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3));723case Match_InvalidOImm4:724return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));725case Match_InvalidOImm5:726return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));727case Match_InvalidOImm6:728return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));729case Match_InvalidOImm8:730return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8));731case Match_InvalidOImm12:732return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12));733case Match_InvalidOImm16:734return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16));735case Match_InvalidUImm1:736return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);737case Match_InvalidUImm2:738return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);739case Match_InvalidUImm3:740return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);741case Match_InvalidUImm4:742return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);743case Match_InvalidUImm5:744return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);745case Match_InvalidUImm6:746return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);747case Match_InvalidUImm7:748return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);749case Match_InvalidUImm8:750return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);751case Match_InvalidUImm12:752return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);753case Match_InvalidUImm16:754return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1);755case Match_InvalidUImm5Shift1:756return generateImmOutOfRangeError(757Operands, ErrorInfo, 0, (1 << 5) - 2,758"immediate must be a multiple of 2 bytes in the range");759case Match_InvalidUImm12Shift1:760return generateImmOutOfRangeError(761Operands, ErrorInfo, 0, (1 << 12) - 2,762"immediate must be a multiple of 2 bytes in the range");763case Match_InvalidUImm5Shift2:764return generateImmOutOfRangeError(765Operands, ErrorInfo, 0, (1 << 5) - 4,766"immediate must be a multiple of 4 bytes in the range");767case Match_InvalidUImm7Shift1:768return generateImmOutOfRangeError(769Operands, ErrorInfo, 0, (1 << 7) - 2,770"immediate must be a multiple of 2 bytes in the range");771case Match_InvalidUImm7Shift2:772return generateImmOutOfRangeError(773Operands, ErrorInfo, 0, (1 << 7) - 4,774"immediate must be a multiple of 4 bytes in the range");775case Match_InvalidUImm8Shift2:776return generateImmOutOfRangeError(777Operands, ErrorInfo, 0, (1 << 8) - 4,778"immediate must be a multiple of 4 bytes in the range");779case Match_InvalidUImm8Shift3:780return generateImmOutOfRangeError(781Operands, ErrorInfo, 0, (1 << 8) - 8,782"immediate must be a multiple of 8 bytes in the range");783case Match_InvalidUImm8Shift8:784return generateImmOutOfRangeError(785Operands, ErrorInfo, 0, (1 << 8) - 256,786"immediate must be a multiple of 256 bytes in the range");787case Match_InvalidUImm12Shift2:788return generateImmOutOfRangeError(789Operands, ErrorInfo, 0, (1 << 12) - 4,790"immediate must be a multiple of 4 bytes in the range");791case Match_InvalidCSKYSymbol: {792SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();793return Error(ErrorLoc, "operand must be a symbol name");794}795case Match_InvalidConstpool: {796SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();797return Error(ErrorLoc, "operand must be a constpool symbol name");798}799case Match_InvalidPSRFlag: {800SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();801return Error(ErrorLoc, "psrset operand is not valid");802}803case Match_InvalidRegSeq: {804SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();805return Error(ErrorLoc, "Register sequence is not valid");806}807case Match_InvalidRegOutOfRange: {808SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();809return Error(ErrorLoc, "register is out of range");810}811case Match_RequiresSameSrcAndDst: {812SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();813return Error(ErrorLoc, "src and dst operand must be same");814}815case Match_InvalidRegList: {816SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();817return Error(ErrorLoc, "invalid register list");818}819}820LLVM_DEBUG(dbgs() << "Result = " << Result);821llvm_unreachable("Unknown match type detected!");822}823824bool CSKYAsmParser::processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {825Inst.setLoc(IDLoc);826827unsigned Opcode;828MCOperand Op;829if (Inst.getOpcode() == CSKY::PseudoLRW16)830Opcode = CSKY::LRW16;831else832Opcode = CSKY::LRW32;833834if (Inst.getOperand(1).isImm()) {835if (isUInt<8>(Inst.getOperand(1).getImm()) &&836Inst.getOperand(0).getReg() <= CSKY::R7) {837Opcode = CSKY::MOVI16;838} else if (getSTI().hasFeature(CSKY::HasE2) &&839isUInt<16>(Inst.getOperand(1).getImm())) {840Opcode = CSKY::MOVI32;841} else {842auto *Expr = getTargetStreamer().addConstantPoolEntry(843MCConstantExpr::create(Inst.getOperand(1).getImm(), getContext()),844Inst.getLoc());845Inst.erase(std::prev(Inst.end()));846Inst.addOperand(MCOperand::createExpr(Expr));847}848} else {849const MCExpr *AdjustExpr = nullptr;850if (const CSKYMCExpr *CSKYExpr =851dyn_cast<CSKYMCExpr>(Inst.getOperand(1).getExpr())) {852if (CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSGD ||853CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSIE ||854CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSLDM) {855MCSymbol *Dot = getContext().createNamedTempSymbol();856Out.emitLabel(Dot);857AdjustExpr = MCSymbolRefExpr::create(Dot, getContext());858}859}860auto *Expr = getTargetStreamer().addConstantPoolEntry(861Inst.getOperand(1).getExpr(), Inst.getLoc(), AdjustExpr);862Inst.erase(std::prev(Inst.end()));863Inst.addOperand(MCOperand::createExpr(Expr));864}865866Inst.setOpcode(Opcode);867868Out.emitInstruction(Inst, getSTI());869return false;870}871872bool CSKYAsmParser::processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {873Inst.setLoc(IDLoc);874875if (Inst.getOperand(0).isImm()) {876const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(877MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()),878Inst.getLoc());879Inst.setOpcode(CSKY::JSRI32);880Inst.erase(std::prev(Inst.end()));881Inst.addOperand(MCOperand::createExpr(Expr));882} else {883const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(884Inst.getOperand(0).getExpr(), Inst.getLoc());885Inst.setOpcode(CSKY::JBSR32);886Inst.addOperand(MCOperand::createExpr(Expr));887}888889Out.emitInstruction(Inst, getSTI());890return false;891}892893bool CSKYAsmParser::processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {894Inst.setLoc(IDLoc);895896if (Inst.getOperand(0).isImm()) {897const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(898MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()),899Inst.getLoc());900Inst.setOpcode(CSKY::JMPI32);901Inst.erase(std::prev(Inst.end()));902Inst.addOperand(MCOperand::createExpr(Expr));903} else {904const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(905Inst.getOperand(0).getExpr(), Inst.getLoc());906Inst.setOpcode(CSKY::JBR32);907Inst.addOperand(MCOperand::createExpr(Expr));908}909910Out.emitInstruction(Inst, getSTI());911return false;912}913914bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,915OperandVector &Operands,916MCStreamer &Out) {917918switch (Inst.getOpcode()) {919default:920break;921case CSKY::LDQ32:922case CSKY::STQ32:923if (Inst.getOperand(1).getReg() != CSKY::R4 ||924Inst.getOperand(2).getReg() != CSKY::R7) {925return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected");926}927Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32);928break;929case CSKY::SEXT32:930case CSKY::ZEXT32:931if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm())932return Error(IDLoc, "msb must be greater or equal to lsb");933break;934case CSKY::INS32:935if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm())936return Error(IDLoc, "msb must be greater or equal to lsb");937break;938case CSKY::IDLY32:939if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0)940return Error(IDLoc, "n must be in range [0,32]");941break;942case CSKY::ADDC32:943case CSKY::SUBC32:944case CSKY::ADDC16:945case CSKY::SUBC16:946Inst.erase(std::next(Inst.begin()));947Inst.erase(std::prev(Inst.end()));948Inst.insert(std::next(Inst.begin()), MCOperand::createReg(CSKY::C));949Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));950break;951case CSKY::CMPNEI32:952case CSKY::CMPNEI16:953case CSKY::CMPNE32:954case CSKY::CMPNE16:955case CSKY::CMPHSI32:956case CSKY::CMPHSI16:957case CSKY::CMPHS32:958case CSKY::CMPHS16:959case CSKY::CMPLTI32:960case CSKY::CMPLTI16:961case CSKY::CMPLT32:962case CSKY::CMPLT16:963case CSKY::BTSTI32:964Inst.erase(Inst.begin());965Inst.insert(Inst.begin(), MCOperand::createReg(CSKY::C));966break;967case CSKY::MVCV32:968Inst.erase(std::next(Inst.begin()));969Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));970break;971case CSKY::PseudoLRW16:972case CSKY::PseudoLRW32:973return processLRW(Inst, IDLoc, Out);974case CSKY::PseudoJSRI32:975return processJSRI(Inst, IDLoc, Out);976case CSKY::PseudoJMPI32:977return processJMPI(Inst, IDLoc, Out);978case CSKY::JBSR32:979case CSKY::JBR16:980case CSKY::JBT16:981case CSKY::JBF16:982case CSKY::JBR32:983case CSKY::JBT32:984case CSKY::JBF32:985unsigned Num = Inst.getNumOperands() - 1;986assert(Inst.getOperand(Num).isExpr());987988const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(989Inst.getOperand(Num).getExpr(), Inst.getLoc());990991Inst.addOperand(MCOperand::createExpr(Expr));992break;993}994995emitToStreamer(Out, Inst);996return false;997}998999// Attempts to match Name as a register (either using the default name or1000// alternative ABI names), setting RegNo to the matching register. Upon1001// failure, returns true and sets RegNo to 0.1002static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg,1003StringRef Name) {1004Reg = MatchRegisterName(Name);10051006if (Reg == CSKY::NoRegister)1007Reg = MatchRegisterAltName(Name);10081009return Reg == CSKY::NoRegister;1010}10111012bool CSKYAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,1013SMLoc &EndLoc) {1014const AsmToken &Tok = getParser().getTok();1015StartLoc = Tok.getLoc();1016EndLoc = Tok.getEndLoc();1017StringRef Name = getLexer().getTok().getIdentifier();10181019if (!matchRegisterNameHelper(getSTI(), Reg, Name)) {1020getParser().Lex(); // Eat identifier token.1021return false;1022}10231024return true;1025}10261027ParseStatus CSKYAsmParser::parseRegister(OperandVector &Operands) {1028SMLoc S = getLoc();1029SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);10301031switch (getLexer().getKind()) {1032default:1033return ParseStatus::NoMatch;1034case AsmToken::Identifier: {1035StringRef Name = getLexer().getTok().getIdentifier();1036MCRegister Reg;10371038if (matchRegisterNameHelper(getSTI(), Reg, Name))1039return ParseStatus::NoMatch;10401041getLexer().Lex();1042Operands.push_back(CSKYOperand::createReg(Reg, S, E));10431044return ParseStatus::Success;1045}1046}1047}10481049ParseStatus CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) {1050assert(getLexer().is(AsmToken::LParen));10511052Operands.push_back(CSKYOperand::createToken("(", getLoc()));10531054auto Tok = getParser().Lex(); // Eat '('10551056if (!parseRegister(Operands).isSuccess()) {1057getLexer().UnLex(Tok);1058Operands.pop_back();1059return ParseStatus::NoMatch;1060}10611062if (getLexer().is(AsmToken::RParen)) {1063Operands.push_back(CSKYOperand::createToken(")", getLoc()));1064getParser().Lex(); // Eat ')'1065return ParseStatus::Success;1066}10671068if (getLexer().isNot(AsmToken::Comma))1069return Error(getLoc(), "expected ','");10701071getParser().Lex(); // Eat ','10721073if (parseRegister(Operands).isSuccess()) {1074if (getLexer().isNot(AsmToken::LessLess))1075return Error(getLoc(), "expected '<<'");10761077Operands.push_back(CSKYOperand::createToken("<<", getLoc()));10781079getParser().Lex(); // Eat '<<'10801081if (!parseImmediate(Operands).isSuccess())1082return Error(getLoc(), "expected imm");10831084} else if (!parseImmediate(Operands).isSuccess()) {1085return Error(getLoc(), "expected imm");1086}10871088if (getLexer().isNot(AsmToken::RParen))1089return Error(getLoc(), "expected ')'");10901091Operands.push_back(CSKYOperand::createToken(")", getLoc()));10921093getParser().Lex(); // Eat ')'10941095return ParseStatus::Success;1096}10971098ParseStatus CSKYAsmParser::parseImmediate(OperandVector &Operands) {1099switch (getLexer().getKind()) {1100default:1101return ParseStatus::NoMatch;1102case AsmToken::LParen:1103case AsmToken::Minus:1104case AsmToken::Plus:1105case AsmToken::Integer:1106case AsmToken::String:1107break;1108}11091110const MCExpr *IdVal;1111SMLoc S = getLoc();1112if (getParser().parseExpression(IdVal))1113return Error(getLoc(), "unknown expression");11141115SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);1116Operands.push_back(CSKYOperand::createImm(IdVal, S, E));1117return ParseStatus::Success;1118}11191120/// Looks at a token type and creates the relevant operand from this1121/// information, adding to Operands. If operand was parsed, returns false, else1122/// true.1123bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {1124// Check if the current operand has a custom associated parser, if so, try to1125// custom parse the operand, or fallback to the general approach.1126ParseStatus Result =1127MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);1128if (Result.isSuccess())1129return false;1130if (Result.isFailure())1131return true;11321133// Attempt to parse token as register1134auto Res = parseRegister(Operands);1135if (Res.isSuccess())1136return false;1137if (Res.isFailure())1138return true;11391140// Attempt to parse token as (register, imm)1141if (getLexer().is(AsmToken::LParen)) {1142Res = parseBaseRegImm(Operands);1143if (Res.isSuccess())1144return false;1145if (Res.isFailure())1146return true;1147}11481149Res = parseImmediate(Operands);1150if (Res.isSuccess())1151return false;1152if (Res.isFailure())1153return true;11541155// Finally we have exhausted all options and must declare defeat.1156Error(getLoc(), "unknown operand");1157return true;1158}11591160ParseStatus CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) {1161SMLoc S = getLoc();1162SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);1163const MCExpr *Res;11641165if (getLexer().getKind() != AsmToken::Identifier)1166return ParseStatus::NoMatch;11671168StringRef Identifier;1169AsmToken Tok = getLexer().getTok();11701171if (getParser().parseIdentifier(Identifier))1172return Error(getLoc(), "unknown identifier");11731174CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None;1175if (Identifier.consume_back("@GOT"))1176Kind = CSKYMCExpr::VK_CSKY_GOT;1177else if (Identifier.consume_back("@GOTOFF"))1178Kind = CSKYMCExpr::VK_CSKY_GOTOFF;1179else if (Identifier.consume_back("@PLT"))1180Kind = CSKYMCExpr::VK_CSKY_PLT;1181else if (Identifier.consume_back("@GOTPC"))1182Kind = CSKYMCExpr::VK_CSKY_GOTPC;1183else if (Identifier.consume_back("@TLSGD32"))1184Kind = CSKYMCExpr::VK_CSKY_TLSGD;1185else if (Identifier.consume_back("@GOTTPOFF"))1186Kind = CSKYMCExpr::VK_CSKY_TLSIE;1187else if (Identifier.consume_back("@TPOFF"))1188Kind = CSKYMCExpr::VK_CSKY_TLSLE;1189else if (Identifier.consume_back("@TLSLDM32"))1190Kind = CSKYMCExpr::VK_CSKY_TLSLDM;1191else if (Identifier.consume_back("@TLSLDO32"))1192Kind = CSKYMCExpr::VK_CSKY_TLSLDO;11931194MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);11951196if (!Sym)1197Sym = getContext().getOrCreateSymbol(Identifier);11981199if (Sym->isVariable()) {1200const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);1201if (!isa<MCSymbolRefExpr>(V)) {1202getLexer().UnLex(Tok); // Put back if it's not a bare symbol.1203return Error(getLoc(), "unknown symbol");1204}1205Res = V;1206} else1207Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());12081209MCBinaryExpr::Opcode Opcode;1210switch (getLexer().getKind()) {1211default:1212if (Kind != CSKYMCExpr::VK_CSKY_None)1213Res = CSKYMCExpr::create(Res, Kind, getContext());12141215Operands.push_back(CSKYOperand::createImm(Res, S, E));1216return ParseStatus::Success;1217case AsmToken::Plus:1218Opcode = MCBinaryExpr::Add;1219break;1220case AsmToken::Minus:1221Opcode = MCBinaryExpr::Sub;1222break;1223}12241225getLexer().Lex(); // eat + or -12261227const MCExpr *Expr;1228if (getParser().parseExpression(Expr))1229return Error(getLoc(), "unknown expression");1230Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());1231Operands.push_back(CSKYOperand::createImm(Res, S, E));1232return ParseStatus::Success;1233}12341235ParseStatus CSKYAsmParser::parseDataSymbol(OperandVector &Operands) {1236SMLoc S = getLoc();1237SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);1238const MCExpr *Res;12391240if (!parseOptionalToken(AsmToken::LBrac))1241return ParseStatus::NoMatch;1242if (getLexer().getKind() != AsmToken::Identifier) {1243const MCExpr *Expr;1244if (getParser().parseExpression(Expr))1245return Error(getLoc(), "unknown expression");12461247if (parseToken(AsmToken::RBrac, "expected ']'"))1248return ParseStatus::Failure;12491250Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));1251return ParseStatus::Success;1252}12531254AsmToken Tok = getLexer().getTok();1255StringRef Identifier;12561257if (getParser().parseIdentifier(Identifier))1258return Error(getLoc(), "unknown identifier " + Identifier);12591260CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None;1261if (Identifier.consume_back("@GOT"))1262Kind = CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4;1263else if (Identifier.consume_back("@PLT"))1264Kind = CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4;12651266MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);12671268if (!Sym)1269Sym = getContext().getOrCreateSymbol(Identifier);12701271if (Sym->isVariable()) {1272const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);1273if (!isa<MCSymbolRefExpr>(V)) {1274getLexer().UnLex(Tok); // Put back if it's not a bare symbol.1275return Error(getLoc(), "unknown symbol");1276}1277Res = V;1278} else {1279Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());1280}12811282MCBinaryExpr::Opcode Opcode;1283switch (getLexer().getKind()) {1284default:1285return Error(getLoc(), "unknown symbol");1286case AsmToken::RBrac:12871288getLexer().Lex(); // Eat ']'.12891290if (Kind != CSKYMCExpr::VK_CSKY_None)1291Res = CSKYMCExpr::create(Res, Kind, getContext());12921293Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));1294return ParseStatus::Success;1295case AsmToken::Plus:1296Opcode = MCBinaryExpr::Add;1297break;1298case AsmToken::Minus:1299Opcode = MCBinaryExpr::Sub;1300break;1301}13021303getLexer().Lex(); // eat + or -13041305const MCExpr *Expr;1306if (getParser().parseExpression(Expr))1307return Error(getLoc(), "unknown expression");1308if (parseToken(AsmToken::RBrac, "expected ']'"))1309return ParseStatus::Failure;13101311Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());1312Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));1313return ParseStatus::Success;1314}13151316ParseStatus CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) {1317SMLoc S = getLoc();1318SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);1319const MCExpr *Res;13201321if (!parseOptionalToken(AsmToken::LBrac))1322return ParseStatus::NoMatch;13231324if (getLexer().getKind() != AsmToken::Identifier) {1325const MCExpr *Expr;1326if (getParser().parseExpression(Expr))1327return Error(getLoc(), "unknown expression");1328if (parseToken(AsmToken::RBrac))1329return ParseStatus::Failure;13301331Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));1332return ParseStatus::Success;1333}13341335AsmToken Tok = getLexer().getTok();1336StringRef Identifier;13371338if (getParser().parseIdentifier(Identifier))1339return Error(getLoc(), "unknown identifier");13401341MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);13421343if (!Sym)1344Sym = getContext().getOrCreateSymbol(Identifier);13451346if (Sym->isVariable()) {1347const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);1348if (!isa<MCSymbolRefExpr>(V)) {1349getLexer().UnLex(Tok); // Put back if it's not a bare symbol.1350return Error(getLoc(), "unknown symbol");1351}1352Res = V;1353} else {1354Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());1355}13561357MCBinaryExpr::Opcode Opcode;1358switch (getLexer().getKind()) {1359default:1360return Error(getLoc(), "unknown symbol");1361case AsmToken::RBrac:13621363getLexer().Lex(); // Eat ']'.13641365Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));1366return ParseStatus::Success;1367case AsmToken::Plus:1368Opcode = MCBinaryExpr::Add;1369break;1370case AsmToken::Minus:1371Opcode = MCBinaryExpr::Sub;1372break;1373}13741375getLexer().Lex(); // eat + or -13761377const MCExpr *Expr;1378if (getParser().parseExpression(Expr))1379return Error(getLoc(), "unknown expression");1380if (parseToken(AsmToken::RBrac, "expected ']'"))1381return ParseStatus::Failure;13821383Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());1384Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));1385return ParseStatus::Success;1386}13871388ParseStatus CSKYAsmParser::parsePSRFlag(OperandVector &Operands) {1389SMLoc S = getLoc();1390SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);13911392unsigned Flag = 0;13931394while (getLexer().isNot(AsmToken::EndOfStatement)) {1395StringRef Identifier;1396if (getParser().parseIdentifier(Identifier))1397return Error(getLoc(), "unknown identifier " + Identifier);13981399if (Identifier == "sie")1400Flag = (1 << 4) | Flag;1401else if (Identifier == "ee")1402Flag = (1 << 3) | Flag;1403else if (Identifier == "ie")1404Flag = (1 << 2) | Flag;1405else if (Identifier == "fe")1406Flag = (1 << 1) | Flag;1407else if (Identifier == "af")1408Flag = (1 << 0) | Flag;1409else1410return Error(getLoc(), "expected " + Identifier);14111412if (getLexer().is(AsmToken::EndOfStatement))1413break;14141415if (parseToken(AsmToken::Comma, "expected ','"))1416return ParseStatus::Failure;1417}14181419Operands.push_back(1420CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E));1421return ParseStatus::Success;1422}14231424ParseStatus CSKYAsmParser::parseRegSeq(OperandVector &Operands) {1425SMLoc S = getLoc();14261427if (!parseRegister(Operands).isSuccess())1428return ParseStatus::NoMatch;14291430auto Ry = Operands.back()->getReg();1431Operands.pop_back();14321433if (parseToken(AsmToken::Minus, "expected '-'"))1434return ParseStatus::Failure;1435if (!parseRegister(Operands).isSuccess())1436return Error(getLoc(), "invalid register");14371438auto Rz = Operands.back()->getReg();1439Operands.pop_back();14401441Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S));1442return ParseStatus::Success;1443}14441445ParseStatus CSKYAsmParser::parseRegList(OperandVector &Operands) {1446SMLoc S = getLoc();14471448SmallVector<unsigned, 4> reglist;14491450while (true) {14511452if (!parseRegister(Operands).isSuccess())1453return Error(getLoc(), "invalid register");14541455auto Ry = Operands.back()->getReg();1456Operands.pop_back();14571458if (parseOptionalToken(AsmToken::Minus)) {1459if (!parseRegister(Operands).isSuccess())1460return Error(getLoc(), "invalid register");14611462auto Rz = Operands.back()->getReg();1463Operands.pop_back();14641465reglist.push_back(Ry);1466reglist.push_back(Rz);14671468if (getLexer().is(AsmToken::EndOfStatement))1469break;1470(void)parseOptionalToken(AsmToken::Comma);1471} else if (parseOptionalToken(AsmToken::Comma)) {1472reglist.push_back(Ry);1473reglist.push_back(Ry);1474} else if (getLexer().is(AsmToken::EndOfStatement)) {1475reglist.push_back(Ry);1476reglist.push_back(Ry);1477break;1478} else {1479return Error(getLoc(), "invalid register list");1480}1481}14821483Operands.push_back(CSKYOperand::createRegList(reglist, S));1484return ParseStatus::Success;1485}14861487bool CSKYAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,1488SMLoc NameLoc, OperandVector &Operands) {1489// First operand is token for instruction.1490Operands.push_back(CSKYOperand::createToken(Name, NameLoc));14911492// If there are no more operands, then finish.1493if (getLexer().is(AsmToken::EndOfStatement))1494return false;14951496// Parse first operand.1497if (parseOperand(Operands, Name))1498return true;14991500// Parse until end of statement, consuming commas between operands.1501while (parseOptionalToken(AsmToken::Comma))1502if (parseOperand(Operands, Name))1503return true;15041505if (getLexer().isNot(AsmToken::EndOfStatement)) {1506SMLoc Loc = getLexer().getLoc();1507getParser().eatToEndOfStatement();1508return Error(Loc, "unexpected token");1509}15101511getParser().Lex(); // Consume the EndOfStatement.1512return false;1513}15141515ParseStatus CSKYAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,1516SMLoc &EndLoc) {1517const AsmToken &Tok = getParser().getTok();1518StartLoc = Tok.getLoc();1519EndLoc = Tok.getEndLoc();15201521StringRef Name = getLexer().getTok().getIdentifier();15221523if (matchRegisterNameHelper(getSTI(), Reg, Name))1524return ParseStatus::NoMatch;15251526getParser().Lex(); // Eat identifier token.1527return ParseStatus::Success;1528}15291530ParseStatus CSKYAsmParser::parseDirective(AsmToken DirectiveID) {1531StringRef IDVal = DirectiveID.getString();15321533if (IDVal == ".csky_attribute")1534return parseDirectiveAttribute();15351536return ParseStatus::NoMatch;1537}15381539/// parseDirectiveAttribute1540/// ::= .attribute expression ',' ( expression | "string" )1541bool CSKYAsmParser::parseDirectiveAttribute() {1542MCAsmParser &Parser = getParser();1543int64_t Tag;1544SMLoc TagLoc;1545TagLoc = Parser.getTok().getLoc();1546if (Parser.getTok().is(AsmToken::Identifier)) {1547StringRef Name = Parser.getTok().getIdentifier();1548std::optional<unsigned> Ret =1549ELFAttrs::attrTypeFromString(Name, CSKYAttrs::getCSKYAttributeTags());1550if (!Ret)1551return Error(TagLoc, "attribute name not recognised: " + Name);1552Tag = *Ret;1553Parser.Lex();1554} else {1555const MCExpr *AttrExpr;15561557TagLoc = Parser.getTok().getLoc();1558if (Parser.parseExpression(AttrExpr))1559return true;15601561const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);1562if (!CE)1563return Error(TagLoc, "expected numeric constant");15641565Tag = CE->getValue();1566}15671568if (Parser.parseComma())1569return true;15701571StringRef StringValue;1572int64_t IntegerValue = 0;1573bool IsIntegerValue = ((Tag != CSKYAttrs::CSKY_ARCH_NAME) &&1574(Tag != CSKYAttrs::CSKY_CPU_NAME) &&1575(Tag != CSKYAttrs::CSKY_FPU_NUMBER_MODULE));15761577SMLoc ValueExprLoc = Parser.getTok().getLoc();1578if (IsIntegerValue) {1579const MCExpr *ValueExpr;1580if (Parser.parseExpression(ValueExpr))1581return true;15821583const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);1584if (!CE)1585return Error(ValueExprLoc, "expected numeric constant");1586IntegerValue = CE->getValue();1587} else {1588if (Parser.getTok().isNot(AsmToken::String))1589return Error(Parser.getTok().getLoc(), "expected string constant");15901591StringValue = Parser.getTok().getStringContents();1592Parser.Lex();1593}15941595if (Parser.parseEOL())1596return true;15971598if (IsIntegerValue)1599getTargetStreamer().emitAttribute(Tag, IntegerValue);1600else if (Tag != CSKYAttrs::CSKY_ARCH_NAME && Tag != CSKYAttrs::CSKY_CPU_NAME)1601getTargetStreamer().emitTextAttribute(Tag, StringValue);1602else {1603CSKY::ArchKind ID = (Tag == CSKYAttrs::CSKY_ARCH_NAME)1604? CSKY::parseArch(StringValue)1605: CSKY::parseCPUArch(StringValue);1606if (ID == CSKY::ArchKind::INVALID)1607return Error(ValueExprLoc, (Tag == CSKYAttrs::CSKY_ARCH_NAME)1608? "unknown arch name"1609: "unknown cpu name");16101611getTargetStreamer().emitTextAttribute(Tag, StringValue);1612}16131614return false;1615}16161617unsigned CSKYAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,1618unsigned Kind) {1619CSKYOperand &Op = static_cast<CSKYOperand &>(AsmOp);16201621if (!Op.isReg())1622return Match_InvalidOperand;16231624MCRegister Reg = Op.getReg();16251626if (CSKYMCRegisterClasses[CSKY::FPR32RegClassID].contains(Reg)) {1627// As the parser couldn't differentiate an FPR64 from an FPR32, coerce the1628// register from FPR32 to FPR64 if necessary.1629if (Kind == MCK_FPR64 || Kind == MCK_sFPR64) {1630Op.Reg.RegNum = convertFPR32ToFPR64(Reg);1631if (Kind == MCK_sFPR64 &&1632(Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F15_64))1633return Match_InvalidRegOutOfRange;1634if (Kind == MCK_FPR64 &&1635(Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F31_64))1636return Match_InvalidRegOutOfRange;1637return Match_Success;1638}1639}16401641if (CSKYMCRegisterClasses[CSKY::GPRRegClassID].contains(Reg)) {1642if (Kind == MCK_GPRPair) {1643Op.Reg.RegNum = MRI->getEncodingValue(Reg) + CSKY::R0_R1;1644return Match_Success;1645}1646}16471648return Match_InvalidOperand;1649}16501651void CSKYAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {1652MCInst CInst;1653bool Res = false;1654if (EnableCompressedInst)1655Res = compressInst(CInst, Inst, getSTI());1656if (Res)1657++CSKYNumInstrsCompressed;1658S.emitInstruction((Res ? CInst : Inst), getSTI());1659}16601661extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser() {1662RegisterMCAsmParser<CSKYAsmParser> X(getTheCSKYTarget());1663}166416651666