1349cc55cSDimitry Andric //===---- CSKYAsmParser.cpp - Parse CSKY assembly to MCInst instructions --===//
2fe6060f1SDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric
9349cc55cSDimitry Andric #include "MCTargetDesc/CSKYInstPrinter.h"
10fe6060f1SDimitry Andric #include "MCTargetDesc/CSKYMCExpr.h"
11fe6060f1SDimitry Andric #include "MCTargetDesc/CSKYMCTargetDesc.h"
1281ad6265SDimitry Andric #include "MCTargetDesc/CSKYTargetStreamer.h"
13fe6060f1SDimitry Andric #include "TargetInfo/CSKYTargetInfo.h"
14fe6060f1SDimitry Andric #include "llvm/ADT/STLExtras.h"
150eae32dcSDimitry Andric #include "llvm/ADT/Statistic.h"
1606c3fb27SDimitry Andric #include "llvm/ADT/StringExtras.h"
17fe6060f1SDimitry Andric #include "llvm/ADT/StringSwitch.h"
1881ad6265SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
19fe6060f1SDimitry Andric #include "llvm/CodeGen/Register.h"
20fe6060f1SDimitry Andric #include "llvm/MC/MCContext.h"
21fe6060f1SDimitry Andric #include "llvm/MC/MCExpr.h"
22fe6060f1SDimitry Andric #include "llvm/MC/MCInst.h"
2381ad6265SDimitry Andric #include "llvm/MC/MCInstrInfo.h"
24fe6060f1SDimitry Andric #include "llvm/MC/MCParser/MCAsmLexer.h"
25fe6060f1SDimitry Andric #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
26fe6060f1SDimitry Andric #include "llvm/MC/MCParser/MCTargetAsmParser.h"
27fe6060f1SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
28349cc55cSDimitry Andric #include "llvm/MC/MCSectionELF.h"
29fe6060f1SDimitry Andric #include "llvm/MC/MCStreamer.h"
30fe6060f1SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
31349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
3281ad6265SDimitry Andric #include "llvm/Support/CSKYAttributes.h"
33fe6060f1SDimitry Andric #include "llvm/Support/Casting.h"
340eae32dcSDimitry Andric #include "llvm/Support/CommandLine.h"
35349cc55cSDimitry Andric #include "llvm/Support/Debug.h"
3606c3fb27SDimitry Andric #include "llvm/TargetParser/CSKYTargetParser.h"
37349cc55cSDimitry Andric
380eae32dcSDimitry Andric using namespace llvm;
390eae32dcSDimitry Andric
40349cc55cSDimitry Andric #define DEBUG_TYPE "csky-asm-parser"
41fe6060f1SDimitry Andric
420eae32dcSDimitry Andric // Include the auto-generated portion of the compress emitter.
430eae32dcSDimitry Andric #define GEN_COMPRESS_INSTR
440eae32dcSDimitry Andric #include "CSKYGenCompressInstEmitter.inc"
450eae32dcSDimitry Andric
460eae32dcSDimitry Andric STATISTIC(CSKYNumInstrsCompressed,
470eae32dcSDimitry Andric "Number of C-SKY Compressed instructions emitted");
480eae32dcSDimitry Andric
490eae32dcSDimitry Andric static cl::opt<bool>
500eae32dcSDimitry Andric EnableCompressedInst("enable-csky-asm-compressed-inst", cl::Hidden,
510eae32dcSDimitry Andric cl::init(false),
520eae32dcSDimitry Andric cl::desc("Enable C-SKY asm compressed instruction"));
53fe6060f1SDimitry Andric
54fe6060f1SDimitry Andric namespace {
55fe6060f1SDimitry Andric struct CSKYOperand;
56fe6060f1SDimitry Andric
57fe6060f1SDimitry Andric class CSKYAsmParser : public MCTargetAsmParser {
58fe6060f1SDimitry Andric
59349cc55cSDimitry Andric const MCRegisterInfo *MRI;
60349cc55cSDimitry Andric
6181ad6265SDimitry Andric unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
6281ad6265SDimitry Andric unsigned Kind) override;
6381ad6265SDimitry Andric
64fe6060f1SDimitry Andric bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
6506c3fb27SDimitry Andric int64_t Lower, int64_t Upper,
6606c3fb27SDimitry Andric const Twine &Msg);
67fe6060f1SDimitry Andric
getLoc() const68fe6060f1SDimitry Andric SMLoc getLoc() const { return getParser().getTok().getLoc(); }
69fe6060f1SDimitry Andric
70fe6060f1SDimitry Andric bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
71fe6060f1SDimitry Andric OperandVector &Operands, MCStreamer &Out,
72fe6060f1SDimitry Andric uint64_t &ErrorInfo,
73fe6060f1SDimitry Andric bool MatchingInlineAsm) override;
74fe6060f1SDimitry Andric
755f757f3fSDimitry Andric bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
76fe6060f1SDimitry Andric
77fe6060f1SDimitry Andric bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
78fe6060f1SDimitry Andric SMLoc NameLoc, OperandVector &Operands) override;
79fe6060f1SDimitry Andric
8006c3fb27SDimitry Andric ParseStatus parseDirective(AsmToken DirectiveID) override;
81fe6060f1SDimitry Andric
820eae32dcSDimitry Andric // Helper to actually emit an instruction to the MCStreamer. Also, when
830eae32dcSDimitry Andric // possible, compression of the instruction is performed.
840eae32dcSDimitry Andric void emitToStreamer(MCStreamer &S, const MCInst &Inst);
850eae32dcSDimitry Andric
865f757f3fSDimitry Andric ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
87fe6060f1SDimitry Andric SMLoc &EndLoc) override;
88fe6060f1SDimitry Andric
89349cc55cSDimitry Andric bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,
90349cc55cSDimitry Andric MCStreamer &Out);
9181ad6265SDimitry Andric bool processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
9281ad6265SDimitry Andric bool processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
9381ad6265SDimitry Andric bool processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
9481ad6265SDimitry Andric
getTargetStreamer()9581ad6265SDimitry Andric CSKYTargetStreamer &getTargetStreamer() {
9681ad6265SDimitry Andric assert(getParser().getStreamer().getTargetStreamer() &&
9781ad6265SDimitry Andric "do not have a target streamer");
9881ad6265SDimitry Andric MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
9981ad6265SDimitry Andric return static_cast<CSKYTargetStreamer &>(TS);
10081ad6265SDimitry Andric }
101349cc55cSDimitry Andric
102fe6060f1SDimitry Andric // Auto-generated instruction matching functions
103fe6060f1SDimitry Andric #define GET_ASSEMBLER_HEADER
104fe6060f1SDimitry Andric #include "CSKYGenAsmMatcher.inc"
105fe6060f1SDimitry Andric
10606c3fb27SDimitry Andric ParseStatus parseImmediate(OperandVector &Operands);
10706c3fb27SDimitry Andric ParseStatus parseRegister(OperandVector &Operands);
10806c3fb27SDimitry Andric ParseStatus parseBaseRegImm(OperandVector &Operands);
10906c3fb27SDimitry Andric ParseStatus parseCSKYSymbol(OperandVector &Operands);
11006c3fb27SDimitry Andric ParseStatus parseConstpoolSymbol(OperandVector &Operands);
11106c3fb27SDimitry Andric ParseStatus parseDataSymbol(OperandVector &Operands);
11206c3fb27SDimitry Andric ParseStatus parsePSRFlag(OperandVector &Operands);
11306c3fb27SDimitry Andric ParseStatus parseRegSeq(OperandVector &Operands);
11406c3fb27SDimitry Andric ParseStatus parseRegList(OperandVector &Operands);
115fe6060f1SDimitry Andric
116fe6060f1SDimitry Andric bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
117fe6060f1SDimitry Andric
11881ad6265SDimitry Andric bool parseDirectiveAttribute();
11981ad6265SDimitry Andric
120fe6060f1SDimitry Andric public:
121fe6060f1SDimitry Andric enum CSKYMatchResultTy {
122fe6060f1SDimitry Andric Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
123349cc55cSDimitry Andric Match_RequiresSameSrcAndDst,
124349cc55cSDimitry Andric Match_InvalidRegOutOfRange,
125fe6060f1SDimitry Andric #define GET_OPERAND_DIAGNOSTIC_TYPES
126fe6060f1SDimitry Andric #include "CSKYGenAsmMatcher.inc"
127fe6060f1SDimitry Andric #undef GET_OPERAND_DIAGNOSTIC_TYPES
128fe6060f1SDimitry Andric };
129fe6060f1SDimitry Andric
CSKYAsmParser(const MCSubtargetInfo & STI,MCAsmParser & Parser,const MCInstrInfo & MII,const MCTargetOptions & Options)130fe6060f1SDimitry Andric CSKYAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
131fe6060f1SDimitry Andric const MCInstrInfo &MII, const MCTargetOptions &Options)
132fe6060f1SDimitry Andric : MCTargetAsmParser(Options, STI, MII) {
13381ad6265SDimitry Andric
13481ad6265SDimitry Andric MCAsmParserExtension::Initialize(Parser);
13581ad6265SDimitry Andric
13681ad6265SDimitry Andric // Cache the MCRegisterInfo.
13781ad6265SDimitry Andric MRI = getContext().getRegisterInfo();
13881ad6265SDimitry Andric
139fe6060f1SDimitry Andric setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
14081ad6265SDimitry Andric getTargetStreamer().emitTargetAttributes(STI);
141fe6060f1SDimitry Andric }
142fe6060f1SDimitry Andric };
143fe6060f1SDimitry Andric
144fe6060f1SDimitry Andric /// Instances of this class represent a parsed machine instruction.
145fe6060f1SDimitry Andric struct CSKYOperand : public MCParsedAsmOperand {
146349cc55cSDimitry Andric
147fe6060f1SDimitry Andric enum KindTy {
148fe6060f1SDimitry Andric Token,
149fe6060f1SDimitry Andric Register,
150fe6060f1SDimitry Andric Immediate,
151349cc55cSDimitry Andric RegisterSeq,
152349cc55cSDimitry Andric CPOP,
153349cc55cSDimitry Andric RegisterList
154fe6060f1SDimitry Andric } Kind;
155fe6060f1SDimitry Andric
156fe6060f1SDimitry Andric struct RegOp {
157fe6060f1SDimitry Andric unsigned RegNum;
158fe6060f1SDimitry Andric };
159fe6060f1SDimitry Andric
160fe6060f1SDimitry Andric struct ImmOp {
161fe6060f1SDimitry Andric const MCExpr *Val;
162fe6060f1SDimitry Andric };
163fe6060f1SDimitry Andric
164349cc55cSDimitry Andric struct ConstpoolOp {
165349cc55cSDimitry Andric const MCExpr *Val;
166349cc55cSDimitry Andric };
167349cc55cSDimitry Andric
168349cc55cSDimitry Andric struct RegSeqOp {
169349cc55cSDimitry Andric unsigned RegNumFrom;
170349cc55cSDimitry Andric unsigned RegNumTo;
171349cc55cSDimitry Andric };
172349cc55cSDimitry Andric
173349cc55cSDimitry Andric struct RegListOp {
174349cc55cSDimitry Andric unsigned List1From = 0;
175349cc55cSDimitry Andric unsigned List1To = 0;
176349cc55cSDimitry Andric unsigned List2From = 0;
177349cc55cSDimitry Andric unsigned List2To = 0;
178349cc55cSDimitry Andric unsigned List3From = 0;
179349cc55cSDimitry Andric unsigned List3To = 0;
180349cc55cSDimitry Andric unsigned List4From = 0;
181349cc55cSDimitry Andric unsigned List4To = 0;
182349cc55cSDimitry Andric };
183349cc55cSDimitry Andric
184fe6060f1SDimitry Andric SMLoc StartLoc, EndLoc;
185fe6060f1SDimitry Andric union {
186fe6060f1SDimitry Andric StringRef Tok;
187fe6060f1SDimitry Andric RegOp Reg;
188fe6060f1SDimitry Andric ImmOp Imm;
189349cc55cSDimitry Andric ConstpoolOp CPool;
190349cc55cSDimitry Andric RegSeqOp RegSeq;
191349cc55cSDimitry Andric RegListOp RegList;
192fe6060f1SDimitry Andric };
193fe6060f1SDimitry Andric
CSKYOperand__anonbb596bd40111::CSKYOperand194fe6060f1SDimitry Andric CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
195fe6060f1SDimitry Andric
196fe6060f1SDimitry Andric public:
CSKYOperand__anonbb596bd40111::CSKYOperand197fe6060f1SDimitry Andric CSKYOperand(const CSKYOperand &o) : MCParsedAsmOperand() {
198fe6060f1SDimitry Andric Kind = o.Kind;
199fe6060f1SDimitry Andric StartLoc = o.StartLoc;
200fe6060f1SDimitry Andric EndLoc = o.EndLoc;
201fe6060f1SDimitry Andric switch (Kind) {
202fe6060f1SDimitry Andric case Register:
203fe6060f1SDimitry Andric Reg = o.Reg;
204fe6060f1SDimitry Andric break;
205349cc55cSDimitry Andric case RegisterSeq:
206349cc55cSDimitry Andric RegSeq = o.RegSeq;
207349cc55cSDimitry Andric break;
208349cc55cSDimitry Andric case CPOP:
209349cc55cSDimitry Andric CPool = o.CPool;
210349cc55cSDimitry Andric break;
211fe6060f1SDimitry Andric case Immediate:
212fe6060f1SDimitry Andric Imm = o.Imm;
213fe6060f1SDimitry Andric break;
214fe6060f1SDimitry Andric case Token:
215fe6060f1SDimitry Andric Tok = o.Tok;
216fe6060f1SDimitry Andric break;
217349cc55cSDimitry Andric case RegisterList:
218349cc55cSDimitry Andric RegList = o.RegList;
219349cc55cSDimitry Andric break;
220fe6060f1SDimitry Andric }
221fe6060f1SDimitry Andric }
222fe6060f1SDimitry Andric
isToken__anonbb596bd40111::CSKYOperand223fe6060f1SDimitry Andric bool isToken() const override { return Kind == Token; }
isReg__anonbb596bd40111::CSKYOperand224fe6060f1SDimitry Andric bool isReg() const override { return Kind == Register; }
isImm__anonbb596bd40111::CSKYOperand225fe6060f1SDimitry Andric bool isImm() const override { return Kind == Immediate; }
isRegisterSeq__anonbb596bd40111::CSKYOperand226349cc55cSDimitry Andric bool isRegisterSeq() const { return Kind == RegisterSeq; }
isRegisterList__anonbb596bd40111::CSKYOperand227349cc55cSDimitry Andric bool isRegisterList() const { return Kind == RegisterList; }
isConstPoolOp__anonbb596bd40111::CSKYOperand228349cc55cSDimitry Andric bool isConstPoolOp() const { return Kind == CPOP; }
229349cc55cSDimitry Andric
isMem__anonbb596bd40111::CSKYOperand230fe6060f1SDimitry Andric bool isMem() const override { return false; }
231fe6060f1SDimitry Andric
evaluateConstantImm__anonbb596bd40111::CSKYOperand232fe6060f1SDimitry Andric static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) {
233fe6060f1SDimitry Andric if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
234fe6060f1SDimitry Andric Imm = CE->getValue();
235fe6060f1SDimitry Andric return true;
236fe6060f1SDimitry Andric }
237fe6060f1SDimitry Andric
238fe6060f1SDimitry Andric return false;
239fe6060f1SDimitry Andric }
240fe6060f1SDimitry Andric
isUImm__anonbb596bd40111::CSKYOperand241fe6060f1SDimitry Andric template <unsigned num, unsigned shift = 0> bool isUImm() const {
242fe6060f1SDimitry Andric if (!isImm())
243fe6060f1SDimitry Andric return false;
244fe6060f1SDimitry Andric
245fe6060f1SDimitry Andric int64_t Imm;
246fe6060f1SDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
247fe6060f1SDimitry Andric return IsConstantImm && isShiftedUInt<num, shift>(Imm);
248fe6060f1SDimitry Andric }
249fe6060f1SDimitry Andric
isOImm__anonbb596bd40111::CSKYOperand250fe6060f1SDimitry Andric template <unsigned num> bool isOImm() const {
251fe6060f1SDimitry Andric if (!isImm())
252fe6060f1SDimitry Andric return false;
253fe6060f1SDimitry Andric
254fe6060f1SDimitry Andric int64_t Imm;
255fe6060f1SDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
256fe6060f1SDimitry Andric return IsConstantImm && isUInt<num>(Imm - 1);
257fe6060f1SDimitry Andric }
258fe6060f1SDimitry Andric
isSImm__anonbb596bd40111::CSKYOperand259fe6060f1SDimitry Andric template <unsigned num, unsigned shift = 0> bool isSImm() const {
260fe6060f1SDimitry Andric if (!isImm())
261fe6060f1SDimitry Andric return false;
262fe6060f1SDimitry Andric
263fe6060f1SDimitry Andric int64_t Imm;
264fe6060f1SDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
265fe6060f1SDimitry Andric return IsConstantImm && isShiftedInt<num, shift>(Imm);
266fe6060f1SDimitry Andric }
267fe6060f1SDimitry Andric
isUImm1__anonbb596bd40111::CSKYOperand268349cc55cSDimitry Andric bool isUImm1() const { return isUImm<1>(); }
isUImm2__anonbb596bd40111::CSKYOperand269fe6060f1SDimitry Andric bool isUImm2() const { return isUImm<2>(); }
isUImm3__anonbb596bd40111::CSKYOperand270349cc55cSDimitry Andric bool isUImm3() const { return isUImm<3>(); }
isUImm4__anonbb596bd40111::CSKYOperand271349cc55cSDimitry Andric bool isUImm4() const { return isUImm<4>(); }
isUImm5__anonbb596bd40111::CSKYOperand272fe6060f1SDimitry Andric bool isUImm5() const { return isUImm<5>(); }
isUImm6__anonbb596bd40111::CSKYOperand273349cc55cSDimitry Andric bool isUImm6() const { return isUImm<6>(); }
isUImm7__anonbb596bd40111::CSKYOperand274349cc55cSDimitry Andric bool isUImm7() const { return isUImm<7>(); }
isUImm8__anonbb596bd40111::CSKYOperand275349cc55cSDimitry Andric bool isUImm8() const { return isUImm<8>(); }
isUImm12__anonbb596bd40111::CSKYOperand276fe6060f1SDimitry Andric bool isUImm12() const { return isUImm<12>(); }
isUImm16__anonbb596bd40111::CSKYOperand277fe6060f1SDimitry Andric bool isUImm16() const { return isUImm<16>(); }
isUImm20__anonbb596bd40111::CSKYOperand278349cc55cSDimitry Andric bool isUImm20() const { return isUImm<20>(); }
isUImm24__anonbb596bd40111::CSKYOperand279349cc55cSDimitry Andric bool isUImm24() const { return isUImm<24>(); }
280fe6060f1SDimitry Andric
isOImm3__anonbb596bd40111::CSKYOperand281349cc55cSDimitry Andric bool isOImm3() const { return isOImm<3>(); }
isOImm4__anonbb596bd40111::CSKYOperand282349cc55cSDimitry Andric bool isOImm4() const { return isOImm<4>(); }
isOImm5__anonbb596bd40111::CSKYOperand283349cc55cSDimitry Andric bool isOImm5() const { return isOImm<5>(); }
isOImm6__anonbb596bd40111::CSKYOperand284349cc55cSDimitry Andric bool isOImm6() const { return isOImm<6>(); }
isOImm8__anonbb596bd40111::CSKYOperand285349cc55cSDimitry Andric bool isOImm8() const { return isOImm<8>(); }
isOImm12__anonbb596bd40111::CSKYOperand286fe6060f1SDimitry Andric bool isOImm12() const { return isOImm<12>(); }
isOImm16__anonbb596bd40111::CSKYOperand287fe6060f1SDimitry Andric bool isOImm16() const { return isOImm<16>(); }
288fe6060f1SDimitry Andric
isSImm8__anonbb596bd40111::CSKYOperand289349cc55cSDimitry Andric bool isSImm8() const { return isSImm<8>(); }
290349cc55cSDimitry Andric
isUImm5Shift1__anonbb596bd40111::CSKYOperand291349cc55cSDimitry Andric bool isUImm5Shift1() { return isUImm<5, 1>(); }
isUImm5Shift2__anonbb596bd40111::CSKYOperand292349cc55cSDimitry Andric bool isUImm5Shift2() { return isUImm<5, 2>(); }
isUImm7Shift1__anonbb596bd40111::CSKYOperand293349cc55cSDimitry Andric bool isUImm7Shift1() { return isUImm<7, 1>(); }
isUImm7Shift2__anonbb596bd40111::CSKYOperand294349cc55cSDimitry Andric bool isUImm7Shift2() { return isUImm<7, 2>(); }
isUImm7Shift3__anonbb596bd40111::CSKYOperand295349cc55cSDimitry Andric bool isUImm7Shift3() { return isUImm<7, 3>(); }
isUImm8Shift2__anonbb596bd40111::CSKYOperand296349cc55cSDimitry Andric bool isUImm8Shift2() { return isUImm<8, 2>(); }
isUImm8Shift3__anonbb596bd40111::CSKYOperand297349cc55cSDimitry Andric bool isUImm8Shift3() { return isUImm<8, 3>(); }
isUImm8Shift8__anonbb596bd40111::CSKYOperand298349cc55cSDimitry Andric bool isUImm8Shift8() { return isUImm<8, 8>(); }
isUImm8Shift16__anonbb596bd40111::CSKYOperand299349cc55cSDimitry Andric bool isUImm8Shift16() { return isUImm<8, 16>(); }
isUImm8Shift24__anonbb596bd40111::CSKYOperand300349cc55cSDimitry Andric bool isUImm8Shift24() { return isUImm<8, 24>(); }
isUImm12Shift1__anonbb596bd40111::CSKYOperand301fe6060f1SDimitry Andric bool isUImm12Shift1() { return isUImm<12, 1>(); }
isUImm12Shift2__anonbb596bd40111::CSKYOperand302fe6060f1SDimitry Andric bool isUImm12Shift2() { return isUImm<12, 2>(); }
isUImm16Shift8__anonbb596bd40111::CSKYOperand303349cc55cSDimitry Andric bool isUImm16Shift8() { return isUImm<16, 8>(); }
isUImm16Shift16__anonbb596bd40111::CSKYOperand304349cc55cSDimitry Andric bool isUImm16Shift16() { return isUImm<16, 16>(); }
isUImm24Shift8__anonbb596bd40111::CSKYOperand305349cc55cSDimitry Andric bool isUImm24Shift8() { return isUImm<24, 8>(); }
306fe6060f1SDimitry Andric
isSImm16Shift1__anonbb596bd40111::CSKYOperand307fe6060f1SDimitry Andric bool isSImm16Shift1() { return isSImm<16, 1>(); }
308fe6060f1SDimitry Andric
isCSKYSymbol__anonbb596bd40111::CSKYOperand309349cc55cSDimitry Andric bool isCSKYSymbol() const { return isImm(); }
310349cc55cSDimitry Andric
isConstpool__anonbb596bd40111::CSKYOperand311349cc55cSDimitry Andric bool isConstpool() const { return isConstPoolOp(); }
isDataSymbol__anonbb596bd40111::CSKYOperand312349cc55cSDimitry Andric bool isDataSymbol() const { return isConstPoolOp(); }
313349cc55cSDimitry Andric
isPSRFlag__anonbb596bd40111::CSKYOperand314349cc55cSDimitry Andric bool isPSRFlag() const {
315fe6060f1SDimitry Andric int64_t Imm;
316349cc55cSDimitry Andric // Must be of 'immediate' type and a constant.
317349cc55cSDimitry Andric if (!isImm() || !evaluateConstantImm(getImm(), Imm))
318349cc55cSDimitry Andric return false;
319349cc55cSDimitry Andric
320349cc55cSDimitry Andric return isUInt<5>(Imm);
321349cc55cSDimitry Andric }
322349cc55cSDimitry Andric
isRegSeqTemplate__anonbb596bd40111::CSKYOperand323349cc55cSDimitry Andric template <unsigned MIN, unsigned MAX> bool isRegSeqTemplate() const {
324349cc55cSDimitry Andric if (!isRegisterSeq())
325349cc55cSDimitry Andric return false;
326349cc55cSDimitry Andric
327349cc55cSDimitry Andric std::pair<unsigned, unsigned> regSeq = getRegSeq();
328349cc55cSDimitry Andric
329349cc55cSDimitry Andric return MIN <= regSeq.first && regSeq.first <= regSeq.second &&
330349cc55cSDimitry Andric regSeq.second <= MAX;
331349cc55cSDimitry Andric }
332349cc55cSDimitry Andric
isRegSeq__anonbb596bd40111::CSKYOperand333349cc55cSDimitry Andric bool isRegSeq() const { return isRegSeqTemplate<CSKY::R0, CSKY::R31>(); }
334349cc55cSDimitry Andric
isRegSeqV1__anonbb596bd40111::CSKYOperand33504eeddc0SDimitry Andric bool isRegSeqV1() const {
33604eeddc0SDimitry Andric return isRegSeqTemplate<CSKY::F0_32, CSKY::F15_32>();
33704eeddc0SDimitry Andric }
33804eeddc0SDimitry Andric
isRegSeqV2__anonbb596bd40111::CSKYOperand33904eeddc0SDimitry Andric bool isRegSeqV2() const {
34004eeddc0SDimitry Andric return isRegSeqTemplate<CSKY::F0_32, CSKY::F31_32>();
34104eeddc0SDimitry Andric }
34204eeddc0SDimitry Andric
isLegalRegList__anonbb596bd40111::CSKYOperand343349cc55cSDimitry Andric static bool isLegalRegList(unsigned from, unsigned to) {
344349cc55cSDimitry Andric if (from == 0 && to == 0)
345349cc55cSDimitry Andric return true;
346349cc55cSDimitry Andric
347349cc55cSDimitry Andric if (from == to) {
348349cc55cSDimitry Andric if (from != CSKY::R4 && from != CSKY::R15 && from != CSKY::R16 &&
349349cc55cSDimitry Andric from != CSKY::R28)
350349cc55cSDimitry Andric return false;
351349cc55cSDimitry Andric
352349cc55cSDimitry Andric return true;
353349cc55cSDimitry Andric } else {
354349cc55cSDimitry Andric if (from != CSKY::R4 && from != CSKY::R16)
355349cc55cSDimitry Andric return false;
356349cc55cSDimitry Andric
357349cc55cSDimitry Andric if (from == CSKY::R4 && to > CSKY::R4 && to < CSKY::R12)
358349cc55cSDimitry Andric return true;
359349cc55cSDimitry Andric else if (from == CSKY::R16 && to > CSKY::R16 && to < CSKY::R18)
360349cc55cSDimitry Andric return true;
361349cc55cSDimitry Andric else
362349cc55cSDimitry Andric return false;
363349cc55cSDimitry Andric }
364349cc55cSDimitry Andric }
365349cc55cSDimitry Andric
isRegList__anonbb596bd40111::CSKYOperand366349cc55cSDimitry Andric bool isRegList() const {
367349cc55cSDimitry Andric if (!isRegisterList())
368349cc55cSDimitry Andric return false;
369349cc55cSDimitry Andric
370349cc55cSDimitry Andric auto regList = getRegList();
371349cc55cSDimitry Andric
372349cc55cSDimitry Andric if (!isLegalRegList(regList.List1From, regList.List1To))
373349cc55cSDimitry Andric return false;
374349cc55cSDimitry Andric if (!isLegalRegList(regList.List2From, regList.List2To))
375349cc55cSDimitry Andric return false;
376349cc55cSDimitry Andric if (!isLegalRegList(regList.List3From, regList.List3To))
377349cc55cSDimitry Andric return false;
378349cc55cSDimitry Andric if (!isLegalRegList(regList.List4From, regList.List4To))
379349cc55cSDimitry Andric return false;
380349cc55cSDimitry Andric
381349cc55cSDimitry Andric return true;
382349cc55cSDimitry Andric }
383349cc55cSDimitry Andric
isExtImm6__anonbb596bd40111::CSKYOperand384349cc55cSDimitry Andric bool isExtImm6() {
385349cc55cSDimitry Andric if (!isImm())
386349cc55cSDimitry Andric return false;
387349cc55cSDimitry Andric
388349cc55cSDimitry Andric int64_t Imm;
389349cc55cSDimitry Andric bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
390349cc55cSDimitry Andric if (!IsConstantImm)
391349cc55cSDimitry Andric return false;
392349cc55cSDimitry Andric
393349cc55cSDimitry Andric int uimm4 = Imm & 0xf;
394349cc55cSDimitry Andric
395349cc55cSDimitry Andric return isShiftedUInt<6, 0>(Imm) && uimm4 >= 0 && uimm4 <= 14;
396fe6060f1SDimitry Andric }
397fe6060f1SDimitry Andric
398fe6060f1SDimitry Andric /// Gets location of the first token of this operand.
getStartLoc__anonbb596bd40111::CSKYOperand399fe6060f1SDimitry Andric SMLoc getStartLoc() const override { return StartLoc; }
400fe6060f1SDimitry Andric /// Gets location of the last token of this operand.
getEndLoc__anonbb596bd40111::CSKYOperand401fe6060f1SDimitry Andric SMLoc getEndLoc() const override { return EndLoc; }
402fe6060f1SDimitry Andric
getReg__anonbb596bd40111::CSKYOperand403*0fca6ea1SDimitry Andric MCRegister getReg() const override {
404fe6060f1SDimitry Andric assert(Kind == Register && "Invalid type access!");
405fe6060f1SDimitry Andric return Reg.RegNum;
406fe6060f1SDimitry Andric }
407fe6060f1SDimitry Andric
getRegSeq__anonbb596bd40111::CSKYOperand408349cc55cSDimitry Andric std::pair<unsigned, unsigned> getRegSeq() const {
409349cc55cSDimitry Andric assert(Kind == RegisterSeq && "Invalid type access!");
410349cc55cSDimitry Andric return std::pair<unsigned, unsigned>(RegSeq.RegNumFrom, RegSeq.RegNumTo);
411349cc55cSDimitry Andric }
412349cc55cSDimitry Andric
getRegList__anonbb596bd40111::CSKYOperand413349cc55cSDimitry Andric RegListOp getRegList() const {
414349cc55cSDimitry Andric assert(Kind == RegisterList && "Invalid type access!");
415349cc55cSDimitry Andric return RegList;
416349cc55cSDimitry Andric }
417349cc55cSDimitry Andric
getImm__anonbb596bd40111::CSKYOperand418fe6060f1SDimitry Andric const MCExpr *getImm() const {
419fe6060f1SDimitry Andric assert(Kind == Immediate && "Invalid type access!");
420fe6060f1SDimitry Andric return Imm.Val;
421fe6060f1SDimitry Andric }
422fe6060f1SDimitry Andric
getConstpoolOp__anonbb596bd40111::CSKYOperand423349cc55cSDimitry Andric const MCExpr *getConstpoolOp() const {
424349cc55cSDimitry Andric assert(Kind == CPOP && "Invalid type access!");
425349cc55cSDimitry Andric return CPool.Val;
426349cc55cSDimitry Andric }
427349cc55cSDimitry Andric
getToken__anonbb596bd40111::CSKYOperand428fe6060f1SDimitry Andric StringRef getToken() const {
429fe6060f1SDimitry Andric assert(Kind == Token && "Invalid type access!");
430fe6060f1SDimitry Andric return Tok;
431fe6060f1SDimitry Andric }
432fe6060f1SDimitry Andric
print__anonbb596bd40111::CSKYOperand433fe6060f1SDimitry Andric void print(raw_ostream &OS) const override {
434bdd1243dSDimitry Andric auto RegName = [](MCRegister Reg) {
435349cc55cSDimitry Andric if (Reg)
436349cc55cSDimitry Andric return CSKYInstPrinter::getRegisterName(Reg);
437349cc55cSDimitry Andric else
438349cc55cSDimitry Andric return "noreg";
439349cc55cSDimitry Andric };
440349cc55cSDimitry Andric
441fe6060f1SDimitry Andric switch (Kind) {
442349cc55cSDimitry Andric case CPOP:
443349cc55cSDimitry Andric OS << *getConstpoolOp();
444349cc55cSDimitry Andric break;
445fe6060f1SDimitry Andric case Immediate:
446fe6060f1SDimitry Andric OS << *getImm();
447fe6060f1SDimitry Andric break;
448349cc55cSDimitry Andric case KindTy::Register:
449349cc55cSDimitry Andric OS << "<register " << RegName(getReg()) << ">";
450349cc55cSDimitry Andric break;
451349cc55cSDimitry Andric case RegisterSeq:
452349cc55cSDimitry Andric OS << "<register-seq ";
453349cc55cSDimitry Andric OS << RegName(getRegSeq().first) << "-" << RegName(getRegSeq().second)
454349cc55cSDimitry Andric << ">";
455349cc55cSDimitry Andric break;
456349cc55cSDimitry Andric case RegisterList:
457349cc55cSDimitry Andric OS << "<register-list ";
458349cc55cSDimitry Andric OS << RegName(getRegList().List1From) << "-"
459349cc55cSDimitry Andric << RegName(getRegList().List1To) << ",";
460349cc55cSDimitry Andric OS << RegName(getRegList().List2From) << "-"
461349cc55cSDimitry Andric << RegName(getRegList().List2To) << ",";
462349cc55cSDimitry Andric OS << RegName(getRegList().List3From) << "-"
463349cc55cSDimitry Andric << RegName(getRegList().List3To) << ",";
464349cc55cSDimitry Andric OS << RegName(getRegList().List4From) << "-"
465349cc55cSDimitry Andric << RegName(getRegList().List4To);
466fe6060f1SDimitry Andric break;
467fe6060f1SDimitry Andric case Token:
468fe6060f1SDimitry Andric OS << "'" << getToken() << "'";
469fe6060f1SDimitry Andric break;
470fe6060f1SDimitry Andric }
471fe6060f1SDimitry Andric }
472fe6060f1SDimitry Andric
createToken__anonbb596bd40111::CSKYOperand473fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) {
474fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Token);
475fe6060f1SDimitry Andric Op->Tok = Str;
476fe6060f1SDimitry Andric Op->StartLoc = S;
477fe6060f1SDimitry Andric Op->EndLoc = S;
478fe6060f1SDimitry Andric return Op;
479fe6060f1SDimitry Andric }
480fe6060f1SDimitry Andric
createReg__anonbb596bd40111::CSKYOperand481fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createReg(unsigned RegNo, SMLoc S,
482fe6060f1SDimitry Andric SMLoc E) {
483fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Register);
484fe6060f1SDimitry Andric Op->Reg.RegNum = RegNo;
485fe6060f1SDimitry Andric Op->StartLoc = S;
486fe6060f1SDimitry Andric Op->EndLoc = E;
487fe6060f1SDimitry Andric return Op;
488fe6060f1SDimitry Andric }
489fe6060f1SDimitry Andric
createRegSeq__anonbb596bd40111::CSKYOperand490349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> createRegSeq(unsigned RegNoFrom,
491349cc55cSDimitry Andric unsigned RegNoTo, SMLoc S) {
492349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(RegisterSeq);
493349cc55cSDimitry Andric Op->RegSeq.RegNumFrom = RegNoFrom;
494349cc55cSDimitry Andric Op->RegSeq.RegNumTo = RegNoTo;
495349cc55cSDimitry Andric Op->StartLoc = S;
496349cc55cSDimitry Andric Op->EndLoc = S;
497349cc55cSDimitry Andric return Op;
498349cc55cSDimitry Andric }
499349cc55cSDimitry Andric
500349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand>
createRegList__anonbb596bd40111::CSKYOperand501349cc55cSDimitry Andric createRegList(SmallVector<unsigned, 4> reglist, SMLoc S) {
502349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(RegisterList);
503349cc55cSDimitry Andric Op->RegList.List1From = 0;
504349cc55cSDimitry Andric Op->RegList.List1To = 0;
505349cc55cSDimitry Andric Op->RegList.List2From = 0;
506349cc55cSDimitry Andric Op->RegList.List2To = 0;
507349cc55cSDimitry Andric Op->RegList.List3From = 0;
508349cc55cSDimitry Andric Op->RegList.List3To = 0;
509349cc55cSDimitry Andric Op->RegList.List4From = 0;
510349cc55cSDimitry Andric Op->RegList.List4To = 0;
511349cc55cSDimitry Andric
512349cc55cSDimitry Andric for (unsigned i = 0; i < reglist.size(); i += 2) {
513349cc55cSDimitry Andric if (Op->RegList.List1From == 0) {
514349cc55cSDimitry Andric Op->RegList.List1From = reglist[i];
515349cc55cSDimitry Andric Op->RegList.List1To = reglist[i + 1];
516349cc55cSDimitry Andric } else if (Op->RegList.List2From == 0) {
517349cc55cSDimitry Andric Op->RegList.List2From = reglist[i];
518349cc55cSDimitry Andric Op->RegList.List2To = reglist[i + 1];
519349cc55cSDimitry Andric } else if (Op->RegList.List3From == 0) {
520349cc55cSDimitry Andric Op->RegList.List3From = reglist[i];
521349cc55cSDimitry Andric Op->RegList.List3To = reglist[i + 1];
522349cc55cSDimitry Andric } else if (Op->RegList.List4From == 0) {
523349cc55cSDimitry Andric Op->RegList.List4From = reglist[i];
524349cc55cSDimitry Andric Op->RegList.List4To = reglist[i + 1];
525349cc55cSDimitry Andric } else {
526349cc55cSDimitry Andric assert(0);
527349cc55cSDimitry Andric }
528349cc55cSDimitry Andric }
529349cc55cSDimitry Andric
530349cc55cSDimitry Andric Op->StartLoc = S;
531349cc55cSDimitry Andric Op->EndLoc = S;
532349cc55cSDimitry Andric return Op;
533349cc55cSDimitry Andric }
534349cc55cSDimitry Andric
createImm__anonbb596bd40111::CSKYOperand535fe6060f1SDimitry Andric static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S,
536fe6060f1SDimitry Andric SMLoc E) {
537fe6060f1SDimitry Andric auto Op = std::make_unique<CSKYOperand>(Immediate);
538fe6060f1SDimitry Andric Op->Imm.Val = Val;
539fe6060f1SDimitry Andric Op->StartLoc = S;
540fe6060f1SDimitry Andric Op->EndLoc = E;
541fe6060f1SDimitry Andric return Op;
542fe6060f1SDimitry Andric }
543fe6060f1SDimitry Andric
createConstpoolOp__anonbb596bd40111::CSKYOperand544349cc55cSDimitry Andric static std::unique_ptr<CSKYOperand> createConstpoolOp(const MCExpr *Val,
545349cc55cSDimitry Andric SMLoc S, SMLoc E) {
546349cc55cSDimitry Andric auto Op = std::make_unique<CSKYOperand>(CPOP);
547349cc55cSDimitry Andric Op->CPool.Val = Val;
548349cc55cSDimitry Andric Op->StartLoc = S;
549349cc55cSDimitry Andric Op->EndLoc = E;
550349cc55cSDimitry Andric return Op;
551349cc55cSDimitry Andric }
552349cc55cSDimitry Andric
addExpr__anonbb596bd40111::CSKYOperand553fe6060f1SDimitry Andric void addExpr(MCInst &Inst, const MCExpr *Expr) const {
554fe6060f1SDimitry Andric assert(Expr && "Expr shouldn't be null!");
555fe6060f1SDimitry Andric if (auto *CE = dyn_cast<MCConstantExpr>(Expr))
556fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createImm(CE->getValue()));
557fe6060f1SDimitry Andric else
558fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr));
559fe6060f1SDimitry Andric }
560fe6060f1SDimitry Andric
561fe6060f1SDimitry Andric // Used by the TableGen Code.
addRegOperands__anonbb596bd40111::CSKYOperand562fe6060f1SDimitry Andric void addRegOperands(MCInst &Inst, unsigned N) const {
563fe6060f1SDimitry Andric assert(N == 1 && "Invalid number of operands!");
564fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createReg(getReg()));
565fe6060f1SDimitry Andric }
566fe6060f1SDimitry Andric
addImmOperands__anonbb596bd40111::CSKYOperand567fe6060f1SDimitry Andric void addImmOperands(MCInst &Inst, unsigned N) const {
568fe6060f1SDimitry Andric assert(N == 1 && "Invalid number of operands!");
569fe6060f1SDimitry Andric addExpr(Inst, getImm());
570fe6060f1SDimitry Andric }
571349cc55cSDimitry Andric
addConstpoolOperands__anonbb596bd40111::CSKYOperand572349cc55cSDimitry Andric void addConstpoolOperands(MCInst &Inst, unsigned N) const {
573349cc55cSDimitry Andric assert(N == 1 && "Invalid number of operands!");
574349cc55cSDimitry Andric Inst.addOperand(MCOperand::createExpr(getConstpoolOp()));
575349cc55cSDimitry Andric }
576349cc55cSDimitry Andric
addRegSeqOperands__anonbb596bd40111::CSKYOperand577349cc55cSDimitry Andric void addRegSeqOperands(MCInst &Inst, unsigned N) const {
578349cc55cSDimitry Andric assert(N == 2 && "Invalid number of operands!");
579349cc55cSDimitry Andric auto regSeq = getRegSeq();
580349cc55cSDimitry Andric
581349cc55cSDimitry Andric Inst.addOperand(MCOperand::createReg(regSeq.first));
582349cc55cSDimitry Andric Inst.addOperand(MCOperand::createReg(regSeq.second));
583349cc55cSDimitry Andric }
584349cc55cSDimitry Andric
getListValue__anonbb596bd40111::CSKYOperand585349cc55cSDimitry Andric static unsigned getListValue(unsigned ListFrom, unsigned ListTo) {
586349cc55cSDimitry Andric if (ListFrom == ListTo && ListFrom == CSKY::R15)
587349cc55cSDimitry Andric return (1 << 4);
588349cc55cSDimitry Andric else if (ListFrom == ListTo && ListFrom == CSKY::R28)
589349cc55cSDimitry Andric return (1 << 8);
590349cc55cSDimitry Andric else if (ListFrom == CSKY::R4)
591349cc55cSDimitry Andric return ListTo - ListFrom + 1;
592349cc55cSDimitry Andric else if (ListFrom == CSKY::R16)
593349cc55cSDimitry Andric return ((ListTo - ListFrom + 1) << 5);
594349cc55cSDimitry Andric else
595349cc55cSDimitry Andric return 0;
596349cc55cSDimitry Andric }
597349cc55cSDimitry Andric
addRegListOperands__anonbb596bd40111::CSKYOperand598349cc55cSDimitry Andric void addRegListOperands(MCInst &Inst, unsigned N) const {
599349cc55cSDimitry Andric assert(N == 1 && "Invalid number of operands!");
600349cc55cSDimitry Andric auto regList = getRegList();
601349cc55cSDimitry Andric
602349cc55cSDimitry Andric unsigned V = 0;
603349cc55cSDimitry Andric
604349cc55cSDimitry Andric unsigned T = getListValue(regList.List1From, regList.List1To);
605349cc55cSDimitry Andric if (T != 0)
606349cc55cSDimitry Andric V = V | T;
607349cc55cSDimitry Andric
608349cc55cSDimitry Andric T = getListValue(regList.List2From, regList.List2To);
609349cc55cSDimitry Andric if (T != 0)
610349cc55cSDimitry Andric V = V | T;
611349cc55cSDimitry Andric
612349cc55cSDimitry Andric T = getListValue(regList.List3From, regList.List3To);
613349cc55cSDimitry Andric if (T != 0)
614349cc55cSDimitry Andric V = V | T;
615349cc55cSDimitry Andric
616349cc55cSDimitry Andric T = getListValue(regList.List4From, regList.List4To);
617349cc55cSDimitry Andric if (T != 0)
618349cc55cSDimitry Andric V = V | T;
619349cc55cSDimitry Andric
620349cc55cSDimitry Andric Inst.addOperand(MCOperand::createImm(V));
621349cc55cSDimitry Andric }
622349cc55cSDimitry Andric
isValidForTie__anonbb596bd40111::CSKYOperand623349cc55cSDimitry Andric bool isValidForTie(const CSKYOperand &Other) const {
624349cc55cSDimitry Andric if (Kind != Other.Kind)
625349cc55cSDimitry Andric return false;
626349cc55cSDimitry Andric
627349cc55cSDimitry Andric switch (Kind) {
628349cc55cSDimitry Andric default:
629349cc55cSDimitry Andric llvm_unreachable("Unexpected kind");
630349cc55cSDimitry Andric return false;
631349cc55cSDimitry Andric case Register:
632349cc55cSDimitry Andric return Reg.RegNum == Other.Reg.RegNum;
633349cc55cSDimitry Andric }
634349cc55cSDimitry Andric }
635fe6060f1SDimitry Andric };
636fe6060f1SDimitry Andric } // end anonymous namespace.
637fe6060f1SDimitry Andric
638fe6060f1SDimitry Andric #define GET_REGISTER_MATCHER
639fe6060f1SDimitry Andric #define GET_SUBTARGET_FEATURE_NAME
640fe6060f1SDimitry Andric #define GET_MATCHER_IMPLEMENTATION
641fe6060f1SDimitry Andric #define GET_MNEMONIC_SPELL_CHECKER
642fe6060f1SDimitry Andric #include "CSKYGenAsmMatcher.inc"
643fe6060f1SDimitry Andric
convertFPR32ToFPR64(MCRegister Reg)64481ad6265SDimitry Andric static MCRegister convertFPR32ToFPR64(MCRegister Reg) {
64581ad6265SDimitry Andric assert(Reg >= CSKY::F0_32 && Reg <= CSKY::F31_32 && "Invalid register");
64681ad6265SDimitry Andric return Reg - CSKY::F0_32 + CSKY::F0_64;
64781ad6265SDimitry Andric }
64881ad6265SDimitry Andric
649fe6060f1SDimitry Andric static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
650fe6060f1SDimitry Andric unsigned VariantID = 0);
651fe6060f1SDimitry Andric
generateImmOutOfRangeError(OperandVector & Operands,uint64_t ErrorInfo,int64_t Lower,int64_t Upper,const Twine & Msg="immediate must be an integer in the range")652fe6060f1SDimitry Andric bool CSKYAsmParser::generateImmOutOfRangeError(
653fe6060f1SDimitry Andric OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
65406c3fb27SDimitry Andric const Twine &Msg = "immediate must be an integer in the range") {
655fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
656fe6060f1SDimitry Andric return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
657fe6060f1SDimitry Andric }
658fe6060f1SDimitry Andric
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)659fe6060f1SDimitry Andric bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
660fe6060f1SDimitry Andric OperandVector &Operands,
661fe6060f1SDimitry Andric MCStreamer &Out,
662fe6060f1SDimitry Andric uint64_t &ErrorInfo,
663fe6060f1SDimitry Andric bool MatchingInlineAsm) {
664fe6060f1SDimitry Andric MCInst Inst;
665fe6060f1SDimitry Andric FeatureBitset MissingFeatures;
666fe6060f1SDimitry Andric
667fe6060f1SDimitry Andric auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
668fe6060f1SDimitry Andric MatchingInlineAsm);
669fe6060f1SDimitry Andric switch (Result) {
670fe6060f1SDimitry Andric default:
671fe6060f1SDimitry Andric break;
672fe6060f1SDimitry Andric case Match_Success:
673349cc55cSDimitry Andric return processInstruction(Inst, IDLoc, Operands, Out);
674fe6060f1SDimitry Andric case Match_MissingFeature: {
675fe6060f1SDimitry Andric assert(MissingFeatures.any() && "Unknown missing features!");
676fe6060f1SDimitry Andric ListSeparator LS;
677fe6060f1SDimitry Andric std::string Msg = "instruction requires the following: ";
678fe6060f1SDimitry Andric for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
679fe6060f1SDimitry Andric if (MissingFeatures[i]) {
680fe6060f1SDimitry Andric Msg += LS;
681fe6060f1SDimitry Andric Msg += getSubtargetFeatureName(i);
682fe6060f1SDimitry Andric }
683fe6060f1SDimitry Andric }
684fe6060f1SDimitry Andric return Error(IDLoc, Msg);
685fe6060f1SDimitry Andric }
686fe6060f1SDimitry Andric case Match_MnemonicFail: {
687fe6060f1SDimitry Andric FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
688fe6060f1SDimitry Andric std::string Suggestion =
689fe6060f1SDimitry Andric CSKYMnemonicSpellCheck(((CSKYOperand &)*Operands[0]).getToken(), FBS);
690fe6060f1SDimitry Andric return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);
691fe6060f1SDimitry Andric }
692fe6060f1SDimitry Andric case Match_InvalidTiedOperand:
693fe6060f1SDimitry Andric case Match_InvalidOperand: {
694fe6060f1SDimitry Andric SMLoc ErrorLoc = IDLoc;
695fe6060f1SDimitry Andric if (ErrorInfo != ~0U) {
696fe6060f1SDimitry Andric if (ErrorInfo >= Operands.size())
697fe6060f1SDimitry Andric return Error(ErrorLoc, "too few operands for instruction");
698fe6060f1SDimitry Andric
699fe6060f1SDimitry Andric ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
700fe6060f1SDimitry Andric if (ErrorLoc == SMLoc())
701fe6060f1SDimitry Andric ErrorLoc = IDLoc;
702fe6060f1SDimitry Andric }
703fe6060f1SDimitry Andric return Error(ErrorLoc, "invalid operand for instruction");
704fe6060f1SDimitry Andric }
705fe6060f1SDimitry Andric }
706fe6060f1SDimitry Andric
707fe6060f1SDimitry Andric // Handle the case when the error message is of specific type
708fe6060f1SDimitry Andric // other than the generic Match_InvalidOperand, and the
709fe6060f1SDimitry Andric // corresponding operand is missing.
710fe6060f1SDimitry Andric if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
711fe6060f1SDimitry Andric SMLoc ErrorLoc = IDLoc;
712fe6060f1SDimitry Andric if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
713fe6060f1SDimitry Andric return Error(ErrorLoc, "too few operands for instruction");
714fe6060f1SDimitry Andric }
715fe6060f1SDimitry Andric
716fe6060f1SDimitry Andric switch (Result) {
717fe6060f1SDimitry Andric default:
718fe6060f1SDimitry Andric break;
719349cc55cSDimitry Andric case Match_InvalidSImm8:
720349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
721349cc55cSDimitry Andric (1 << 7) - 1);
722349cc55cSDimitry Andric case Match_InvalidOImm3:
723349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 3));
724349cc55cSDimitry Andric case Match_InvalidOImm4:
725349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
726349cc55cSDimitry Andric case Match_InvalidOImm5:
727349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
728349cc55cSDimitry Andric case Match_InvalidOImm6:
729349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
730349cc55cSDimitry Andric case Match_InvalidOImm8:
731349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 8));
732fe6060f1SDimitry Andric case Match_InvalidOImm12:
733fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12));
734fe6060f1SDimitry Andric case Match_InvalidOImm16:
735fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16));
736349cc55cSDimitry Andric case Match_InvalidUImm1:
737349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
738fe6060f1SDimitry Andric case Match_InvalidUImm2:
739fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
740349cc55cSDimitry Andric case Match_InvalidUImm3:
741349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
742349cc55cSDimitry Andric case Match_InvalidUImm4:
743349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
744fe6060f1SDimitry Andric case Match_InvalidUImm5:
745fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
746349cc55cSDimitry Andric case Match_InvalidUImm6:
747349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
748349cc55cSDimitry Andric case Match_InvalidUImm7:
749349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
750349cc55cSDimitry Andric case Match_InvalidUImm8:
751349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
752fe6060f1SDimitry Andric case Match_InvalidUImm12:
753fe6060f1SDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);
754349cc55cSDimitry Andric case Match_InvalidUImm16:
755349cc55cSDimitry Andric return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1);
756349cc55cSDimitry Andric case Match_InvalidUImm5Shift1:
757349cc55cSDimitry Andric return generateImmOutOfRangeError(
758349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 5) - 2,
759349cc55cSDimitry Andric "immediate must be a multiple of 2 bytes in the range");
760fe6060f1SDimitry Andric case Match_InvalidUImm12Shift1:
761fe6060f1SDimitry Andric return generateImmOutOfRangeError(
762fe6060f1SDimitry Andric Operands, ErrorInfo, 0, (1 << 12) - 2,
763fe6060f1SDimitry Andric "immediate must be a multiple of 2 bytes in the range");
764349cc55cSDimitry Andric case Match_InvalidUImm5Shift2:
765349cc55cSDimitry Andric return generateImmOutOfRangeError(
766349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 5) - 4,
767349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range");
768349cc55cSDimitry Andric case Match_InvalidUImm7Shift1:
769349cc55cSDimitry Andric return generateImmOutOfRangeError(
770349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 7) - 2,
771349cc55cSDimitry Andric "immediate must be a multiple of 2 bytes in the range");
772349cc55cSDimitry Andric case Match_InvalidUImm7Shift2:
773349cc55cSDimitry Andric return generateImmOutOfRangeError(
774349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 7) - 4,
775349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range");
776349cc55cSDimitry Andric case Match_InvalidUImm8Shift2:
777349cc55cSDimitry Andric return generateImmOutOfRangeError(
778349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 4,
779349cc55cSDimitry Andric "immediate must be a multiple of 4 bytes in the range");
780349cc55cSDimitry Andric case Match_InvalidUImm8Shift3:
781349cc55cSDimitry Andric return generateImmOutOfRangeError(
782349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 8,
783349cc55cSDimitry Andric "immediate must be a multiple of 8 bytes in the range");
784349cc55cSDimitry Andric case Match_InvalidUImm8Shift8:
785349cc55cSDimitry Andric return generateImmOutOfRangeError(
786349cc55cSDimitry Andric Operands, ErrorInfo, 0, (1 << 8) - 256,
787349cc55cSDimitry Andric "immediate must be a multiple of 256 bytes in the range");
788fe6060f1SDimitry Andric case Match_InvalidUImm12Shift2:
789fe6060f1SDimitry Andric return generateImmOutOfRangeError(
790fe6060f1SDimitry Andric Operands, ErrorInfo, 0, (1 << 12) - 4,
791fe6060f1SDimitry Andric "immediate must be a multiple of 4 bytes in the range");
792fe6060f1SDimitry Andric case Match_InvalidCSKYSymbol: {
793fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
794fe6060f1SDimitry Andric return Error(ErrorLoc, "operand must be a symbol name");
795fe6060f1SDimitry Andric }
796fe6060f1SDimitry Andric case Match_InvalidConstpool: {
797fe6060f1SDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
798fe6060f1SDimitry Andric return Error(ErrorLoc, "operand must be a constpool symbol name");
799fe6060f1SDimitry Andric }
800349cc55cSDimitry Andric case Match_InvalidPSRFlag: {
801349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
802349cc55cSDimitry Andric return Error(ErrorLoc, "psrset operand is not valid");
803349cc55cSDimitry Andric }
804349cc55cSDimitry Andric case Match_InvalidRegSeq: {
805349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
806349cc55cSDimitry Andric return Error(ErrorLoc, "Register sequence is not valid");
807349cc55cSDimitry Andric }
808349cc55cSDimitry Andric case Match_InvalidRegOutOfRange: {
809349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
810349cc55cSDimitry Andric return Error(ErrorLoc, "register is out of range");
811349cc55cSDimitry Andric }
812349cc55cSDimitry Andric case Match_RequiresSameSrcAndDst: {
813349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
814349cc55cSDimitry Andric return Error(ErrorLoc, "src and dst operand must be same");
815349cc55cSDimitry Andric }
816349cc55cSDimitry Andric case Match_InvalidRegList: {
817349cc55cSDimitry Andric SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
818349cc55cSDimitry Andric return Error(ErrorLoc, "invalid register list");
819349cc55cSDimitry Andric }
820349cc55cSDimitry Andric }
821349cc55cSDimitry Andric LLVM_DEBUG(dbgs() << "Result = " << Result);
822349cc55cSDimitry Andric llvm_unreachable("Unknown match type detected!");
823fe6060f1SDimitry Andric }
824fe6060f1SDimitry Andric
processLRW(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)82581ad6265SDimitry Andric bool CSKYAsmParser::processLRW(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
82681ad6265SDimitry Andric Inst.setLoc(IDLoc);
82781ad6265SDimitry Andric
82881ad6265SDimitry Andric unsigned Opcode;
82981ad6265SDimitry Andric MCOperand Op;
83081ad6265SDimitry Andric if (Inst.getOpcode() == CSKY::PseudoLRW16)
83181ad6265SDimitry Andric Opcode = CSKY::LRW16;
83281ad6265SDimitry Andric else
83381ad6265SDimitry Andric Opcode = CSKY::LRW32;
83481ad6265SDimitry Andric
83581ad6265SDimitry Andric if (Inst.getOperand(1).isImm()) {
83681ad6265SDimitry Andric if (isUInt<8>(Inst.getOperand(1).getImm()) &&
83781ad6265SDimitry Andric Inst.getOperand(0).getReg() <= CSKY::R7) {
83881ad6265SDimitry Andric Opcode = CSKY::MOVI16;
83906c3fb27SDimitry Andric } else if (getSTI().hasFeature(CSKY::HasE2) &&
84081ad6265SDimitry Andric isUInt<16>(Inst.getOperand(1).getImm())) {
84181ad6265SDimitry Andric Opcode = CSKY::MOVI32;
84281ad6265SDimitry Andric } else {
84381ad6265SDimitry Andric auto *Expr = getTargetStreamer().addConstantPoolEntry(
84481ad6265SDimitry Andric MCConstantExpr::create(Inst.getOperand(1).getImm(), getContext()),
84581ad6265SDimitry Andric Inst.getLoc());
84681ad6265SDimitry Andric Inst.erase(std::prev(Inst.end()));
84781ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr));
84881ad6265SDimitry Andric }
84981ad6265SDimitry Andric } else {
85081ad6265SDimitry Andric const MCExpr *AdjustExpr = nullptr;
85181ad6265SDimitry Andric if (const CSKYMCExpr *CSKYExpr =
85281ad6265SDimitry Andric dyn_cast<CSKYMCExpr>(Inst.getOperand(1).getExpr())) {
85381ad6265SDimitry Andric if (CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSGD ||
85481ad6265SDimitry Andric CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSIE ||
85581ad6265SDimitry Andric CSKYExpr->getKind() == CSKYMCExpr::VK_CSKY_TLSLDM) {
85681ad6265SDimitry Andric MCSymbol *Dot = getContext().createNamedTempSymbol();
85781ad6265SDimitry Andric Out.emitLabel(Dot);
85881ad6265SDimitry Andric AdjustExpr = MCSymbolRefExpr::create(Dot, getContext());
85981ad6265SDimitry Andric }
86081ad6265SDimitry Andric }
86181ad6265SDimitry Andric auto *Expr = getTargetStreamer().addConstantPoolEntry(
86281ad6265SDimitry Andric Inst.getOperand(1).getExpr(), Inst.getLoc(), AdjustExpr);
86381ad6265SDimitry Andric Inst.erase(std::prev(Inst.end()));
86481ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr));
86581ad6265SDimitry Andric }
86681ad6265SDimitry Andric
86781ad6265SDimitry Andric Inst.setOpcode(Opcode);
86881ad6265SDimitry Andric
86981ad6265SDimitry Andric Out.emitInstruction(Inst, getSTI());
87081ad6265SDimitry Andric return false;
87181ad6265SDimitry Andric }
87281ad6265SDimitry Andric
processJSRI(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)87381ad6265SDimitry Andric bool CSKYAsmParser::processJSRI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
87481ad6265SDimitry Andric Inst.setLoc(IDLoc);
87581ad6265SDimitry Andric
87681ad6265SDimitry Andric if (Inst.getOperand(0).isImm()) {
87781ad6265SDimitry Andric const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
87881ad6265SDimitry Andric MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()),
87981ad6265SDimitry Andric Inst.getLoc());
88081ad6265SDimitry Andric Inst.setOpcode(CSKY::JSRI32);
88181ad6265SDimitry Andric Inst.erase(std::prev(Inst.end()));
88281ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr));
88381ad6265SDimitry Andric } else {
88481ad6265SDimitry Andric const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
88581ad6265SDimitry Andric Inst.getOperand(0).getExpr(), Inst.getLoc());
88681ad6265SDimitry Andric Inst.setOpcode(CSKY::JBSR32);
88781ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr));
88881ad6265SDimitry Andric }
88981ad6265SDimitry Andric
89081ad6265SDimitry Andric Out.emitInstruction(Inst, getSTI());
89181ad6265SDimitry Andric return false;
89281ad6265SDimitry Andric }
89381ad6265SDimitry Andric
processJMPI(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)89481ad6265SDimitry Andric bool CSKYAsmParser::processJMPI(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out) {
89581ad6265SDimitry Andric Inst.setLoc(IDLoc);
89681ad6265SDimitry Andric
89781ad6265SDimitry Andric if (Inst.getOperand(0).isImm()) {
89881ad6265SDimitry Andric const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
89981ad6265SDimitry Andric MCConstantExpr::create(Inst.getOperand(0).getImm(), getContext()),
90081ad6265SDimitry Andric Inst.getLoc());
90181ad6265SDimitry Andric Inst.setOpcode(CSKY::JMPI32);
90281ad6265SDimitry Andric Inst.erase(std::prev(Inst.end()));
90381ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr));
90481ad6265SDimitry Andric } else {
90581ad6265SDimitry Andric const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
90681ad6265SDimitry Andric Inst.getOperand(0).getExpr(), Inst.getLoc());
90781ad6265SDimitry Andric Inst.setOpcode(CSKY::JBR32);
90881ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr));
90981ad6265SDimitry Andric }
91081ad6265SDimitry Andric
91181ad6265SDimitry Andric Out.emitInstruction(Inst, getSTI());
91281ad6265SDimitry Andric return false;
91381ad6265SDimitry Andric }
91481ad6265SDimitry Andric
processInstruction(MCInst & Inst,SMLoc IDLoc,OperandVector & Operands,MCStreamer & Out)915349cc55cSDimitry Andric bool CSKYAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
916349cc55cSDimitry Andric OperandVector &Operands,
917349cc55cSDimitry Andric MCStreamer &Out) {
918349cc55cSDimitry Andric
9190eae32dcSDimitry Andric switch (Inst.getOpcode()) {
9200eae32dcSDimitry Andric default:
9210eae32dcSDimitry Andric break;
9220eae32dcSDimitry Andric case CSKY::LDQ32:
9230eae32dcSDimitry Andric case CSKY::STQ32:
924349cc55cSDimitry Andric if (Inst.getOperand(1).getReg() != CSKY::R4 ||
925349cc55cSDimitry Andric Inst.getOperand(2).getReg() != CSKY::R7) {
926349cc55cSDimitry Andric return Error(IDLoc, "Register sequence is not valid. 'r4-r7' expected");
927349cc55cSDimitry Andric }
928349cc55cSDimitry Andric Inst.setOpcode(Inst.getOpcode() == CSKY::LDQ32 ? CSKY::LDM32 : CSKY::STM32);
9290eae32dcSDimitry Andric break;
9300eae32dcSDimitry Andric case CSKY::SEXT32:
9310eae32dcSDimitry Andric case CSKY::ZEXT32:
932349cc55cSDimitry Andric if (Inst.getOperand(2).getImm() < Inst.getOperand(3).getImm())
933349cc55cSDimitry Andric return Error(IDLoc, "msb must be greater or equal to lsb");
9340eae32dcSDimitry Andric break;
9350eae32dcSDimitry Andric case CSKY::INS32:
936349cc55cSDimitry Andric if (Inst.getOperand(3).getImm() < Inst.getOperand(4).getImm())
937349cc55cSDimitry Andric return Error(IDLoc, "msb must be greater or equal to lsb");
9380eae32dcSDimitry Andric break;
9390eae32dcSDimitry Andric case CSKY::IDLY32:
940349cc55cSDimitry Andric if (Inst.getOperand(0).getImm() > 32 || Inst.getOperand(0).getImm() < 0)
941349cc55cSDimitry Andric return Error(IDLoc, "n must be in range [0,32]");
9420eae32dcSDimitry Andric break;
9430eae32dcSDimitry Andric case CSKY::ADDC32:
9440eae32dcSDimitry Andric case CSKY::SUBC32:
9450eae32dcSDimitry Andric case CSKY::ADDC16:
9460eae32dcSDimitry Andric case CSKY::SUBC16:
9470eae32dcSDimitry Andric Inst.erase(std::next(Inst.begin()));
9480eae32dcSDimitry Andric Inst.erase(std::prev(Inst.end()));
9490eae32dcSDimitry Andric Inst.insert(std::next(Inst.begin()), MCOperand::createReg(CSKY::C));
9500eae32dcSDimitry Andric Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));
9510eae32dcSDimitry Andric break;
9520eae32dcSDimitry Andric case CSKY::CMPNEI32:
9530eae32dcSDimitry Andric case CSKY::CMPNEI16:
9540eae32dcSDimitry Andric case CSKY::CMPNE32:
9550eae32dcSDimitry Andric case CSKY::CMPNE16:
9560eae32dcSDimitry Andric case CSKY::CMPHSI32:
9570eae32dcSDimitry Andric case CSKY::CMPHSI16:
9580eae32dcSDimitry Andric case CSKY::CMPHS32:
9590eae32dcSDimitry Andric case CSKY::CMPHS16:
9600eae32dcSDimitry Andric case CSKY::CMPLTI32:
9610eae32dcSDimitry Andric case CSKY::CMPLTI16:
9620eae32dcSDimitry Andric case CSKY::CMPLT32:
9630eae32dcSDimitry Andric case CSKY::CMPLT16:
9640eae32dcSDimitry Andric case CSKY::BTSTI32:
9650eae32dcSDimitry Andric Inst.erase(Inst.begin());
9660eae32dcSDimitry Andric Inst.insert(Inst.begin(), MCOperand::createReg(CSKY::C));
9670eae32dcSDimitry Andric break;
9680eae32dcSDimitry Andric case CSKY::MVCV32:
9690eae32dcSDimitry Andric Inst.erase(std::next(Inst.begin()));
9700eae32dcSDimitry Andric Inst.insert(Inst.end(), MCOperand::createReg(CSKY::C));
9710eae32dcSDimitry Andric break;
97281ad6265SDimitry Andric case CSKY::PseudoLRW16:
97381ad6265SDimitry Andric case CSKY::PseudoLRW32:
97481ad6265SDimitry Andric return processLRW(Inst, IDLoc, Out);
97581ad6265SDimitry Andric case CSKY::PseudoJSRI32:
97681ad6265SDimitry Andric return processJSRI(Inst, IDLoc, Out);
97781ad6265SDimitry Andric case CSKY::PseudoJMPI32:
97881ad6265SDimitry Andric return processJMPI(Inst, IDLoc, Out);
97981ad6265SDimitry Andric case CSKY::JBSR32:
98081ad6265SDimitry Andric case CSKY::JBR16:
98181ad6265SDimitry Andric case CSKY::JBT16:
98281ad6265SDimitry Andric case CSKY::JBF16:
98381ad6265SDimitry Andric case CSKY::JBR32:
98481ad6265SDimitry Andric case CSKY::JBT32:
98581ad6265SDimitry Andric case CSKY::JBF32:
98681ad6265SDimitry Andric unsigned Num = Inst.getNumOperands() - 1;
98781ad6265SDimitry Andric assert(Inst.getOperand(Num).isExpr());
98881ad6265SDimitry Andric
98981ad6265SDimitry Andric const MCExpr *Expr = getTargetStreamer().addConstantPoolEntry(
99081ad6265SDimitry Andric Inst.getOperand(Num).getExpr(), Inst.getLoc());
99181ad6265SDimitry Andric
99281ad6265SDimitry Andric Inst.addOperand(MCOperand::createExpr(Expr));
99381ad6265SDimitry Andric break;
994349cc55cSDimitry Andric }
995349cc55cSDimitry Andric
9960eae32dcSDimitry Andric emitToStreamer(Out, Inst);
997349cc55cSDimitry Andric return false;
998fe6060f1SDimitry Andric }
999fe6060f1SDimitry Andric
1000fe6060f1SDimitry Andric // Attempts to match Name as a register (either using the default name or
1001fe6060f1SDimitry Andric // alternative ABI names), setting RegNo to the matching register. Upon
1002fe6060f1SDimitry Andric // failure, returns true and sets RegNo to 0.
matchRegisterNameHelper(const MCSubtargetInfo & STI,MCRegister & Reg,StringRef Name)10035f757f3fSDimitry Andric static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg,
10045f757f3fSDimitry Andric StringRef Name) {
10055f757f3fSDimitry Andric Reg = MatchRegisterName(Name);
1006fe6060f1SDimitry Andric
10075f757f3fSDimitry Andric if (Reg == CSKY::NoRegister)
10085f757f3fSDimitry Andric Reg = MatchRegisterAltName(Name);
1009fe6060f1SDimitry Andric
10105f757f3fSDimitry Andric return Reg == CSKY::NoRegister;
1011fe6060f1SDimitry Andric }
1012fe6060f1SDimitry Andric
parseRegister(MCRegister & Reg,SMLoc & StartLoc,SMLoc & EndLoc)10135f757f3fSDimitry Andric bool CSKYAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
1014fe6060f1SDimitry Andric SMLoc &EndLoc) {
1015fe6060f1SDimitry Andric const AsmToken &Tok = getParser().getTok();
1016fe6060f1SDimitry Andric StartLoc = Tok.getLoc();
1017fe6060f1SDimitry Andric EndLoc = Tok.getEndLoc();
1018fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier();
1019fe6060f1SDimitry Andric
10205f757f3fSDimitry Andric if (!matchRegisterNameHelper(getSTI(), Reg, Name)) {
1021fe6060f1SDimitry Andric getParser().Lex(); // Eat identifier token.
1022fe6060f1SDimitry Andric return false;
1023fe6060f1SDimitry Andric }
1024fe6060f1SDimitry Andric
102506c3fb27SDimitry Andric return true;
1026fe6060f1SDimitry Andric }
1027fe6060f1SDimitry Andric
parseRegister(OperandVector & Operands)102806c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseRegister(OperandVector &Operands) {
1029fe6060f1SDimitry Andric SMLoc S = getLoc();
1030fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1031fe6060f1SDimitry Andric
1032fe6060f1SDimitry Andric switch (getLexer().getKind()) {
1033fe6060f1SDimitry Andric default:
103406c3fb27SDimitry Andric return ParseStatus::NoMatch;
1035fe6060f1SDimitry Andric case AsmToken::Identifier: {
1036fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier();
10375f757f3fSDimitry Andric MCRegister Reg;
1038fe6060f1SDimitry Andric
10395f757f3fSDimitry Andric if (matchRegisterNameHelper(getSTI(), Reg, Name))
104006c3fb27SDimitry Andric return ParseStatus::NoMatch;
1041fe6060f1SDimitry Andric
1042fe6060f1SDimitry Andric getLexer().Lex();
10435f757f3fSDimitry Andric Operands.push_back(CSKYOperand::createReg(Reg, S, E));
1044fe6060f1SDimitry Andric
104506c3fb27SDimitry Andric return ParseStatus::Success;
1046fe6060f1SDimitry Andric }
1047fe6060f1SDimitry Andric }
1048fe6060f1SDimitry Andric }
1049fe6060f1SDimitry Andric
parseBaseRegImm(OperandVector & Operands)105006c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) {
1051fe6060f1SDimitry Andric assert(getLexer().is(AsmToken::LParen));
1052fe6060f1SDimitry Andric
1053fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken("(", getLoc()));
1054fe6060f1SDimitry Andric
1055fe6060f1SDimitry Andric auto Tok = getParser().Lex(); // Eat '('
1056fe6060f1SDimitry Andric
105706c3fb27SDimitry Andric if (!parseRegister(Operands).isSuccess()) {
1058fe6060f1SDimitry Andric getLexer().UnLex(Tok);
1059fe6060f1SDimitry Andric Operands.pop_back();
106006c3fb27SDimitry Andric return ParseStatus::NoMatch;
1061349cc55cSDimitry Andric }
1062349cc55cSDimitry Andric
1063349cc55cSDimitry Andric if (getLexer().is(AsmToken::RParen)) {
1064349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createToken(")", getLoc()));
1065349cc55cSDimitry Andric getParser().Lex(); // Eat ')'
106606c3fb27SDimitry Andric return ParseStatus::Success;
1067fe6060f1SDimitry Andric }
1068fe6060f1SDimitry Andric
106906c3fb27SDimitry Andric if (getLexer().isNot(AsmToken::Comma))
107006c3fb27SDimitry Andric return Error(getLoc(), "expected ','");
1071fe6060f1SDimitry Andric
1072fe6060f1SDimitry Andric getParser().Lex(); // Eat ','
1073fe6060f1SDimitry Andric
107406c3fb27SDimitry Andric if (parseRegister(Operands).isSuccess()) {
107506c3fb27SDimitry Andric if (getLexer().isNot(AsmToken::LessLess))
107606c3fb27SDimitry Andric return Error(getLoc(), "expected '<<'");
1077fe6060f1SDimitry Andric
1078fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken("<<", getLoc()));
1079fe6060f1SDimitry Andric
1080fe6060f1SDimitry Andric getParser().Lex(); // Eat '<<'
1081fe6060f1SDimitry Andric
108206c3fb27SDimitry Andric if (!parseImmediate(Operands).isSuccess())
108306c3fb27SDimitry Andric return Error(getLoc(), "expected imm");
108406c3fb27SDimitry Andric
108506c3fb27SDimitry Andric } else if (!parseImmediate(Operands).isSuccess()) {
108606c3fb27SDimitry Andric return Error(getLoc(), "expected imm");
1087fe6060f1SDimitry Andric }
1088fe6060f1SDimitry Andric
108906c3fb27SDimitry Andric if (getLexer().isNot(AsmToken::RParen))
109006c3fb27SDimitry Andric return Error(getLoc(), "expected ')'");
1091fe6060f1SDimitry Andric
1092fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken(")", getLoc()));
1093fe6060f1SDimitry Andric
1094fe6060f1SDimitry Andric getParser().Lex(); // Eat ')'
1095fe6060f1SDimitry Andric
109606c3fb27SDimitry Andric return ParseStatus::Success;
1097fe6060f1SDimitry Andric }
1098fe6060f1SDimitry Andric
parseImmediate(OperandVector & Operands)109906c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseImmediate(OperandVector &Operands) {
1100fe6060f1SDimitry Andric switch (getLexer().getKind()) {
1101fe6060f1SDimitry Andric default:
110206c3fb27SDimitry Andric return ParseStatus::NoMatch;
1103fe6060f1SDimitry Andric case AsmToken::LParen:
1104fe6060f1SDimitry Andric case AsmToken::Minus:
1105fe6060f1SDimitry Andric case AsmToken::Plus:
1106fe6060f1SDimitry Andric case AsmToken::Integer:
1107fe6060f1SDimitry Andric case AsmToken::String:
1108fe6060f1SDimitry Andric break;
1109fe6060f1SDimitry Andric }
1110fe6060f1SDimitry Andric
1111fe6060f1SDimitry Andric const MCExpr *IdVal;
1112fe6060f1SDimitry Andric SMLoc S = getLoc();
111306c3fb27SDimitry Andric if (getParser().parseExpression(IdVal))
111406c3fb27SDimitry Andric return Error(getLoc(), "unknown expression");
1115fe6060f1SDimitry Andric
1116fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1117fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createImm(IdVal, S, E));
111806c3fb27SDimitry Andric return ParseStatus::Success;
1119fe6060f1SDimitry Andric }
1120fe6060f1SDimitry Andric
1121fe6060f1SDimitry Andric /// Looks at a token type and creates the relevant operand from this
1122fe6060f1SDimitry Andric /// information, adding to Operands. If operand was parsed, returns false, else
1123fe6060f1SDimitry Andric /// true.
parseOperand(OperandVector & Operands,StringRef Mnemonic)1124fe6060f1SDimitry Andric bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1125fe6060f1SDimitry Andric // Check if the current operand has a custom associated parser, if so, try to
1126fe6060f1SDimitry Andric // custom parse the operand, or fallback to the general approach.
112706c3fb27SDimitry Andric ParseStatus Result =
1128fe6060f1SDimitry Andric MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
112906c3fb27SDimitry Andric if (Result.isSuccess())
1130fe6060f1SDimitry Andric return false;
113106c3fb27SDimitry Andric if (Result.isFailure())
1132fe6060f1SDimitry Andric return true;
1133fe6060f1SDimitry Andric
1134fe6060f1SDimitry Andric // Attempt to parse token as register
1135349cc55cSDimitry Andric auto Res = parseRegister(Operands);
113606c3fb27SDimitry Andric if (Res.isSuccess())
1137fe6060f1SDimitry Andric return false;
113806c3fb27SDimitry Andric if (Res.isFailure())
1139349cc55cSDimitry Andric return true;
1140fe6060f1SDimitry Andric
1141fe6060f1SDimitry Andric // Attempt to parse token as (register, imm)
1142349cc55cSDimitry Andric if (getLexer().is(AsmToken::LParen)) {
1143349cc55cSDimitry Andric Res = parseBaseRegImm(Operands);
114406c3fb27SDimitry Andric if (Res.isSuccess())
1145fe6060f1SDimitry Andric return false;
114606c3fb27SDimitry Andric if (Res.isFailure())
1147349cc55cSDimitry Andric return true;
1148349cc55cSDimitry Andric }
1149fe6060f1SDimitry Andric
1150349cc55cSDimitry Andric Res = parseImmediate(Operands);
115106c3fb27SDimitry Andric if (Res.isSuccess())
1152fe6060f1SDimitry Andric return false;
115306c3fb27SDimitry Andric if (Res.isFailure())
1154349cc55cSDimitry Andric return true;
1155fe6060f1SDimitry Andric
1156fe6060f1SDimitry Andric // Finally we have exhausted all options and must declare defeat.
1157fe6060f1SDimitry Andric Error(getLoc(), "unknown operand");
1158fe6060f1SDimitry Andric return true;
1159fe6060f1SDimitry Andric }
1160fe6060f1SDimitry Andric
parseCSKYSymbol(OperandVector & Operands)116106c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) {
1162fe6060f1SDimitry Andric SMLoc S = getLoc();
1163fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1164349cc55cSDimitry Andric const MCExpr *Res;
1165fe6060f1SDimitry Andric
1166fe6060f1SDimitry Andric if (getLexer().getKind() != AsmToken::Identifier)
116706c3fb27SDimitry Andric return ParseStatus::NoMatch;
1168fe6060f1SDimitry Andric
1169fe6060f1SDimitry Andric StringRef Identifier;
1170349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok();
1171349cc55cSDimitry Andric
117206c3fb27SDimitry Andric if (getParser().parseIdentifier(Identifier))
117306c3fb27SDimitry Andric return Error(getLoc(), "unknown identifier");
1174fe6060f1SDimitry Andric
1175fe6060f1SDimitry Andric CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None;
1176fe6060f1SDimitry Andric if (Identifier.consume_back("@GOT"))
1177fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOT;
1178fe6060f1SDimitry Andric else if (Identifier.consume_back("@GOTOFF"))
1179fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOTOFF;
1180fe6060f1SDimitry Andric else if (Identifier.consume_back("@PLT"))
1181fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_PLT;
1182fe6060f1SDimitry Andric else if (Identifier.consume_back("@GOTPC"))
1183fe6060f1SDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOTPC;
1184349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSGD32"))
1185349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSGD;
1186349cc55cSDimitry Andric else if (Identifier.consume_back("@GOTTPOFF"))
1187349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSIE;
1188349cc55cSDimitry Andric else if (Identifier.consume_back("@TPOFF"))
1189349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLE;
1190349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSLDM32"))
1191349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLDM;
1192349cc55cSDimitry Andric else if (Identifier.consume_back("@TLSLDO32"))
1193349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_TLSLDO;
1194fe6060f1SDimitry Andric
1195349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1196fe6060f1SDimitry Andric
1197349cc55cSDimitry Andric if (!Sym)
1198349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier);
1199349cc55cSDimitry Andric
1200349cc55cSDimitry Andric if (Sym->isVariable()) {
1201349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1202349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) {
1203349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
120406c3fb27SDimitry Andric return Error(getLoc(), "unknown symbol");
1205349cc55cSDimitry Andric }
1206349cc55cSDimitry Andric Res = V;
1207349cc55cSDimitry Andric } else
1208349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1209349cc55cSDimitry Andric
1210349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode;
1211349cc55cSDimitry Andric switch (getLexer().getKind()) {
1212349cc55cSDimitry Andric default:
1213fe6060f1SDimitry Andric if (Kind != CSKYMCExpr::VK_CSKY_None)
1214fe6060f1SDimitry Andric Res = CSKYMCExpr::create(Res, Kind, getContext());
1215fe6060f1SDimitry Andric
1216fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createImm(Res, S, E));
121706c3fb27SDimitry Andric return ParseStatus::Success;
1218349cc55cSDimitry Andric case AsmToken::Plus:
1219349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add;
1220349cc55cSDimitry Andric break;
1221349cc55cSDimitry Andric case AsmToken::Minus:
1222349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub;
1223349cc55cSDimitry Andric break;
1224349cc55cSDimitry Andric }
1225349cc55cSDimitry Andric
1226349cc55cSDimitry Andric getLexer().Lex(); // eat + or -
1227349cc55cSDimitry Andric
1228349cc55cSDimitry Andric const MCExpr *Expr;
122906c3fb27SDimitry Andric if (getParser().parseExpression(Expr))
123006c3fb27SDimitry Andric return Error(getLoc(), "unknown expression");
1231349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1232349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createImm(Res, S, E));
123306c3fb27SDimitry Andric return ParseStatus::Success;
1234349cc55cSDimitry Andric }
1235349cc55cSDimitry Andric
parseDataSymbol(OperandVector & Operands)123606c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseDataSymbol(OperandVector &Operands) {
1237349cc55cSDimitry Andric SMLoc S = getLoc();
1238349cc55cSDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1239349cc55cSDimitry Andric const MCExpr *Res;
1240349cc55cSDimitry Andric
124106c3fb27SDimitry Andric if (!parseOptionalToken(AsmToken::LBrac))
124206c3fb27SDimitry Andric return ParseStatus::NoMatch;
1243349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) {
1244349cc55cSDimitry Andric const MCExpr *Expr;
124506c3fb27SDimitry Andric if (getParser().parseExpression(Expr))
124606c3fb27SDimitry Andric return Error(getLoc(), "unknown expression");
1247349cc55cSDimitry Andric
124806c3fb27SDimitry Andric if (parseToken(AsmToken::RBrac, "expected ']'"))
124906c3fb27SDimitry Andric return ParseStatus::Failure;
1250349cc55cSDimitry Andric
1251349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));
125206c3fb27SDimitry Andric return ParseStatus::Success;
1253349cc55cSDimitry Andric }
1254349cc55cSDimitry Andric
1255349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok();
1256349cc55cSDimitry Andric StringRef Identifier;
1257349cc55cSDimitry Andric
125806c3fb27SDimitry Andric if (getParser().parseIdentifier(Identifier))
125906c3fb27SDimitry Andric return Error(getLoc(), "unknown identifier " + Identifier);
1260349cc55cSDimitry Andric
1261349cc55cSDimitry Andric CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None;
1262349cc55cSDimitry Andric if (Identifier.consume_back("@GOT"))
1263349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4;
1264349cc55cSDimitry Andric else if (Identifier.consume_back("@PLT"))
1265349cc55cSDimitry Andric Kind = CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4;
1266349cc55cSDimitry Andric
1267349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1268349cc55cSDimitry Andric
1269349cc55cSDimitry Andric if (!Sym)
1270349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier);
1271349cc55cSDimitry Andric
1272349cc55cSDimitry Andric if (Sym->isVariable()) {
1273349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1274349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) {
1275349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
127606c3fb27SDimitry Andric return Error(getLoc(), "unknown symbol");
1277349cc55cSDimitry Andric }
1278349cc55cSDimitry Andric Res = V;
1279349cc55cSDimitry Andric } else {
1280349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1281349cc55cSDimitry Andric }
1282349cc55cSDimitry Andric
1283349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode;
1284349cc55cSDimitry Andric switch (getLexer().getKind()) {
1285349cc55cSDimitry Andric default:
128606c3fb27SDimitry Andric return Error(getLoc(), "unknown symbol");
1287349cc55cSDimitry Andric case AsmToken::RBrac:
1288349cc55cSDimitry Andric
1289349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'.
1290349cc55cSDimitry Andric
1291349cc55cSDimitry Andric if (Kind != CSKYMCExpr::VK_CSKY_None)
1292349cc55cSDimitry Andric Res = CSKYMCExpr::create(Res, Kind, getContext());
1293349cc55cSDimitry Andric
1294349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
129506c3fb27SDimitry Andric return ParseStatus::Success;
1296349cc55cSDimitry Andric case AsmToken::Plus:
1297349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add;
1298349cc55cSDimitry Andric break;
1299349cc55cSDimitry Andric case AsmToken::Minus:
1300349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub;
1301349cc55cSDimitry Andric break;
1302349cc55cSDimitry Andric }
1303349cc55cSDimitry Andric
1304349cc55cSDimitry Andric getLexer().Lex(); // eat + or -
1305349cc55cSDimitry Andric
1306349cc55cSDimitry Andric const MCExpr *Expr;
130706c3fb27SDimitry Andric if (getParser().parseExpression(Expr))
130806c3fb27SDimitry Andric return Error(getLoc(), "unknown expression");
130906c3fb27SDimitry Andric if (parseToken(AsmToken::RBrac, "expected ']'"))
131006c3fb27SDimitry Andric return ParseStatus::Failure;
1311349cc55cSDimitry Andric
1312349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1313349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
131406c3fb27SDimitry Andric return ParseStatus::Success;
1315fe6060f1SDimitry Andric }
1316fe6060f1SDimitry Andric
parseConstpoolSymbol(OperandVector & Operands)131706c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) {
1318fe6060f1SDimitry Andric SMLoc S = getLoc();
1319fe6060f1SDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1320349cc55cSDimitry Andric const MCExpr *Res;
1321fe6060f1SDimitry Andric
132206c3fb27SDimitry Andric if (!parseOptionalToken(AsmToken::LBrac))
132306c3fb27SDimitry Andric return ParseStatus::NoMatch;
1324fe6060f1SDimitry Andric
1325349cc55cSDimitry Andric if (getLexer().getKind() != AsmToken::Identifier) {
1326349cc55cSDimitry Andric const MCExpr *Expr;
132706c3fb27SDimitry Andric if (getParser().parseExpression(Expr))
132806c3fb27SDimitry Andric return Error(getLoc(), "unknown expression");
132906c3fb27SDimitry Andric if (parseToken(AsmToken::RBrac))
133006c3fb27SDimitry Andric return ParseStatus::Failure;
1331fe6060f1SDimitry Andric
1332349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Expr, S, E));
133306c3fb27SDimitry Andric return ParseStatus::Success;
1334349cc55cSDimitry Andric }
1335349cc55cSDimitry Andric
1336349cc55cSDimitry Andric AsmToken Tok = getLexer().getTok();
1337349cc55cSDimitry Andric StringRef Identifier;
1338349cc55cSDimitry Andric
133906c3fb27SDimitry Andric if (getParser().parseIdentifier(Identifier))
134006c3fb27SDimitry Andric return Error(getLoc(), "unknown identifier");
1341349cc55cSDimitry Andric
1342349cc55cSDimitry Andric MCSymbol *Sym = getContext().getInlineAsmLabel(Identifier);
1343349cc55cSDimitry Andric
1344349cc55cSDimitry Andric if (!Sym)
1345349cc55cSDimitry Andric Sym = getContext().getOrCreateSymbol(Identifier);
1346349cc55cSDimitry Andric
1347349cc55cSDimitry Andric if (Sym->isVariable()) {
1348349cc55cSDimitry Andric const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1349349cc55cSDimitry Andric if (!isa<MCSymbolRefExpr>(V)) {
1350349cc55cSDimitry Andric getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
135106c3fb27SDimitry Andric return Error(getLoc(), "unknown symbol");
1352349cc55cSDimitry Andric }
1353349cc55cSDimitry Andric Res = V;
1354349cc55cSDimitry Andric } else {
1355349cc55cSDimitry Andric Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1356349cc55cSDimitry Andric }
1357349cc55cSDimitry Andric
1358349cc55cSDimitry Andric MCBinaryExpr::Opcode Opcode;
1359349cc55cSDimitry Andric switch (getLexer().getKind()) {
1360349cc55cSDimitry Andric default:
136106c3fb27SDimitry Andric return Error(getLoc(), "unknown symbol");
1362349cc55cSDimitry Andric case AsmToken::RBrac:
1363349cc55cSDimitry Andric
1364349cc55cSDimitry Andric getLexer().Lex(); // Eat ']'.
1365349cc55cSDimitry Andric
1366349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
136706c3fb27SDimitry Andric return ParseStatus::Success;
1368349cc55cSDimitry Andric case AsmToken::Plus:
1369349cc55cSDimitry Andric Opcode = MCBinaryExpr::Add;
1370349cc55cSDimitry Andric break;
1371349cc55cSDimitry Andric case AsmToken::Minus:
1372349cc55cSDimitry Andric Opcode = MCBinaryExpr::Sub;
1373349cc55cSDimitry Andric break;
1374349cc55cSDimitry Andric }
1375349cc55cSDimitry Andric
1376349cc55cSDimitry Andric getLexer().Lex(); // eat + or -
1377349cc55cSDimitry Andric
1378349cc55cSDimitry Andric const MCExpr *Expr;
137906c3fb27SDimitry Andric if (getParser().parseExpression(Expr))
138006c3fb27SDimitry Andric return Error(getLoc(), "unknown expression");
138106c3fb27SDimitry Andric if (parseToken(AsmToken::RBrac, "expected ']'"))
138206c3fb27SDimitry Andric return ParseStatus::Failure;
1383349cc55cSDimitry Andric
1384349cc55cSDimitry Andric Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1385349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createConstpoolOp(Res, S, E));
138606c3fb27SDimitry Andric return ParseStatus::Success;
1387349cc55cSDimitry Andric }
1388349cc55cSDimitry Andric
parsePSRFlag(OperandVector & Operands)138906c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parsePSRFlag(OperandVector &Operands) {
1390349cc55cSDimitry Andric SMLoc S = getLoc();
1391349cc55cSDimitry Andric SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1392349cc55cSDimitry Andric
1393349cc55cSDimitry Andric unsigned Flag = 0;
1394349cc55cSDimitry Andric
1395349cc55cSDimitry Andric while (getLexer().isNot(AsmToken::EndOfStatement)) {
1396349cc55cSDimitry Andric StringRef Identifier;
139706c3fb27SDimitry Andric if (getParser().parseIdentifier(Identifier))
139806c3fb27SDimitry Andric return Error(getLoc(), "unknown identifier " + Identifier);
1399349cc55cSDimitry Andric
1400349cc55cSDimitry Andric if (Identifier == "sie")
1401349cc55cSDimitry Andric Flag = (1 << 4) | Flag;
1402349cc55cSDimitry Andric else if (Identifier == "ee")
1403349cc55cSDimitry Andric Flag = (1 << 3) | Flag;
1404349cc55cSDimitry Andric else if (Identifier == "ie")
1405349cc55cSDimitry Andric Flag = (1 << 2) | Flag;
1406349cc55cSDimitry Andric else if (Identifier == "fe")
1407349cc55cSDimitry Andric Flag = (1 << 1) | Flag;
1408349cc55cSDimitry Andric else if (Identifier == "af")
1409349cc55cSDimitry Andric Flag = (1 << 0) | Flag;
141006c3fb27SDimitry Andric else
141106c3fb27SDimitry Andric return Error(getLoc(), "expected " + Identifier);
1412349cc55cSDimitry Andric
1413349cc55cSDimitry Andric if (getLexer().is(AsmToken::EndOfStatement))
1414349cc55cSDimitry Andric break;
1415349cc55cSDimitry Andric
141606c3fb27SDimitry Andric if (parseToken(AsmToken::Comma, "expected ','"))
141706c3fb27SDimitry Andric return ParseStatus::Failure;
1418349cc55cSDimitry Andric }
1419349cc55cSDimitry Andric
1420349cc55cSDimitry Andric Operands.push_back(
1421349cc55cSDimitry Andric CSKYOperand::createImm(MCConstantExpr::create(Flag, getContext()), S, E));
142206c3fb27SDimitry Andric return ParseStatus::Success;
1423349cc55cSDimitry Andric }
1424349cc55cSDimitry Andric
parseRegSeq(OperandVector & Operands)142506c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseRegSeq(OperandVector &Operands) {
1426349cc55cSDimitry Andric SMLoc S = getLoc();
1427349cc55cSDimitry Andric
142806c3fb27SDimitry Andric if (!parseRegister(Operands).isSuccess())
142906c3fb27SDimitry Andric return ParseStatus::NoMatch;
1430349cc55cSDimitry Andric
1431349cc55cSDimitry Andric auto Ry = Operands.back()->getReg();
1432349cc55cSDimitry Andric Operands.pop_back();
1433349cc55cSDimitry Andric
143406c3fb27SDimitry Andric if (parseToken(AsmToken::Minus, "expected '-'"))
143506c3fb27SDimitry Andric return ParseStatus::Failure;
143606c3fb27SDimitry Andric if (!parseRegister(Operands).isSuccess())
143706c3fb27SDimitry Andric return Error(getLoc(), "invalid register");
1438349cc55cSDimitry Andric
1439349cc55cSDimitry Andric auto Rz = Operands.back()->getReg();
1440349cc55cSDimitry Andric Operands.pop_back();
1441349cc55cSDimitry Andric
1442349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createRegSeq(Ry, Rz, S));
144306c3fb27SDimitry Andric return ParseStatus::Success;
1444349cc55cSDimitry Andric }
1445349cc55cSDimitry Andric
parseRegList(OperandVector & Operands)144606c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseRegList(OperandVector &Operands) {
1447349cc55cSDimitry Andric SMLoc S = getLoc();
1448349cc55cSDimitry Andric
1449349cc55cSDimitry Andric SmallVector<unsigned, 4> reglist;
1450349cc55cSDimitry Andric
1451349cc55cSDimitry Andric while (true) {
1452349cc55cSDimitry Andric
145306c3fb27SDimitry Andric if (!parseRegister(Operands).isSuccess())
145406c3fb27SDimitry Andric return Error(getLoc(), "invalid register");
1455349cc55cSDimitry Andric
1456349cc55cSDimitry Andric auto Ry = Operands.back()->getReg();
1457349cc55cSDimitry Andric Operands.pop_back();
1458349cc55cSDimitry Andric
145906c3fb27SDimitry Andric if (parseOptionalToken(AsmToken::Minus)) {
146006c3fb27SDimitry Andric if (!parseRegister(Operands).isSuccess())
146106c3fb27SDimitry Andric return Error(getLoc(), "invalid register");
1462349cc55cSDimitry Andric
1463349cc55cSDimitry Andric auto Rz = Operands.back()->getReg();
1464349cc55cSDimitry Andric Operands.pop_back();
1465349cc55cSDimitry Andric
1466349cc55cSDimitry Andric reglist.push_back(Ry);
1467349cc55cSDimitry Andric reglist.push_back(Rz);
1468349cc55cSDimitry Andric
146906c3fb27SDimitry Andric if (getLexer().is(AsmToken::EndOfStatement))
1470349cc55cSDimitry Andric break;
147106c3fb27SDimitry Andric (void)parseOptionalToken(AsmToken::Comma);
147206c3fb27SDimitry Andric } else if (parseOptionalToken(AsmToken::Comma)) {
1473349cc55cSDimitry Andric reglist.push_back(Ry);
1474349cc55cSDimitry Andric reglist.push_back(Ry);
1475349cc55cSDimitry Andric } else if (getLexer().is(AsmToken::EndOfStatement)) {
1476349cc55cSDimitry Andric reglist.push_back(Ry);
1477349cc55cSDimitry Andric reglist.push_back(Ry);
1478349cc55cSDimitry Andric break;
1479349cc55cSDimitry Andric } else {
148006c3fb27SDimitry Andric return Error(getLoc(), "invalid register list");
1481349cc55cSDimitry Andric }
1482349cc55cSDimitry Andric }
1483349cc55cSDimitry Andric
1484349cc55cSDimitry Andric Operands.push_back(CSKYOperand::createRegList(reglist, S));
148506c3fb27SDimitry Andric return ParseStatus::Success;
1486fe6060f1SDimitry Andric }
1487fe6060f1SDimitry Andric
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)1488fe6060f1SDimitry Andric bool CSKYAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
1489fe6060f1SDimitry Andric SMLoc NameLoc, OperandVector &Operands) {
1490fe6060f1SDimitry Andric // First operand is token for instruction.
1491fe6060f1SDimitry Andric Operands.push_back(CSKYOperand::createToken(Name, NameLoc));
1492fe6060f1SDimitry Andric
1493fe6060f1SDimitry Andric // If there are no more operands, then finish.
1494fe6060f1SDimitry Andric if (getLexer().is(AsmToken::EndOfStatement))
1495fe6060f1SDimitry Andric return false;
1496fe6060f1SDimitry Andric
1497fe6060f1SDimitry Andric // Parse first operand.
1498fe6060f1SDimitry Andric if (parseOperand(Operands, Name))
1499fe6060f1SDimitry Andric return true;
1500fe6060f1SDimitry Andric
1501fe6060f1SDimitry Andric // Parse until end of statement, consuming commas between operands.
150206c3fb27SDimitry Andric while (parseOptionalToken(AsmToken::Comma))
1503fe6060f1SDimitry Andric if (parseOperand(Operands, Name))
1504fe6060f1SDimitry Andric return true;
1505fe6060f1SDimitry Andric
1506fe6060f1SDimitry Andric if (getLexer().isNot(AsmToken::EndOfStatement)) {
1507fe6060f1SDimitry Andric SMLoc Loc = getLexer().getLoc();
1508fe6060f1SDimitry Andric getParser().eatToEndOfStatement();
1509fe6060f1SDimitry Andric return Error(Loc, "unexpected token");
1510fe6060f1SDimitry Andric }
1511fe6060f1SDimitry Andric
1512fe6060f1SDimitry Andric getParser().Lex(); // Consume the EndOfStatement.
1513fe6060f1SDimitry Andric return false;
1514fe6060f1SDimitry Andric }
1515fe6060f1SDimitry Andric
tryParseRegister(MCRegister & Reg,SMLoc & StartLoc,SMLoc & EndLoc)15165f757f3fSDimitry Andric ParseStatus CSKYAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
1517fe6060f1SDimitry Andric SMLoc &EndLoc) {
1518fe6060f1SDimitry Andric const AsmToken &Tok = getParser().getTok();
1519fe6060f1SDimitry Andric StartLoc = Tok.getLoc();
1520fe6060f1SDimitry Andric EndLoc = Tok.getEndLoc();
1521fe6060f1SDimitry Andric
1522fe6060f1SDimitry Andric StringRef Name = getLexer().getTok().getIdentifier();
1523fe6060f1SDimitry Andric
15245f757f3fSDimitry Andric if (matchRegisterNameHelper(getSTI(), Reg, Name))
15255f757f3fSDimitry Andric return ParseStatus::NoMatch;
1526fe6060f1SDimitry Andric
1527fe6060f1SDimitry Andric getParser().Lex(); // Eat identifier token.
15285f757f3fSDimitry Andric return ParseStatus::Success;
1529fe6060f1SDimitry Andric }
1530fe6060f1SDimitry Andric
parseDirective(AsmToken DirectiveID)153106c3fb27SDimitry Andric ParseStatus CSKYAsmParser::parseDirective(AsmToken DirectiveID) {
153281ad6265SDimitry Andric StringRef IDVal = DirectiveID.getString();
153381ad6265SDimitry Andric
153481ad6265SDimitry Andric if (IDVal == ".csky_attribute")
153581ad6265SDimitry Andric return parseDirectiveAttribute();
153681ad6265SDimitry Andric
153706c3fb27SDimitry Andric return ParseStatus::NoMatch;
153881ad6265SDimitry Andric }
153981ad6265SDimitry Andric
154081ad6265SDimitry Andric /// parseDirectiveAttribute
154181ad6265SDimitry Andric /// ::= .attribute expression ',' ( expression | "string" )
parseDirectiveAttribute()154281ad6265SDimitry Andric bool CSKYAsmParser::parseDirectiveAttribute() {
154381ad6265SDimitry Andric MCAsmParser &Parser = getParser();
154481ad6265SDimitry Andric int64_t Tag;
154581ad6265SDimitry Andric SMLoc TagLoc;
154681ad6265SDimitry Andric TagLoc = Parser.getTok().getLoc();
154781ad6265SDimitry Andric if (Parser.getTok().is(AsmToken::Identifier)) {
154881ad6265SDimitry Andric StringRef Name = Parser.getTok().getIdentifier();
1549bdd1243dSDimitry Andric std::optional<unsigned> Ret =
155081ad6265SDimitry Andric ELFAttrs::attrTypeFromString(Name, CSKYAttrs::getCSKYAttributeTags());
155106c3fb27SDimitry Andric if (!Ret)
155206c3fb27SDimitry Andric return Error(TagLoc, "attribute name not recognised: " + Name);
1553bdd1243dSDimitry Andric Tag = *Ret;
155481ad6265SDimitry Andric Parser.Lex();
155581ad6265SDimitry Andric } else {
155681ad6265SDimitry Andric const MCExpr *AttrExpr;
155781ad6265SDimitry Andric
155881ad6265SDimitry Andric TagLoc = Parser.getTok().getLoc();
155981ad6265SDimitry Andric if (Parser.parseExpression(AttrExpr))
156081ad6265SDimitry Andric return true;
156181ad6265SDimitry Andric
156281ad6265SDimitry Andric const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
156306c3fb27SDimitry Andric if (!CE)
156406c3fb27SDimitry Andric return Error(TagLoc, "expected numeric constant");
156581ad6265SDimitry Andric
156681ad6265SDimitry Andric Tag = CE->getValue();
156781ad6265SDimitry Andric }
156881ad6265SDimitry Andric
156906c3fb27SDimitry Andric if (Parser.parseComma())
157081ad6265SDimitry Andric return true;
157181ad6265SDimitry Andric
157281ad6265SDimitry Andric StringRef StringValue;
157381ad6265SDimitry Andric int64_t IntegerValue = 0;
157481ad6265SDimitry Andric bool IsIntegerValue = ((Tag != CSKYAttrs::CSKY_ARCH_NAME) &&
157581ad6265SDimitry Andric (Tag != CSKYAttrs::CSKY_CPU_NAME) &&
157681ad6265SDimitry Andric (Tag != CSKYAttrs::CSKY_FPU_NUMBER_MODULE));
157781ad6265SDimitry Andric
157881ad6265SDimitry Andric SMLoc ValueExprLoc = Parser.getTok().getLoc();
157981ad6265SDimitry Andric if (IsIntegerValue) {
158081ad6265SDimitry Andric const MCExpr *ValueExpr;
158181ad6265SDimitry Andric if (Parser.parseExpression(ValueExpr))
158281ad6265SDimitry Andric return true;
158381ad6265SDimitry Andric
158481ad6265SDimitry Andric const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
158581ad6265SDimitry Andric if (!CE)
158681ad6265SDimitry Andric return Error(ValueExprLoc, "expected numeric constant");
158781ad6265SDimitry Andric IntegerValue = CE->getValue();
158881ad6265SDimitry Andric } else {
158981ad6265SDimitry Andric if (Parser.getTok().isNot(AsmToken::String))
159081ad6265SDimitry Andric return Error(Parser.getTok().getLoc(), "expected string constant");
159181ad6265SDimitry Andric
159281ad6265SDimitry Andric StringValue = Parser.getTok().getStringContents();
159381ad6265SDimitry Andric Parser.Lex();
159481ad6265SDimitry Andric }
159581ad6265SDimitry Andric
159681ad6265SDimitry Andric if (Parser.parseEOL())
159781ad6265SDimitry Andric return true;
159881ad6265SDimitry Andric
159981ad6265SDimitry Andric if (IsIntegerValue)
160081ad6265SDimitry Andric getTargetStreamer().emitAttribute(Tag, IntegerValue);
160181ad6265SDimitry Andric else if (Tag != CSKYAttrs::CSKY_ARCH_NAME && Tag != CSKYAttrs::CSKY_CPU_NAME)
160281ad6265SDimitry Andric getTargetStreamer().emitTextAttribute(Tag, StringValue);
160381ad6265SDimitry Andric else {
160481ad6265SDimitry Andric CSKY::ArchKind ID = (Tag == CSKYAttrs::CSKY_ARCH_NAME)
160581ad6265SDimitry Andric ? CSKY::parseArch(StringValue)
160681ad6265SDimitry Andric : CSKY::parseCPUArch(StringValue);
160781ad6265SDimitry Andric if (ID == CSKY::ArchKind::INVALID)
160881ad6265SDimitry Andric return Error(ValueExprLoc, (Tag == CSKYAttrs::CSKY_ARCH_NAME)
160981ad6265SDimitry Andric ? "unknown arch name"
161081ad6265SDimitry Andric : "unknown cpu name");
161181ad6265SDimitry Andric
161281ad6265SDimitry Andric getTargetStreamer().emitTextAttribute(Tag, StringValue);
161381ad6265SDimitry Andric }
161481ad6265SDimitry Andric
161581ad6265SDimitry Andric return false;
161681ad6265SDimitry Andric }
161781ad6265SDimitry Andric
validateTargetOperandClass(MCParsedAsmOperand & AsmOp,unsigned Kind)161881ad6265SDimitry Andric unsigned CSKYAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
161981ad6265SDimitry Andric unsigned Kind) {
162081ad6265SDimitry Andric CSKYOperand &Op = static_cast<CSKYOperand &>(AsmOp);
162181ad6265SDimitry Andric
162281ad6265SDimitry Andric if (!Op.isReg())
162381ad6265SDimitry Andric return Match_InvalidOperand;
162481ad6265SDimitry Andric
162581ad6265SDimitry Andric MCRegister Reg = Op.getReg();
162681ad6265SDimitry Andric
162781ad6265SDimitry Andric if (CSKYMCRegisterClasses[CSKY::FPR32RegClassID].contains(Reg)) {
162881ad6265SDimitry Andric // As the parser couldn't differentiate an FPR64 from an FPR32, coerce the
162981ad6265SDimitry Andric // register from FPR32 to FPR64 if necessary.
163081ad6265SDimitry Andric if (Kind == MCK_FPR64 || Kind == MCK_sFPR64) {
163181ad6265SDimitry Andric Op.Reg.RegNum = convertFPR32ToFPR64(Reg);
163281ad6265SDimitry Andric if (Kind == MCK_sFPR64 &&
163381ad6265SDimitry Andric (Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F15_64))
163481ad6265SDimitry Andric return Match_InvalidRegOutOfRange;
163581ad6265SDimitry Andric if (Kind == MCK_FPR64 &&
163681ad6265SDimitry Andric (Op.Reg.RegNum < CSKY::F0_64 || Op.Reg.RegNum > CSKY::F31_64))
163781ad6265SDimitry Andric return Match_InvalidRegOutOfRange;
163881ad6265SDimitry Andric return Match_Success;
163981ad6265SDimitry Andric }
164081ad6265SDimitry Andric }
164181ad6265SDimitry Andric
164281ad6265SDimitry Andric if (CSKYMCRegisterClasses[CSKY::GPRRegClassID].contains(Reg)) {
164381ad6265SDimitry Andric if (Kind == MCK_GPRPair) {
164481ad6265SDimitry Andric Op.Reg.RegNum = MRI->getEncodingValue(Reg) + CSKY::R0_R1;
164581ad6265SDimitry Andric return Match_Success;
164681ad6265SDimitry Andric }
164781ad6265SDimitry Andric }
164881ad6265SDimitry Andric
164981ad6265SDimitry Andric return Match_InvalidOperand;
165081ad6265SDimitry Andric }
1651fe6060f1SDimitry Andric
emitToStreamer(MCStreamer & S,const MCInst & Inst)16520eae32dcSDimitry Andric void CSKYAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
16530eae32dcSDimitry Andric MCInst CInst;
16540eae32dcSDimitry Andric bool Res = false;
16550eae32dcSDimitry Andric if (EnableCompressedInst)
1656bdd1243dSDimitry Andric Res = compressInst(CInst, Inst, getSTI());
16570eae32dcSDimitry Andric if (Res)
16580eae32dcSDimitry Andric ++CSKYNumInstrsCompressed;
16590eae32dcSDimitry Andric S.emitInstruction((Res ? CInst : Inst), getSTI());
16600eae32dcSDimitry Andric }
16610eae32dcSDimitry Andric
LLVMInitializeCSKYAsmParser()1662fe6060f1SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser() {
1663fe6060f1SDimitry Andric RegisterMCAsmParser<CSKYAsmParser> X(getTheCSKYTarget());
1664fe6060f1SDimitry Andric }
1665