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