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/RISCVAsmBackend.h"
11 #include "MCTargetDesc/RISCVMCExpr.h"
12 #include "MCTargetDesc/RISCVMCTargetDesc.h"
13 #include "MCTargetDesc/RISCVTargetStreamer.h"
14 #include "Utils/RISCVBaseInfo.h"
15 #include "Utils/RISCVMatInt.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/MC/MCAssembler.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/MC/MCInstBuilder.h"
24 #include "llvm/MC/MCParser/MCAsmLexer.h"
25 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
26 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
27 #include "llvm/MC/MCRegisterInfo.h"
28 #include "llvm/MC/MCStreamer.h"
29 #include "llvm/MC/MCSubtargetInfo.h"
30 #include "llvm/Support/Casting.h"
31 #include "llvm/Support/MathExtras.h"
32 #include "llvm/Support/TargetRegistry.h"
33
34 #include <limits>
35
36 using namespace llvm;
37
38 // Include the auto-generated portion of the compress emitter.
39 #define GEN_COMPRESS_INSTR
40 #include "RISCVGenCompressInstEmitter.inc"
41
42 namespace {
43 struct RISCVOperand;
44
45 class RISCVAsmParser : public MCTargetAsmParser {
46 SmallVector<FeatureBitset, 4> FeatureBitStack;
47
getLoc() const48 SMLoc getLoc() const { return getParser().getTok().getLoc(); }
isRV64() const49 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
50
getTargetStreamer()51 RISCVTargetStreamer &getTargetStreamer() {
52 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
53 return static_cast<RISCVTargetStreamer &>(TS);
54 }
55
56 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
57 unsigned Kind) override;
58
59 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
60 int64_t Lower, int64_t Upper, Twine Msg);
61
62 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
63 OperandVector &Operands, MCStreamer &Out,
64 uint64_t &ErrorInfo,
65 bool MatchingInlineAsm) override;
66
67 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
68
69 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
70 SMLoc NameLoc, OperandVector &Operands) override;
71
72 bool ParseDirective(AsmToken DirectiveID) override;
73
74 // Helper to actually emit an instruction to the MCStreamer. Also, when
75 // possible, compression of the instruction is performed.
76 void emitToStreamer(MCStreamer &S, const MCInst &Inst);
77
78 // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that
79 // synthesize the desired immedate value into the destination register.
80 void emitLoadImm(unsigned DestReg, int64_t Value, MCStreamer &Out);
81
82 // Helper to emit pseudo instruction "lla" used in PC-rel addressing.
83 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
84
85 /// Helper for processing MC instructions that have been successfully matched
86 /// by MatchAndEmitInstruction. Modifications to the emitted instructions,
87 /// like the expansion of pseudo instructions (e.g., "li"), can be performed
88 /// in this method.
89 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
90
91 // Auto-generated instruction matching functions
92 #define GET_ASSEMBLER_HEADER
93 #include "RISCVGenAsmMatcher.inc"
94
95 OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands);
96 OperandMatchResultTy parseImmediate(OperandVector &Operands);
97 OperandMatchResultTy parseRegister(OperandVector &Operands,
98 bool AllowParens = false);
99 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
100 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
101 OperandMatchResultTy parseBareSymbol(OperandVector &Operands);
102 OperandMatchResultTy parseJALOffset(OperandVector &Operands);
103
104 bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
105
106 bool parseDirectiveOption();
107
setFeatureBits(uint64_t Feature,StringRef FeatureString)108 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
109 if (!(getSTI().getFeatureBits()[Feature])) {
110 MCSubtargetInfo &STI = copySTI();
111 setAvailableFeatures(
112 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
113 }
114 }
115
clearFeatureBits(uint64_t Feature,StringRef FeatureString)116 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
117 if (getSTI().getFeatureBits()[Feature]) {
118 MCSubtargetInfo &STI = copySTI();
119 setAvailableFeatures(
120 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
121 }
122 }
123
pushFeatureBits()124 void pushFeatureBits() {
125 FeatureBitStack.push_back(getSTI().getFeatureBits());
126 }
127
popFeatureBits()128 bool popFeatureBits() {
129 if (FeatureBitStack.empty())
130 return true;
131
132 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
133 copySTI().setFeatureBits(FeatureBits);
134 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
135
136 return false;
137 }
138 public:
139 enum RISCVMatchResultTy {
140 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
141 #define GET_OPERAND_DIAGNOSTIC_TYPES
142 #include "RISCVGenAsmMatcher.inc"
143 #undef GET_OPERAND_DIAGNOSTIC_TYPES
144 };
145
146 static bool classifySymbolRef(const MCExpr *Expr,
147 RISCVMCExpr::VariantKind &Kind,
148 int64_t &Addend);
149
RISCVAsmParser(const MCSubtargetInfo & STI,MCAsmParser & Parser,const MCInstrInfo & MII,const MCTargetOptions & Options)150 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
151 const MCInstrInfo &MII, const MCTargetOptions &Options)
152 : MCTargetAsmParser(Options, STI, MII) {
153 Parser.addAliasForDirective(".half", ".2byte");
154 Parser.addAliasForDirective(".hword", ".2byte");
155 Parser.addAliasForDirective(".word", ".4byte");
156 Parser.addAliasForDirective(".dword", ".8byte");
157 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
158 }
159 };
160
161 /// RISCVOperand - Instances of this class represent a parsed machine
162 /// instruction
163 struct RISCVOperand : public MCParsedAsmOperand {
164
165 enum KindTy {
166 Token,
167 Register,
168 Immediate,
169 SystemRegister
170 } Kind;
171
172 bool IsRV64;
173
174 struct RegOp {
175 unsigned RegNum;
176 };
177
178 struct ImmOp {
179 const MCExpr *Val;
180 };
181
182 struct SysRegOp {
183 const char *Data;
184 unsigned Length;
185 unsigned Encoding;
186 // FIXME: Add the Encoding parsed fields as needed for checks,
187 // e.g.: read/write or user/supervisor/machine privileges.
188 };
189
190 SMLoc StartLoc, EndLoc;
191 union {
192 StringRef Tok;
193 RegOp Reg;
194 ImmOp Imm;
195 struct SysRegOp SysReg;
196 };
197
RISCVOperand__anond849e6730111::RISCVOperand198 RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
199
200 public:
RISCVOperand__anond849e6730111::RISCVOperand201 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() {
202 Kind = o.Kind;
203 IsRV64 = o.IsRV64;
204 StartLoc = o.StartLoc;
205 EndLoc = o.EndLoc;
206 switch (Kind) {
207 case Register:
208 Reg = o.Reg;
209 break;
210 case Immediate:
211 Imm = o.Imm;
212 break;
213 case Token:
214 Tok = o.Tok;
215 break;
216 case SystemRegister:
217 SysReg = o.SysReg;
218 break;
219 }
220 }
221
isToken__anond849e6730111::RISCVOperand222 bool isToken() const override { return Kind == Token; }
isReg__anond849e6730111::RISCVOperand223 bool isReg() const override { return Kind == Register; }
isImm__anond849e6730111::RISCVOperand224 bool isImm() const override { return Kind == Immediate; }
isMem__anond849e6730111::RISCVOperand225 bool isMem() const override { return false; }
isSystemRegister__anond849e6730111::RISCVOperand226 bool isSystemRegister() const { return Kind == SystemRegister; }
227
evaluateConstantImm__anond849e6730111::RISCVOperand228 static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
229 RISCVMCExpr::VariantKind &VK) {
230 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
231 VK = RE->getKind();
232 return RE->evaluateAsConstant(Imm);
233 }
234
235 if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
236 VK = RISCVMCExpr::VK_RISCV_None;
237 Imm = CE->getValue();
238 return true;
239 }
240
241 return false;
242 }
243
244 // True if operand is a symbol with no modifiers, or a constant with no
245 // modifiers and isShiftedInt<N-1, 1>(Op).
isBareSimmNLsb0__anond849e6730111::RISCVOperand246 template <int N> bool isBareSimmNLsb0() const {
247 int64_t Imm;
248 RISCVMCExpr::VariantKind VK;
249 if (!isImm())
250 return false;
251 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
252 bool IsValid;
253 if (!IsConstantImm)
254 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
255 else
256 IsValid = isShiftedInt<N - 1, 1>(Imm);
257 return IsValid && VK == RISCVMCExpr::VK_RISCV_None;
258 }
259
260 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td
261
isBareSymbol__anond849e6730111::RISCVOperand262 bool isBareSymbol() const {
263 int64_t Imm;
264 RISCVMCExpr::VariantKind VK;
265 // Must be of 'immediate' type but not a constant.
266 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
267 return false;
268 return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
269 VK == RISCVMCExpr::VK_RISCV_None;
270 }
271
isCSRSystemRegister__anond849e6730111::RISCVOperand272 bool isCSRSystemRegister() const { return isSystemRegister(); }
273
274 /// Return true if the operand is a valid for the fence instruction e.g.
275 /// ('iorw').
isFenceArg__anond849e6730111::RISCVOperand276 bool isFenceArg() const {
277 if (!isImm())
278 return false;
279 const MCExpr *Val = getImm();
280 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
281 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
282 return false;
283
284 StringRef Str = SVal->getSymbol().getName();
285 // Letters must be unique, taken from 'iorw', and in ascending order. This
286 // holds as long as each individual character is one of 'iorw' and is
287 // greater than the previous character.
288 char Prev = '\0';
289 for (char c : Str) {
290 if (c != 'i' && c != 'o' && c != 'r' && c != 'w')
291 return false;
292 if (c <= Prev)
293 return false;
294 Prev = c;
295 }
296 return true;
297 }
298
299 /// Return true if the operand is a valid floating point rounding mode.
isFRMArg__anond849e6730111::RISCVOperand300 bool isFRMArg() const {
301 if (!isImm())
302 return false;
303 const MCExpr *Val = getImm();
304 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
305 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
306 return false;
307
308 StringRef Str = SVal->getSymbol().getName();
309
310 return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid;
311 }
312
isImmXLenLI__anond849e6730111::RISCVOperand313 bool isImmXLenLI() const {
314 int64_t Imm;
315 RISCVMCExpr::VariantKind VK;
316 if (!isImm())
317 return false;
318 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
319 if (VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO)
320 return true;
321 // Given only Imm, ensuring that the actually specified constant is either
322 // a signed or unsigned 64-bit number is unfortunately impossible.
323 bool IsInRange = isRV64() ? true : isInt<32>(Imm) || isUInt<32>(Imm);
324 return IsConstantImm && IsInRange && VK == RISCVMCExpr::VK_RISCV_None;
325 }
326
isUImmLog2XLen__anond849e6730111::RISCVOperand327 bool isUImmLog2XLen() const {
328 int64_t Imm;
329 RISCVMCExpr::VariantKind VK;
330 if (!isImm())
331 return false;
332 if (!evaluateConstantImm(getImm(), Imm, VK) ||
333 VK != RISCVMCExpr::VK_RISCV_None)
334 return false;
335 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
336 }
337
isUImmLog2XLenNonZero__anond849e6730111::RISCVOperand338 bool isUImmLog2XLenNonZero() const {
339 int64_t Imm;
340 RISCVMCExpr::VariantKind VK;
341 if (!isImm())
342 return false;
343 if (!evaluateConstantImm(getImm(), Imm, VK) ||
344 VK != RISCVMCExpr::VK_RISCV_None)
345 return false;
346 if (Imm == 0)
347 return false;
348 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
349 }
350
isUImm5__anond849e6730111::RISCVOperand351 bool isUImm5() const {
352 int64_t Imm;
353 RISCVMCExpr::VariantKind VK;
354 if (!isImm())
355 return false;
356 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
357 return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
358 }
359
isUImm5NonZero__anond849e6730111::RISCVOperand360 bool isUImm5NonZero() const {
361 int64_t Imm;
362 RISCVMCExpr::VariantKind VK;
363 if (!isImm())
364 return false;
365 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
366 return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) &&
367 VK == RISCVMCExpr::VK_RISCV_None;
368 }
369
isSImm6__anond849e6730111::RISCVOperand370 bool isSImm6() const {
371 if (!isImm())
372 return false;
373 RISCVMCExpr::VariantKind VK;
374 int64_t Imm;
375 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
376 return IsConstantImm && isInt<6>(Imm) &&
377 VK == RISCVMCExpr::VK_RISCV_None;
378 }
379
isSImm6NonZero__anond849e6730111::RISCVOperand380 bool isSImm6NonZero() const {
381 if (!isImm())
382 return false;
383 RISCVMCExpr::VariantKind VK;
384 int64_t Imm;
385 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
386 return IsConstantImm && isInt<6>(Imm) && (Imm != 0) &&
387 VK == RISCVMCExpr::VK_RISCV_None;
388 }
389
isCLUIImm__anond849e6730111::RISCVOperand390 bool isCLUIImm() const {
391 if (!isImm())
392 return false;
393 int64_t Imm;
394 RISCVMCExpr::VariantKind VK;
395 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
396 return IsConstantImm && (Imm != 0) &&
397 (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) &&
398 VK == RISCVMCExpr::VK_RISCV_None;
399 }
400
isUImm7Lsb00__anond849e6730111::RISCVOperand401 bool isUImm7Lsb00() const {
402 if (!isImm())
403 return false;
404 int64_t Imm;
405 RISCVMCExpr::VariantKind VK;
406 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
407 return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
408 VK == RISCVMCExpr::VK_RISCV_None;
409 }
410
isUImm8Lsb00__anond849e6730111::RISCVOperand411 bool isUImm8Lsb00() const {
412 if (!isImm())
413 return false;
414 int64_t Imm;
415 RISCVMCExpr::VariantKind VK;
416 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
417 return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
418 VK == RISCVMCExpr::VK_RISCV_None;
419 }
420
isUImm8Lsb000__anond849e6730111::RISCVOperand421 bool isUImm8Lsb000() const {
422 if (!isImm())
423 return false;
424 int64_t Imm;
425 RISCVMCExpr::VariantKind VK;
426 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
427 return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
428 VK == RISCVMCExpr::VK_RISCV_None;
429 }
430
isSImm9Lsb0__anond849e6730111::RISCVOperand431 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); }
432
isUImm9Lsb000__anond849e6730111::RISCVOperand433 bool isUImm9Lsb000() const {
434 if (!isImm())
435 return false;
436 int64_t Imm;
437 RISCVMCExpr::VariantKind VK;
438 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
439 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
440 VK == RISCVMCExpr::VK_RISCV_None;
441 }
442
isUImm10Lsb00NonZero__anond849e6730111::RISCVOperand443 bool isUImm10Lsb00NonZero() const {
444 if (!isImm())
445 return false;
446 int64_t Imm;
447 RISCVMCExpr::VariantKind VK;
448 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
449 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) &&
450 VK == RISCVMCExpr::VK_RISCV_None;
451 }
452
isSImm12__anond849e6730111::RISCVOperand453 bool isSImm12() const {
454 RISCVMCExpr::VariantKind VK;
455 int64_t Imm;
456 bool IsValid;
457 if (!isImm())
458 return false;
459 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
460 if (!IsConstantImm)
461 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
462 else
463 IsValid = isInt<12>(Imm);
464 return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) ||
465 VK == RISCVMCExpr::VK_RISCV_LO ||
466 VK == RISCVMCExpr::VK_RISCV_PCREL_LO);
467 }
468
isSImm12Lsb0__anond849e6730111::RISCVOperand469 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); }
470
isSImm13Lsb0__anond849e6730111::RISCVOperand471 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
472
isSImm10Lsb0000NonZero__anond849e6730111::RISCVOperand473 bool isSImm10Lsb0000NonZero() const {
474 if (!isImm())
475 return false;
476 int64_t Imm;
477 RISCVMCExpr::VariantKind VK;
478 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
479 return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) &&
480 VK == RISCVMCExpr::VK_RISCV_None;
481 }
482
isUImm20LUI__anond849e6730111::RISCVOperand483 bool isUImm20LUI() const {
484 RISCVMCExpr::VariantKind VK;
485 int64_t Imm;
486 bool IsValid;
487 if (!isImm())
488 return false;
489 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
490 if (!IsConstantImm) {
491 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
492 return IsValid && VK == RISCVMCExpr::VK_RISCV_HI;
493 } else {
494 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
495 VK == RISCVMCExpr::VK_RISCV_HI);
496 }
497 }
498
isUImm20AUIPC__anond849e6730111::RISCVOperand499 bool isUImm20AUIPC() const {
500 RISCVMCExpr::VariantKind VK;
501 int64_t Imm;
502 bool IsValid;
503 if (!isImm())
504 return false;
505 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
506 if (!IsConstantImm) {
507 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
508 return IsValid && VK == RISCVMCExpr::VK_RISCV_PCREL_HI;
509 } else {
510 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
511 VK == RISCVMCExpr::VK_RISCV_PCREL_HI);
512 }
513 }
514
isSImm21Lsb0JAL__anond849e6730111::RISCVOperand515 bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); }
516
517 /// getStartLoc - Gets location of the first token of this operand
getStartLoc__anond849e6730111::RISCVOperand518 SMLoc getStartLoc() const override { return StartLoc; }
519 /// getEndLoc - Gets location of the last token of this operand
getEndLoc__anond849e6730111::RISCVOperand520 SMLoc getEndLoc() const override { return EndLoc; }
521 /// True if this operand is for an RV64 instruction
isRV64__anond849e6730111::RISCVOperand522 bool isRV64() const { return IsRV64; }
523
getReg__anond849e6730111::RISCVOperand524 unsigned getReg() const override {
525 assert(Kind == Register && "Invalid type access!");
526 return Reg.RegNum;
527 }
528
getSysReg__anond849e6730111::RISCVOperand529 StringRef getSysReg() const {
530 assert(Kind == SystemRegister && "Invalid access!");
531 return StringRef(SysReg.Data, SysReg.Length);
532 }
533
getImm__anond849e6730111::RISCVOperand534 const MCExpr *getImm() const {
535 assert(Kind == Immediate && "Invalid type access!");
536 return Imm.Val;
537 }
538
getToken__anond849e6730111::RISCVOperand539 StringRef getToken() const {
540 assert(Kind == Token && "Invalid type access!");
541 return Tok;
542 }
543
print__anond849e6730111::RISCVOperand544 void print(raw_ostream &OS) const override {
545 switch (Kind) {
546 case Immediate:
547 OS << *getImm();
548 break;
549 case Register:
550 OS << "<register x";
551 OS << getReg() << ">";
552 break;
553 case Token:
554 OS << "'" << getToken() << "'";
555 break;
556 case SystemRegister:
557 OS << "<sysreg: " << getSysReg() << '>';
558 break;
559 }
560 }
561
createToken__anond849e6730111::RISCVOperand562 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S,
563 bool IsRV64) {
564 auto Op = make_unique<RISCVOperand>(Token);
565 Op->Tok = Str;
566 Op->StartLoc = S;
567 Op->EndLoc = S;
568 Op->IsRV64 = IsRV64;
569 return Op;
570 }
571
createReg__anond849e6730111::RISCVOperand572 static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
573 SMLoc E, bool IsRV64) {
574 auto Op = make_unique<RISCVOperand>(Register);
575 Op->Reg.RegNum = RegNo;
576 Op->StartLoc = S;
577 Op->EndLoc = E;
578 Op->IsRV64 = IsRV64;
579 return Op;
580 }
581
createImm__anond849e6730111::RISCVOperand582 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S,
583 SMLoc E, bool IsRV64) {
584 auto Op = make_unique<RISCVOperand>(Immediate);
585 Op->Imm.Val = Val;
586 Op->StartLoc = S;
587 Op->EndLoc = E;
588 Op->IsRV64 = IsRV64;
589 return Op;
590 }
591
592 static std::unique_ptr<RISCVOperand>
createSysReg__anond849e6730111::RISCVOperand593 createSysReg(StringRef Str, SMLoc S, unsigned Encoding, bool IsRV64) {
594 auto Op = make_unique<RISCVOperand>(SystemRegister);
595 Op->SysReg.Data = Str.data();
596 Op->SysReg.Length = Str.size();
597 Op->SysReg.Encoding = Encoding;
598 Op->StartLoc = S;
599 Op->IsRV64 = IsRV64;
600 return Op;
601 }
602
addExpr__anond849e6730111::RISCVOperand603 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
604 assert(Expr && "Expr shouldn't be null!");
605 int64_t Imm = 0;
606 RISCVMCExpr::VariantKind VK;
607 bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
608
609 if (IsConstant)
610 Inst.addOperand(MCOperand::createImm(Imm));
611 else
612 Inst.addOperand(MCOperand::createExpr(Expr));
613 }
614
615 // Used by the TableGen Code
addRegOperands__anond849e6730111::RISCVOperand616 void addRegOperands(MCInst &Inst, unsigned N) const {
617 assert(N == 1 && "Invalid number of operands!");
618 Inst.addOperand(MCOperand::createReg(getReg()));
619 }
620
addImmOperands__anond849e6730111::RISCVOperand621 void addImmOperands(MCInst &Inst, unsigned N) const {
622 assert(N == 1 && "Invalid number of operands!");
623 addExpr(Inst, getImm());
624 }
625
addFenceArgOperands__anond849e6730111::RISCVOperand626 void addFenceArgOperands(MCInst &Inst, unsigned N) const {
627 assert(N == 1 && "Invalid number of operands!");
628 // isFenceArg has validated the operand, meaning this cast is safe
629 auto SE = cast<MCSymbolRefExpr>(getImm());
630
631 unsigned Imm = 0;
632 for (char c : SE->getSymbol().getName()) {
633 switch (c) {
634 default:
635 llvm_unreachable("FenceArg must contain only [iorw]");
636 case 'i': Imm |= RISCVFenceField::I; break;
637 case 'o': Imm |= RISCVFenceField::O; break;
638 case 'r': Imm |= RISCVFenceField::R; break;
639 case 'w': Imm |= RISCVFenceField::W; break;
640 }
641 }
642 Inst.addOperand(MCOperand::createImm(Imm));
643 }
644
addCSRSystemRegisterOperands__anond849e6730111::RISCVOperand645 void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
646 assert(N == 1 && "Invalid number of operands!");
647 Inst.addOperand(MCOperand::createImm(SysReg.Encoding));
648 }
649
650 // Returns the rounding mode represented by this RISCVOperand. Should only
651 // be called after checking isFRMArg.
getRoundingMode__anond849e6730111::RISCVOperand652 RISCVFPRndMode::RoundingMode getRoundingMode() const {
653 // isFRMArg has validated the operand, meaning this cast is safe.
654 auto SE = cast<MCSymbolRefExpr>(getImm());
655 RISCVFPRndMode::RoundingMode FRM =
656 RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName());
657 assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode");
658 return FRM;
659 }
660
addFRMArgOperands__anond849e6730111::RISCVOperand661 void addFRMArgOperands(MCInst &Inst, unsigned N) const {
662 assert(N == 1 && "Invalid number of operands!");
663 Inst.addOperand(MCOperand::createImm(getRoundingMode()));
664 }
665 };
666 } // end anonymous namespace.
667
668 #define GET_REGISTER_MATCHER
669 #define GET_MATCHER_IMPLEMENTATION
670 #include "RISCVGenAsmMatcher.inc"
671
672 // Return the matching FPR64 register for the given FPR32.
673 // FIXME: Ideally this function could be removed in favour of using
674 // information from TableGen.
convertFPR32ToFPR64(unsigned Reg)675 unsigned convertFPR32ToFPR64(unsigned Reg) {
676 switch (Reg) {
677 default:
678 llvm_unreachable("Not a recognised FPR32 register");
679 case RISCV::F0_32: return RISCV::F0_64;
680 case RISCV::F1_32: return RISCV::F1_64;
681 case RISCV::F2_32: return RISCV::F2_64;
682 case RISCV::F3_32: return RISCV::F3_64;
683 case RISCV::F4_32: return RISCV::F4_64;
684 case RISCV::F5_32: return RISCV::F5_64;
685 case RISCV::F6_32: return RISCV::F6_64;
686 case RISCV::F7_32: return RISCV::F7_64;
687 case RISCV::F8_32: return RISCV::F8_64;
688 case RISCV::F9_32: return RISCV::F9_64;
689 case RISCV::F10_32: return RISCV::F10_64;
690 case RISCV::F11_32: return RISCV::F11_64;
691 case RISCV::F12_32: return RISCV::F12_64;
692 case RISCV::F13_32: return RISCV::F13_64;
693 case RISCV::F14_32: return RISCV::F14_64;
694 case RISCV::F15_32: return RISCV::F15_64;
695 case RISCV::F16_32: return RISCV::F16_64;
696 case RISCV::F17_32: return RISCV::F17_64;
697 case RISCV::F18_32: return RISCV::F18_64;
698 case RISCV::F19_32: return RISCV::F19_64;
699 case RISCV::F20_32: return RISCV::F20_64;
700 case RISCV::F21_32: return RISCV::F21_64;
701 case RISCV::F22_32: return RISCV::F22_64;
702 case RISCV::F23_32: return RISCV::F23_64;
703 case RISCV::F24_32: return RISCV::F24_64;
704 case RISCV::F25_32: return RISCV::F25_64;
705 case RISCV::F26_32: return RISCV::F26_64;
706 case RISCV::F27_32: return RISCV::F27_64;
707 case RISCV::F28_32: return RISCV::F28_64;
708 case RISCV::F29_32: return RISCV::F29_64;
709 case RISCV::F30_32: return RISCV::F30_64;
710 case RISCV::F31_32: return RISCV::F31_64;
711 }
712 }
713
validateTargetOperandClass(MCParsedAsmOperand & AsmOp,unsigned Kind)714 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
715 unsigned Kind) {
716 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp);
717 if (!Op.isReg())
718 return Match_InvalidOperand;
719
720 unsigned Reg = Op.getReg();
721 bool IsRegFPR32 =
722 RISCVMCRegisterClasses[RISCV::FPR32RegClassID].contains(Reg);
723 bool IsRegFPR32C =
724 RISCVMCRegisterClasses[RISCV::FPR32CRegClassID].contains(Reg);
725
726 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
727 // register from FPR32 to FPR64 or FPR32C to FPR64C if necessary.
728 if ((IsRegFPR32 && Kind == MCK_FPR64) ||
729 (IsRegFPR32C && Kind == MCK_FPR64C)) {
730 Op.Reg.RegNum = convertFPR32ToFPR64(Reg);
731 return Match_Success;
732 }
733 return Match_InvalidOperand;
734 }
735
generateImmOutOfRangeError(OperandVector & Operands,uint64_t ErrorInfo,int64_t Lower,int64_t Upper,Twine Msg="immediate must be an integer in the range")736 bool RISCVAsmParser::generateImmOutOfRangeError(
737 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
738 Twine Msg = "immediate must be an integer in the range") {
739 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
740 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
741 }
742
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)743 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
744 OperandVector &Operands,
745 MCStreamer &Out,
746 uint64_t &ErrorInfo,
747 bool MatchingInlineAsm) {
748 MCInst Inst;
749
750 auto Result =
751 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
752 switch (Result) {
753 default:
754 break;
755 case Match_Success:
756 return processInstruction(Inst, IDLoc, Out);
757 case Match_MissingFeature:
758 return Error(IDLoc, "instruction use requires an option to be enabled");
759 case Match_MnemonicFail:
760 return Error(IDLoc, "unrecognized instruction mnemonic");
761 case Match_InvalidOperand: {
762 SMLoc ErrorLoc = IDLoc;
763 if (ErrorInfo != ~0U) {
764 if (ErrorInfo >= Operands.size())
765 return Error(ErrorLoc, "too few operands for instruction");
766
767 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
768 if (ErrorLoc == SMLoc())
769 ErrorLoc = IDLoc;
770 }
771 return Error(ErrorLoc, "invalid operand for instruction");
772 }
773 }
774
775 // Handle the case when the error message is of specific type
776 // other than the generic Match_InvalidOperand, and the
777 // corresponding operand is missing.
778 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
779 SMLoc ErrorLoc = IDLoc;
780 if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
781 return Error(ErrorLoc, "too few operands for instruction");
782 }
783
784 switch(Result) {
785 default:
786 break;
787 case Match_InvalidImmXLenLI:
788 if (isRV64()) {
789 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
790 return Error(ErrorLoc, "operand must be a constant 64-bit integer");
791 }
792 return generateImmOutOfRangeError(Operands, ErrorInfo,
793 std::numeric_limits<int32_t>::min(),
794 std::numeric_limits<uint32_t>::max());
795 case Match_InvalidUImmLog2XLen:
796 if (isRV64())
797 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
798 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
799 case Match_InvalidUImmLog2XLenNonZero:
800 if (isRV64())
801 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
802 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
803 case Match_InvalidUImm5:
804 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
805 case Match_InvalidSImm6:
806 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
807 (1 << 5) - 1);
808 case Match_InvalidSImm6NonZero:
809 return generateImmOutOfRangeError(
810 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
811 "immediate must be non-zero in the range");
812 case Match_InvalidCLUIImm:
813 return generateImmOutOfRangeError(
814 Operands, ErrorInfo, 1, (1 << 5) - 1,
815 "immediate must be in [0xfffe0, 0xfffff] or");
816 case Match_InvalidUImm7Lsb00:
817 return generateImmOutOfRangeError(
818 Operands, ErrorInfo, 0, (1 << 7) - 4,
819 "immediate must be a multiple of 4 bytes in the range");
820 case Match_InvalidUImm8Lsb00:
821 return generateImmOutOfRangeError(
822 Operands, ErrorInfo, 0, (1 << 8) - 4,
823 "immediate must be a multiple of 4 bytes in the range");
824 case Match_InvalidUImm8Lsb000:
825 return generateImmOutOfRangeError(
826 Operands, ErrorInfo, 0, (1 << 8) - 8,
827 "immediate must be a multiple of 8 bytes in the range");
828 case Match_InvalidSImm9Lsb0:
829 return generateImmOutOfRangeError(
830 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
831 "immediate must be a multiple of 2 bytes in the range");
832 case Match_InvalidUImm9Lsb000:
833 return generateImmOutOfRangeError(
834 Operands, ErrorInfo, 0, (1 << 9) - 8,
835 "immediate must be a multiple of 8 bytes in the range");
836 case Match_InvalidUImm10Lsb00NonZero:
837 return generateImmOutOfRangeError(
838 Operands, ErrorInfo, 4, (1 << 10) - 4,
839 "immediate must be a multiple of 4 bytes in the range");
840 case Match_InvalidSImm10Lsb0000NonZero:
841 return generateImmOutOfRangeError(
842 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
843 "immediate must be a multiple of 16 bytes and non-zero in the range");
844 case Match_InvalidSImm12:
845 return generateImmOutOfRangeError(
846 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
847 "operand must be a symbol with %lo/%pcrel_lo modifier or an integer in "
848 "the range");
849 case Match_InvalidSImm12Lsb0:
850 return generateImmOutOfRangeError(
851 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
852 "immediate must be a multiple of 2 bytes in the range");
853 case Match_InvalidSImm13Lsb0:
854 return generateImmOutOfRangeError(
855 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
856 "immediate must be a multiple of 2 bytes in the range");
857 case Match_InvalidUImm20LUI:
858 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1,
859 "operand must be a symbol with %hi() "
860 "modifier or an integer in the range");
861 case Match_InvalidUImm20AUIPC:
862 return generateImmOutOfRangeError(
863 Operands, ErrorInfo, 0, (1 << 20) - 1,
864 "operand must be a symbol with %pcrel_hi() modifier or an integer in "
865 "the range");
866 case Match_InvalidSImm21Lsb0JAL:
867 return generateImmOutOfRangeError(
868 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
869 "immediate must be a multiple of 2 bytes in the range");
870 case Match_InvalidCSRSystemRegister: {
871 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
872 "operand must be a valid system register "
873 "name or an integer in the range");
874 }
875 case Match_InvalidFenceArg: {
876 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
877 return Error(
878 ErrorLoc,
879 "operand must be formed of letters selected in-order from 'iorw'");
880 }
881 case Match_InvalidFRMArg: {
882 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
883 return Error(
884 ErrorLoc,
885 "operand must be a valid floating point rounding mode mnemonic");
886 }
887 case Match_InvalidBareSymbol: {
888 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
889 return Error(ErrorLoc, "operand must be a bare symbol name");
890 }
891 }
892
893 llvm_unreachable("Unknown match type detected!");
894 }
895
ParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)896 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
897 SMLoc &EndLoc) {
898 const AsmToken &Tok = getParser().getTok();
899 StartLoc = Tok.getLoc();
900 EndLoc = Tok.getEndLoc();
901 RegNo = 0;
902 StringRef Name = getLexer().getTok().getIdentifier();
903
904 if (!MatchRegisterName(Name) || !MatchRegisterAltName(Name)) {
905 getParser().Lex(); // Eat identifier token.
906 return false;
907 }
908
909 return Error(StartLoc, "invalid register name");
910 }
911
parseRegister(OperandVector & Operands,bool AllowParens)912 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands,
913 bool AllowParens) {
914 SMLoc FirstS = getLoc();
915 bool HadParens = false;
916 AsmToken Buf[2];
917
918 // If this a parenthesised register name is allowed, parse it atomically
919 if (AllowParens && getLexer().is(AsmToken::LParen)) {
920 size_t ReadCount = getLexer().peekTokens(Buf);
921 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
922 HadParens = true;
923 getParser().Lex(); // Eat '('
924 }
925 }
926
927 switch (getLexer().getKind()) {
928 default:
929 return MatchOperand_NoMatch;
930 case AsmToken::Identifier:
931 StringRef Name = getLexer().getTok().getIdentifier();
932 unsigned RegNo = MatchRegisterName(Name);
933 if (RegNo == 0) {
934 RegNo = MatchRegisterAltName(Name);
935 if (RegNo == 0) {
936 if (HadParens)
937 getLexer().UnLex(Buf[0]);
938 return MatchOperand_NoMatch;
939 }
940 }
941 if (HadParens)
942 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64()));
943 SMLoc S = getLoc();
944 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
945 getLexer().Lex();
946 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
947 }
948
949 if (HadParens) {
950 getParser().Lex(); // Eat ')'
951 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
952 }
953
954 return MatchOperand_Success;
955 }
956
957 OperandMatchResultTy
parseCSRSystemRegister(OperandVector & Operands)958 RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
959 SMLoc S = getLoc();
960 const MCExpr *Res;
961
962 switch (getLexer().getKind()) {
963 default:
964 return MatchOperand_NoMatch;
965 case AsmToken::LParen:
966 case AsmToken::Minus:
967 case AsmToken::Plus:
968 case AsmToken::Integer:
969 case AsmToken::String: {
970 if (getParser().parseExpression(Res))
971 return MatchOperand_ParseFail;
972
973 auto *CE = dyn_cast<MCConstantExpr>(Res);
974 if (CE) {
975 int64_t Imm = CE->getValue();
976 if (isUInt<12>(Imm)) {
977 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
978 // Accept an immediate representing a named or un-named Sys Reg
979 // if the range is valid, regardless of the required features.
980 Operands.push_back(RISCVOperand::createSysReg(
981 SysReg ? SysReg->Name : "", S, Imm, isRV64()));
982 return MatchOperand_Success;
983 }
984 }
985
986 Twine Msg = "immediate must be an integer in the range";
987 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
988 return MatchOperand_ParseFail;
989 }
990 case AsmToken::Identifier: {
991 StringRef Identifier;
992 if (getParser().parseIdentifier(Identifier))
993 return MatchOperand_ParseFail;
994
995 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
996 // Accept a named Sys Reg if the required features are present.
997 if (SysReg) {
998 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) {
999 Error(S, "system register use requires an option to be enabled");
1000 return MatchOperand_ParseFail;
1001 }
1002 Operands.push_back(RISCVOperand::createSysReg(
1003 Identifier, S, SysReg->Encoding, isRV64()));
1004 return MatchOperand_Success;
1005 }
1006
1007 Twine Msg = "operand must be a valid system register name "
1008 "or an integer in the range";
1009 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1010 return MatchOperand_ParseFail;
1011 }
1012 case AsmToken::Percent: {
1013 // Discard operand with modifier.
1014 Twine Msg = "immediate must be an integer in the range";
1015 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1016 return MatchOperand_ParseFail;
1017 }
1018 }
1019
1020 return MatchOperand_NoMatch;
1021 }
1022
parseImmediate(OperandVector & Operands)1023 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) {
1024 SMLoc S = getLoc();
1025 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1026 const MCExpr *Res;
1027
1028 switch (getLexer().getKind()) {
1029 default:
1030 return MatchOperand_NoMatch;
1031 case AsmToken::LParen:
1032 case AsmToken::Minus:
1033 case AsmToken::Plus:
1034 case AsmToken::Integer:
1035 case AsmToken::String:
1036 case AsmToken::Identifier:
1037 if (getParser().parseExpression(Res))
1038 return MatchOperand_ParseFail;
1039 break;
1040 case AsmToken::Percent:
1041 return parseOperandWithModifier(Operands);
1042 }
1043
1044 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1045 return MatchOperand_Success;
1046 }
1047
1048 OperandMatchResultTy
parseOperandWithModifier(OperandVector & Operands)1049 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
1050 SMLoc S = getLoc();
1051 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1052
1053 if (getLexer().getKind() != AsmToken::Percent) {
1054 Error(getLoc(), "expected '%' for operand modifier");
1055 return MatchOperand_ParseFail;
1056 }
1057
1058 getParser().Lex(); // Eat '%'
1059
1060 if (getLexer().getKind() != AsmToken::Identifier) {
1061 Error(getLoc(), "expected valid identifier for operand modifier");
1062 return MatchOperand_ParseFail;
1063 }
1064 StringRef Identifier = getParser().getTok().getIdentifier();
1065 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier);
1066 if (VK == RISCVMCExpr::VK_RISCV_Invalid) {
1067 Error(getLoc(), "unrecognized operand modifier");
1068 return MatchOperand_ParseFail;
1069 }
1070
1071 getParser().Lex(); // Eat the identifier
1072 if (getLexer().getKind() != AsmToken::LParen) {
1073 Error(getLoc(), "expected '('");
1074 return MatchOperand_ParseFail;
1075 }
1076 getParser().Lex(); // Eat '('
1077
1078 const MCExpr *SubExpr;
1079 if (getParser().parseParenExpression(SubExpr, E)) {
1080 return MatchOperand_ParseFail;
1081 }
1082
1083 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext());
1084 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
1085 return MatchOperand_Success;
1086 }
1087
parseBareSymbol(OperandVector & Operands)1088 OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) {
1089 SMLoc S = getLoc();
1090 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1091 const MCExpr *Res;
1092
1093 if (getLexer().getKind() != AsmToken::Identifier)
1094 return MatchOperand_NoMatch;
1095
1096 StringRef Identifier;
1097 if (getParser().parseIdentifier(Identifier))
1098 return MatchOperand_ParseFail;
1099
1100 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1101 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1102 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1103 return MatchOperand_Success;
1104 }
1105
parseJALOffset(OperandVector & Operands)1106 OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) {
1107 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo`
1108 // both being acceptable forms. When parsing `jal ra, foo` this function
1109 // will be called for the `ra` register operand in an attempt to match the
1110 // single-operand alias. parseJALOffset must fail for this case. It would
1111 // seem logical to try parse the operand using parseImmediate and return
1112 // NoMatch if the next token is a comma (meaning we must be parsing a jal in
1113 // the second form rather than the first). We can't do this as there's no
1114 // way of rewinding the lexer state. Instead, return NoMatch if this operand
1115 // is an identifier and is followed by a comma.
1116 if (getLexer().is(AsmToken::Identifier) &&
1117 getLexer().peekTok().is(AsmToken::Comma))
1118 return MatchOperand_NoMatch;
1119
1120 return parseImmediate(Operands);
1121 }
1122
1123 OperandMatchResultTy
parseMemOpBaseReg(OperandVector & Operands)1124 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
1125 if (getLexer().isNot(AsmToken::LParen)) {
1126 Error(getLoc(), "expected '('");
1127 return MatchOperand_ParseFail;
1128 }
1129
1130 getParser().Lex(); // Eat '('
1131 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64()));
1132
1133 if (parseRegister(Operands) != MatchOperand_Success) {
1134 Error(getLoc(), "expected register");
1135 return MatchOperand_ParseFail;
1136 }
1137
1138 if (getLexer().isNot(AsmToken::RParen)) {
1139 Error(getLoc(), "expected ')'");
1140 return MatchOperand_ParseFail;
1141 }
1142
1143 getParser().Lex(); // Eat ')'
1144 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
1145
1146 return MatchOperand_Success;
1147 }
1148
1149 /// Looks at a token type and creates the relevant operand from this
1150 /// information, adding to Operands. If operand was parsed, returns false, else
1151 /// true.
parseOperand(OperandVector & Operands,StringRef Mnemonic)1152 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1153 // Check if the current operand has a custom associated parser, if so, try to
1154 // custom parse the operand, or fallback to the general approach.
1155 OperandMatchResultTy Result =
1156 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
1157 if (Result == MatchOperand_Success)
1158 return false;
1159 if (Result == MatchOperand_ParseFail)
1160 return true;
1161
1162 // Attempt to parse token as a register.
1163 if (parseRegister(Operands, true) == MatchOperand_Success)
1164 return false;
1165
1166 // Attempt to parse token as an immediate
1167 if (parseImmediate(Operands) == MatchOperand_Success) {
1168 // Parse memory base register if present
1169 if (getLexer().is(AsmToken::LParen))
1170 return parseMemOpBaseReg(Operands) != MatchOperand_Success;
1171 return false;
1172 }
1173
1174 // Finally we have exhausted all options and must declare defeat.
1175 Error(getLoc(), "unknown operand");
1176 return true;
1177 }
1178
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)1179 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1180 StringRef Name, SMLoc NameLoc,
1181 OperandVector &Operands) {
1182 // Ensure that if the instruction occurs when relaxation is enabled,
1183 // relocations are forced for the file. Ideally this would be done when there
1184 // is enough information to reliably determine if the instruction itself may
1185 // cause relaxations. Unfortunately instruction processing stage occurs in the
1186 // same pass as relocation emission, so it's too late to set a 'sticky bit'
1187 // for the entire file.
1188 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) {
1189 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
1190 if (Assembler != nullptr) {
1191 RISCVAsmBackend &MAB =
1192 static_cast<RISCVAsmBackend &>(Assembler->getBackend());
1193 MAB.setForceRelocs();
1194 }
1195 }
1196
1197 // First operand is token for instruction
1198 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64()));
1199
1200 // If there are no more operands, then finish
1201 if (getLexer().is(AsmToken::EndOfStatement))
1202 return false;
1203
1204 // Parse first operand
1205 if (parseOperand(Operands, Name))
1206 return true;
1207
1208 // Parse until end of statement, consuming commas between operands
1209 unsigned OperandIdx = 1;
1210 while (getLexer().is(AsmToken::Comma)) {
1211 // Consume comma token
1212 getLexer().Lex();
1213
1214 // Parse next operand
1215 if (parseOperand(Operands, Name))
1216 return true;
1217
1218 ++OperandIdx;
1219 }
1220
1221 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1222 SMLoc Loc = getLexer().getLoc();
1223 getParser().eatToEndOfStatement();
1224 return Error(Loc, "unexpected token");
1225 }
1226
1227 getParser().Lex(); // Consume the EndOfStatement.
1228 return false;
1229 }
1230
classifySymbolRef(const MCExpr * Expr,RISCVMCExpr::VariantKind & Kind,int64_t & Addend)1231 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,
1232 RISCVMCExpr::VariantKind &Kind,
1233 int64_t &Addend) {
1234 Kind = RISCVMCExpr::VK_RISCV_None;
1235 Addend = 0;
1236
1237 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
1238 Kind = RE->getKind();
1239 Expr = RE->getSubExpr();
1240 }
1241
1242 // It's a simple symbol reference or constant with no addend.
1243 if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr))
1244 return true;
1245
1246 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
1247 if (!BE)
1248 return false;
1249
1250 if (!isa<MCSymbolRefExpr>(BE->getLHS()))
1251 return false;
1252
1253 if (BE->getOpcode() != MCBinaryExpr::Add &&
1254 BE->getOpcode() != MCBinaryExpr::Sub)
1255 return false;
1256
1257 // We are able to support the subtraction of two symbol references
1258 if (BE->getOpcode() == MCBinaryExpr::Sub &&
1259 isa<MCSymbolRefExpr>(BE->getRHS()))
1260 return true;
1261
1262 // See if the addend is a constant, otherwise there's more going
1263 // on here than we can deal with.
1264 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
1265 if (!AddendExpr)
1266 return false;
1267
1268 Addend = AddendExpr->getValue();
1269 if (BE->getOpcode() == MCBinaryExpr::Sub)
1270 Addend = -Addend;
1271
1272 // It's some symbol reference + a constant addend
1273 return Kind != RISCVMCExpr::VK_RISCV_Invalid;
1274 }
1275
ParseDirective(AsmToken DirectiveID)1276 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) {
1277 // This returns false if this function recognizes the directive
1278 // regardless of whether it is successfully handles or reports an
1279 // error. Otherwise it returns true to give the generic parser a
1280 // chance at recognizing it.
1281 StringRef IDVal = DirectiveID.getString();
1282
1283 if (IDVal == ".option")
1284 return parseDirectiveOption();
1285
1286 return true;
1287 }
1288
parseDirectiveOption()1289 bool RISCVAsmParser::parseDirectiveOption() {
1290 MCAsmParser &Parser = getParser();
1291 // Get the option token.
1292 AsmToken Tok = Parser.getTok();
1293 // At the moment only identifiers are supported.
1294 if (Tok.isNot(AsmToken::Identifier))
1295 return Error(Parser.getTok().getLoc(),
1296 "unexpected token, expected identifier");
1297
1298 StringRef Option = Tok.getIdentifier();
1299
1300 if (Option == "push") {
1301 getTargetStreamer().emitDirectiveOptionPush();
1302
1303 Parser.Lex();
1304 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1305 return Error(Parser.getTok().getLoc(),
1306 "unexpected token, expected end of statement");
1307
1308 pushFeatureBits();
1309 return false;
1310 }
1311
1312 if (Option == "pop") {
1313 SMLoc StartLoc = Parser.getTok().getLoc();
1314 getTargetStreamer().emitDirectiveOptionPop();
1315
1316 Parser.Lex();
1317 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1318 return Error(Parser.getTok().getLoc(),
1319 "unexpected token, expected end of statement");
1320
1321 if (popFeatureBits())
1322 return Error(StartLoc, ".option pop with no .option push");
1323
1324 return false;
1325 }
1326
1327 if (Option == "rvc") {
1328 getTargetStreamer().emitDirectiveOptionRVC();
1329
1330 Parser.Lex();
1331 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1332 return Error(Parser.getTok().getLoc(),
1333 "unexpected token, expected end of statement");
1334
1335 setFeatureBits(RISCV::FeatureStdExtC, "c");
1336 return false;
1337 }
1338
1339 if (Option == "norvc") {
1340 getTargetStreamer().emitDirectiveOptionNoRVC();
1341
1342 Parser.Lex();
1343 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1344 return Error(Parser.getTok().getLoc(),
1345 "unexpected token, expected end of statement");
1346
1347 clearFeatureBits(RISCV::FeatureStdExtC, "c");
1348 return false;
1349 }
1350
1351 if (Option == "relax") {
1352 getTargetStreamer().emitDirectiveOptionRelax();
1353
1354 Parser.Lex();
1355 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1356 return Error(Parser.getTok().getLoc(),
1357 "unexpected token, expected end of statement");
1358
1359 setFeatureBits(RISCV::FeatureRelax, "relax");
1360 return false;
1361 }
1362
1363 if (Option == "norelax") {
1364 getTargetStreamer().emitDirectiveOptionNoRelax();
1365
1366 Parser.Lex();
1367 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1368 return Error(Parser.getTok().getLoc(),
1369 "unexpected token, expected end of statement");
1370
1371 clearFeatureBits(RISCV::FeatureRelax, "relax");
1372 return false;
1373 }
1374
1375 // Unknown option.
1376 Warning(Parser.getTok().getLoc(),
1377 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or "
1378 "'norelax'");
1379 Parser.eatToEndOfStatement();
1380 return false;
1381 }
1382
emitToStreamer(MCStreamer & S,const MCInst & Inst)1383 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
1384 MCInst CInst;
1385 bool Res = compressInst(CInst, Inst, getSTI(), S.getContext());
1386 CInst.setLoc(Inst.getLoc());
1387 S.EmitInstruction((Res ? CInst : Inst), getSTI());
1388 }
1389
emitLoadImm(unsigned DestReg,int64_t Value,MCStreamer & Out)1390 void RISCVAsmParser::emitLoadImm(unsigned DestReg, int64_t Value,
1391 MCStreamer &Out) {
1392 RISCVMatInt::InstSeq Seq;
1393 RISCVMatInt::generateInstSeq(Value, isRV64(), Seq);
1394
1395 unsigned SrcReg = RISCV::X0;
1396 for (RISCVMatInt::Inst &Inst : Seq) {
1397 if (Inst.Opc == RISCV::LUI) {
1398 emitToStreamer(
1399 Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm));
1400 } else {
1401 emitToStreamer(
1402 Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm(
1403 Inst.Imm));
1404 }
1405
1406 // Only the first instruction has X0 as its source.
1407 SrcReg = DestReg;
1408 }
1409 }
1410
emitLoadLocalAddress(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)1411 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
1412 MCStreamer &Out) {
1413 // The local load address pseudo-instruction "lla" is used in PC-relative
1414 // addressing of symbols:
1415 // lla rdest, symbol
1416 // expands to
1417 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
1418 // ADDI rdest, %pcrel_lo(TmpLabel)
1419 MCContext &Ctx = getContext();
1420
1421 MCSymbol *TmpLabel = Ctx.createTempSymbol(
1422 "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false);
1423 Out.EmitLabel(TmpLabel);
1424
1425 MCOperand DestReg = Inst.getOperand(0);
1426 const RISCVMCExpr *Symbol = RISCVMCExpr::create(
1427 Inst.getOperand(1).getExpr(), RISCVMCExpr::VK_RISCV_PCREL_HI, Ctx);
1428
1429 emitToStreamer(
1430 Out, MCInstBuilder(RISCV::AUIPC).addOperand(DestReg).addExpr(Symbol));
1431
1432 const MCExpr *RefToLinkTmpLabel =
1433 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx),
1434 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx);
1435
1436 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
1437 .addOperand(DestReg)
1438 .addOperand(DestReg)
1439 .addExpr(RefToLinkTmpLabel));
1440 }
1441
processInstruction(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)1442 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1443 MCStreamer &Out) {
1444 Inst.setLoc(IDLoc);
1445
1446 if (Inst.getOpcode() == RISCV::PseudoLI) {
1447 unsigned Reg = Inst.getOperand(0).getReg();
1448 const MCOperand &Op1 = Inst.getOperand(1);
1449 if (Op1.isExpr()) {
1450 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar.
1451 // Just convert to an addi. This allows compatibility with gas.
1452 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
1453 .addReg(Reg)
1454 .addReg(RISCV::X0)
1455 .addExpr(Op1.getExpr()));
1456 return false;
1457 }
1458 int64_t Imm = Inst.getOperand(1).getImm();
1459 // On RV32 the immediate here can either be a signed or an unsigned
1460 // 32-bit number. Sign extension has to be performed to ensure that Imm
1461 // represents the expected signed 64-bit number.
1462 if (!isRV64())
1463 Imm = SignExtend64<32>(Imm);
1464 emitLoadImm(Reg, Imm, Out);
1465 return false;
1466 } else if (Inst.getOpcode() == RISCV::PseudoLLA) {
1467 emitLoadLocalAddress(Inst, IDLoc, Out);
1468 return false;
1469 }
1470
1471 emitToStreamer(Out, Inst);
1472 return false;
1473 }
1474
LLVMInitializeRISCVAsmParser()1475 extern "C" void LLVMInitializeRISCVAsmParser() {
1476 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target());
1477 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target());
1478 }
1479