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