1 //===-- CSKYAsmParser.cpp - Parse CSKY assembly to MCInst instructions --===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "MCTargetDesc/CSKYMCExpr.h"
11 #include "MCTargetDesc/CSKYMCTargetDesc.h"
12 #include "TargetInfo/CSKYTargetInfo.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/StringSwitch.h"
15 #include "llvm/CodeGen/Register.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCParser/MCAsmLexer.h"
20 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
21 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
22 #include "llvm/MC/MCRegisterInfo.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/Support/Casting.h"
26 #include "llvm/Support/TargetRegistry.h"
27
28 using namespace llvm;
29
30 namespace {
31 struct CSKYOperand;
32
33 class CSKYAsmParser : public MCTargetAsmParser {
34
35 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
36 int64_t Lower, int64_t Upper, Twine Msg);
37
getLoc() const38 SMLoc getLoc() const { return getParser().getTok().getLoc(); }
39
40 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
41 OperandVector &Operands, MCStreamer &Out,
42 uint64_t &ErrorInfo,
43 bool MatchingInlineAsm) override;
44
45 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
46
47 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
48 SMLoc NameLoc, OperandVector &Operands) override;
49
50 bool ParseDirective(AsmToken DirectiveID) override;
51
52 OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
53 SMLoc &EndLoc) override;
54
55 // Auto-generated instruction matching functions
56 #define GET_ASSEMBLER_HEADER
57 #include "CSKYGenAsmMatcher.inc"
58
59 OperandMatchResultTy parseImmediate(OperandVector &Operands);
60 OperandMatchResultTy parseRegister(OperandVector &Operands);
61 OperandMatchResultTy parseBaseRegImm(OperandVector &Operands);
62 OperandMatchResultTy parseCSKYSymbol(OperandVector &Operands);
63 OperandMatchResultTy parseConstpoolSymbol(OperandVector &Operands);
64
65 bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
66
67 public:
68 enum CSKYMatchResultTy {
69 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
70 #define GET_OPERAND_DIAGNOSTIC_TYPES
71 #include "CSKYGenAsmMatcher.inc"
72 #undef GET_OPERAND_DIAGNOSTIC_TYPES
73 };
74
CSKYAsmParser(const MCSubtargetInfo & STI,MCAsmParser & Parser,const MCInstrInfo & MII,const MCTargetOptions & Options)75 CSKYAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
76 const MCInstrInfo &MII, const MCTargetOptions &Options)
77 : MCTargetAsmParser(Options, STI, MII) {
78 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
79 }
80 };
81
82 /// Instances of this class represent a parsed machine instruction.
83 struct CSKYOperand : public MCParsedAsmOperand {
84 enum KindTy {
85 Token,
86 Register,
87 Immediate,
88 } Kind;
89
90 struct RegOp {
91 unsigned RegNum;
92 };
93
94 struct ImmOp {
95 const MCExpr *Val;
96 };
97
98 SMLoc StartLoc, EndLoc;
99 union {
100 StringRef Tok;
101 RegOp Reg;
102 ImmOp Imm;
103 };
104
CSKYOperand__anon9994b65a0111::CSKYOperand105 CSKYOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
106
107 public:
CSKYOperand__anon9994b65a0111::CSKYOperand108 CSKYOperand(const CSKYOperand &o) : MCParsedAsmOperand() {
109 Kind = o.Kind;
110 StartLoc = o.StartLoc;
111 EndLoc = o.EndLoc;
112 switch (Kind) {
113 case Register:
114 Reg = o.Reg;
115 break;
116 case Immediate:
117 Imm = o.Imm;
118 break;
119 case Token:
120 Tok = o.Tok;
121 break;
122 }
123 }
124
isToken__anon9994b65a0111::CSKYOperand125 bool isToken() const override { return Kind == Token; }
isReg__anon9994b65a0111::CSKYOperand126 bool isReg() const override { return Kind == Register; }
isImm__anon9994b65a0111::CSKYOperand127 bool isImm() const override { return Kind == Immediate; }
isMem__anon9994b65a0111::CSKYOperand128 bool isMem() const override { return false; }
129
evaluateConstantImm__anon9994b65a0111::CSKYOperand130 static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm) {
131 if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
132 Imm = CE->getValue();
133 return true;
134 }
135
136 return false;
137 }
138
isUImm__anon9994b65a0111::CSKYOperand139 template <unsigned num, unsigned shift = 0> bool isUImm() const {
140 if (!isImm())
141 return false;
142
143 int64_t Imm;
144 bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
145 return IsConstantImm && isShiftedUInt<num, shift>(Imm);
146 }
147
isOImm__anon9994b65a0111::CSKYOperand148 template <unsigned num> bool isOImm() const {
149 if (!isImm())
150 return false;
151
152 int64_t Imm;
153 bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
154 return IsConstantImm && isUInt<num>(Imm - 1);
155 }
156
isSImm__anon9994b65a0111::CSKYOperand157 template <unsigned num, unsigned shift = 0> bool isSImm() const {
158 if (!isImm())
159 return false;
160
161 int64_t Imm;
162 bool IsConstantImm = evaluateConstantImm(getImm(), Imm);
163 return IsConstantImm && isShiftedInt<num, shift>(Imm);
164 }
165
isUImm2__anon9994b65a0111::CSKYOperand166 bool isUImm2() const { return isUImm<2>(); }
isUImm5__anon9994b65a0111::CSKYOperand167 bool isUImm5() const { return isUImm<5>(); }
isUImm12__anon9994b65a0111::CSKYOperand168 bool isUImm12() const { return isUImm<12>(); }
isUImm16__anon9994b65a0111::CSKYOperand169 bool isUImm16() const { return isUImm<16>(); }
170
isOImm12__anon9994b65a0111::CSKYOperand171 bool isOImm12() const { return isOImm<12>(); }
isOImm16__anon9994b65a0111::CSKYOperand172 bool isOImm16() const { return isOImm<16>(); }
173
isUImm12Shift1__anon9994b65a0111::CSKYOperand174 bool isUImm12Shift1() { return isUImm<12, 1>(); }
isUImm12Shift2__anon9994b65a0111::CSKYOperand175 bool isUImm12Shift2() { return isUImm<12, 2>(); }
176
isSImm16Shift1__anon9994b65a0111::CSKYOperand177 bool isSImm16Shift1() { return isSImm<16, 1>(); }
178
isCSKYSymbol__anon9994b65a0111::CSKYOperand179 bool isCSKYSymbol() const {
180 int64_t Imm;
181 // Must be of 'immediate' type but not a constant.
182 return isImm() && !evaluateConstantImm(getImm(), Imm);
183 }
184
isConstpoolSymbol__anon9994b65a0111::CSKYOperand185 bool isConstpoolSymbol() const {
186 int64_t Imm;
187 // Must be of 'immediate' type but not a constant.
188 return isImm() && !evaluateConstantImm(getImm(), Imm);
189 }
190
191 /// Gets location of the first token of this operand.
getStartLoc__anon9994b65a0111::CSKYOperand192 SMLoc getStartLoc() const override { return StartLoc; }
193 /// Gets location of the last token of this operand.
getEndLoc__anon9994b65a0111::CSKYOperand194 SMLoc getEndLoc() const override { return EndLoc; }
195
getReg__anon9994b65a0111::CSKYOperand196 unsigned getReg() const override {
197 assert(Kind == Register && "Invalid type access!");
198 return Reg.RegNum;
199 }
200
getImm__anon9994b65a0111::CSKYOperand201 const MCExpr *getImm() const {
202 assert(Kind == Immediate && "Invalid type access!");
203 return Imm.Val;
204 }
205
getToken__anon9994b65a0111::CSKYOperand206 StringRef getToken() const {
207 assert(Kind == Token && "Invalid type access!");
208 return Tok;
209 }
210
print__anon9994b65a0111::CSKYOperand211 void print(raw_ostream &OS) const override {
212 switch (Kind) {
213 case Immediate:
214 OS << *getImm();
215 break;
216 case Register:
217 OS << "<register x" << getReg() << ">";
218 break;
219 case Token:
220 OS << "'" << getToken() << "'";
221 break;
222 }
223 }
224
createToken__anon9994b65a0111::CSKYOperand225 static std::unique_ptr<CSKYOperand> createToken(StringRef Str, SMLoc S) {
226 auto Op = std::make_unique<CSKYOperand>(Token);
227 Op->Tok = Str;
228 Op->StartLoc = S;
229 Op->EndLoc = S;
230 return Op;
231 }
232
createReg__anon9994b65a0111::CSKYOperand233 static std::unique_ptr<CSKYOperand> createReg(unsigned RegNo, SMLoc S,
234 SMLoc E) {
235 auto Op = std::make_unique<CSKYOperand>(Register);
236 Op->Reg.RegNum = RegNo;
237 Op->StartLoc = S;
238 Op->EndLoc = E;
239 return Op;
240 }
241
createImm__anon9994b65a0111::CSKYOperand242 static std::unique_ptr<CSKYOperand> createImm(const MCExpr *Val, SMLoc S,
243 SMLoc E) {
244 auto Op = std::make_unique<CSKYOperand>(Immediate);
245 Op->Imm.Val = Val;
246 Op->StartLoc = S;
247 Op->EndLoc = E;
248 return Op;
249 }
250
addExpr__anon9994b65a0111::CSKYOperand251 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
252 assert(Expr && "Expr shouldn't be null!");
253 if (auto *CE = dyn_cast<MCConstantExpr>(Expr))
254 Inst.addOperand(MCOperand::createImm(CE->getValue()));
255 else
256 Inst.addOperand(MCOperand::createExpr(Expr));
257 }
258
259 // Used by the TableGen Code.
addRegOperands__anon9994b65a0111::CSKYOperand260 void addRegOperands(MCInst &Inst, unsigned N) const {
261 assert(N == 1 && "Invalid number of operands!");
262 Inst.addOperand(MCOperand::createReg(getReg()));
263 }
264
addImmOperands__anon9994b65a0111::CSKYOperand265 void addImmOperands(MCInst &Inst, unsigned N) const {
266 assert(N == 1 && "Invalid number of operands!");
267 addExpr(Inst, getImm());
268 }
269 };
270 } // end anonymous namespace.
271
272 #define GET_REGISTER_MATCHER
273 #define GET_SUBTARGET_FEATURE_NAME
274 #define GET_MATCHER_IMPLEMENTATION
275 #define GET_MNEMONIC_SPELL_CHECKER
276 #include "CSKYGenAsmMatcher.inc"
277
278 static std::string CSKYMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
279 unsigned VariantID = 0);
280
generateImmOutOfRangeError(OperandVector & Operands,uint64_t ErrorInfo,int64_t Lower,int64_t Upper,Twine Msg="immediate must be an integer in the range")281 bool CSKYAsmParser::generateImmOutOfRangeError(
282 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
283 Twine Msg = "immediate must be an integer in the range") {
284 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
285 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
286 }
287
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)288 bool CSKYAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
289 OperandVector &Operands,
290 MCStreamer &Out,
291 uint64_t &ErrorInfo,
292 bool MatchingInlineAsm) {
293 MCInst Inst;
294 FeatureBitset MissingFeatures;
295
296 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
297 MatchingInlineAsm);
298 switch (Result) {
299 default:
300 break;
301 case Match_Success:
302 Inst.setLoc(IDLoc);
303 Out.emitInstruction(Inst, getSTI());
304 return false;
305 case Match_MissingFeature: {
306 assert(MissingFeatures.any() && "Unknown missing features!");
307 ListSeparator LS;
308 std::string Msg = "instruction requires the following: ";
309 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
310 if (MissingFeatures[i]) {
311 Msg += LS;
312 Msg += getSubtargetFeatureName(i);
313 }
314 }
315 return Error(IDLoc, Msg);
316 }
317 case Match_MnemonicFail: {
318 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
319 std::string Suggestion =
320 CSKYMnemonicSpellCheck(((CSKYOperand &)*Operands[0]).getToken(), FBS);
321 return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);
322 }
323 case Match_InvalidTiedOperand:
324 case Match_InvalidOperand: {
325 SMLoc ErrorLoc = IDLoc;
326 if (ErrorInfo != ~0U) {
327 if (ErrorInfo >= Operands.size())
328 return Error(ErrorLoc, "too few operands for instruction");
329
330 ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
331 if (ErrorLoc == SMLoc())
332 ErrorLoc = IDLoc;
333 }
334 return Error(ErrorLoc, "invalid operand for instruction");
335 }
336 }
337
338 // Handle the case when the error message is of specific type
339 // other than the generic Match_InvalidOperand, and the
340 // corresponding operand is missing.
341 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
342 SMLoc ErrorLoc = IDLoc;
343 if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
344 return Error(ErrorLoc, "too few operands for instruction");
345 }
346
347 switch (Result) {
348 default:
349 break;
350 case Match_InvalidOImm12:
351 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 12));
352 case Match_InvalidOImm16:
353 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16));
354 case Match_InvalidUImm2:
355 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
356 case Match_InvalidUImm5:
357 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
358 case Match_InvalidUImm12:
359 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);
360 case Match_InvalidUImm12Shift1:
361 return generateImmOutOfRangeError(
362 Operands, ErrorInfo, 0, (1 << 12) - 2,
363 "immediate must be a multiple of 2 bytes in the range");
364 case Match_InvalidUImm12Shift2:
365 return generateImmOutOfRangeError(
366 Operands, ErrorInfo, 0, (1 << 12) - 4,
367 "immediate must be a multiple of 4 bytes in the range");
368 case Match_InvalidUImm16:
369 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 16) - 1);
370 case Match_InvalidCSKYSymbol: {
371 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
372 return Error(ErrorLoc, "operand must be a symbol name");
373 }
374 case Match_InvalidConstpool: {
375 SMLoc ErrorLoc = ((CSKYOperand &)*Operands[ErrorInfo]).getStartLoc();
376 return Error(ErrorLoc, "operand must be a constpool symbol name");
377 }
378 }
379
380 llvm_unreachable("Unknown match type detected!");
381 }
382
383 // Attempts to match Name as a register (either using the default name or
384 // alternative ABI names), setting RegNo to the matching register. Upon
385 // failure, returns true and sets RegNo to 0.
matchRegisterNameHelper(MCRegister & RegNo,StringRef Name)386 static bool matchRegisterNameHelper(MCRegister &RegNo, StringRef Name) {
387 RegNo = MatchRegisterName(Name);
388
389 if (RegNo == CSKY::NoRegister)
390 RegNo = MatchRegisterAltName(Name);
391
392 return RegNo == CSKY::NoRegister;
393 }
394
ParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)395 bool CSKYAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
396 SMLoc &EndLoc) {
397 const AsmToken &Tok = getParser().getTok();
398 StartLoc = Tok.getLoc();
399 EndLoc = Tok.getEndLoc();
400 StringRef Name = getLexer().getTok().getIdentifier();
401
402 if (!matchRegisterNameHelper((MCRegister &)RegNo, Name)) {
403 getParser().Lex(); // Eat identifier token.
404 return false;
405 }
406
407 return Error(StartLoc, "invalid register name");
408 }
409
parseRegister(OperandVector & Operands)410 OperandMatchResultTy CSKYAsmParser::parseRegister(OperandVector &Operands) {
411 SMLoc S = getLoc();
412 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
413
414 switch (getLexer().getKind()) {
415 default:
416 return MatchOperand_NoMatch;
417 case AsmToken::Identifier: {
418 StringRef Name = getLexer().getTok().getIdentifier();
419 MCRegister RegNo;
420
421 if (matchRegisterNameHelper((MCRegister &)RegNo, Name))
422 return MatchOperand_NoMatch;
423
424 getLexer().Lex();
425 Operands.push_back(CSKYOperand::createReg(RegNo, S, E));
426
427 return MatchOperand_Success;
428 }
429 }
430 }
431
parseBaseRegImm(OperandVector & Operands)432 OperandMatchResultTy CSKYAsmParser::parseBaseRegImm(OperandVector &Operands) {
433 assert(getLexer().is(AsmToken::LParen));
434
435 Operands.push_back(CSKYOperand::createToken("(", getLoc()));
436
437 auto Tok = getParser().Lex(); // Eat '('
438
439 if (parseRegister(Operands) != MatchOperand_Success) {
440 getLexer().UnLex(Tok);
441 Operands.pop_back();
442 return MatchOperand_ParseFail;
443 }
444
445 if (getLexer().isNot(AsmToken::Comma)) {
446 Error(getLoc(), "expected ','");
447 return MatchOperand_ParseFail;
448 }
449
450 getParser().Lex(); // Eat ','
451
452 if (parseRegister(Operands) == MatchOperand_Success) {
453 if (getLexer().isNot(AsmToken::LessLess)) {
454 Error(getLoc(), "expected '<<'");
455 return MatchOperand_ParseFail;
456 }
457
458 Operands.push_back(CSKYOperand::createToken("<<", getLoc()));
459
460 getParser().Lex(); // Eat '<<'
461
462 if (parseImmediate(Operands) != MatchOperand_Success) {
463 Error(getLoc(), "expected imm");
464 return MatchOperand_ParseFail;
465 }
466
467 } else if (parseImmediate(Operands) != MatchOperand_Success) {
468 Error(getLoc(), "expected imm");
469 return MatchOperand_ParseFail;
470 }
471
472 if (getLexer().isNot(AsmToken::RParen)) {
473 Error(getLoc(), "expected ')'");
474 return MatchOperand_ParseFail;
475 }
476
477 Operands.push_back(CSKYOperand::createToken(")", getLoc()));
478
479 getParser().Lex(); // Eat ')'
480
481 return MatchOperand_Success;
482 }
483
parseImmediate(OperandVector & Operands)484 OperandMatchResultTy CSKYAsmParser::parseImmediate(OperandVector &Operands) {
485 switch (getLexer().getKind()) {
486 default:
487 return MatchOperand_NoMatch;
488 case AsmToken::LParen:
489 case AsmToken::Minus:
490 case AsmToken::Plus:
491 case AsmToken::Integer:
492 case AsmToken::String:
493 break;
494 }
495
496 const MCExpr *IdVal;
497 SMLoc S = getLoc();
498 if (getParser().parseExpression(IdVal))
499 return MatchOperand_ParseFail;
500
501 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
502 Operands.push_back(CSKYOperand::createImm(IdVal, S, E));
503 return MatchOperand_Success;
504 }
505
506 /// Looks at a token type and creates the relevant operand from this
507 /// information, adding to Operands. If operand was parsed, returns false, else
508 /// true.
parseOperand(OperandVector & Operands,StringRef Mnemonic)509 bool CSKYAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
510 // Check if the current operand has a custom associated parser, if so, try to
511 // custom parse the operand, or fallback to the general approach.
512 OperandMatchResultTy Result =
513 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
514 if (Result == MatchOperand_Success)
515 return false;
516 if (Result == MatchOperand_ParseFail)
517 return true;
518
519 // Attempt to parse token as register
520 if (parseRegister(Operands) == MatchOperand_Success)
521 return false;
522
523 // Attempt to parse token as (register, imm)
524 if (getLexer().is(AsmToken::LParen))
525 if (parseBaseRegImm(Operands) == MatchOperand_Success)
526 return false;
527
528 // Attempt to parse token as a imm.
529 if (parseImmediate(Operands) == MatchOperand_Success)
530 return false;
531
532 // Finally we have exhausted all options and must declare defeat.
533 Error(getLoc(), "unknown operand");
534 return true;
535 }
536
parseCSKYSymbol(OperandVector & Operands)537 OperandMatchResultTy CSKYAsmParser::parseCSKYSymbol(OperandVector &Operands) {
538 SMLoc S = getLoc();
539 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
540
541 if (getLexer().getKind() != AsmToken::Identifier)
542 return MatchOperand_NoMatch;
543
544 StringRef Identifier;
545 if (getParser().parseIdentifier(Identifier))
546 return MatchOperand_ParseFail;
547
548 CSKYMCExpr::VariantKind Kind = CSKYMCExpr::VK_CSKY_None;
549
550 if (Identifier.consume_back("@GOT"))
551 Kind = CSKYMCExpr::VK_CSKY_GOT;
552 else if (Identifier.consume_back("@GOTOFF"))
553 Kind = CSKYMCExpr::VK_CSKY_GOTOFF;
554 else if (Identifier.consume_back("@PLT"))
555 Kind = CSKYMCExpr::VK_CSKY_PLT;
556 else if (Identifier.consume_back("@GOTPC"))
557 Kind = CSKYMCExpr::VK_CSKY_GOTPC;
558
559 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
560 const MCExpr *Res =
561 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
562
563 if (Kind != CSKYMCExpr::VK_CSKY_None)
564 Res = CSKYMCExpr::create(Res, Kind, getContext());
565
566 Operands.push_back(CSKYOperand::createImm(Res, S, E));
567 return MatchOperand_Success;
568 }
569
570 OperandMatchResultTy
parseConstpoolSymbol(OperandVector & Operands)571 CSKYAsmParser::parseConstpoolSymbol(OperandVector &Operands) {
572 SMLoc S = getLoc();
573 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
574
575 if (getLexer().getKind() != AsmToken::LBrac)
576 return MatchOperand_NoMatch;
577
578 getLexer().Lex(); // Eat '['.
579
580 if (getLexer().getKind() != AsmToken::Identifier)
581 return MatchOperand_NoMatch;
582
583 StringRef Identifier;
584 if (getParser().parseIdentifier(Identifier))
585 return MatchOperand_ParseFail;
586
587 if (getLexer().getKind() != AsmToken::RBrac)
588 return MatchOperand_NoMatch;
589
590 getLexer().Lex(); // Eat ']'.
591
592 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
593 const MCExpr *Res =
594 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
595 Operands.push_back(CSKYOperand::createImm(Res, S, E));
596 return MatchOperand_Success;
597 }
598
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)599 bool CSKYAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
600 SMLoc NameLoc, OperandVector &Operands) {
601 // First operand is token for instruction.
602 Operands.push_back(CSKYOperand::createToken(Name, NameLoc));
603
604 // If there are no more operands, then finish.
605 if (getLexer().is(AsmToken::EndOfStatement))
606 return false;
607
608 // Parse first operand.
609 if (parseOperand(Operands, Name))
610 return true;
611
612 // Parse until end of statement, consuming commas between operands.
613 while (getLexer().is(AsmToken::Comma)) {
614 // Consume comma token.
615 getLexer().Lex();
616
617 // Parse next operand.
618 if (parseOperand(Operands, Name))
619 return true;
620 }
621
622 if (getLexer().isNot(AsmToken::EndOfStatement)) {
623 SMLoc Loc = getLexer().getLoc();
624 getParser().eatToEndOfStatement();
625 return Error(Loc, "unexpected token");
626 }
627
628 getParser().Lex(); // Consume the EndOfStatement.
629 return false;
630 }
631
tryParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)632 OperandMatchResultTy CSKYAsmParser::tryParseRegister(unsigned &RegNo,
633 SMLoc &StartLoc,
634 SMLoc &EndLoc) {
635 const AsmToken &Tok = getParser().getTok();
636 StartLoc = Tok.getLoc();
637 EndLoc = Tok.getEndLoc();
638
639 StringRef Name = getLexer().getTok().getIdentifier();
640
641 if (matchRegisterNameHelper((MCRegister &)RegNo, Name))
642 return MatchOperand_NoMatch;
643
644 getParser().Lex(); // Eat identifier token.
645 return MatchOperand_Success;
646 }
647
ParseDirective(AsmToken DirectiveID)648 bool CSKYAsmParser::ParseDirective(AsmToken DirectiveID) { return true; }
649
LLVMInitializeCSKYAsmParser()650 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmParser() {
651 RegisterMCAsmParser<CSKYAsmParser> X(getTheCSKYTarget());
652 }
653