blob: 99ad876add314f190218c9c4b95729e04403f190 [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
Kito Cheng303217e2019-02-20 03:31:32 +000094 // Helper to emit pseudo load/store instruction with a symbol.
95 void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,
96 MCStreamer &Out, bool HasTmpReg);
97
Alex Bradbury6a4b5442018-06-07 15:35:47 +000098 /// Helper for processing MC instructions that have been successfully matched
99 /// by MatchAndEmitInstruction. Modifications to the emitted instructions,
100 /// like the expansion of pseudo instructions (e.g., "li"), can be performed
101 /// in this method.
102 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
103
Alex Bradbury04f06d92017-08-08 14:43:36 +0000104// Auto-generated instruction matching functions
105#define GET_ASSEMBLER_HEADER
106#include "RISCVGenAsmMatcher.inc"
107
Ana Pazos9d6c5532018-10-04 21:50:54 +0000108 OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000109 OperandMatchResultTy parseImmediate(OperandVector &Operands);
Alex Bradbury8c345c52017-11-09 15:00:03 +0000110 OperandMatchResultTy parseRegister(OperandVector &Operands,
111 bool AllowParens = false);
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000112 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000113 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
Alex Bradbury68f73c12018-09-18 15:18:16 +0000114 OperandMatchResultTy parseBareSymbol(OperandVector &Operands);
Alex Bradbury226f3ef2018-09-20 08:10:35 +0000115 OperandMatchResultTy parseJALOffset(OperandVector &Operands);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000116
Alex Bradbury68f73c12018-09-18 15:18:16 +0000117 bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000118
Alex Bradburybca0c3c2018-05-11 17:30:28 +0000119 bool parseDirectiveOption();
120
121 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
122 if (!(getSTI().getFeatureBits()[Feature])) {
123 MCSubtargetInfo &STI = copySTI();
124 setAvailableFeatures(
125 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
126 }
127 }
128
129 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
130 if (getSTI().getFeatureBits()[Feature]) {
131 MCSubtargetInfo &STI = copySTI();
132 setAvailableFeatures(
133 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
134 }
135 }
Ana Pazos9d6c5532018-10-04 21:50:54 +0000136
Alex Bradbury893e5bc2018-11-28 16:39:14 +0000137 void pushFeatureBits() {
138 FeatureBitStack.push_back(getSTI().getFeatureBits());
139 }
140
141 bool popFeatureBits() {
142 if (FeatureBitStack.empty())
143 return true;
144
145 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
146 copySTI().setFeatureBits(FeatureBits);
147 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
148
149 return false;
150 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000151public:
152 enum RISCVMatchResultTy {
153 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
154#define GET_OPERAND_DIAGNOSTIC_TYPES
155#include "RISCVGenAsmMatcher.inc"
156#undef GET_OPERAND_DIAGNOSTIC_TYPES
157 };
158
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000159 static bool classifySymbolRef(const MCExpr *Expr,
160 RISCVMCExpr::VariantKind &Kind,
161 int64_t &Addend);
162
Alex Bradbury04f06d92017-08-08 14:43:36 +0000163 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
164 const MCInstrInfo &MII, const MCTargetOptions &Options)
Oliver Stannard4191b9e2017-10-11 09:17:43 +0000165 : MCTargetAsmParser(Options, STI, MII) {
Alex Bradburycea6db02018-05-17 05:58:08 +0000166 Parser.addAliasForDirective(".half", ".2byte");
167 Parser.addAliasForDirective(".hword", ".2byte");
168 Parser.addAliasForDirective(".word", ".4byte");
169 Parser.addAliasForDirective(".dword", ".8byte");
Alex Bradbury04f06d92017-08-08 14:43:36 +0000170 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
171 }
172};
173
174/// RISCVOperand - Instances of this class represent a parsed machine
175/// instruction
176struct RISCVOperand : public MCParsedAsmOperand {
177
178 enum KindTy {
179 Token,
180 Register,
181 Immediate,
Ana Pazos9d6c5532018-10-04 21:50:54 +0000182 SystemRegister
Alex Bradbury04f06d92017-08-08 14:43:36 +0000183 } Kind;
184
Alex Bradburya6e62482017-12-07 10:53:48 +0000185 bool IsRV64;
186
Alex Bradbury04f06d92017-08-08 14:43:36 +0000187 struct RegOp {
188 unsigned RegNum;
189 };
190
191 struct ImmOp {
192 const MCExpr *Val;
193 };
194
Ana Pazos9d6c5532018-10-04 21:50:54 +0000195 struct SysRegOp {
196 const char *Data;
197 unsigned Length;
198 unsigned Encoding;
199 // FIXME: Add the Encoding parsed fields as needed for checks,
200 // e.g.: read/write or user/supervisor/machine privileges.
201 };
202
Alex Bradbury04f06d92017-08-08 14:43:36 +0000203 SMLoc StartLoc, EndLoc;
204 union {
205 StringRef Tok;
206 RegOp Reg;
207 ImmOp Imm;
Ana Pazos9d6c5532018-10-04 21:50:54 +0000208 struct SysRegOp SysReg;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000209 };
210
211 RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
212
213public:
214 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() {
215 Kind = o.Kind;
Alex Bradburya6e62482017-12-07 10:53:48 +0000216 IsRV64 = o.IsRV64;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000217 StartLoc = o.StartLoc;
218 EndLoc = o.EndLoc;
219 switch (Kind) {
220 case Register:
221 Reg = o.Reg;
222 break;
223 case Immediate:
224 Imm = o.Imm;
225 break;
226 case Token:
227 Tok = o.Tok;
228 break;
Ana Pazos9d6c5532018-10-04 21:50:54 +0000229 case SystemRegister:
230 SysReg = o.SysReg;
231 break;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000232 }
233 }
234
235 bool isToken() const override { return Kind == Token; }
236 bool isReg() const override { return Kind == Register; }
237 bool isImm() const override { return Kind == Immediate; }
238 bool isMem() const override { return false; }
Ana Pazos9d6c5532018-10-04 21:50:54 +0000239 bool isSystemRegister() const { return Kind == SystemRegister; }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000240
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000241 static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
242 RISCVMCExpr::VariantKind &VK) {
243 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000244 VK = RE->getKind();
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000245 return RE->evaluateAsConstant(Imm);
246 }
247
248 if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000249 VK = RISCVMCExpr::VK_RISCV_None;
250 Imm = CE->getValue();
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000251 return true;
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000252 }
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000253
254 return false;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000255 }
256
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000257 // True if operand is a symbol with no modifiers, or a constant with no
258 // modifiers and isShiftedInt<N-1, 1>(Op).
259 template <int N> bool isBareSimmNLsb0() const {
260 int64_t Imm;
261 RISCVMCExpr::VariantKind VK;
Alex Bradbury3c941e72017-10-19 16:22:51 +0000262 if (!isImm())
263 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000264 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000265 bool IsValid;
266 if (!IsConstantImm)
267 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
268 else
269 IsValid = isShiftedInt<N - 1, 1>(Imm);
270 return IsValid && VK == RISCVMCExpr::VK_RISCV_None;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000271 }
272
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000273 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td
274
Shiva Chen98f93892018-04-25 14:18:55 +0000275 bool isBareSymbol() const {
276 int64_t Imm;
277 RISCVMCExpr::VariantKind VK;
278 // Must be of 'immediate' type but not a constant.
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000279 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
Shiva Chen98f93892018-04-25 14:18:55 +0000280 return false;
281 return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) &&
282 VK == RISCVMCExpr::VK_RISCV_None;
283 }
284
Ana Pazos9d6c5532018-10-04 21:50:54 +0000285 bool isCSRSystemRegister() const { return isSystemRegister(); }
286
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000287 /// Return true if the operand is a valid for the fence instruction e.g.
288 /// ('iorw').
289 bool isFenceArg() const {
290 if (!isImm())
291 return false;
292 const MCExpr *Val = getImm();
293 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
294 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
295 return false;
296
297 StringRef Str = SVal->getSymbol().getName();
298 // Letters must be unique, taken from 'iorw', and in ascending order. This
299 // holds as long as each individual character is one of 'iorw' and is
300 // greater than the previous character.
301 char Prev = '\0';
302 for (char c : Str) {
303 if (c != 'i' && c != 'o' && c != 'r' && c != 'w')
304 return false;
305 if (c <= Prev)
306 return false;
307 Prev = c;
308 }
309 return true;
310 }
311
Alex Bradbury0d6cf902017-12-07 10:26:05 +0000312 /// Return true if the operand is a valid floating point rounding mode.
313 bool isFRMArg() const {
314 if (!isImm())
315 return false;
316 const MCExpr *Val = getImm();
317 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
318 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
319 return false;
320
321 StringRef Str = SVal->getSymbol().getName();
322
323 return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid;
324 }
325
Alex Bradbury2ba76be2019-01-03 14:41:41 +0000326 bool isImmXLenLI() const {
Alex Bradbury6a4b5442018-06-07 15:35:47 +0000327 int64_t Imm;
328 RISCVMCExpr::VariantKind VK;
329 if (!isImm())
330 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000331 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury2ba76be2019-01-03 14:41:41 +0000332 if (VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO)
333 return true;
Alex Bradbury6a4b5442018-06-07 15:35:47 +0000334 // Given only Imm, ensuring that the actually specified constant is either
335 // a signed or unsigned 64-bit number is unfortunately impossible.
336 bool IsInRange = isRV64() ? true : isInt<32>(Imm) || isUInt<32>(Imm);
337 return IsConstantImm && IsInRange && VK == RISCVMCExpr::VK_RISCV_None;
338 }
339
Alex Bradburya6e62482017-12-07 10:53:48 +0000340 bool isUImmLog2XLen() const {
341 int64_t Imm;
342 RISCVMCExpr::VariantKind VK;
343 if (!isImm())
344 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000345 if (!evaluateConstantImm(getImm(), Imm, VK) ||
346 VK != RISCVMCExpr::VK_RISCV_None)
Alex Bradburya6e62482017-12-07 10:53:48 +0000347 return false;
348 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
349 }
350
Alex Bradbury0ad4c262017-12-15 10:20:51 +0000351 bool isUImmLog2XLenNonZero() const {
352 int64_t Imm;
353 RISCVMCExpr::VariantKind VK;
354 if (!isImm())
355 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000356 if (!evaluateConstantImm(getImm(), Imm, VK) ||
357 VK != RISCVMCExpr::VK_RISCV_None)
Alex Bradbury0ad4c262017-12-15 10:20:51 +0000358 return false;
359 if (Imm == 0)
360 return false;
361 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
362 }
363
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000364 bool isUImm5() const {
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000365 int64_t Imm;
366 RISCVMCExpr::VariantKind VK;
Alex Bradbury3c941e72017-10-19 16:22:51 +0000367 if (!isImm())
368 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000369 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000370 return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000371 }
372
Alex Bradbury60714f92017-12-13 09:32:55 +0000373 bool isUImm5NonZero() const {
374 int64_t Imm;
375 RISCVMCExpr::VariantKind VK;
376 if (!isImm())
377 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000378 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury60714f92017-12-13 09:32:55 +0000379 return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) &&
380 VK == RISCVMCExpr::VK_RISCV_None;
381 }
382
Alex Bradbury581d6b02017-12-13 09:41:21 +0000383 bool isSImm6() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000384 if (!isImm())
385 return false;
Alex Bradbury581d6b02017-12-13 09:41:21 +0000386 RISCVMCExpr::VariantKind VK;
387 int64_t Imm;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000388 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Ana Pazos065b0882018-09-13 18:37:23 +0000389 return IsConstantImm && isInt<6>(Imm) &&
390 VK == RISCVMCExpr::VK_RISCV_None;
Alex Bradbury581d6b02017-12-13 09:41:21 +0000391 }
392
Shiva Chenb22c1d22018-02-02 02:43:23 +0000393 bool isSImm6NonZero() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000394 if (!isImm())
395 return false;
Shiva Chenb22c1d22018-02-02 02:43:23 +0000396 RISCVMCExpr::VariantKind VK;
397 int64_t Imm;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000398 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Ana Pazos065b0882018-09-13 18:37:23 +0000399 return IsConstantImm && isInt<6>(Imm) && (Imm != 0) &&
400 VK == RISCVMCExpr::VK_RISCV_None;
Shiva Chenb22c1d22018-02-02 02:43:23 +0000401 }
402
Shiva Chen7c172422018-02-22 15:02:28 +0000403 bool isCLUIImm() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000404 if (!isImm())
405 return false;
Alex Bradbury60714f92017-12-13 09:32:55 +0000406 int64_t Imm;
407 RISCVMCExpr::VariantKind VK;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000408 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Shiva Chen7c172422018-02-22 15:02:28 +0000409 return IsConstantImm && (Imm != 0) &&
410 (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) &&
Ana Pazos9d6c5532018-10-04 21:50:54 +0000411 VK == RISCVMCExpr::VK_RISCV_None;
Alex Bradbury60714f92017-12-13 09:32:55 +0000412 }
413
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000414 bool isUImm7Lsb00() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000415 if (!isImm())
416 return false;
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000417 int64_t Imm;
418 RISCVMCExpr::VariantKind VK;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000419 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000420 return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
421 VK == RISCVMCExpr::VK_RISCV_None;
422 }
423
424 bool isUImm8Lsb00() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000425 if (!isImm())
426 return false;
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000427 int64_t Imm;
428 RISCVMCExpr::VariantKind VK;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000429 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000430 return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
431 VK == RISCVMCExpr::VK_RISCV_None;
432 }
433
434 bool isUImm8Lsb000() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000435 if (!isImm())
436 return false;
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000437 int64_t Imm;
438 RISCVMCExpr::VariantKind VK;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000439 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000440 return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
441 VK == RISCVMCExpr::VK_RISCV_None;
442 }
443
Alex Bradburyf8f4b902017-12-07 13:19:57 +0000444 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); }
445
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000446 bool isUImm9Lsb000() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000447 if (!isImm())
448 return false;
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000449 int64_t Imm;
450 RISCVMCExpr::VariantKind VK;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000451 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000452 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
453 VK == RISCVMCExpr::VK_RISCV_None;
454 }
455
Alex Bradbury60714f92017-12-13 09:32:55 +0000456 bool isUImm10Lsb00NonZero() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000457 if (!isImm())
458 return false;
Alex Bradbury60714f92017-12-13 09:32:55 +0000459 int64_t Imm;
460 RISCVMCExpr::VariantKind VK;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000461 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury60714f92017-12-13 09:32:55 +0000462 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) &&
463 VK == RISCVMCExpr::VK_RISCV_None;
464 }
465
Alex Bradbury04f06d92017-08-08 14:43:36 +0000466 bool isSImm12() const {
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000467 RISCVMCExpr::VariantKind VK;
468 int64_t Imm;
469 bool IsValid;
Alex Bradbury3c941e72017-10-19 16:22:51 +0000470 if (!isImm())
471 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000472 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000473 if (!IsConstantImm)
474 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
475 else
476 IsValid = isInt<12>(Imm);
Alex Bradbury7d0e18d2018-09-18 15:13:29 +0000477 return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) ||
Ahmed Charles646ab872018-02-06 00:55:23 +0000478 VK == RISCVMCExpr::VK_RISCV_LO ||
479 VK == RISCVMCExpr::VK_RISCV_PCREL_LO);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000480 }
481
Alex Bradburyf8f4b902017-12-07 13:19:57 +0000482 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); }
483
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000484 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000485
Shiva Chenb22c1d22018-02-02 02:43:23 +0000486 bool isSImm10Lsb0000NonZero() const {
Ana Pazosecc65ed2018-08-24 23:47:49 +0000487 if (!isImm())
488 return false;
Alex Bradbury60714f92017-12-13 09:32:55 +0000489 int64_t Imm;
490 RISCVMCExpr::VariantKind VK;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000491 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Shiva Chenb22c1d22018-02-02 02:43:23 +0000492 return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) &&
Alex Bradbury60714f92017-12-13 09:32:55 +0000493 VK == RISCVMCExpr::VK_RISCV_None;
494 }
495
Alex Bradbury74340f12018-09-18 15:08:35 +0000496 bool isUImm20LUI() const {
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000497 RISCVMCExpr::VariantKind VK;
498 int64_t Imm;
499 bool IsValid;
Alex Bradbury3c941e72017-10-19 16:22:51 +0000500 if (!isImm())
501 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000502 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury74340f12018-09-18 15:08:35 +0000503 if (!IsConstantImm) {
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000504 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
Alex Bradbury74340f12018-09-18 15:08:35 +0000505 return IsValid && VK == RISCVMCExpr::VK_RISCV_HI;
506 } else {
507 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
508 VK == RISCVMCExpr::VK_RISCV_HI);
509 }
510 }
511
512 bool isUImm20AUIPC() const {
513 RISCVMCExpr::VariantKind VK;
514 int64_t Imm;
515 bool IsValid;
516 if (!isImm())
517 return false;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000518 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
Alex Bradbury74340f12018-09-18 15:08:35 +0000519 if (!IsConstantImm) {
520 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
Alex Bradbury8eb87e52019-02-15 09:43:46 +0000521 return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
522 VK == RISCVMCExpr::VK_RISCV_GOT_HI);
Alex Bradbury74340f12018-09-18 15:08:35 +0000523 } else {
524 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
Alex Bradbury8eb87e52019-02-15 09:43:46 +0000525 VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
526 VK == RISCVMCExpr::VK_RISCV_GOT_HI);
Alex Bradbury74340f12018-09-18 15:08:35 +0000527 }
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000528 }
529
Alex Bradbury226f3ef2018-09-20 08:10:35 +0000530 bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); }
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000531
Alex Bradbury04f06d92017-08-08 14:43:36 +0000532 /// getStartLoc - Gets location of the first token of this operand
533 SMLoc getStartLoc() const override { return StartLoc; }
534 /// getEndLoc - Gets location of the last token of this operand
535 SMLoc getEndLoc() const override { return EndLoc; }
Alex Bradburya6e62482017-12-07 10:53:48 +0000536 /// True if this operand is for an RV64 instruction
537 bool isRV64() const { return IsRV64; }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000538
539 unsigned getReg() const override {
540 assert(Kind == Register && "Invalid type access!");
541 return Reg.RegNum;
542 }
543
Ana Pazos9d6c5532018-10-04 21:50:54 +0000544 StringRef getSysReg() const {
545 assert(Kind == SystemRegister && "Invalid access!");
546 return StringRef(SysReg.Data, SysReg.Length);
547 }
548
Alex Bradbury04f06d92017-08-08 14:43:36 +0000549 const MCExpr *getImm() const {
550 assert(Kind == Immediate && "Invalid type access!");
551 return Imm.Val;
552 }
553
554 StringRef getToken() const {
555 assert(Kind == Token && "Invalid type access!");
556 return Tok;
557 }
558
559 void print(raw_ostream &OS) const override {
560 switch (Kind) {
561 case Immediate:
562 OS << *getImm();
563 break;
564 case Register:
565 OS << "<register x";
566 OS << getReg() << ">";
567 break;
568 case Token:
569 OS << "'" << getToken() << "'";
570 break;
Ana Pazos9d6c5532018-10-04 21:50:54 +0000571 case SystemRegister:
572 OS << "<sysreg: " << getSysReg() << '>';
573 break;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000574 }
575 }
576
Alex Bradburya6e62482017-12-07 10:53:48 +0000577 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S,
578 bool IsRV64) {
Alex Bradbury04f06d92017-08-08 14:43:36 +0000579 auto Op = make_unique<RISCVOperand>(Token);
580 Op->Tok = Str;
581 Op->StartLoc = S;
582 Op->EndLoc = S;
Alex Bradburya6e62482017-12-07 10:53:48 +0000583 Op->IsRV64 = IsRV64;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000584 return Op;
585 }
586
587 static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
Alex Bradburya6e62482017-12-07 10:53:48 +0000588 SMLoc E, bool IsRV64) {
Alex Bradbury04f06d92017-08-08 14:43:36 +0000589 auto Op = make_unique<RISCVOperand>(Register);
590 Op->Reg.RegNum = RegNo;
591 Op->StartLoc = S;
592 Op->EndLoc = E;
Alex Bradburya6e62482017-12-07 10:53:48 +0000593 Op->IsRV64 = IsRV64;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000594 return Op;
595 }
596
597 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S,
Alex Bradburya6e62482017-12-07 10:53:48 +0000598 SMLoc E, bool IsRV64) {
Alex Bradbury04f06d92017-08-08 14:43:36 +0000599 auto Op = make_unique<RISCVOperand>(Immediate);
600 Op->Imm.Val = Val;
601 Op->StartLoc = S;
602 Op->EndLoc = E;
Alex Bradburya6e62482017-12-07 10:53:48 +0000603 Op->IsRV64 = IsRV64;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000604 return Op;
605 }
606
Ana Pazos9d6c5532018-10-04 21:50:54 +0000607 static std::unique_ptr<RISCVOperand>
608 createSysReg(StringRef Str, SMLoc S, unsigned Encoding, bool IsRV64) {
609 auto Op = make_unique<RISCVOperand>(SystemRegister);
610 Op->SysReg.Data = Str.data();
611 Op->SysReg.Length = Str.size();
612 Op->SysReg.Encoding = Encoding;
613 Op->StartLoc = S;
614 Op->IsRV64 = IsRV64;
615 return Op;
616 }
617
Alex Bradbury04f06d92017-08-08 14:43:36 +0000618 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
619 assert(Expr && "Expr shouldn't be null!");
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000620 int64_t Imm = 0;
Alex Bradbury96ed75d2018-09-20 11:40:43 +0000621 RISCVMCExpr::VariantKind VK;
622 bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000623
624 if (IsConstant)
625 Inst.addOperand(MCOperand::createImm(Imm));
Alex Bradbury04f06d92017-08-08 14:43:36 +0000626 else
627 Inst.addOperand(MCOperand::createExpr(Expr));
628 }
629
630 // Used by the TableGen Code
631 void addRegOperands(MCInst &Inst, unsigned N) const {
632 assert(N == 1 && "Invalid number of operands!");
633 Inst.addOperand(MCOperand::createReg(getReg()));
634 }
635
636 void addImmOperands(MCInst &Inst, unsigned N) const {
637 assert(N == 1 && "Invalid number of operands!");
638 addExpr(Inst, getImm());
639 }
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000640
641 void addFenceArgOperands(MCInst &Inst, unsigned N) const {
642 assert(N == 1 && "Invalid number of operands!");
643 // isFenceArg has validated the operand, meaning this cast is safe
644 auto SE = cast<MCSymbolRefExpr>(getImm());
645
646 unsigned Imm = 0;
647 for (char c : SE->getSymbol().getName()) {
648 switch (c) {
Ana Pazos9d6c5532018-10-04 21:50:54 +0000649 default:
650 llvm_unreachable("FenceArg must contain only [iorw]");
651 case 'i': Imm |= RISCVFenceField::I; break;
652 case 'o': Imm |= RISCVFenceField::O; break;
653 case 'r': Imm |= RISCVFenceField::R; break;
654 case 'w': Imm |= RISCVFenceField::W; break;
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000655 }
656 }
657 Inst.addOperand(MCOperand::createImm(Imm));
658 }
Alex Bradbury0d6cf902017-12-07 10:26:05 +0000659
Ana Pazos9d6c5532018-10-04 21:50:54 +0000660 void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
661 assert(N == 1 && "Invalid number of operands!");
662 Inst.addOperand(MCOperand::createImm(SysReg.Encoding));
663 }
664
Alex Bradbury0d6cf902017-12-07 10:26:05 +0000665 // Returns the rounding mode represented by this RISCVOperand. Should only
666 // be called after checking isFRMArg.
667 RISCVFPRndMode::RoundingMode getRoundingMode() const {
668 // isFRMArg has validated the operand, meaning this cast is safe.
669 auto SE = cast<MCSymbolRefExpr>(getImm());
670 RISCVFPRndMode::RoundingMode FRM =
671 RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName());
672 assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode");
673 return FRM;
674 }
675
676 void addFRMArgOperands(MCInst &Inst, unsigned N) const {
677 assert(N == 1 && "Invalid number of operands!");
678 Inst.addOperand(MCOperand::createImm(getRoundingMode()));
679 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000680};
681} // end anonymous namespace.
682
683#define GET_REGISTER_MATCHER
684#define GET_MATCHER_IMPLEMENTATION
Alex Bradbury04f06d92017-08-08 14:43:36 +0000685#include "RISCVGenAsmMatcher.inc"
686
Alex Bradbury7bc2a952017-12-07 10:46:23 +0000687// Return the matching FPR64 register for the given FPR32.
688// FIXME: Ideally this function could be removed in favour of using
689// information from TableGen.
690unsigned convertFPR32ToFPR64(unsigned Reg) {
691 switch (Reg) {
Ana Pazos9d6c5532018-10-04 21:50:54 +0000692 default:
693 llvm_unreachable("Not a recognised FPR32 register");
694 case RISCV::F0_32: return RISCV::F0_64;
695 case RISCV::F1_32: return RISCV::F1_64;
696 case RISCV::F2_32: return RISCV::F2_64;
697 case RISCV::F3_32: return RISCV::F3_64;
698 case RISCV::F4_32: return RISCV::F4_64;
699 case RISCV::F5_32: return RISCV::F5_64;
700 case RISCV::F6_32: return RISCV::F6_64;
701 case RISCV::F7_32: return RISCV::F7_64;
702 case RISCV::F8_32: return RISCV::F8_64;
703 case RISCV::F9_32: return RISCV::F9_64;
704 case RISCV::F10_32: return RISCV::F10_64;
705 case RISCV::F11_32: return RISCV::F11_64;
706 case RISCV::F12_32: return RISCV::F12_64;
707 case RISCV::F13_32: return RISCV::F13_64;
708 case RISCV::F14_32: return RISCV::F14_64;
709 case RISCV::F15_32: return RISCV::F15_64;
710 case RISCV::F16_32: return RISCV::F16_64;
711 case RISCV::F17_32: return RISCV::F17_64;
712 case RISCV::F18_32: return RISCV::F18_64;
713 case RISCV::F19_32: return RISCV::F19_64;
714 case RISCV::F20_32: return RISCV::F20_64;
715 case RISCV::F21_32: return RISCV::F21_64;
716 case RISCV::F22_32: return RISCV::F22_64;
717 case RISCV::F23_32: return RISCV::F23_64;
718 case RISCV::F24_32: return RISCV::F24_64;
719 case RISCV::F25_32: return RISCV::F25_64;
720 case RISCV::F26_32: return RISCV::F26_64;
721 case RISCV::F27_32: return RISCV::F27_64;
722 case RISCV::F28_32: return RISCV::F28_64;
723 case RISCV::F29_32: return RISCV::F29_64;
724 case RISCV::F30_32: return RISCV::F30_64;
725 case RISCV::F31_32: return RISCV::F31_64;
Alex Bradbury7bc2a952017-12-07 10:46:23 +0000726 }
727}
728
729unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
730 unsigned Kind) {
731 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp);
732 if (!Op.isReg())
733 return Match_InvalidOperand;
734
735 unsigned Reg = Op.getReg();
736 bool IsRegFPR32 =
737 RISCVMCRegisterClasses[RISCV::FPR32RegClassID].contains(Reg);
Alex Bradbury60714f92017-12-13 09:32:55 +0000738 bool IsRegFPR32C =
739 RISCVMCRegisterClasses[RISCV::FPR32CRegClassID].contains(Reg);
Alex Bradbury7bc2a952017-12-07 10:46:23 +0000740
741 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
Alex Bradbury60714f92017-12-13 09:32:55 +0000742 // register from FPR32 to FPR64 or FPR32C to FPR64C if necessary.
743 if ((IsRegFPR32 && Kind == MCK_FPR64) ||
744 (IsRegFPR32C && Kind == MCK_FPR64C)) {
Alex Bradbury7bc2a952017-12-07 10:46:23 +0000745 Op.Reg.RegNum = convertFPR32ToFPR64(Reg);
746 return Match_Success;
747 }
748 return Match_InvalidOperand;
749}
750
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000751bool RISCVAsmParser::generateImmOutOfRangeError(
Alex Bradbury6a4b5442018-06-07 15:35:47 +0000752 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000753 Twine Msg = "immediate must be an integer in the range") {
754 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
755 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
756}
757
Alex Bradbury04f06d92017-08-08 14:43:36 +0000758bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
759 OperandVector &Operands,
760 MCStreamer &Out,
761 uint64_t &ErrorInfo,
762 bool MatchingInlineAsm) {
763 MCInst Inst;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000764
Ana Pazos6b34051b2018-08-30 19:43:19 +0000765 auto Result =
766 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
767 switch (Result) {
Alex Bradbury04f06d92017-08-08 14:43:36 +0000768 default:
769 break;
Alex Bradbury6a4b5442018-06-07 15:35:47 +0000770 case Match_Success:
771 return processInstruction(Inst, IDLoc, Out);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000772 case Match_MissingFeature:
773 return Error(IDLoc, "instruction use requires an option to be enabled");
774 case Match_MnemonicFail:
775 return Error(IDLoc, "unrecognized instruction mnemonic");
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000776 case Match_InvalidOperand: {
777 SMLoc ErrorLoc = IDLoc;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000778 if (ErrorInfo != ~0U) {
779 if (ErrorInfo >= Operands.size())
780 return Error(ErrorLoc, "too few operands for instruction");
781
782 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
783 if (ErrorLoc == SMLoc())
784 ErrorLoc = IDLoc;
785 }
786 return Error(ErrorLoc, "invalid operand for instruction");
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000787 }
Ana Pazos6b34051b2018-08-30 19:43:19 +0000788 }
789
790 // Handle the case when the error message is of specific type
791 // other than the generic Match_InvalidOperand, and the
792 // corresponding operand is missing.
793 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
794 SMLoc ErrorLoc = IDLoc;
795 if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
796 return Error(ErrorLoc, "too few operands for instruction");
797 }
798
799 switch(Result) {
800 default:
801 break;
Alex Bradbury2ba76be2019-01-03 14:41:41 +0000802 case Match_InvalidImmXLenLI:
Alex Bradbury6a4b5442018-06-07 15:35:47 +0000803 if (isRV64()) {
804 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
805 return Error(ErrorLoc, "operand must be a constant 64-bit integer");
806 }
807 return generateImmOutOfRangeError(Operands, ErrorInfo,
808 std::numeric_limits<int32_t>::min(),
809 std::numeric_limits<uint32_t>::max());
Alex Bradburya6e62482017-12-07 10:53:48 +0000810 case Match_InvalidUImmLog2XLen:
811 if (isRV64())
812 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
813 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
Alex Bradbury0ad4c262017-12-15 10:20:51 +0000814 case Match_InvalidUImmLog2XLenNonZero:
815 if (isRV64())
816 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
817 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000818 case Match_InvalidUImm5:
819 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
Alex Bradbury581d6b02017-12-13 09:41:21 +0000820 case Match_InvalidSImm6:
821 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
822 (1 << 5) - 1);
Shiva Chenb22c1d22018-02-02 02:43:23 +0000823 case Match_InvalidSImm6NonZero:
Ana Pazos9d6c5532018-10-04 21:50:54 +0000824 return generateImmOutOfRangeError(
825 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
Shiva Chenb22c1d22018-02-02 02:43:23 +0000826 "immediate must be non-zero in the range");
Shiva Chen7c172422018-02-22 15:02:28 +0000827 case Match_InvalidCLUIImm:
828 return generateImmOutOfRangeError(
829 Operands, ErrorInfo, 1, (1 << 5) - 1,
830 "immediate must be in [0xfffe0, 0xfffff] or");
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000831 case Match_InvalidUImm7Lsb00:
832 return generateImmOutOfRangeError(
833 Operands, ErrorInfo, 0, (1 << 7) - 4,
834 "immediate must be a multiple of 4 bytes in the range");
835 case Match_InvalidUImm8Lsb00:
836 return generateImmOutOfRangeError(
837 Operands, ErrorInfo, 0, (1 << 8) - 4,
838 "immediate must be a multiple of 4 bytes in the range");
839 case Match_InvalidUImm8Lsb000:
840 return generateImmOutOfRangeError(
841 Operands, ErrorInfo, 0, (1 << 8) - 8,
842 "immediate must be a multiple of 8 bytes in the range");
Alex Bradburyf8f4b902017-12-07 13:19:57 +0000843 case Match_InvalidSImm9Lsb0:
844 return generateImmOutOfRangeError(
845 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
846 "immediate must be a multiple of 2 bytes in the range");
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000847 case Match_InvalidUImm9Lsb000:
848 return generateImmOutOfRangeError(
849 Operands, ErrorInfo, 0, (1 << 9) - 8,
850 "immediate must be a multiple of 8 bytes in the range");
Alex Bradbury60714f92017-12-13 09:32:55 +0000851 case Match_InvalidUImm10Lsb00NonZero:
852 return generateImmOutOfRangeError(
853 Operands, ErrorInfo, 4, (1 << 10) - 4,
854 "immediate must be a multiple of 4 bytes in the range");
Shiva Chenb22c1d22018-02-02 02:43:23 +0000855 case Match_InvalidSImm10Lsb0000NonZero:
Alex Bradbury60714f92017-12-13 09:32:55 +0000856 return generateImmOutOfRangeError(
857 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
Shiva Chenb22c1d22018-02-02 02:43:23 +0000858 "immediate must be a multiple of 16 bytes and non-zero in the range");
Alex Bradbury04f06d92017-08-08 14:43:36 +0000859 case Match_InvalidSImm12:
Alex Bradbury7d0e18d2018-09-18 15:13:29 +0000860 return generateImmOutOfRangeError(
861 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
862 "operand must be a symbol with %lo/%pcrel_lo modifier or an integer in "
863 "the range");
Alex Bradburyf8f4b902017-12-07 13:19:57 +0000864 case Match_InvalidSImm12Lsb0:
865 return generateImmOutOfRangeError(
866 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
867 "immediate must be a multiple of 2 bytes in the range");
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000868 case Match_InvalidSImm13Lsb0:
869 return generateImmOutOfRangeError(
870 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
871 "immediate must be a multiple of 2 bytes in the range");
Alex Bradbury74340f12018-09-18 15:08:35 +0000872 case Match_InvalidUImm20LUI:
873 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1,
874 "operand must be a symbol with %hi() "
875 "modifier or an integer in the range");
876 case Match_InvalidUImm20AUIPC:
877 return generateImmOutOfRangeError(
878 Operands, ErrorInfo, 0, (1 << 20) - 1,
Alex Bradbury8eb87e52019-02-15 09:43:46 +0000879 "operand must be a symbol with a %pcrel_hi/%got_pcrel_hi modifier "
880 "or an integer in the range");
Alex Bradbury226f3ef2018-09-20 08:10:35 +0000881 case Match_InvalidSImm21Lsb0JAL:
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000882 return generateImmOutOfRangeError(
883 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
884 "immediate must be a multiple of 2 bytes in the range");
Ana Pazos9d6c5532018-10-04 21:50:54 +0000885 case Match_InvalidCSRSystemRegister: {
886 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
887 "operand must be a valid system register "
888 "name or an integer in the range");
889 }
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000890 case Match_InvalidFenceArg: {
Alex Bradbury04f06d92017-08-08 14:43:36 +0000891 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000892 return Error(
893 ErrorLoc,
894 "operand must be formed of letters selected in-order from 'iorw'");
895 }
Alex Bradbury0d6cf902017-12-07 10:26:05 +0000896 case Match_InvalidFRMArg: {
897 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
898 return Error(
899 ErrorLoc,
900 "operand must be a valid floating point rounding mode mnemonic");
901 }
Shiva Chen98f93892018-04-25 14:18:55 +0000902 case Match_InvalidBareSymbol: {
903 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
904 return Error(ErrorLoc, "operand must be a bare symbol name");
905 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000906 }
907
908 llvm_unreachable("Unknown match type detected!");
909}
910
911bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
912 SMLoc &EndLoc) {
913 const AsmToken &Tok = getParser().getTok();
914 StartLoc = Tok.getLoc();
915 EndLoc = Tok.getEndLoc();
916 RegNo = 0;
917 StringRef Name = getLexer().getTok().getIdentifier();
918
Alex Bradburyb18e3142019-03-17 12:00:58 +0000919 RegNo = MatchRegisterName(Name);
920 if (RegNo == 0)
921 RegNo = MatchRegisterAltName(Name);
922 if (RegNo == 0)
923 return Error(StartLoc, "invalid register name");
Alex Bradbury04f06d92017-08-08 14:43:36 +0000924
Alex Bradburyb18e3142019-03-17 12:00:58 +0000925 getParser().Lex(); // Eat identifier token.
926 return false;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000927}
928
Alex Bradbury8c345c52017-11-09 15:00:03 +0000929OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands,
930 bool AllowParens) {
931 SMLoc FirstS = getLoc();
932 bool HadParens = false;
933 AsmToken Buf[2];
934
935 // If this a parenthesised register name is allowed, parse it atomically
936 if (AllowParens && getLexer().is(AsmToken::LParen)) {
937 size_t ReadCount = getLexer().peekTokens(Buf);
938 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
939 HadParens = true;
940 getParser().Lex(); // Eat '('
941 }
942 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000943
944 switch (getLexer().getKind()) {
945 default:
946 return MatchOperand_NoMatch;
947 case AsmToken::Identifier:
948 StringRef Name = getLexer().getTok().getIdentifier();
949 unsigned RegNo = MatchRegisterName(Name);
950 if (RegNo == 0) {
951 RegNo = MatchRegisterAltName(Name);
Alex Bradbury8c345c52017-11-09 15:00:03 +0000952 if (RegNo == 0) {
953 if (HadParens)
954 getLexer().UnLex(Buf[0]);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000955 return MatchOperand_NoMatch;
Alex Bradbury8c345c52017-11-09 15:00:03 +0000956 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000957 }
Alex Bradbury8c345c52017-11-09 15:00:03 +0000958 if (HadParens)
Alex Bradburya6e62482017-12-07 10:53:48 +0000959 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64()));
Alex Bradbury8c345c52017-11-09 15:00:03 +0000960 SMLoc S = getLoc();
961 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000962 getLexer().Lex();
Alex Bradburya6e62482017-12-07 10:53:48 +0000963 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
Alex Bradbury04f06d92017-08-08 14:43:36 +0000964 }
Alex Bradbury8c345c52017-11-09 15:00:03 +0000965
966 if (HadParens) {
967 getParser().Lex(); // Eat ')'
Alex Bradburya6e62482017-12-07 10:53:48 +0000968 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
Alex Bradbury8c345c52017-11-09 15:00:03 +0000969 }
970
Alex Bradbury04f06d92017-08-08 14:43:36 +0000971 return MatchOperand_Success;
972}
973
Ana Pazos9d6c5532018-10-04 21:50:54 +0000974OperandMatchResultTy
975RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
976 SMLoc S = getLoc();
977 const MCExpr *Res;
978
979 switch (getLexer().getKind()) {
980 default:
981 return MatchOperand_NoMatch;
982 case AsmToken::LParen:
983 case AsmToken::Minus:
984 case AsmToken::Plus:
985 case AsmToken::Integer:
986 case AsmToken::String: {
987 if (getParser().parseExpression(Res))
988 return MatchOperand_ParseFail;
989
990 auto *CE = dyn_cast<MCConstantExpr>(Res);
991 if (CE) {
992 int64_t Imm = CE->getValue();
993 if (isUInt<12>(Imm)) {
994 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
995 // Accept an immediate representing a named or un-named Sys Reg
996 // if the range is valid, regardless of the required features.
997 Operands.push_back(RISCVOperand::createSysReg(
998 SysReg ? SysReg->Name : "", S, Imm, isRV64()));
999 return MatchOperand_Success;
1000 }
1001 }
1002
1003 Twine Msg = "immediate must be an integer in the range";
1004 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1005 return MatchOperand_ParseFail;
1006 }
1007 case AsmToken::Identifier: {
1008 StringRef Identifier;
1009 if (getParser().parseIdentifier(Identifier))
1010 return MatchOperand_ParseFail;
1011
1012 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1013 // Accept a named Sys Reg if the required features are present.
1014 if (SysReg) {
1015 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) {
1016 Error(S, "system register use requires an option to be enabled");
1017 return MatchOperand_ParseFail;
1018 }
1019 Operands.push_back(RISCVOperand::createSysReg(
1020 Identifier, S, SysReg->Encoding, isRV64()));
1021 return MatchOperand_Success;
1022 }
1023
1024 Twine Msg = "operand must be a valid system register name "
1025 "or an integer in the range";
1026 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1027 return MatchOperand_ParseFail;
1028 }
1029 case AsmToken::Percent: {
1030 // Discard operand with modifier.
1031 Twine Msg = "immediate must be an integer in the range";
1032 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1033 return MatchOperand_ParseFail;
1034 }
1035 }
1036
1037 return MatchOperand_NoMatch;
1038}
1039
Alex Bradbury04f06d92017-08-08 14:43:36 +00001040OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) {
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001041 SMLoc S = getLoc();
1042 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1043 const MCExpr *Res;
1044
Alex Bradbury04f06d92017-08-08 14:43:36 +00001045 switch (getLexer().getKind()) {
1046 default:
1047 return MatchOperand_NoMatch;
1048 case AsmToken::LParen:
1049 case AsmToken::Minus:
1050 case AsmToken::Plus:
1051 case AsmToken::Integer:
1052 case AsmToken::String:
Alex Bradbury6f302b82019-01-10 15:33:17 +00001053 case AsmToken::Identifier:
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001054 if (getParser().parseExpression(Res))
1055 return MatchOperand_ParseFail;
1056 break;
Alex Bradbury9d3f1252017-09-28 08:26:24 +00001057 case AsmToken::Percent:
1058 return parseOperandWithModifier(Operands);
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001059 }
Alex Bradbury04f06d92017-08-08 14:43:36 +00001060
Alex Bradburya6e62482017-12-07 10:53:48 +00001061 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
Alex Bradbury9d3f1252017-09-28 08:26:24 +00001062 return MatchOperand_Success;
1063}
1064
1065OperandMatchResultTy
1066RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
1067 SMLoc S = getLoc();
1068 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1069
1070 if (getLexer().getKind() != AsmToken::Percent) {
1071 Error(getLoc(), "expected '%' for operand modifier");
1072 return MatchOperand_ParseFail;
1073 }
1074
1075 getParser().Lex(); // Eat '%'
1076
1077 if (getLexer().getKind() != AsmToken::Identifier) {
1078 Error(getLoc(), "expected valid identifier for operand modifier");
1079 return MatchOperand_ParseFail;
1080 }
1081 StringRef Identifier = getParser().getTok().getIdentifier();
1082 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier);
1083 if (VK == RISCVMCExpr::VK_RISCV_Invalid) {
1084 Error(getLoc(), "unrecognized operand modifier");
1085 return MatchOperand_ParseFail;
1086 }
1087
1088 getParser().Lex(); // Eat the identifier
1089 if (getLexer().getKind() != AsmToken::LParen) {
1090 Error(getLoc(), "expected '('");
1091 return MatchOperand_ParseFail;
1092 }
1093 getParser().Lex(); // Eat '('
1094
1095 const MCExpr *SubExpr;
1096 if (getParser().parseParenExpression(SubExpr, E)) {
1097 return MatchOperand_ParseFail;
1098 }
1099
1100 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext());
Alex Bradburya6e62482017-12-07 10:53:48 +00001101 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001102 return MatchOperand_Success;
1103}
1104
Alex Bradbury68f73c12018-09-18 15:18:16 +00001105OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) {
1106 SMLoc S = getLoc();
1107 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1108 const MCExpr *Res;
1109
1110 if (getLexer().getKind() != AsmToken::Identifier)
1111 return MatchOperand_NoMatch;
1112
1113 StringRef Identifier;
Kito Cheng303217e2019-02-20 03:31:32 +00001114 AsmToken Tok = getLexer().getTok();
1115
Alex Bradbury68f73c12018-09-18 15:18:16 +00001116 if (getParser().parseIdentifier(Identifier))
1117 return MatchOperand_ParseFail;
1118
1119 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
Kito Cheng303217e2019-02-20 03:31:32 +00001120
1121 if (Sym->isVariable()) {
1122 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1123 if (!isa<MCSymbolRefExpr>(V)) {
1124 getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1125 return MatchOperand_NoMatch;
1126 }
1127 Res = V;
1128 } else
1129 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
Alex Bradbury68f73c12018-09-18 15:18:16 +00001130 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1131 return MatchOperand_Success;
1132}
1133
Alex Bradbury226f3ef2018-09-20 08:10:35 +00001134OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) {
1135 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo`
1136 // both being acceptable forms. When parsing `jal ra, foo` this function
1137 // will be called for the `ra` register operand in an attempt to match the
1138 // single-operand alias. parseJALOffset must fail for this case. It would
1139 // seem logical to try parse the operand using parseImmediate and return
1140 // NoMatch if the next token is a comma (meaning we must be parsing a jal in
1141 // the second form rather than the first). We can't do this as there's no
1142 // way of rewinding the lexer state. Instead, return NoMatch if this operand
1143 // is an identifier and is followed by a comma.
1144 if (getLexer().is(AsmToken::Identifier) &&
1145 getLexer().peekTok().is(AsmToken::Comma))
1146 return MatchOperand_NoMatch;
1147
1148 return parseImmediate(Operands);
1149}
1150
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001151OperandMatchResultTy
1152RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
1153 if (getLexer().isNot(AsmToken::LParen)) {
1154 Error(getLoc(), "expected '('");
Alex Bradbury04f06d92017-08-08 14:43:36 +00001155 return MatchOperand_ParseFail;
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001156 }
Alex Bradbury04f06d92017-08-08 14:43:36 +00001157
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001158 getParser().Lex(); // Eat '('
Alex Bradburya6e62482017-12-07 10:53:48 +00001159 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64()));
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001160
1161 if (parseRegister(Operands) != MatchOperand_Success) {
1162 Error(getLoc(), "expected register");
1163 return MatchOperand_ParseFail;
1164 }
1165
1166 if (getLexer().isNot(AsmToken::RParen)) {
1167 Error(getLoc(), "expected ')'");
1168 return MatchOperand_ParseFail;
1169 }
1170
1171 getParser().Lex(); // Eat ')'
Alex Bradburya6e62482017-12-07 10:53:48 +00001172 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001173
Alex Bradbury04f06d92017-08-08 14:43:36 +00001174 return MatchOperand_Success;
1175}
1176
Alex Bradburycd8688a2018-04-25 17:25:29 +00001177/// Looks at a token type and creates the relevant operand from this
1178/// information, adding to Operands. If operand was parsed, returns false, else
Alex Bradbury68f73c12018-09-18 15:18:16 +00001179/// true.
1180bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1181 // Check if the current operand has a custom associated parser, if so, try to
1182 // custom parse the operand, or fallback to the general approach.
1183 OperandMatchResultTy Result =
1184 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
1185 if (Result == MatchOperand_Success)
1186 return false;
1187 if (Result == MatchOperand_ParseFail)
1188 return true;
1189
1190 // Attempt to parse token as a register.
1191 if (parseRegister(Operands, true) == MatchOperand_Success)
Alex Bradbury04f06d92017-08-08 14:43:36 +00001192 return false;
1193
1194 // Attempt to parse token as an immediate
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001195 if (parseImmediate(Operands) == MatchOperand_Success) {
1196 // Parse memory base register if present
1197 if (getLexer().is(AsmToken::LParen))
1198 return parseMemOpBaseReg(Operands) != MatchOperand_Success;
Alex Bradbury04f06d92017-08-08 14:43:36 +00001199 return false;
Alex Bradbury6758ecb2017-09-17 14:27:35 +00001200 }
Alex Bradbury04f06d92017-08-08 14:43:36 +00001201
1202 // Finally we have exhausted all options and must declare defeat.
1203 Error(getLoc(), "unknown operand");
1204 return true;
1205}
1206
1207bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1208 StringRef Name, SMLoc NameLoc,
1209 OperandVector &Operands) {
Alex Bradbury9c03e4c2018-11-12 14:25:07 +00001210 // Ensure that if the instruction occurs when relaxation is enabled,
1211 // relocations are forced for the file. Ideally this would be done when there
1212 // is enough information to reliably determine if the instruction itself may
1213 // cause relaxations. Unfortunately instruction processing stage occurs in the
1214 // same pass as relocation emission, so it's too late to set a 'sticky bit'
1215 // for the entire file.
1216 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) {
1217 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
1218 if (Assembler != nullptr) {
1219 RISCVAsmBackend &MAB =
1220 static_cast<RISCVAsmBackend &>(Assembler->getBackend());
1221 MAB.setForceRelocs();
1222 }
1223 }
1224
Alex Bradbury04f06d92017-08-08 14:43:36 +00001225 // First operand is token for instruction
Alex Bradburya6e62482017-12-07 10:53:48 +00001226 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64()));
Alex Bradbury04f06d92017-08-08 14:43:36 +00001227
1228 // If there are no more operands, then finish
1229 if (getLexer().is(AsmToken::EndOfStatement))
1230 return false;
1231
1232 // Parse first operand
Alex Bradbury68f73c12018-09-18 15:18:16 +00001233 if (parseOperand(Operands, Name))
Alex Bradbury04f06d92017-08-08 14:43:36 +00001234 return true;
1235
1236 // Parse until end of statement, consuming commas between operands
Roger Ferrer Ibanez577a97e2018-08-09 07:08:20 +00001237 unsigned OperandIdx = 1;
Alex Bradbury04f06d92017-08-08 14:43:36 +00001238 while (getLexer().is(AsmToken::Comma)) {
1239 // Consume comma token
1240 getLexer().Lex();
1241
1242 // Parse next operand
Alex Bradbury68f73c12018-09-18 15:18:16 +00001243 if (parseOperand(Operands, Name))
Alex Bradbury04f06d92017-08-08 14:43:36 +00001244 return true;
Roger Ferrer Ibanez577a97e2018-08-09 07:08:20 +00001245
1246 ++OperandIdx;
Alex Bradbury04f06d92017-08-08 14:43:36 +00001247 }
1248
1249 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1250 SMLoc Loc = getLexer().getLoc();
1251 getParser().eatToEndOfStatement();
1252 return Error(Loc, "unexpected token");
1253 }
1254
1255 getParser().Lex(); // Consume the EndOfStatement.
1256 return false;
1257}
1258
Alex Bradbury9d3f1252017-09-28 08:26:24 +00001259bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,
1260 RISCVMCExpr::VariantKind &Kind,
1261 int64_t &Addend) {
1262 Kind = RISCVMCExpr::VK_RISCV_None;
1263 Addend = 0;
1264
1265 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
1266 Kind = RE->getKind();
1267 Expr = RE->getSubExpr();
1268 }
1269
1270 // It's a simple symbol reference or constant with no addend.
1271 if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr))
1272 return true;
1273
1274 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
1275 if (!BE)
1276 return false;
1277
1278 if (!isa<MCSymbolRefExpr>(BE->getLHS()))
1279 return false;
1280
1281 if (BE->getOpcode() != MCBinaryExpr::Add &&
1282 BE->getOpcode() != MCBinaryExpr::Sub)
1283 return false;
1284
1285 // We are able to support the subtraction of two symbol references
1286 if (BE->getOpcode() == MCBinaryExpr::Sub &&
1287 isa<MCSymbolRefExpr>(BE->getRHS()))
1288 return true;
1289
Hiroshi Inoue9ff23802018-04-09 04:37:53 +00001290 // See if the addend is a constant, otherwise there's more going
Alex Bradbury9d3f1252017-09-28 08:26:24 +00001291 // on here than we can deal with.
1292 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
1293 if (!AddendExpr)
1294 return false;
1295
1296 Addend = AddendExpr->getValue();
1297 if (BE->getOpcode() == MCBinaryExpr::Sub)
1298 Addend = -Addend;
1299
1300 // It's some symbol reference + a constant addend
1301 return Kind != RISCVMCExpr::VK_RISCV_Invalid;
1302}
1303
Alex Bradburybca0c3c2018-05-11 17:30:28 +00001304bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) {
1305 // This returns false if this function recognizes the directive
1306 // regardless of whether it is successfully handles or reports an
1307 // error. Otherwise it returns true to give the generic parser a
1308 // chance at recognizing it.
1309 StringRef IDVal = DirectiveID.getString();
1310
1311 if (IDVal == ".option")
1312 return parseDirectiveOption();
1313
1314 return true;
1315}
1316
1317bool RISCVAsmParser::parseDirectiveOption() {
1318 MCAsmParser &Parser = getParser();
1319 // Get the option token.
1320 AsmToken Tok = Parser.getTok();
1321 // At the moment only identifiers are supported.
1322 if (Tok.isNot(AsmToken::Identifier))
1323 return Error(Parser.getTok().getLoc(),
1324 "unexpected token, expected identifier");
1325
1326 StringRef Option = Tok.getIdentifier();
1327
Alex Bradbury893e5bc2018-11-28 16:39:14 +00001328 if (Option == "push") {
1329 getTargetStreamer().emitDirectiveOptionPush();
1330
1331 Parser.Lex();
1332 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1333 return Error(Parser.getTok().getLoc(),
1334 "unexpected token, expected end of statement");
1335
1336 pushFeatureBits();
1337 return false;
1338 }
1339
1340 if (Option == "pop") {
1341 SMLoc StartLoc = Parser.getTok().getLoc();
1342 getTargetStreamer().emitDirectiveOptionPop();
1343
1344 Parser.Lex();
1345 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1346 return Error(Parser.getTok().getLoc(),
1347 "unexpected token, expected end of statement");
1348
1349 if (popFeatureBits())
1350 return Error(StartLoc, ".option pop with no .option push");
1351
1352 return false;
1353 }
1354
Alex Bradburybca0c3c2018-05-11 17:30:28 +00001355 if (Option == "rvc") {
1356 getTargetStreamer().emitDirectiveOptionRVC();
1357
1358 Parser.Lex();
1359 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1360 return Error(Parser.getTok().getLoc(),
1361 "unexpected token, expected end of statement");
1362
1363 setFeatureBits(RISCV::FeatureStdExtC, "c");
1364 return false;
1365 }
1366
1367 if (Option == "norvc") {
1368 getTargetStreamer().emitDirectiveOptionNoRVC();
1369
1370 Parser.Lex();
1371 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1372 return Error(Parser.getTok().getLoc(),
1373 "unexpected token, expected end of statement");
1374
1375 clearFeatureBits(RISCV::FeatureStdExtC, "c");
1376 return false;
1377 }
1378
Alex Bradbury9c03e4c2018-11-12 14:25:07 +00001379 if (Option == "relax") {
1380 getTargetStreamer().emitDirectiveOptionRelax();
1381
1382 Parser.Lex();
1383 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1384 return Error(Parser.getTok().getLoc(),
1385 "unexpected token, expected end of statement");
1386
1387 setFeatureBits(RISCV::FeatureRelax, "relax");
1388 return false;
1389 }
1390
1391 if (Option == "norelax") {
1392 getTargetStreamer().emitDirectiveOptionNoRelax();
1393
1394 Parser.Lex();
1395 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1396 return Error(Parser.getTok().getLoc(),
1397 "unexpected token, expected end of statement");
1398
1399 clearFeatureBits(RISCV::FeatureRelax, "relax");
1400 return false;
1401 }
1402
Alex Bradburybca0c3c2018-05-11 17:30:28 +00001403 // Unknown option.
1404 Warning(Parser.getTok().getLoc(),
Alex Bradbury893e5bc2018-11-28 16:39:14 +00001405 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or "
1406 "'norelax'");
Alex Bradburybca0c3c2018-05-11 17:30:28 +00001407 Parser.eatToEndOfStatement();
1408 return false;
1409}
Alex Bradbury04f06d92017-08-08 14:43:36 +00001410
Alex Bradbury6a4b5442018-06-07 15:35:47 +00001411void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
1412 MCInst CInst;
1413 bool Res = compressInst(CInst, Inst, getSTI(), S.getContext());
1414 CInst.setLoc(Inst.getLoc());
1415 S.EmitInstruction((Res ? CInst : Inst), getSTI());
1416}
1417
1418void RISCVAsmParser::emitLoadImm(unsigned DestReg, int64_t Value,
1419 MCStreamer &Out) {
Alex Bradbury22c091f2018-11-15 10:11:31 +00001420 RISCVMatInt::InstSeq Seq;
1421 RISCVMatInt::generateInstSeq(Value, isRV64(), Seq);
Alex Bradbury6a4b5442018-06-07 15:35:47 +00001422
Alex Bradbury22c091f2018-11-15 10:11:31 +00001423 unsigned SrcReg = RISCV::X0;
1424 for (RISCVMatInt::Inst &Inst : Seq) {
1425 if (Inst.Opc == RISCV::LUI) {
1426 emitToStreamer(
1427 Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm));
1428 } else {
1429 emitToStreamer(
1430 Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm(
1431 Inst.Imm));
Alex Bradbury6a4b5442018-06-07 15:35:47 +00001432 }
1433
Alex Bradbury22c091f2018-11-15 10:11:31 +00001434 // Only the first instruction has X0 as its source.
1435 SrcReg = DestReg;
Alex Bradbury6a4b5442018-06-07 15:35:47 +00001436 }
Alex Bradbury6a4b5442018-06-07 15:35:47 +00001437}
1438
Alex Bradbury22531c42019-02-15 09:53:32 +00001439void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
1440 const MCExpr *Symbol,
1441 RISCVMCExpr::VariantKind VKHi,
1442 unsigned SecondOpcode, SMLoc IDLoc,
1443 MCStreamer &Out) {
1444 // A pair of instructions for PC-relative addressing; expands to
1445 // TmpLabel: AUIPC TmpReg, VKHi(symbol)
1446 // OP DestReg, TmpReg, %pcrel_lo(TmpLabel)
Roger Ferrer Ibanez577a97e2018-08-09 07:08:20 +00001447 MCContext &Ctx = getContext();
1448
1449 MCSymbol *TmpLabel = Ctx.createTempSymbol(
1450 "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false);
1451 Out.EmitLabel(TmpLabel);
1452
Alex Bradbury22531c42019-02-15 09:53:32 +00001453 const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx);
Roger Ferrer Ibanezc8f4dbb2018-08-14 08:30:42 +00001454 emitToStreamer(
Alex Bradbury22531c42019-02-15 09:53:32 +00001455 Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi));
Roger Ferrer Ibanez577a97e2018-08-09 07:08:20 +00001456
1457 const MCExpr *RefToLinkTmpLabel =
1458 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx),
1459 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx);
1460
Alex Bradbury22531c42019-02-15 09:53:32 +00001461 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
Roger Ferrer Ibanezc8f4dbb2018-08-14 08:30:42 +00001462 .addOperand(DestReg)
Alex Bradbury22531c42019-02-15 09:53:32 +00001463 .addOperand(TmpReg)
Roger Ferrer Ibanezc8f4dbb2018-08-14 08:30:42 +00001464 .addExpr(RefToLinkTmpLabel));
Roger Ferrer Ibanez577a97e2018-08-09 07:08:20 +00001465}
1466
Alex Bradbury22531c42019-02-15 09:53:32 +00001467void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
1468 MCStreamer &Out) {
1469 // The load local address pseudo-instruction "lla" is used in PC-relative
1470 // addressing of local symbols:
1471 // lla rdest, symbol
1472 // expands to
1473 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
1474 // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
1475 MCOperand DestReg = Inst.getOperand(0);
1476 const MCExpr *Symbol = Inst.getOperand(1).getExpr();
1477 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
1478 RISCV::ADDI, IDLoc, Out);
1479}
1480
1481void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
1482 MCStreamer &Out) {
1483 // The load address pseudo-instruction "la" is used in PC-relative and
1484 // GOT-indirect addressing of global symbols:
1485 // la rdest, symbol
1486 // expands to either (for non-PIC)
1487 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
1488 // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
1489 // or (for PIC)
1490 // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol)
1491 // Lx rdest, %pcrel_lo(TmpLabel)(rdest)
1492 MCOperand DestReg = Inst.getOperand(0);
1493 const MCExpr *Symbol = Inst.getOperand(1).getExpr();
1494 unsigned SecondOpcode;
1495 RISCVMCExpr::VariantKind VKHi;
1496 // FIXME: Should check .option (no)pic when implemented
1497 if (getContext().getObjectFileInfo()->isPositionIndependent()) {
1498 SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
1499 VKHi = RISCVMCExpr::VK_RISCV_GOT_HI;
1500 } else {
1501 SecondOpcode = RISCV::ADDI;
1502 VKHi = RISCVMCExpr::VK_RISCV_PCREL_HI;
1503 }
1504 emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out);
1505}
1506
Kito Cheng303217e2019-02-20 03:31:32 +00001507void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode,
1508 SMLoc IDLoc, MCStreamer &Out,
1509 bool HasTmpReg) {
1510 // The load/store pseudo-instruction does a pc-relative load with
1511 // a symbol.
1512 //
1513 // The expansion looks like this
1514 //
1515 // TmpLabel: AUIPC tmp, %pcrel_hi(symbol)
1516 // [S|L]X rd, %pcrel_lo(TmpLabel)(tmp)
1517 MCOperand DestReg = Inst.getOperand(0);
1518 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
1519 unsigned TmpRegOpIdx = HasTmpReg ? 1 : 0;
1520 MCOperand TmpReg = Inst.getOperand(TmpRegOpIdx);
1521 const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr();
1522 emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
1523 Opcode, IDLoc, Out);
1524}
1525
Alex Bradbury6a4b5442018-06-07 15:35:47 +00001526bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1527 MCStreamer &Out) {
1528 Inst.setLoc(IDLoc);
1529
Alex Bradbury22531c42019-02-15 09:53:32 +00001530 switch (Inst.getOpcode()) {
1531 default:
1532 break;
1533 case RISCV::PseudoLI: {
Alex Bradbury2ba76be2019-01-03 14:41:41 +00001534 unsigned Reg = Inst.getOperand(0).getReg();
1535 const MCOperand &Op1 = Inst.getOperand(1);
1536 if (Op1.isExpr()) {
1537 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar.
1538 // Just convert to an addi. This allows compatibility with gas.
1539 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
1540 .addReg(Reg)
1541 .addReg(RISCV::X0)
1542 .addExpr(Op1.getExpr()));
1543 return false;
1544 }
Alex Bradbury6a4b5442018-06-07 15:35:47 +00001545 int64_t Imm = Inst.getOperand(1).getImm();
1546 // On RV32 the immediate here can either be a signed or an unsigned
1547 // 32-bit number. Sign extension has to be performed to ensure that Imm
1548 // represents the expected signed 64-bit number.
1549 if (!isRV64())
1550 Imm = SignExtend64<32>(Imm);
1551 emitLoadImm(Reg, Imm, Out);
1552 return false;
Alex Bradbury22531c42019-02-15 09:53:32 +00001553 }
1554 case RISCV::PseudoLLA:
Roger Ferrer Ibanez577a97e2018-08-09 07:08:20 +00001555 emitLoadLocalAddress(Inst, IDLoc, Out);
1556 return false;
Alex Bradbury22531c42019-02-15 09:53:32 +00001557 case RISCV::PseudoLA:
1558 emitLoadAddress(Inst, IDLoc, Out);
1559 return false;
Kito Cheng303217e2019-02-20 03:31:32 +00001560 case RISCV::PseudoLB:
1561 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false);
1562 return false;
1563 case RISCV::PseudoLBU:
1564 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false);
1565 return false;
1566 case RISCV::PseudoLH:
1567 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false);
1568 return false;
1569 case RISCV::PseudoLHU:
1570 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false);
1571 return false;
1572 case RISCV::PseudoLW:
1573 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false);
1574 return false;
1575 case RISCV::PseudoLWU:
1576 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false);
1577 return false;
1578 case RISCV::PseudoLD:
1579 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false);
1580 return false;
1581 case RISCV::PseudoFLW:
1582 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true);
1583 return false;
1584 case RISCV::PseudoFLD:
1585 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true);
1586 return false;
1587 case RISCV::PseudoSB:
1588 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true);
1589 return false;
1590 case RISCV::PseudoSH:
1591 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true);
1592 return false;
1593 case RISCV::PseudoSW:
1594 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true);
1595 return false;
1596 case RISCV::PseudoSD:
1597 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true);
1598 return false;
1599 case RISCV::PseudoFSW:
1600 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true);
1601 return false;
1602 case RISCV::PseudoFSD:
1603 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true);
1604 return false;
Alex Bradbury6a4b5442018-06-07 15:35:47 +00001605 }
1606
1607 emitToStreamer(Out, Inst);
1608 return false;
1609}
1610
Alex Bradbury04f06d92017-08-08 14:43:36 +00001611extern "C" void LLVMInitializeRISCVAsmParser() {
1612 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target());
1613 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target());
1614}