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