1 //===-- RISCVAsmParser.cpp - Parse RISCV 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/RISCVBaseInfo.h"
11 #include "MCTargetDesc/RISCVMCExpr.h"
12 #include "MCTargetDesc/RISCVMCTargetDesc.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/StringSwitch.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCParser/MCAsmLexer.h"
19 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
20 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/MC/MCStreamer.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/Support/Casting.h"
25 #include "llvm/Support/TargetRegistry.h"
26 
27 using namespace llvm;
28 
29 namespace {
30 struct RISCVOperand;
31 
32 class RISCVAsmParser : public MCTargetAsmParser {
33   SMLoc getLoc() const { return getParser().getTok().getLoc(); }
34 
35   bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
36                                   int Lower, int Upper, Twine Msg);
37 
38   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
39                                OperandVector &Operands, MCStreamer &Out,
40                                uint64_t &ErrorInfo,
41                                bool MatchingInlineAsm) override;
42 
43   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
44 
45   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
46                         SMLoc NameLoc, OperandVector &Operands) override;
47 
48   bool ParseDirective(AsmToken DirectiveID) override;
49 
50 // Auto-generated instruction matching functions
51 #define GET_ASSEMBLER_HEADER
52 #include "RISCVGenAsmMatcher.inc"
53 
54   OperandMatchResultTy parseImmediate(OperandVector &Operands);
55   OperandMatchResultTy parseRegister(OperandVector &Operands,
56                                      bool AllowParens = false);
57   OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
58   OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
59 
60   bool parseOperand(OperandVector &Operands);
61 
62 public:
63   enum RISCVMatchResultTy {
64     Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
65 #define GET_OPERAND_DIAGNOSTIC_TYPES
66 #include "RISCVGenAsmMatcher.inc"
67 #undef GET_OPERAND_DIAGNOSTIC_TYPES
68   };
69 
70   static bool classifySymbolRef(const MCExpr *Expr,
71                                 RISCVMCExpr::VariantKind &Kind,
72                                 int64_t &Addend);
73 
74   RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
75                  const MCInstrInfo &MII, const MCTargetOptions &Options)
76       : MCTargetAsmParser(Options, STI, MII) {
77     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
78   }
79 };
80 
81 /// RISCVOperand - Instances of this class represent a parsed machine
82 /// instruction
83 struct RISCVOperand : public MCParsedAsmOperand {
84 
85   enum KindTy {
86     Token,
87     Register,
88     Immediate,
89   } Kind;
90 
91   struct RegOp {
92     unsigned RegNum;
93   };
94 
95   struct ImmOp {
96     const MCExpr *Val;
97   };
98 
99   SMLoc StartLoc, EndLoc;
100   union {
101     StringRef Tok;
102     RegOp Reg;
103     ImmOp Imm;
104   };
105 
106   RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
107 
108 public:
109   RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() {
110     Kind = o.Kind;
111     StartLoc = o.StartLoc;
112     EndLoc = o.EndLoc;
113     switch (Kind) {
114     case Register:
115       Reg = o.Reg;
116       break;
117     case Immediate:
118       Imm = o.Imm;
119       break;
120     case Token:
121       Tok = o.Tok;
122       break;
123     }
124   }
125 
126   bool isToken() const override { return Kind == Token; }
127   bool isReg() const override { return Kind == Register; }
128   bool isImm() const override { return Kind == Immediate; }
129   bool isMem() const override { return false; }
130 
131   bool evaluateConstantImm(int64_t &Imm, RISCVMCExpr::VariantKind &VK) const {
132     const MCExpr *Val = getImm();
133     bool Ret = false;
134     if (auto *RE = dyn_cast<RISCVMCExpr>(Val)) {
135       Ret = RE->evaluateAsConstant(Imm);
136       VK = RE->getKind();
137     } else if (auto CE = dyn_cast<MCConstantExpr>(Val)) {
138       Ret = true;
139       VK = RISCVMCExpr::VK_RISCV_None;
140       Imm = CE->getValue();
141     }
142     return Ret;
143   }
144 
145   // True if operand is a symbol with no modifiers, or a constant with no
146   // modifiers and isShiftedInt<N-1, 1>(Op).
147   template <int N> bool isBareSimmNLsb0() const {
148     int64_t Imm;
149     RISCVMCExpr::VariantKind VK;
150     if (!isImm())
151       return false;
152     bool IsConstantImm = evaluateConstantImm(Imm, VK);
153     bool IsValid;
154     if (!IsConstantImm)
155       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
156     else
157       IsValid = isShiftedInt<N - 1, 1>(Imm);
158     return IsValid && VK == RISCVMCExpr::VK_RISCV_None;
159   }
160 
161   // Predicate methods for AsmOperands defined in RISCVInstrInfo.td
162 
163   /// Return true if the operand is a valid for the fence instruction e.g.
164   /// ('iorw').
165   bool isFenceArg() const {
166     if (!isImm())
167       return false;
168     const MCExpr *Val = getImm();
169     auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
170     if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
171       return false;
172 
173     StringRef Str = SVal->getSymbol().getName();
174     // Letters must be unique, taken from 'iorw', and in ascending order. This
175     // holds as long as each individual character is one of 'iorw' and is
176     // greater than the previous character.
177     char Prev = '\0';
178     for (char c : Str) {
179       if (c != 'i' && c != 'o' && c != 'r' && c != 'w')
180         return false;
181       if (c <= Prev)
182         return false;
183       Prev = c;
184     }
185     return true;
186   }
187 
188   bool isUImm5() const {
189     int64_t Imm;
190     RISCVMCExpr::VariantKind VK;
191     if (!isImm())
192       return false;
193     bool IsConstantImm = evaluateConstantImm(Imm, VK);
194     return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
195   }
196 
197   bool isSImm12() const {
198     RISCVMCExpr::VariantKind VK;
199     int64_t Imm;
200     bool IsValid;
201     if (!isImm())
202       return false;
203     bool IsConstantImm = evaluateConstantImm(Imm, VK);
204     if (!IsConstantImm)
205       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
206     else
207       IsValid = isInt<12>(Imm);
208     return IsValid &&
209            (VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO);
210   }
211 
212   bool isUImm12() const {
213     int64_t Imm;
214     RISCVMCExpr::VariantKind VK;
215     if (!isImm())
216       return false;
217     bool IsConstantImm = evaluateConstantImm(Imm, VK);
218     return IsConstantImm && isUInt<12>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
219   }
220 
221   bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
222 
223   bool isUImm20() const {
224     RISCVMCExpr::VariantKind VK;
225     int64_t Imm;
226     bool IsValid;
227     if (!isImm())
228       return false;
229     bool IsConstantImm = evaluateConstantImm(Imm, VK);
230     if (!IsConstantImm)
231       IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
232     else
233       IsValid = isUInt<20>(Imm);
234     return IsValid && (VK == RISCVMCExpr::VK_RISCV_None ||
235                        VK == RISCVMCExpr::VK_RISCV_HI ||
236                        VK == RISCVMCExpr::VK_RISCV_PCREL_HI);
237   }
238 
239   bool isSImm21Lsb0() const { return isBareSimmNLsb0<21>(); }
240 
241   /// getStartLoc - Gets location of the first token of this operand
242   SMLoc getStartLoc() const override { return StartLoc; }
243   /// getEndLoc - Gets location of the last token of this operand
244   SMLoc getEndLoc() const override { return EndLoc; }
245 
246   unsigned getReg() const override {
247     assert(Kind == Register && "Invalid type access!");
248     return Reg.RegNum;
249   }
250 
251   const MCExpr *getImm() const {
252     assert(Kind == Immediate && "Invalid type access!");
253     return Imm.Val;
254   }
255 
256   StringRef getToken() const {
257     assert(Kind == Token && "Invalid type access!");
258     return Tok;
259   }
260 
261   void print(raw_ostream &OS) const override {
262     switch (Kind) {
263     case Immediate:
264       OS << *getImm();
265       break;
266     case Register:
267       OS << "<register x";
268       OS << getReg() << ">";
269       break;
270     case Token:
271       OS << "'" << getToken() << "'";
272       break;
273     }
274   }
275 
276   static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
277     auto Op = make_unique<RISCVOperand>(Token);
278     Op->Tok = Str;
279     Op->StartLoc = S;
280     Op->EndLoc = S;
281     return Op;
282   }
283 
284   static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
285                                                  SMLoc E) {
286     auto Op = make_unique<RISCVOperand>(Register);
287     Op->Reg.RegNum = RegNo;
288     Op->StartLoc = S;
289     Op->EndLoc = E;
290     return Op;
291   }
292 
293   static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S,
294                                                  SMLoc E) {
295     auto Op = make_unique<RISCVOperand>(Immediate);
296     Op->Imm.Val = Val;
297     Op->StartLoc = S;
298     Op->EndLoc = E;
299     return Op;
300   }
301 
302   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
303     assert(Expr && "Expr shouldn't be null!");
304     int64_t Imm = 0;
305     bool IsConstant = false;
306     if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
307       IsConstant = RE->evaluateAsConstant(Imm);
308     } else if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
309       IsConstant = true;
310       Imm = CE->getValue();
311     }
312 
313     if (IsConstant)
314       Inst.addOperand(MCOperand::createImm(Imm));
315     else
316       Inst.addOperand(MCOperand::createExpr(Expr));
317   }
318 
319   // Used by the TableGen Code
320   void addRegOperands(MCInst &Inst, unsigned N) const {
321     assert(N == 1 && "Invalid number of operands!");
322     Inst.addOperand(MCOperand::createReg(getReg()));
323   }
324 
325   void addImmOperands(MCInst &Inst, unsigned N) const {
326     assert(N == 1 && "Invalid number of operands!");
327     addExpr(Inst, getImm());
328   }
329 
330   void addFenceArgOperands(MCInst &Inst, unsigned N) const {
331     assert(N == 1 && "Invalid number of operands!");
332     // isFenceArg has validated the operand, meaning this cast is safe
333     auto SE = cast<MCSymbolRefExpr>(getImm());
334 
335     unsigned Imm = 0;
336     for (char c : SE->getSymbol().getName()) {
337       switch (c) {
338         default: llvm_unreachable("FenceArg must contain only [iorw]");
339         case 'i': Imm |= RISCVFenceField::I; break;
340         case 'o': Imm |= RISCVFenceField::O; break;
341         case 'r': Imm |= RISCVFenceField::R; break;
342         case 'w': Imm |= RISCVFenceField::W; break;
343       }
344     }
345     Inst.addOperand(MCOperand::createImm(Imm));
346   }
347 };
348 } // end anonymous namespace.
349 
350 #define GET_REGISTER_MATCHER
351 #define GET_MATCHER_IMPLEMENTATION
352 #include "RISCVGenAsmMatcher.inc"
353 
354 bool RISCVAsmParser::generateImmOutOfRangeError(
355     OperandVector &Operands, uint64_t ErrorInfo, int Lower, int Upper,
356     Twine Msg = "immediate must be an integer in the range") {
357   SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
358   return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
359 }
360 
361 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
362                                              OperandVector &Operands,
363                                              MCStreamer &Out,
364                                              uint64_t &ErrorInfo,
365                                              bool MatchingInlineAsm) {
366   MCInst Inst;
367 
368   switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
369   default:
370     break;
371   case Match_Success:
372     Inst.setLoc(IDLoc);
373     Out.EmitInstruction(Inst, getSTI());
374     return false;
375   case Match_MissingFeature:
376     return Error(IDLoc, "instruction use requires an option to be enabled");
377   case Match_MnemonicFail:
378     return Error(IDLoc, "unrecognized instruction mnemonic");
379   case Match_InvalidOperand: {
380     SMLoc ErrorLoc = IDLoc;
381     if (ErrorInfo != ~0U) {
382       if (ErrorInfo >= Operands.size())
383         return Error(ErrorLoc, "too few operands for instruction");
384 
385       ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
386       if (ErrorLoc == SMLoc())
387         ErrorLoc = IDLoc;
388     }
389     return Error(ErrorLoc, "invalid operand for instruction");
390   }
391   case Match_InvalidUImm5:
392     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
393   case Match_InvalidSImm12:
394     return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
395                                       (1 << 11) - 1);
396   case Match_InvalidUImm12:
397     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);
398   case Match_InvalidSImm13Lsb0:
399     return generateImmOutOfRangeError(
400         Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
401         "immediate must be a multiple of 2 bytes in the range");
402   case Match_InvalidUImm20:
403     return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
404   case Match_InvalidSImm21Lsb0:
405     return generateImmOutOfRangeError(
406         Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
407         "immediate must be a multiple of 2 bytes in the range");
408   case Match_InvalidFenceArg: {
409     SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
410     return Error(
411         ErrorLoc,
412         "operand must be formed of letters selected in-order from 'iorw'");
413   }
414   }
415 
416   llvm_unreachable("Unknown match type detected!");
417 }
418 
419 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
420                                    SMLoc &EndLoc) {
421   const AsmToken &Tok = getParser().getTok();
422   StartLoc = Tok.getLoc();
423   EndLoc = Tok.getEndLoc();
424   RegNo = 0;
425   StringRef Name = getLexer().getTok().getIdentifier();
426 
427   if (!MatchRegisterName(Name) || !MatchRegisterAltName(Name)) {
428     getParser().Lex(); // Eat identifier token.
429     return false;
430   }
431 
432   return Error(StartLoc, "invalid register name");
433 }
434 
435 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands,
436                                                    bool AllowParens) {
437   SMLoc FirstS = getLoc();
438   bool HadParens = false;
439   AsmToken Buf[2];
440 
441   // If this a parenthesised register name is allowed, parse it atomically
442   if (AllowParens && getLexer().is(AsmToken::LParen)) {
443     size_t ReadCount = getLexer().peekTokens(Buf);
444     if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
445       HadParens = true;
446       getParser().Lex(); // Eat '('
447     }
448   }
449 
450   switch (getLexer().getKind()) {
451   default:
452     return MatchOperand_NoMatch;
453   case AsmToken::Identifier:
454     StringRef Name = getLexer().getTok().getIdentifier();
455     unsigned RegNo = MatchRegisterName(Name);
456     if (RegNo == 0) {
457       RegNo = MatchRegisterAltName(Name);
458       if (RegNo == 0) {
459         if (HadParens)
460           getLexer().UnLex(Buf[0]);
461         return MatchOperand_NoMatch;
462       }
463     }
464     if (HadParens)
465       Operands.push_back(RISCVOperand::createToken("(", FirstS));
466     SMLoc S = getLoc();
467     SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
468     getLexer().Lex();
469     Operands.push_back(RISCVOperand::createReg(RegNo, S, E));
470   }
471 
472   if (HadParens) {
473     getParser().Lex(); // Eat ')'
474     Operands.push_back(RISCVOperand::createToken(")", getLoc()));
475   }
476 
477   return MatchOperand_Success;
478 }
479 
480 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) {
481   SMLoc S = getLoc();
482   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
483   const MCExpr *Res;
484 
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     if (getParser().parseExpression(Res))
494       return MatchOperand_ParseFail;
495     break;
496   case AsmToken::Identifier: {
497     StringRef Identifier;
498     if (getParser().parseIdentifier(Identifier))
499       return MatchOperand_ParseFail;
500     MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
501     Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
502     break;
503   }
504   case AsmToken::Percent:
505     return parseOperandWithModifier(Operands);
506   }
507 
508   Operands.push_back(RISCVOperand::createImm(Res, S, E));
509   return MatchOperand_Success;
510 }
511 
512 OperandMatchResultTy
513 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
514   SMLoc S = getLoc();
515   SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
516 
517   if (getLexer().getKind() != AsmToken::Percent) {
518     Error(getLoc(), "expected '%' for operand modifier");
519     return MatchOperand_ParseFail;
520   }
521 
522   getParser().Lex(); // Eat '%'
523 
524   if (getLexer().getKind() != AsmToken::Identifier) {
525     Error(getLoc(), "expected valid identifier for operand modifier");
526     return MatchOperand_ParseFail;
527   }
528   StringRef Identifier = getParser().getTok().getIdentifier();
529   RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier);
530   if (VK == RISCVMCExpr::VK_RISCV_Invalid) {
531     Error(getLoc(), "unrecognized operand modifier");
532     return MatchOperand_ParseFail;
533   }
534 
535   getParser().Lex(); // Eat the identifier
536   if (getLexer().getKind() != AsmToken::LParen) {
537     Error(getLoc(), "expected '('");
538     return MatchOperand_ParseFail;
539   }
540   getParser().Lex(); // Eat '('
541 
542   const MCExpr *SubExpr;
543   if (getParser().parseParenExpression(SubExpr, E)) {
544     return MatchOperand_ParseFail;
545   }
546 
547   const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext());
548   Operands.push_back(RISCVOperand::createImm(ModExpr, S, E));
549   return MatchOperand_Success;
550 }
551 
552 OperandMatchResultTy
553 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
554   if (getLexer().isNot(AsmToken::LParen)) {
555     Error(getLoc(), "expected '('");
556     return MatchOperand_ParseFail;
557   }
558 
559   getParser().Lex(); // Eat '('
560   Operands.push_back(RISCVOperand::createToken("(", getLoc()));
561 
562   if (parseRegister(Operands) != MatchOperand_Success) {
563     Error(getLoc(), "expected register");
564     return MatchOperand_ParseFail;
565   }
566 
567   if (getLexer().isNot(AsmToken::RParen)) {
568     Error(getLoc(), "expected ')'");
569     return MatchOperand_ParseFail;
570   }
571 
572   getParser().Lex(); // Eat ')'
573   Operands.push_back(RISCVOperand::createToken(")", getLoc()));
574 
575   return MatchOperand_Success;
576 }
577 
578 /// Looks at a token type and creates the relevant operand
579 /// from this information, adding to Operands.
580 /// If operand was parsed, returns false, else true.
581 bool RISCVAsmParser::parseOperand(OperandVector &Operands) {
582   // Attempt to parse token as register
583   if (parseRegister(Operands, true) == MatchOperand_Success)
584     return false;
585 
586   // Attempt to parse token as an immediate
587   if (parseImmediate(Operands) == MatchOperand_Success) {
588     // Parse memory base register if present
589     if (getLexer().is(AsmToken::LParen))
590       return parseMemOpBaseReg(Operands) != MatchOperand_Success;
591     return false;
592   }
593 
594   // Finally we have exhausted all options and must declare defeat.
595   Error(getLoc(), "unknown operand");
596   return true;
597 }
598 
599 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
600                                       StringRef Name, SMLoc NameLoc,
601                                       OperandVector &Operands) {
602   // First operand is token for instruction
603   Operands.push_back(RISCVOperand::createToken(Name, NameLoc));
604 
605   // If there are no more operands, then finish
606   if (getLexer().is(AsmToken::EndOfStatement))
607     return false;
608 
609   // Parse first operand
610   if (parseOperand(Operands))
611     return true;
612 
613   // Parse until end of statement, consuming commas between operands
614   while (getLexer().is(AsmToken::Comma)) {
615     // Consume comma token
616     getLexer().Lex();
617 
618     // Parse next operand
619     if (parseOperand(Operands))
620       return true;
621   }
622 
623   if (getLexer().isNot(AsmToken::EndOfStatement)) {
624     SMLoc Loc = getLexer().getLoc();
625     getParser().eatToEndOfStatement();
626     return Error(Loc, "unexpected token");
627   }
628 
629   getParser().Lex(); // Consume the EndOfStatement.
630   return false;
631 }
632 
633 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,
634                                        RISCVMCExpr::VariantKind &Kind,
635                                        int64_t &Addend) {
636   Kind = RISCVMCExpr::VK_RISCV_None;
637   Addend = 0;
638 
639   if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
640     Kind = RE->getKind();
641     Expr = RE->getSubExpr();
642   }
643 
644   // It's a simple symbol reference or constant with no addend.
645   if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr))
646     return true;
647 
648   const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
649   if (!BE)
650     return false;
651 
652   if (!isa<MCSymbolRefExpr>(BE->getLHS()))
653     return false;
654 
655   if (BE->getOpcode() != MCBinaryExpr::Add &&
656       BE->getOpcode() != MCBinaryExpr::Sub)
657     return false;
658 
659   // We are able to support the subtraction of two symbol references
660   if (BE->getOpcode() == MCBinaryExpr::Sub &&
661       isa<MCSymbolRefExpr>(BE->getRHS()))
662     return true;
663 
664   // See if the addend is is a constant, otherwise there's more going
665   // on here than we can deal with.
666   auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
667   if (!AddendExpr)
668     return false;
669 
670   Addend = AddendExpr->getValue();
671   if (BE->getOpcode() == MCBinaryExpr::Sub)
672     Addend = -Addend;
673 
674   // It's some symbol reference + a constant addend
675   return Kind != RISCVMCExpr::VK_RISCV_Invalid;
676 }
677 
678 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { return true; }
679 
680 extern "C" void LLVMInitializeRISCVAsmParser() {
681   RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target());
682   RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target());
683 }
684