blob: 2d797f3f1d6b6c71c02a9af7f6122f1f4bfceb4e [file] [log] [blame]
Alex Bradbury04f06d92017-08-08 14:43:36 +00001//===-- RISCVAsmParser.cpp - Parse RISCV assembly to MCInst instructions --===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Alex Bradbury04f06d92017-08-08 14:43:36 +00006//
7//===----------------------------------------------------------------------===//
8
Alex Bradbury9c03e4c2018-11-12 14:25:07 +00009#include "MCTargetDesc/RISCVAsmBackend.h"
Alex Bradbury9d3f1252017-09-28 08:26:24 +000010#include "MCTargetDesc/RISCVMCExpr.h"
Alex Bradbury04f06d92017-08-08 14:43:36 +000011#include "MCTargetDesc/RISCVMCTargetDesc.h"
Alex Bradburybca0c3c2018-05-11 17:30:28 +000012#include "MCTargetDesc/RISCVTargetStreamer.h"
Ana Pazos9d6c5532018-10-04 21:50:54 +000013#include "Utils/RISCVBaseInfo.h"
Alex Bradbury22c091f2018-11-15 10:11:31 +000014#include "Utils/RISCVMatInt.h"
Alex Bradbury4f7f0da2017-09-06 09:21:21 +000015#include "llvm/ADT/STLExtras.h"
Alex Bradbury893e5bc2018-11-28 16:39:14 +000016#include "llvm/ADT/SmallVector.h"
Alex Bradbury4f7f0da2017-09-06 09:21:21 +000017#include "llvm/ADT/StringSwitch.h"
Alex Bradbury9c03e4c2018-11-12 14:25:07 +000018#include "llvm/MC/MCAssembler.h"
Alex Bradbury4f7f0da2017-09-06 09:21:21 +000019#include "llvm/MC/MCContext.h"
20#include "llvm/MC/MCExpr.h"
21#include "llvm/MC/MCInst.h"
Alex Bradbury6a4b5442018-06-07 15:35:47 +000022#include "llvm/MC/MCInstBuilder.h"
Alex Bradbury22531c42019-02-15 09:53:32 +000023#include "llvm/MC/MCObjectFileInfo.h"
Alex Bradbury04f06d92017-08-08 14:43:36 +000024#include "llvm/MC/MCParser/MCAsmLexer.h"
25#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
26#include "llvm/MC/MCParser/MCTargetAsmParser.h"
Alex Bradbury04f06d92017-08-08 14:43:36 +000027#include "llvm/MC/MCRegisterInfo.h"
28#include "llvm/MC/MCStreamer.h"
29#include "llvm/MC/MCSubtargetInfo.h"
Alex Bradbury04f06d92017-08-08 14:43:36 +000030#include "llvm/Support/Casting.h"
Alex Bradbury6a4b5442018-06-07 15:35:47 +000031#include "llvm/Support/MathExtras.h"
Alex Bradbury04f06d92017-08-08 14:43:36 +000032#include "llvm/Support/TargetRegistry.h"
33
Alex Bradbury6a4b5442018-06-07 15:35:47 +000034#include <limits>
35
Alex Bradbury04f06d92017-08-08 14:43:36 +000036using namespace llvm;
37
Sameer AbuAsalc1b0e662018-04-06 21:07:05 +000038// Include the auto-generated portion of the compress emitter.
39#define GEN_COMPRESS_INSTR
40#include "RISCVGenCompressInstEmitter.inc"
41
Alex Bradbury04f06d92017-08-08 14:43:36 +000042namespace {
43struct RISCVOperand;
44
45class RISCVAsmParser : public MCTargetAsmParser {
Alex Bradbury893e5bc2018-11-28 16:39:14 +000046 SmallVector<FeatureBitset, 4> FeatureBitStack;
47
Alex Bradbury04f06d92017-08-08 14:43:36 +000048 SMLoc getLoc() const { return getParser().getTok().getLoc(); }
Alex Bradburya6e62482017-12-07 10:53:48 +000049 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
Alex Bradbury04f06d92017-08-08 14:43:36 +000050
Alex Bradburybca0c3c2018-05-11 17:30:28 +000051 RISCVTargetStreamer &getTargetStreamer() {
52 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
53 return static_cast<RISCVTargetStreamer &>(TS);
54 }
55
Alex Bradbury7bc2a952017-12-07 10:46:23 +000056 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
57 unsigned Kind) override;
58
Alex Bradbury6758ecb2017-09-17 14:27:35 +000059 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
Alex Bradbury6a4b5442018-06-07 15:35:47 +000060 int64_t Lower, int64_t Upper, Twine Msg);
Alex Bradbury6758ecb2017-09-17 14:27:35 +000061
Alex Bradbury04f06d92017-08-08 14:43:36 +000062 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
Alex Bradbury6a4b5442018-06-07 15:35:47 +000074 // 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
Alex Bradbury22531c42019-02-15 09:53:32 +000082 // Helper to emit a combination of AUIPC and SecondOpcode. Used to implement
83 // helpers such as emitLoadLocalAddress and emitLoadAddress.
84 void emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
85 const MCExpr *Symbol, RISCVMCExpr::VariantKind VKHi,
86 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
87
Roger Ferrer Ibanez577a97e2018-08-09 07:08:20 +000088 // Helper to emit pseudo instruction "lla" used in PC-rel addressing.
89 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
90
Alex Bradbury22531c42019-02-15 09:53:32 +000091 // Helper to emit pseudo instruction "la" used in GOT/PC-rel addressing.
92 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
93
Alex Bradbury6a4b5442018-06-07 15:35:47 +000094 /// Helper for processing MC instructions that have been successfully matched
95 /// by MatchAndEmitInstruction. Modifications to the emitted instructions,
96 /// like the expansion of pseudo instructions (e.g., "li"), can be performed
97 /// in this method.
98 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
99
Alex Bradbury04f06d92017-08-08 14:43:36 +0000100// Auto-generated instruction matching functions
101#define GET_ASSEMBLER_HEADER
102#include "RISCVGenAsmMatcher.inc"
103
Ana Pazos9d6c5532018-10-04 21:50:54 +0000104 OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000105 OperandMatchResultTy parseImmediate(OperandVector &Operands);
Alex Bradbury8c345c52017-11-09 15:00:03 +0000106 OperandMatchResultTy parseRegister(OperandVector &Operands,
107 bool AllowParens = false);
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000108 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000109 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
Alex Bradbury68f73c12018-09-18 15:18:16 +0000110 OperandMatchResultTy parseBareSymbol(OperandVector &Operands);
Alex Bradbury226f3ef2018-09-20 08:10:35 +0000111 OperandMatchResultTy parseJALOffset(OperandVector &Operands);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000112
Alex Bradbury68f73c12018-09-18 15:18:16 +0000113 bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000114
Alex Bradburybca0c3c2018-05-11 17:30:28 +0000115 bool parseDirectiveOption();
116
117 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
118 if (!(getSTI().getFeatureBits()[Feature])) {
119 MCSubtargetInfo &STI = copySTI();
120 setAvailableFeatures(
121 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
122 }
123 }
124
125 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
126 if (getSTI().getFeatureBits()[Feature]) {
127 MCSubtargetInfo &STI = copySTI();
128 setAvailableFeatures(
129 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
130 }
131 }
Ana Pazos9d6c5532018-10-04 21:50:54 +0000132
Alex Bradbury893e5bc2018-11-28 16:39:14 +0000133 void pushFeatureBits() {
134 FeatureBitStack.push_back(getSTI().getFeatureBits());
135 }
136
137 bool popFeatureBits() {
138 if (FeatureBitStack.empty())
139 return true;
140
141 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
142 copySTI().setFeatureBits(FeatureBits);
143 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
144
145 return false;
146 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000147public:
148 enum RISCVMatchResultTy {
149 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
150#define GET_OPERAND_DIAGNOSTIC_TYPES
151#include "RISCVGenAsmMatcher.inc"
152#undef GET_OPERAND_DIAGNOSTIC_TYPES
153 };
154
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000155 static bool classifySymbolRef(const MCExpr *Expr,
156 RISCVMCExpr::VariantKind &Kind,
157 int64_t &Addend);
158
Alex Bradbury04f06d92017-08-08 14:43:36 +0000159 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
160 const MCInstrInfo &MII, const MCTargetOptions &Options)
Oliver Stannard4191b9e2017-10-11 09:17:43 +0000161 : MCTargetAsmParser(Options, STI, MII) {
Alex Bradburycea6db02018-05-17 05:58:08 +0000162 Parser.addAliasForDirective(".half", ".2byte");
163 Parser.addAliasForDirective(".hword", ".2byte");
164 Parser.addAliasForDirective(".word", ".4byte");
165 Parser.addAliasForDirective(".dword", ".8byte");
Alex Bradbury04f06d92017-08-08 14:43:36 +0000166 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
167 }
168};
169
170/// RISCVOperand - Instances of this class represent a parsed machine
171/// instruction
172struct RISCVOperand : public MCParsedAsmOperand {
173
174 enum KindTy {
175 Token,
176 Register,
177 Immediate,
Ana Pazos9d6c5532018-10-04 21:50:54 +0000178 SystemRegister
Alex Bradbury04f06d92017-08-08 14:43:36 +0000179 } Kind;
180
Alex Bradburya6e62482017-12-07 10:53:48 +0000181 bool IsRV64;
182
Alex Bradbury04f06d92017-08-08 14:43:36 +0000183 struct RegOp {
184 unsigned RegNum;
185 };
186
187 struct ImmOp {
188 const MCExpr *Val;
189 };
190
Ana Pazos9d6c5532018-10-04 21:50:54 +0000191 struct SysRegOp {
192 const char *Data;
193 unsigned Length;
194 unsigned Encoding;
195 // FIXME: Add the Encoding parsed fields as needed for checks,
196 // e.g.: read/write or user/supervisor/machine privileges.
197 };
198
Alex Bradbury04f06d92017-08-08 14:43:36 +0000199 SMLoc StartLoc, EndLoc;
200 union {
201 StringRef Tok;
202 RegOp Reg;
203 ImmOp Imm;
Ana Pazos9d6c5532018-10-04 21:50:54 +0000204 struct SysRegOp SysReg;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000205 };
206
207 RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
208
209public:
210 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() {
211 Kind = o.Kind;
Alex Bradburya6e62482017-12-07 10:53:48 +0000212 IsRV64 = o.IsRV64;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000213 StartLoc = o.StartLoc;
214 EndLoc = o.EndLoc;
215 switch (Kind) {
216 case Register:
217 Reg = o.Reg;
218 break;
219 case Immediate:
220 Imm = o.Imm;
221 break;
222 case Token:
223 Tok = o.Tok;
224 break;
Ana Pazos9d6c5532018-10-04 21:50:54 +0000225 case SystemRegister:
226 SysReg = o.SysReg;
227 break;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000228 }
229 }
230
231 bool isToken() const override { return Kind == Token; }
232 bool isReg() const override { return Kind == Register; }
233 bool isImm() const override { return Kind == Immediate; }
234 bool isMem() const override { return false; }
Ana Pazos9d6c5532018-10-04 21:50:54 +0000235 bool isSystemRegister() const { return Kind == SystemRegister; }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000236
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000237 static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
238 RISCVMCExpr::VariantKind &VK) {
239 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000240 VK = RE->getKind();
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000241 return RE->evaluateAsConstant(Imm);
242 }
243
244 if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000245 VK = RISCVMCExpr::VK_RISCV_None;
246 Imm = CE->getValue();
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000247 return true;
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000248 }
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000249
250 return false;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000251 }
252
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000253 // True if operand is a symbol with no modifiers, or a constant with no
254 // modifiers and isShiftedInt<N-1, 1>(Op).
255 template <int N> bool isBareSimmNLsb0() const {
256 int64_t Imm;
257 RISCVMCExpr::VariantKind VK;
Alex Bradbury3c941e72017-10-19 16:22:51 +0000258 if (!isImm())
259 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000260 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000261 bool IsValid;
262 if (!IsConstantImm)
263 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
264 else
265 IsValid = isShiftedInt<N - 1, 1>(Imm);
266 return IsValid && VK == RISCVMCExpr::VK_RISCV_None;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000267 }
268
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000269 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td
270
Shiva Chen98f93892018-04-25 14:18:55 +0000271 bool isBareSymbol() const {
272 int64_t Imm;
273 RISCVMCExpr::VariantKind VK;
274 // Must be of 'immediate' type but not a constant.
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000275 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
Shiva Chen98f93892018-04-25 14:18:55 +0000276 return false;
277 return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
278 VK == RISCVMCExpr::VK_RISCV_None;
279 }
280
Ana Pazos9d6c5532018-10-04 21:50:54 +0000281 bool isCSRSystemRegister() const { return isSystemRegister(); }
282
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000283 /// Return true if the operand is a valid for the fence instruction e.g.
284 /// ('iorw').
285 bool isFenceArg() const {
286 if (!isImm())
287 return false;
288 const MCExpr *Val = getImm();
289 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
290 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
291 return false;
292
293 StringRef Str = SVal->getSymbol().getName();
294 // Letters must be unique, taken from 'iorw', and in ascending order. This
295 // holds as long as each individual character is one of 'iorw' and is
296 // greater than the previous character.
297 char Prev = '\0';
298 for (char c : Str) {
299 if (c != 'i' && c != 'o' && c != 'r' && c != 'w')
300 return false;
301 if (c <= Prev)
302 return false;
303 Prev = c;
304 }
305 return true;
306 }
307
Alex Bradbury0d6cf902017-12-07 10:26:05 +0000308 /// Return true if the operand is a valid floating point rounding mode.
309 bool isFRMArg() const {
310 if (!isImm())
311 return false;
312 const MCExpr *Val = getImm();
313 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
314 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
315 return false;
316
317 StringRef Str = SVal->getSymbol().getName();
318
319 return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid;
320 }
321
Alex Bradbury2ba76be2019-01-03 14:41:41 +0000322 bool isImmXLenLI() const {
Alex Bradbury6a4b5442018-06-07 15:35:47 +0000323 int64_t Imm;
324 RISCVMCExpr::VariantKind VK;
325 if (!isImm())
326 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000327 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury2ba76be2019-01-03 14:41:41 +0000328 if (VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO)
329 return true;
Alex Bradbury6a4b5442018-06-07 15:35:47 +0000330 // Given only Imm, ensuring that the actually specified constant is either
331 // a signed or unsigned 64-bit number is unfortunately impossible.
332 bool IsInRange = isRV64() ? true : isInt<32>(Imm) || isUInt<32>(Imm);
333 return IsConstantImm && IsInRange && VK == RISCVMCExpr::VK_RISCV_None;
334 }
335
Alex Bradburya6e62482017-12-07 10:53:48 +0000336 bool isUImmLog2XLen() const {
337 int64_t Imm;
338 RISCVMCExpr::VariantKind VK;
339 if (!isImm())
340 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000341 if (!evaluateConstantImm(getImm(), Imm, VK) ||
342 VK != RISCVMCExpr::VK_RISCV_None)
Alex Bradburya6e62482017-12-07 10:53:48 +0000343 return false;
344 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
345 }
346
Alex Bradbury0ad4c262017-12-15 10:20:51 +0000347 bool isUImmLog2XLenNonZero() const {
348 int64_t Imm;
349 RISCVMCExpr::VariantKind VK;
350 if (!isImm())
351 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000352 if (!evaluateConstantImm(getImm(), Imm, VK) ||
353 VK != RISCVMCExpr::VK_RISCV_None)
Alex Bradbury0ad4c262017-12-15 10:20:51 +0000354 return false;
355 if (Imm == 0)
356 return false;
357 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
358 }
359
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000360 bool isUImm5() const {
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000361 int64_t Imm;
362 RISCVMCExpr::VariantKind VK;
Alex Bradbury3c941e72017-10-19 16:22:51 +0000363 if (!isImm())
364 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000365 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000366 return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000367 }
368
Alex Bradbury60714f92017-12-13 09:32:55 +0000369 bool isUImm5NonZero() const {
370 int64_t Imm;
371 RISCVMCExpr::VariantKind VK;
372 if (!isImm())
373 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000374 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury60714f92017-12-13 09:32:55 +0000375 return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) &&
376 VK == RISCVMCExpr::VK_RISCV_None;
377 }
378
Alex Bradbury581d6b02017-12-13 09:41:21 +0000379 bool isSImm6() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000380 if (!isImm())
381 return false;
Alex Bradbury581d6b02017-12-13 09:41:21 +0000382 RISCVMCExpr::VariantKind VK;
383 int64_t Imm;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000384 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Ana Pazos065b0882018-09-13 18:37:23 +0000385 return IsConstantImm && isInt<6>(Imm) &&
386 VK == RISCVMCExpr::VK_RISCV_None;
Alex Bradbury581d6b02017-12-13 09:41:21 +0000387 }
388
Shiva Chenb22c1d22018-02-02 02:43:23 +0000389 bool isSImm6NonZero() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000390 if (!isImm())
391 return false;
Shiva Chenb22c1d22018-02-02 02:43:23 +0000392 RISCVMCExpr::VariantKind VK;
393 int64_t Imm;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000394 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Ana Pazos065b0882018-09-13 18:37:23 +0000395 return IsConstantImm && isInt<6>(Imm) && (Imm != 0) &&
396 VK == RISCVMCExpr::VK_RISCV_None;
Shiva Chenb22c1d22018-02-02 02:43:23 +0000397 }
398
Shiva Chen7c172422018-02-22 15:02:28 +0000399 bool isCLUIImm() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000400 if (!isImm())
401 return false;
Alex Bradbury60714f92017-12-13 09:32:55 +0000402 int64_t Imm;
403 RISCVMCExpr::VariantKind VK;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000404 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Shiva Chen7c172422018-02-22 15:02:28 +0000405 return IsConstantImm && (Imm != 0) &&
406 (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) &&
Ana Pazos9d6c5532018-10-04 21:50:54 +0000407 VK == RISCVMCExpr::VK_RISCV_None;
Alex Bradbury60714f92017-12-13 09:32:55 +0000408 }
409
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000410 bool isUImm7Lsb00() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000411 if (!isImm())
412 return false;
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000413 int64_t Imm;
414 RISCVMCExpr::VariantKind VK;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000415 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000416 return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
417 VK == RISCVMCExpr::VK_RISCV_None;
418 }
419
420 bool isUImm8Lsb00() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000421 if (!isImm())
422 return false;
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000423 int64_t Imm;
424 RISCVMCExpr::VariantKind VK;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000425 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000426 return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
427 VK == RISCVMCExpr::VK_RISCV_None;
428 }
429
430 bool isUImm8Lsb000() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000431 if (!isImm())
432 return false;
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000433 int64_t Imm;
434 RISCVMCExpr::VariantKind VK;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000435 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000436 return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
437 VK == RISCVMCExpr::VK_RISCV_None;
438 }
439
Alex Bradburyf8f4b902017-12-07 13:19:57 +0000440 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); }
441
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000442 bool isUImm9Lsb000() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000443 if (!isImm())
444 return false;
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000445 int64_t Imm;
446 RISCVMCExpr::VariantKind VK;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000447 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000448 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
449 VK == RISCVMCExpr::VK_RISCV_None;
450 }
451
Alex Bradbury60714f92017-12-13 09:32:55 +0000452 bool isUImm10Lsb00NonZero() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000453 if (!isImm())
454 return false;
Alex Bradbury60714f92017-12-13 09:32:55 +0000455 int64_t Imm;
456 RISCVMCExpr::VariantKind VK;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000457 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury60714f92017-12-13 09:32:55 +0000458 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) &&
459 VK == RISCVMCExpr::VK_RISCV_None;
460 }
461
Alex Bradbury04f06d92017-08-08 14:43:36 +0000462 bool isSImm12() const {
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000463 RISCVMCExpr::VariantKind VK;
464 int64_t Imm;
465 bool IsValid;
Alex Bradbury3c941e72017-10-19 16:22:51 +0000466 if (!isImm())
467 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000468 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000469 if (!IsConstantImm)
470 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
471 else
472 IsValid = isInt<12>(Imm);
Alex Bradbury7d0e18d2018-09-18 15:13:29 +0000473 return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) ||
Ahmed Charles646ab872018-02-06 00:55:23 +0000474 VK == RISCVMCExpr::VK_RISCV_LO ||
475 VK == RISCVMCExpr::VK_RISCV_PCREL_LO);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000476 }
477
Alex Bradburyf8f4b902017-12-07 13:19:57 +0000478 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); }
479
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000480 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000481
Shiva Chenb22c1d22018-02-02 02:43:23 +0000482 bool isSImm10Lsb0000NonZero() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000483 if (!isImm())
484 return false;
Alex Bradbury60714f92017-12-13 09:32:55 +0000485 int64_t Imm;
486 RISCVMCExpr::VariantKind VK;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000487 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Shiva Chenb22c1d22018-02-02 02:43:23 +0000488 return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) &&
Alex Bradbury60714f92017-12-13 09:32:55 +0000489 VK == RISCVMCExpr::VK_RISCV_None;
490 }
491
Alex Bradbury74340f12018-09-18 15:08:35 +0000492 bool isUImm20LUI() const {
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000493 RISCVMCExpr::VariantKind VK;
494 int64_t Imm;
495 bool IsValid;
Alex Bradbury3c941e72017-10-19 16:22:51 +0000496 if (!isImm())
497 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000498 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury74340f12018-09-18 15:08:35 +0000499 if (!IsConstantImm) {
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000500 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
Alex Bradbury74340f12018-09-18 15:08:35 +0000501 return IsValid && VK == RISCVMCExpr::VK_RISCV_HI;
502 } else {
503 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
504 VK == RISCVMCExpr::VK_RISCV_HI);
505 }
506 }
507
508 bool isUImm20AUIPC() const {
509 RISCVMCExpr::VariantKind VK;
510 int64_t Imm;
511 bool IsValid;
512 if (!isImm())
513 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000514 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury74340f12018-09-18 15:08:35 +0000515 if (!IsConstantImm) {
516 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
Alex Bradbury8eb87e52019-02-15 09:43:46 +0000517 return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
518 VK == RISCVMCExpr::VK_RISCV_GOT_HI);
Alex Bradbury74340f12018-09-18 15:08:35 +0000519 } else {
520 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
Alex Bradbury8eb87e52019-02-15 09:43:46 +0000521 VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
522 VK == RISCVMCExpr::VK_RISCV_GOT_HI);
Alex Bradbury74340f12018-09-18 15:08:35 +0000523 }
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000524 }
525
Alex Bradbury226f3ef2018-09-20 08:10:35 +0000526 bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); }
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000527
Alex Bradbury04f06d92017-08-08 14:43:36 +0000528 /// getStartLoc - Gets location of the first token of this operand
529 SMLoc getStartLoc() const override { return StartLoc; }
530 /// getEndLoc - Gets location of the last token of this operand
531 SMLoc getEndLoc() const override { return EndLoc; }
Alex Bradburya6e62482017-12-07 10:53:48 +0000532 /// True if this operand is for an RV64 instruction
533 bool isRV64() const { return IsRV64; }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000534
535 unsigned getReg() const override {
536 assert(Kind == Register && "Invalid type access!");
537 return Reg.RegNum;
538 }
539
Ana Pazos9d6c5532018-10-04 21:50:54 +0000540 StringRef getSysReg() const {
541 assert(Kind == SystemRegister && "Invalid access!");
542 return StringRef(SysReg.Data, SysReg.Length);
543 }
544
Alex Bradbury04f06d92017-08-08 14:43:36 +0000545 const MCExpr *getImm() const {
546 assert(Kind == Immediate && "Invalid type access!");
547 return Imm.Val;
548 }
549
550 StringRef getToken() const {
551 assert(Kind == Token && "Invalid type access!");
552 return Tok;
553 }
554
555 void print(raw_ostream &OS) const override {
556 switch (Kind) {
557 case Immediate:
558 OS << *getImm();
559 break;
560 case Register:
561 OS << "<register x";
562 OS << getReg() << ">";
563 break;
564 case Token:
565 OS << "'" << getToken() << "'";
566 break;
Ana Pazos9d6c5532018-10-04 21:50:54 +0000567 case SystemRegister:
568 OS << "<sysreg: " << getSysReg() << '>';
569 break;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000570 }
571 }
572
Alex Bradburya6e62482017-12-07 10:53:48 +0000573 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S,
574 bool IsRV64) {
Alex Bradbury04f06d92017-08-08 14:43:36 +0000575 auto Op = make_unique<RISCVOperand>(Token);
576 Op->Tok = Str;
577 Op->StartLoc = S;
578 Op->EndLoc = S;
Alex Bradburya6e62482017-12-07 10:53:48 +0000579 Op->IsRV64 = IsRV64;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000580 return Op;
581 }
582
583 static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
Alex Bradburya6e62482017-12-07 10:53:48 +0000584 SMLoc E, bool IsRV64) {
Alex Bradbury04f06d92017-08-08 14:43:36 +0000585 auto Op = make_unique<RISCVOperand>(Register);
586 Op->Reg.RegNum = RegNo;
587 Op->StartLoc = S;
588 Op->EndLoc = E;
Alex Bradburya6e62482017-12-07 10:53:48 +0000589 Op->IsRV64 = IsRV64;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000590 return Op;
591 }
592
593 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S,
Alex Bradburya6e62482017-12-07 10:53:48 +0000594 SMLoc E, bool IsRV64) {
Alex Bradbury04f06d92017-08-08 14:43:36 +0000595 auto Op = make_unique<RISCVOperand>(Immediate);
596 Op->Imm.Val = Val;
597 Op->StartLoc = S;
598 Op->EndLoc = E;
Alex Bradburya6e62482017-12-07 10:53:48 +0000599 Op->IsRV64 = IsRV64;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000600 return Op;
601 }
602
Ana Pazos9d6c5532018-10-04 21:50:54 +0000603 static std::unique_ptr<RISCVOperand>
604 createSysReg(StringRef Str, SMLoc S, unsigned Encoding, bool IsRV64) {
605 auto Op = make_unique<RISCVOperand>(SystemRegister);
606 Op->SysReg.Data = Str.data();
607 Op->SysReg.Length = Str.size();
608 Op->SysReg.Encoding = Encoding;
609 Op->StartLoc = S;
610 Op->IsRV64 = IsRV64;
611 return Op;
612 }
613
Alex Bradbury04f06d92017-08-08 14:43:36 +0000614 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
615 assert(Expr && "Expr shouldn't be null!");
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000616 int64_t Imm = 0;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000617 RISCVMCExpr::VariantKind VK;
618 bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000619
620 if (IsConstant)
621 Inst.addOperand(MCOperand::createImm(Imm));
Alex Bradbury04f06d92017-08-08 14:43:36 +0000622 else
623 Inst.addOperand(MCOperand::createExpr(Expr));
624 }
625
626 // Used by the TableGen Code
627 void addRegOperands(MCInst &Inst, unsigned N) const {
628 assert(N == 1 && "Invalid number of operands!");
629 Inst.addOperand(MCOperand::createReg(getReg()));
630 }
631
632 void addImmOperands(MCInst &Inst, unsigned N) const {
633 assert(N == 1 && "Invalid number of operands!");
634 addExpr(Inst, getImm());
635 }
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000636
637 void addFenceArgOperands(MCInst &Inst, unsigned N) const {
638 assert(N == 1 && "Invalid number of operands!");
639 // isFenceArg has validated the operand, meaning this cast is safe
640 auto SE = cast<MCSymbolRefExpr>(getImm());
641
642 unsigned Imm = 0;
643 for (char c : SE->getSymbol().getName()) {
644 switch (c) {
Ana Pazos9d6c5532018-10-04 21:50:54 +0000645 default:
646 llvm_unreachable("FenceArg must contain only [iorw]");
647 case 'i': Imm |= RISCVFenceField::I; break;
648 case 'o': Imm |= RISCVFenceField::O; break;
649 case 'r': Imm |= RISCVFenceField::R; break;
650 case 'w': Imm |= RISCVFenceField::W; break;
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000651 }
652 }
653 Inst.addOperand(MCOperand::createImm(Imm));
654 }
Alex Bradbury0d6cf902017-12-07 10:26:05 +0000655
Ana Pazos9d6c5532018-10-04 21:50:54 +0000656 void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
657 assert(N == 1 && "Invalid number of operands!");
658 Inst.addOperand(MCOperand::createImm(SysReg.Encoding));
659 }
660
Alex Bradbury0d6cf902017-12-07 10:26:05 +0000661 // Returns the rounding mode represented by this RISCVOperand. Should only
662 // be called after checking isFRMArg.
663 RISCVFPRndMode::RoundingMode getRoundingMode() const {
664 // isFRMArg has validated the operand, meaning this cast is safe.
665 auto SE = cast<MCSymbolRefExpr>(getImm());
666 RISCVFPRndMode::RoundingMode FRM =
667 RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName());
668 assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode");
669 return FRM;
670 }
671
672 void addFRMArgOperands(MCInst &Inst, unsigned N) const {
673 assert(N == 1 && "Invalid number of operands!");
674 Inst.addOperand(MCOperand::createImm(getRoundingMode()));
675 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000676};
677} // end anonymous namespace.
678
679#define GET_REGISTER_MATCHER
680#define GET_MATCHER_IMPLEMENTATION
Alex Bradbury04f06d92017-08-08 14:43:36 +0000681#include "RISCVGenAsmMatcher.inc"
682
Alex Bradbury7bc2a952017-12-07 10:46:23 +0000683// Return the matching FPR64 register for the given FPR32.
684// FIXME: Ideally this function could be removed in favour of using
685// information from TableGen.
686unsigned convertFPR32ToFPR64(unsigned Reg) {
687 switch (Reg) {
Ana Pazos9d6c5532018-10-04 21:50:54 +0000688 default:
689 llvm_unreachable("Not a recognised FPR32 register");
690 case RISCV::F0_32: return RISCV::F0_64;
691 case RISCV::F1_32: return RISCV::F1_64;
692 case RISCV::F2_32: return RISCV::F2_64;
693 case RISCV::F3_32: return RISCV::F3_64;
694 case RISCV::F4_32: return RISCV::F4_64;
695 case RISCV::F5_32: return RISCV::F5_64;
696 case RISCV::F6_32: return RISCV::F6_64;
697 case RISCV::F7_32: return RISCV::F7_64;
698 case RISCV::F8_32: return RISCV::F8_64;
699 case RISCV::F9_32: return RISCV::F9_64;
700 case RISCV::F10_32: return RISCV::F10_64;
701 case RISCV::F11_32: return RISCV::F11_64;
702 case RISCV::F12_32: return RISCV::F12_64;
703 case RISCV::F13_32: return RISCV::F13_64;
704 case RISCV::F14_32: return RISCV::F14_64;
705 case RISCV::F15_32: return RISCV::F15_64;
706 case RISCV::F16_32: return RISCV::F16_64;
707 case RISCV::F17_32: return RISCV::F17_64;
708 case RISCV::F18_32: return RISCV::F18_64;
709 case RISCV::F19_32: return RISCV::F19_64;
710 case RISCV::F20_32: return RISCV::F20_64;
711 case RISCV::F21_32: return RISCV::F21_64;
712 case RISCV::F22_32: return RISCV::F22_64;
713 case RISCV::F23_32: return RISCV::F23_64;
714 case RISCV::F24_32: return RISCV::F24_64;
715 case RISCV::F25_32: return RISCV::F25_64;
716 case RISCV::F26_32: return RISCV::F26_64;
717 case RISCV::F27_32: return RISCV::F27_64;
718 case RISCV::F28_32: return RISCV::F28_64;
719 case RISCV::F29_32: return RISCV::F29_64;
720 case RISCV::F30_32: return RISCV::F30_64;
721 case RISCV::F31_32: return RISCV::F31_64;
Alex Bradbury7bc2a952017-12-07 10:46:23 +0000722 }
723}
724
725unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
726 unsigned Kind) {
727 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp);
728 if (!Op.isReg())
729 return Match_InvalidOperand;
730
731 unsigned Reg = Op.getReg();
732 bool IsRegFPR32 =
733 RISCVMCRegisterClasses[RISCV::FPR32RegClassID].contains(Reg);
Alex Bradbury60714f92017-12-13 09:32:55 +0000734 bool IsRegFPR32C =
735 RISCVMCRegisterClasses[RISCV::FPR32CRegClassID].contains(Reg);
Alex Bradbury7bc2a952017-12-07 10:46:23 +0000736
737 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
Alex Bradbury60714f92017-12-13 09:32:55 +0000738 // register from FPR32 to FPR64 or FPR32C to FPR64C if necessary.
739 if ((IsRegFPR32 && Kind == MCK_FPR64) ||
740 (IsRegFPR32C && Kind == MCK_FPR64C)) {
Alex Bradbury7bc2a952017-12-07 10:46:23 +0000741 Op.Reg.RegNum = convertFPR32ToFPR64(Reg);
742 return Match_Success;
743 }
744 return Match_InvalidOperand;
745}
746
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000747bool RISCVAsmParser::generateImmOutOfRangeError(
Alex Bradbury6a4b5442018-06-07 15:35:47 +0000748 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000749 Twine Msg = "immediate must be an integer in the range") {
750 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
751 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
752}
753
Alex Bradbury04f06d92017-08-08 14:43:36 +0000754bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
755 OperandVector &Operands,
756 MCStreamer &Out,
757 uint64_t &ErrorInfo,
758 bool MatchingInlineAsm) {
759 MCInst Inst;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000760
Ana Pazos6b34051b2018-08-30 19:43:19 +0000761 auto Result =
762 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
763 switch (Result) {
Alex Bradbury04f06d92017-08-08 14:43:36 +0000764 default:
765 break;
Alex Bradbury6a4b5442018-06-07 15:35:47 +0000766 case Match_Success:
767 return processInstruction(Inst, IDLoc, Out);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000768 case Match_MissingFeature:
769 return Error(IDLoc, "instruction use requires an option to be enabled");
770 case Match_MnemonicFail:
771 return Error(IDLoc, "unrecognized instruction mnemonic");
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000772 case Match_InvalidOperand: {
773 SMLoc ErrorLoc = IDLoc;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000774 if (ErrorInfo != ~0U) {
775 if (ErrorInfo >= Operands.size())
776 return Error(ErrorLoc, "too few operands for instruction");
777
778 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
779 if (ErrorLoc == SMLoc())
780 ErrorLoc = IDLoc;
781 }
782 return Error(ErrorLoc, "invalid operand for instruction");
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000783 }
Ana Pazos6b34051b2018-08-30 19:43:19 +0000784 }
785
786 // Handle the case when the error message is of specific type
787 // other than the generic Match_InvalidOperand, and the
788 // corresponding operand is missing.
789 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
790 SMLoc ErrorLoc = IDLoc;
791 if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
792 return Error(ErrorLoc, "too few operands for instruction");
793 }
794
795 switch(Result) {
796 default:
797 break;
Alex Bradbury2ba76be2019-01-03 14:41:41 +0000798 case Match_InvalidImmXLenLI:
Alex Bradbury6a4b5442018-06-07 15:35:47 +0000799 if (isRV64()) {
800 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
801 return Error(ErrorLoc, "operand must be a constant 64-bit integer");
802 }
803 return generateImmOutOfRangeError(Operands, ErrorInfo,
804 std::numeric_limits<int32_t>::min(),
805 std::numeric_limits<uint32_t>::max());
Alex Bradburya6e62482017-12-07 10:53:48 +0000806 case Match_InvalidUImmLog2XLen:
807 if (isRV64())
808 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
809 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
Alex Bradbury0ad4c262017-12-15 10:20:51 +0000810 case Match_InvalidUImmLog2XLenNonZero:
811 if (isRV64())
812 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
813 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000814 case Match_InvalidUImm5:
815 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
Alex Bradbury581d6b02017-12-13 09:41:21 +0000816 case Match_InvalidSImm6:
817 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
818 (1 << 5) - 1);
Shiva Chenb22c1d22018-02-02 02:43:23 +0000819 case Match_InvalidSImm6NonZero:
Ana Pazos9d6c5532018-10-04 21:50:54 +0000820 return generateImmOutOfRangeError(
821 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
Shiva Chenb22c1d22018-02-02 02:43:23 +0000822 "immediate must be non-zero in the range");
Shiva Chen7c172422018-02-22 15:02:28 +0000823 case Match_InvalidCLUIImm:
824 return generateImmOutOfRangeError(
825 Operands, ErrorInfo, 1, (1 << 5) - 1,
826 "immediate must be in [0xfffe0, 0xfffff] or");
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000827 case Match_InvalidUImm7Lsb00:
828 return generateImmOutOfRangeError(
829 Operands, ErrorInfo, 0, (1 << 7) - 4,
830 "immediate must be a multiple of 4 bytes in the range");
831 case Match_InvalidUImm8Lsb00:
832 return generateImmOutOfRangeError(
833 Operands, ErrorInfo, 0, (1 << 8) - 4,
834 "immediate must be a multiple of 4 bytes in the range");
835 case Match_InvalidUImm8Lsb000:
836 return generateImmOutOfRangeError(
837 Operands, ErrorInfo, 0, (1 << 8) - 8,
838 "immediate must be a multiple of 8 bytes in the range");
Alex Bradburyf8f4b902017-12-07 13:19:57 +0000839 case Match_InvalidSImm9Lsb0:
840 return generateImmOutOfRangeError(
841 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
842 "immediate must be a multiple of 2 bytes in the range");
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000843 case Match_InvalidUImm9Lsb000:
844 return generateImmOutOfRangeError(
845 Operands, ErrorInfo, 0, (1 << 9) - 8,
846 "immediate must be a multiple of 8 bytes in the range");
Alex Bradbury60714f92017-12-13 09:32:55 +0000847 case Match_InvalidUImm10Lsb00NonZero:
848 return generateImmOutOfRangeError(
849 Operands, ErrorInfo, 4, (1 << 10) - 4,
850 "immediate must be a multiple of 4 bytes in the range");
Shiva Chenb22c1d22018-02-02 02:43:23 +0000851 case Match_InvalidSImm10Lsb0000NonZero:
Alex Bradbury60714f92017-12-13 09:32:55 +0000852 return generateImmOutOfRangeError(
853 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
Shiva Chenb22c1d22018-02-02 02:43:23 +0000854 "immediate must be a multiple of 16 bytes and non-zero in the range");
Alex Bradbury04f06d92017-08-08 14:43:36 +0000855 case Match_InvalidSImm12:
Alex Bradbury7d0e18d2018-09-18 15:13:29 +0000856 return generateImmOutOfRangeError(
857 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
858 "operand must be a symbol with %lo/%pcrel_lo modifier or an integer in "
859 "the range");
Alex Bradburyf8f4b902017-12-07 13:19:57 +0000860 case Match_InvalidSImm12Lsb0:
861 return generateImmOutOfRangeError(
862 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
863 "immediate must be a multiple of 2 bytes in the range");
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000864 case Match_InvalidSImm13Lsb0:
865 return generateImmOutOfRangeError(
866 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
867 "immediate must be a multiple of 2 bytes in the range");
Alex Bradbury74340f12018-09-18 15:08:35 +0000868 case Match_InvalidUImm20LUI:
869 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1,
870 "operand must be a symbol with %hi() "
871 "modifier or an integer in the range");
872 case Match_InvalidUImm20AUIPC:
873 return generateImmOutOfRangeError(
874 Operands, ErrorInfo, 0, (1 << 20) - 1,
Alex Bradbury8eb87e52019-02-15 09:43:46 +0000875 "operand must be a symbol with a %pcrel_hi/%got_pcrel_hi modifier "
876 "or an integer in the range");
Alex Bradbury226f3ef2018-09-20 08:10:35 +0000877 case Match_InvalidSImm21Lsb0JAL:
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000878 return generateImmOutOfRangeError(
879 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
880 "immediate must be a multiple of 2 bytes in the range");
Ana Pazos9d6c5532018-10-04 21:50:54 +0000881 case Match_InvalidCSRSystemRegister: {
882 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
883 "operand must be a valid system register "
884 "name or an integer in the range");
885 }
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000886 case Match_InvalidFenceArg: {
Alex Bradbury04f06d92017-08-08 14:43:36 +0000887 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000888 return Error(
889 ErrorLoc,
890 "operand must be formed of letters selected in-order from 'iorw'");
891 }
Alex Bradbury0d6cf902017-12-07 10:26:05 +0000892 case Match_InvalidFRMArg: {
893 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
894 return Error(
895 ErrorLoc,
896 "operand must be a valid floating point rounding mode mnemonic");
897 }
Shiva Chen98f93892018-04-25 14:18:55 +0000898 case Match_InvalidBareSymbol: {
899 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
900 return Error(ErrorLoc, "operand must be a bare symbol name");
901 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000902 }
903
904 llvm_unreachable("Unknown match type detected!");
905}
906
907bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
908 SMLoc &EndLoc) {
909 const AsmToken &Tok = getParser().getTok();
910 StartLoc = Tok.getLoc();
911 EndLoc = Tok.getEndLoc();
912 RegNo = 0;
913 StringRef Name = getLexer().getTok().getIdentifier();
914
915 if (!MatchRegisterName(Name) || !MatchRegisterAltName(Name)) {
916 getParser().Lex(); // Eat identifier token.
917 return false;
918 }
919
920 return Error(StartLoc, "invalid register name");
921}
922
Alex Bradbury8c345c52017-11-09 15:00:03 +0000923OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands,
924 bool AllowParens) {
925 SMLoc FirstS = getLoc();
926 bool HadParens = false;
927 AsmToken Buf[2];
928
929 // If this a parenthesised register name is allowed, parse it atomically
930 if (AllowParens && getLexer().is(AsmToken::LParen)) {
931 size_t ReadCount = getLexer().peekTokens(Buf);
932 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
933 HadParens = true;
934 getParser().Lex(); // Eat '('
935 }
936 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000937
938 switch (getLexer().getKind()) {
939 default:
940 return MatchOperand_NoMatch;
941 case AsmToken::Identifier:
942 StringRef Name = getLexer().getTok().getIdentifier();
943 unsigned RegNo = MatchRegisterName(Name);
944 if (RegNo == 0) {
945 RegNo = MatchRegisterAltName(Name);
Alex Bradbury8c345c52017-11-09 15:00:03 +0000946 if (RegNo == 0) {
947 if (HadParens)
948 getLexer().UnLex(Buf[0]);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000949 return MatchOperand_NoMatch;
Alex Bradbury8c345c52017-11-09 15:00:03 +0000950 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000951 }
Alex Bradbury8c345c52017-11-09 15:00:03 +0000952 if (HadParens)
Alex Bradburya6e62482017-12-07 10:53:48 +0000953 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64()));
Alex Bradbury8c345c52017-11-09 15:00:03 +0000954 SMLoc S = getLoc();
955 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000956 getLexer().Lex();
Alex Bradburya6e62482017-12-07 10:53:48 +0000957 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
Alex Bradbury04f06d92017-08-08 14:43:36 +0000958 }
Alex Bradbury8c345c52017-11-09 15:00:03 +0000959
960 if (HadParens) {
961 getParser().Lex(); // Eat ')'
Alex Bradburya6e62482017-12-07 10:53:48 +0000962 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
Alex Bradbury8c345c52017-11-09 15:00:03 +0000963 }
964
Alex Bradbury04f06d92017-08-08 14:43:36 +0000965 return MatchOperand_Success;
966}
967
Ana Pazos9d6c5532018-10-04 21:50:54 +0000968OperandMatchResultTy
969RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
970 SMLoc S = getLoc();
971 const MCExpr *Res;
972
973 switch (getLexer().getKind()) {
974 default:
975 return MatchOperand_NoMatch;
976 case AsmToken::LParen:
977 case AsmToken::Minus:
978 case AsmToken::Plus:
979 case AsmToken::Integer:
980 case AsmToken::String: {
981 if (getParser().parseExpression(Res))
982 return MatchOperand_ParseFail;
983
984 auto *CE = dyn_cast<MCConstantExpr>(Res);
985 if (CE) {
986 int64_t Imm = CE->getValue();
987 if (isUInt<12>(Imm)) {
988 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
989 // Accept an immediate representing a named or un-named Sys Reg
990 // if the range is valid, regardless of the required features.
991 Operands.push_back(RISCVOperand::createSysReg(
992 SysReg ? SysReg->Name : "", S, Imm, isRV64()));
993 return MatchOperand_Success;
994 }
995 }
996
997 Twine Msg = "immediate must be an integer in the range";
998 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
999 return MatchOperand_ParseFail;
1000 }
1001 case AsmToken::Identifier: {
1002 StringRef Identifier;
1003 if (getParser().parseIdentifier(Identifier))
1004 return MatchOperand_ParseFail;
1005
1006 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1007 // Accept a named Sys Reg if the required features are present.
1008 if (SysReg) {
1009 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) {
1010 Error(S, "system register use requires an option to be enabled");
1011 return MatchOperand_ParseFail;
1012 }
1013 Operands.push_back(RISCVOperand::createSysReg(
1014 Identifier, S, SysReg->Encoding, isRV64()));
1015 return MatchOperand_Success;
1016 }
1017
1018 Twine Msg = "operand must be a valid system register name "
1019 "or an integer in the range";
1020 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1021 return MatchOperand_ParseFail;
1022 }
1023 case AsmToken::Percent: {
1024 // Discard operand with modifier.
1025 Twine Msg = "immediate must be an integer in the range";
1026 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1027 return MatchOperand_ParseFail;
1028 }
1029 }
1030
1031 return MatchOperand_NoMatch;
1032}
1033
Alex Bradbury04f06d92017-08-08 14:43:36 +00001034OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) {
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001035 SMLoc S = getLoc();
1036 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1037 const MCExpr *Res;
1038
Alex Bradbury04f06d92017-08-08 14:43:36 +00001039 switch (getLexer().getKind()) {
1040 default:
1041 return MatchOperand_NoMatch;
1042 case AsmToken::LParen:
1043 case AsmToken::Minus:
1044 case AsmToken::Plus:
1045 case AsmToken::Integer:
1046 case AsmToken::String:
Alex Bradbury6f302b82019-01-10 15:33:17 +00001047 case AsmToken::Identifier:
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001048 if (getParser().parseExpression(Res))
1049 return MatchOperand_ParseFail;
1050 break;
Alex Bradbury9d3f1252017-09-28 08:26:24 +00001051 case AsmToken::Percent:
1052 return parseOperandWithModifier(Operands);
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001053 }
Alex Bradbury04f06d92017-08-08 14:43:36 +00001054
Alex Bradburya6e62482017-12-07 10:53:48 +00001055 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
Alex Bradbury9d3f1252017-09-28 08:26:24 +00001056 return MatchOperand_Success;
1057}
1058
1059OperandMatchResultTy
1060RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
1061 SMLoc S = getLoc();
1062 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1063
1064 if (getLexer().getKind() != AsmToken::Percent) {
1065 Error(getLoc(), "expected '%' for operand modifier");
1066 return MatchOperand_ParseFail;
1067 }
1068
1069 getParser().Lex(); // Eat '%'
1070
1071 if (getLexer().getKind() != AsmToken::Identifier) {
1072 Error(getLoc(), "expected valid identifier for operand modifier");
1073 return MatchOperand_ParseFail;
1074 }
1075 StringRef Identifier = getParser().getTok().getIdentifier();
1076 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier);
1077 if (VK == RISCVMCExpr::VK_RISCV_Invalid) {
1078 Error(getLoc(), "unrecognized operand modifier");
1079 return MatchOperand_ParseFail;
1080 }
1081
1082 getParser().Lex(); // Eat the identifier
1083 if (getLexer().getKind() != AsmToken::LParen) {
1084 Error(getLoc(), "expected '('");
1085 return MatchOperand_ParseFail;
1086 }
1087 getParser().Lex(); // Eat '('
1088
1089 const MCExpr *SubExpr;
1090 if (getParser().parseParenExpression(SubExpr, E)) {
1091 return MatchOperand_ParseFail;
1092 }
1093
1094 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext());
Alex Bradburya6e62482017-12-07 10:53:48 +00001095 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001096 return MatchOperand_Success;
1097}
1098
Alex Bradbury68f73c12018-09-18 15:18:16 +00001099OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) {
1100 SMLoc S = getLoc();
1101 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1102 const MCExpr *Res;
1103
1104 if (getLexer().getKind() != AsmToken::Identifier)
1105 return MatchOperand_NoMatch;
1106
1107 StringRef Identifier;
1108 if (getParser().parseIdentifier(Identifier))
1109 return MatchOperand_ParseFail;
1110
1111 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1112 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1113 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1114 return MatchOperand_Success;
1115}
1116
Alex Bradbury226f3ef2018-09-20 08:10:35 +00001117OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) {
1118 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo`
1119 // both being acceptable forms. When parsing `jal ra, foo` this function
1120 // will be called for the `ra` register operand in an attempt to match the
1121 // single-operand alias. parseJALOffset must fail for this case. It would
1122 // seem logical to try parse the operand using parseImmediate and return
1123 // NoMatch if the next token is a comma (meaning we must be parsing a jal in
1124 // the second form rather than the first). We can't do this as there's no
1125 // way of rewinding the lexer state. Instead, return NoMatch if this operand
1126 // is an identifier and is followed by a comma.
1127 if (getLexer().is(AsmToken::Identifier) &&
1128 getLexer().peekTok().is(AsmToken::Comma))
1129 return MatchOperand_NoMatch;
1130
1131 return parseImmediate(Operands);
1132}
1133
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001134OperandMatchResultTy
1135RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
1136 if (getLexer().isNot(AsmToken::LParen)) {
1137 Error(getLoc(), "expected '('");
Alex Bradbury04f06d92017-08-08 14:43:36 +00001138 return MatchOperand_ParseFail;
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001139 }
Alex Bradbury04f06d92017-08-08 14:43:36 +00001140
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001141 getParser().Lex(); // Eat '('
Alex Bradburya6e62482017-12-07 10:53:48 +00001142 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64()));
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001143
1144 if (parseRegister(Operands) != MatchOperand_Success) {
1145 Error(getLoc(), "expected register");
1146 return MatchOperand_ParseFail;
1147 }
1148
1149 if (getLexer().isNot(AsmToken::RParen)) {
1150 Error(getLoc(), "expected ')'");
1151 return MatchOperand_ParseFail;
1152 }
1153
1154 getParser().Lex(); // Eat ')'
Alex Bradburya6e62482017-12-07 10:53:48 +00001155 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001156
Alex Bradbury04f06d92017-08-08 14:43:36 +00001157 return MatchOperand_Success;
1158}
1159
Alex Bradburycd8688a2018-04-25 17:25:29 +00001160/// Looks at a token type and creates the relevant operand from this
1161/// information, adding to Operands. If operand was parsed, returns false, else
Alex Bradbury68f73c12018-09-18 15:18:16 +00001162/// true.
1163bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1164 // Check if the current operand has a custom associated parser, if so, try to
1165 // custom parse the operand, or fallback to the general approach.
1166 OperandMatchResultTy Result =
1167 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
1168 if (Result == MatchOperand_Success)
1169 return false;
1170 if (Result == MatchOperand_ParseFail)
1171 return true;
1172
1173 // Attempt to parse token as a register.
1174 if (parseRegister(Operands, true) == MatchOperand_Success)
Alex Bradbury04f06d92017-08-08 14:43:36 +00001175 return false;
1176
1177 // Attempt to parse token as an immediate
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001178 if (parseImmediate(Operands) == MatchOperand_Success) {
1179 // Parse memory base register if present
1180 if (getLexer().is(AsmToken::LParen))
1181 return parseMemOpBaseReg(Operands) != MatchOperand_Success;
Alex Bradbury04f06d92017-08-08 14:43:36 +00001182 return false;
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001183 }
Alex Bradbury04f06d92017-08-08 14:43:36 +00001184
1185 // Finally we have exhausted all options and must declare defeat.
1186 Error(getLoc(), "unknown operand");
1187 return true;
1188}
1189
1190bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1191 StringRef Name, SMLoc NameLoc,
1192 OperandVector &Operands) {
Alex Bradbury9c03e4c2018-11-12 14:25:07 +00001193 // Ensure that if the instruction occurs when relaxation is enabled,
1194 // relocations are forced for the file. Ideally this would be done when there
1195 // is enough information to reliably determine if the instruction itself may
1196 // cause relaxations. Unfortunately instruction processing stage occurs in the
1197 // same pass as relocation emission, so it's too late to set a 'sticky bit'
1198 // for the entire file.
1199 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) {
1200 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
1201 if (Assembler != nullptr) {
1202 RISCVAsmBackend &MAB =
1203 static_cast<RISCVAsmBackend &>(Assembler->getBackend());
1204 MAB.setForceRelocs();
1205 }
1206 }
1207
Alex Bradbury04f06d92017-08-08 14:43:36 +00001208 // First operand is token for instruction
Alex Bradburya6e62482017-12-07 10:53:48 +00001209 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64()));
Alex Bradbury04f06d92017-08-08 14:43:36 +00001210
1211 // If there are no more operands, then finish
1212 if (getLexer().is(AsmToken::EndOfStatement))
1213 return false;
1214
1215 // Parse first operand
Alex Bradbury68f73c12018-09-18 15:18:16 +00001216 if (parseOperand(Operands, Name))
Alex Bradbury04f06d92017-08-08 14:43:36 +00001217 return true;
1218
1219 // Parse until end of statement, consuming commas between operands
Roger Ferrer Ibanez577a97e2018-08-09 07:08:20 +00001220 unsigned OperandIdx = 1;
Alex Bradbury04f06d92017-08-08 14:43:36 +00001221 while (getLexer().is(AsmToken::Comma)) {
1222 // Consume comma token
1223 getLexer().Lex();
1224
1225 // Parse next operand
Alex Bradbury68f73c12018-09-18 15:18:16 +00001226 if (parseOperand(Operands, Name))
Alex Bradbury04f06d92017-08-08 14:43:36 +00001227 return true;
Roger Ferrer Ibanez577a97e2018-08-09 07:08:20 +00001228
1229 ++OperandIdx;
Alex Bradbury04f06d92017-08-08 14:43:36 +00001230 }
1231
1232 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1233 SMLoc Loc = getLexer().getLoc();
1234 getParser().eatToEndOfStatement();
1235 return Error(Loc, "unexpected token");
1236 }
1237
1238 getParser().Lex(); // Consume the EndOfStatement.
1239 return false;
1240}
1241
Alex Bradbury9d3f1252017-09-28 08:26:24 +00001242bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,
1243 RISCVMCExpr::VariantKind &Kind,
1244 int64_t &Addend) {
1245 Kind = RISCVMCExpr::VK_RISCV_None;
1246 Addend = 0;
1247
1248 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
1249 Kind = RE->getKind();
1250 Expr = RE->getSubExpr();
1251 }
1252
1253 // It's a simple symbol reference or constant with no addend.
1254 if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr))
1255 return true;
1256
1257 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
1258 if (!BE)
1259 return false;
1260
1261 if (!isa<MCSymbolRefExpr>(BE->getLHS()))
1262 return false;
1263
1264 if (BE->getOpcode() != MCBinaryExpr::Add &&
1265 BE->getOpcode() != MCBinaryExpr::Sub)
1266 return false;
1267
1268 // We are able to support the subtraction of two symbol references
1269 if (BE->getOpcode() == MCBinaryExpr::Sub &&
1270 isa<MCSymbolRefExpr>(BE->getRHS()))
1271 return true;
1272
Hiroshi Inoue9ff23802018-04-09 04:37:53 +00001273 // See if the addend is a constant, otherwise there's more going
Alex Bradbury9d3f1252017-09-28 08:26:24 +00001274 // on here than we can deal with.
1275 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
1276 if (!AddendExpr)
1277 return false;
1278
1279 Addend = AddendExpr->getValue();
1280 if (BE->getOpcode() == MCBinaryExpr::Sub)
1281 Addend = -Addend;
1282
1283 // It's some symbol reference + a constant addend
1284 return Kind != RISCVMCExpr::VK_RISCV_Invalid;
1285}
1286
Alex Bradburybca0c3c2018-05-11 17:30:28 +00001287bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) {
1288 // This returns false if this function recognizes the directive
1289 // regardless of whether it is successfully handles or reports an
1290 // error. Otherwise it returns true to give the generic parser a
1291 // chance at recognizing it.
1292 StringRef IDVal = DirectiveID.getString();
1293
1294 if (IDVal == ".option")
1295 return parseDirectiveOption();
1296
1297 return true;
1298}
1299
1300bool RISCVAsmParser::parseDirectiveOption() {
1301 MCAsmParser &Parser = getParser();
1302 // Get the option token.
1303 AsmToken Tok = Parser.getTok();
1304 // At the moment only identifiers are supported.
1305 if (Tok.isNot(AsmToken::Identifier))
1306 return Error(Parser.getTok().getLoc(),
1307 "unexpected token, expected identifier");
1308
1309 StringRef Option = Tok.getIdentifier();
1310
Alex Bradbury893e5bc2018-11-28 16:39:14 +00001311 if (Option == "push") {
1312 getTargetStreamer().emitDirectiveOptionPush();
1313
1314 Parser.Lex();
1315 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1316 return Error(Parser.getTok().getLoc(),
1317 "unexpected token, expected end of statement");
1318
1319 pushFeatureBits();
1320 return false;
1321 }
1322
1323 if (Option == "pop") {
1324 SMLoc StartLoc = Parser.getTok().getLoc();
1325 getTargetStreamer().emitDirectiveOptionPop();
1326
1327 Parser.Lex();
1328 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1329 return Error(Parser.getTok().getLoc(),
1330 "unexpected token, expected end of statement");
1331
1332 if (popFeatureBits())
1333 return Error(StartLoc, ".option pop with no .option push");
1334
1335 return false;
1336 }
1337
Alex Bradburybca0c3c2018-05-11 17:30:28 +00001338 if (Option == "rvc") {
1339 getTargetStreamer().emitDirectiveOptionRVC();
1340
1341 Parser.Lex();
1342 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1343 return Error(Parser.getTok().getLoc(),
1344 "unexpected token, expected end of statement");
1345
1346 setFeatureBits(RISCV::FeatureStdExtC, "c");
1347 return false;
1348 }
1349
1350 if (Option == "norvc") {
1351 getTargetStreamer().emitDirectiveOptionNoRVC();
1352
1353 Parser.Lex();
1354 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1355 return Error(Parser.getTok().getLoc(),
1356 "unexpected token, expected end of statement");
1357
1358 clearFeatureBits(RISCV::FeatureStdExtC, "c");
1359 return false;
1360 }
1361
Alex Bradbury9c03e4c2018-11-12 14:25:07 +00001362 if (Option == "relax") {
1363 getTargetStreamer().emitDirectiveOptionRelax();
1364
1365 Parser.Lex();
1366 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1367 return Error(Parser.getTok().getLoc(),
1368 "unexpected token, expected end of statement");
1369
1370 setFeatureBits(RISCV::FeatureRelax, "relax");
1371 return false;
1372 }
1373
1374 if (Option == "norelax") {
1375 getTargetStreamer().emitDirectiveOptionNoRelax();
1376
1377 Parser.Lex();
1378 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1379 return Error(Parser.getTok().getLoc(),
1380 "unexpected token, expected end of statement");
1381
1382 clearFeatureBits(RISCV::FeatureRelax, "relax");
1383 return false;
1384 }
1385
Alex Bradburybca0c3c2018-05-11 17:30:28 +00001386 // Unknown option.
1387 Warning(Parser.getTok().getLoc(),
Alex Bradbury893e5bc2018-11-28 16:39:14 +00001388 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or "
1389 "'norelax'");
Alex Bradburybca0c3c2018-05-11 17:30:28 +00001390 Parser.eatToEndOfStatement();
1391 return false;
1392}
Alex Bradbury04f06d92017-08-08 14:43:36 +00001393
Alex Bradbury6a4b5442018-06-07 15:35:47 +00001394void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
1395 MCInst CInst;
1396 bool Res = compressInst(CInst, Inst, getSTI(), S.getContext());
1397 CInst.setLoc(Inst.getLoc());
1398 S.EmitInstruction((Res ? CInst : Inst), getSTI());
1399}
1400
1401void RISCVAsmParser::emitLoadImm(unsigned DestReg, int64_t Value,
1402 MCStreamer &Out) {
Alex Bradbury22c091f2018-11-15 10:11:31 +00001403 RISCVMatInt::InstSeq Seq;
1404 RISCVMatInt::generateInstSeq(Value, isRV64(), Seq);
Alex Bradbury6a4b5442018-06-07 15:35:47 +00001405
Alex Bradbury22c091f2018-11-15 10:11:31 +00001406 unsigned SrcReg = RISCV::X0;
1407 for (RISCVMatInt::Inst &Inst : Seq) {
1408 if (Inst.Opc == RISCV::LUI) {
1409 emitToStreamer(
1410 Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm));
1411 } else {
1412 emitToStreamer(
1413 Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm(
1414 Inst.Imm));
Alex Bradbury6a4b5442018-06-07 15:35:47 +00001415 }
1416
Alex Bradbury22c091f2018-11-15 10:11:31 +00001417 // Only the first instruction has X0 as its source.
1418 SrcReg = DestReg;
Alex Bradbury6a4b5442018-06-07 15:35:47 +00001419 }
Alex Bradbury6a4b5442018-06-07 15:35:47 +00001420}
1421
Alex Bradbury22531c42019-02-15 09:53:32 +00001422void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
1423 const MCExpr *Symbol,
1424 RISCVMCExpr::VariantKind VKHi,
1425 unsigned SecondOpcode, SMLoc IDLoc,
1426 MCStreamer &Out) {
1427 // A pair of instructions for PC-relative addressing; expands to
1428 // TmpLabel: AUIPC TmpReg, VKHi(symbol)
1429 // OP DestReg, TmpReg, %pcrel_lo(TmpLabel)
Roger Ferrer Ibanez577a97e2018-08-09 07:08:20 +00001430 MCContext &Ctx = getContext();
1431
1432 MCSymbol *TmpLabel = Ctx.createTempSymbol(
1433 "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false);
1434 Out.EmitLabel(TmpLabel);
1435
Alex Bradbury22531c42019-02-15 09:53:32 +00001436 const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx);
Roger Ferrer Ibanezc8f4dbb2018-08-14 08:30:42 +00001437 emitToStreamer(
Alex Bradbury22531c42019-02-15 09:53:32 +00001438 Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi));
Roger Ferrer Ibanez577a97e2018-08-09 07:08:20 +00001439
1440 const MCExpr *RefToLinkTmpLabel =
1441 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx),
1442 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx);
1443
Alex Bradbury22531c42019-02-15 09:53:32 +00001444 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
Roger Ferrer Ibanezc8f4dbb2018-08-14 08:30:42 +00001445 .addOperand(DestReg)
Alex Bradbury22531c42019-02-15 09:53:32 +00001446 .addOperand(TmpReg)
Roger Ferrer Ibanezc8f4dbb2018-08-14 08:30:42 +00001447 .addExpr(RefToLinkTmpLabel));
Roger Ferrer Ibanez577a97e2018-08-09 07:08:20 +00001448}
1449
Alex Bradbury22531c42019-02-15 09:53:32 +00001450void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
1451 MCStreamer &Out) {
1452 // The load local address pseudo-instruction "lla" is used in PC-relative
1453 // addressing of local symbols:
1454 // lla rdest, symbol
1455 // expands to
1456 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
1457 // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
1458 MCOperand DestReg = Inst.getOperand(0);
1459 const MCExpr *Symbol = Inst.getOperand(1).getExpr();
1460 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
1461 RISCV::ADDI, IDLoc, Out);
1462}
1463
1464void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
1465 MCStreamer &Out) {
1466 // The load address pseudo-instruction "la" is used in PC-relative and
1467 // GOT-indirect addressing of global symbols:
1468 // la rdest, symbol
1469 // expands to either (for non-PIC)
1470 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
1471 // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
1472 // or (for PIC)
1473 // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol)
1474 // Lx rdest, %pcrel_lo(TmpLabel)(rdest)
1475 MCOperand DestReg = Inst.getOperand(0);
1476 const MCExpr *Symbol = Inst.getOperand(1).getExpr();
1477 unsigned SecondOpcode;
1478 RISCVMCExpr::VariantKind VKHi;
1479 // FIXME: Should check .option (no)pic when implemented
1480 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1481 SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
1482 VKHi = RISCVMCExpr::VK_RISCV_GOT_HI;
1483 } else {
1484 SecondOpcode = RISCV::ADDI;
1485 VKHi = RISCVMCExpr::VK_RISCV_PCREL_HI;
1486 }
1487 emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out);
1488}
1489
Alex Bradbury6a4b5442018-06-07 15:35:47 +00001490bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1491 MCStreamer &Out) {
1492 Inst.setLoc(IDLoc);
1493
Alex Bradbury22531c42019-02-15 09:53:32 +00001494 switch (Inst.getOpcode()) {
1495 default:
1496 break;
1497 case RISCV::PseudoLI: {
Alex Bradbury2ba76be2019-01-03 14:41:41 +00001498 unsigned Reg = Inst.getOperand(0).getReg();
1499 const MCOperand &Op1 = Inst.getOperand(1);
1500 if (Op1.isExpr()) {
1501 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar.
1502 // Just convert to an addi. This allows compatibility with gas.
1503 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
1504 .addReg(Reg)
1505 .addReg(RISCV::X0)
1506 .addExpr(Op1.getExpr()));
1507 return false;
1508 }
Alex Bradbury6a4b5442018-06-07 15:35:47 +00001509 int64_t Imm = Inst.getOperand(1).getImm();
1510 // On RV32 the immediate here can either be a signed or an unsigned
1511 // 32-bit number. Sign extension has to be performed to ensure that Imm
1512 // represents the expected signed 64-bit number.
1513 if (!isRV64())
1514 Imm = SignExtend64<32>(Imm);
1515 emitLoadImm(Reg, Imm, Out);
1516 return false;
Alex Bradbury22531c42019-02-15 09:53:32 +00001517 }
1518 case RISCV::PseudoLLA:
Roger Ferrer Ibanez577a97e2018-08-09 07:08:20 +00001519 emitLoadLocalAddress(Inst, IDLoc, Out);
1520 return false;
Alex Bradbury22531c42019-02-15 09:53:32 +00001521 case RISCV::PseudoLA:
1522 emitLoadAddress(Inst, IDLoc, Out);
1523 return false;
Alex Bradbury6a4b5442018-06-07 15:35:47 +00001524 }
1525
1526 emitToStreamer(Out, Inst);
1527 return false;
1528}
1529
Alex Bradbury04f06d92017-08-08 14:43:36 +00001530extern "C" void LLVMInitializeRISCVAsmParser() {
1531 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target());
1532 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target());
1533}