blob: 7f0433410d042b20b0812009b79ec4106de98ecd [file] [log] [blame]
Alex Bradbury04f06d92017-08-08 14:43:36 +00001//===-- RISCVAsmParser.cpp - Parse RISCV assembly to MCInst instructions --===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Alex Bradbury6758ecb2017-09-17 14:27:35 +000010#include "MCTargetDesc/RISCVBaseInfo.h"
Alex Bradbury9d3f1252017-09-28 08:26:24 +000011#include "MCTargetDesc/RISCVMCExpr.h"
Alex Bradbury480b7bc2018-04-17 21:56:40 +000012#include "MCTargetDesc/RISCVMCPseudoExpansion.h"
Alex Bradbury04f06d92017-08-08 14:43:36 +000013#include "MCTargetDesc/RISCVMCTargetDesc.h"
Alex Bradbury4f7f0da2017-09-06 09:21:21 +000014#include "llvm/ADT/STLExtras.h"
15#include "llvm/ADT/StringSwitch.h"
16#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCExpr.h"
18#include "llvm/MC/MCInst.h"
Alex Bradbury04f06d92017-08-08 14:43:36 +000019#include "llvm/MC/MCParser/MCAsmLexer.h"
20#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
21#include "llvm/MC/MCParser/MCTargetAsmParser.h"
Alex Bradbury04f06d92017-08-08 14:43:36 +000022#include "llvm/MC/MCRegisterInfo.h"
23#include "llvm/MC/MCStreamer.h"
24#include "llvm/MC/MCSubtargetInfo.h"
Alex Bradbury04f06d92017-08-08 14:43:36 +000025#include "llvm/Support/Casting.h"
Alex Bradbury480b7bc2018-04-17 21:56:40 +000026#include "llvm/Support/MathExtras.h"
Alex Bradbury04f06d92017-08-08 14:43:36 +000027#include "llvm/Support/TargetRegistry.h"
28
Alex Bradbury480b7bc2018-04-17 21:56:40 +000029#include <limits>
30
Alex Bradbury04f06d92017-08-08 14:43:36 +000031using namespace llvm;
32
Sameer AbuAsalc1b0e662018-04-06 21:07:05 +000033// Include the auto-generated portion of the compress emitter.
34#define GEN_COMPRESS_INSTR
35#include "RISCVGenCompressInstEmitter.inc"
36
Alex Bradbury04f06d92017-08-08 14:43:36 +000037namespace {
38struct RISCVOperand;
39
40class RISCVAsmParser : public MCTargetAsmParser {
41 SMLoc getLoc() const { return getParser().getTok().getLoc(); }
Alex Bradburya6e62482017-12-07 10:53:48 +000042 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
Alex Bradbury04f06d92017-08-08 14:43:36 +000043
Alex Bradbury7bc2a952017-12-07 10:46:23 +000044 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
45 unsigned Kind) override;
46
Alex Bradbury6758ecb2017-09-17 14:27:35 +000047 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
Alex Bradbury480b7bc2018-04-17 21:56:40 +000048 int64_t Lower, int64_t Upper, Twine Msg);
Alex Bradbury6758ecb2017-09-17 14:27:35 +000049
Alex Bradbury04f06d92017-08-08 14:43:36 +000050 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
51 OperandVector &Operands, MCStreamer &Out,
52 uint64_t &ErrorInfo,
53 bool MatchingInlineAsm) override;
54
55 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
56
57 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
58 SMLoc NameLoc, OperandVector &Operands) override;
59
60 bool ParseDirective(AsmToken DirectiveID) override;
61
Alex Bradbury480b7bc2018-04-17 21:56:40 +000062 /// Helper for emitting MC instructions that have been successfully matched
63 /// by MatchAndEmitInstruction. Modifications to the emitted instructions,
64 /// like the expansion of pseudo instructions (e.g., "li"), can be performed
65 /// in this method.
66 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
67
Alex Bradbury04f06d92017-08-08 14:43:36 +000068// Auto-generated instruction matching functions
69#define GET_ASSEMBLER_HEADER
70#include "RISCVGenAsmMatcher.inc"
71
72 OperandMatchResultTy parseImmediate(OperandVector &Operands);
Alex Bradbury8c345c52017-11-09 15:00:03 +000073 OperandMatchResultTy parseRegister(OperandVector &Operands,
74 bool AllowParens = false);
Alex Bradbury6758ecb2017-09-17 14:27:35 +000075 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
Alex Bradbury9d3f1252017-09-28 08:26:24 +000076 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
Alex Bradbury04f06d92017-08-08 14:43:36 +000077
78 bool parseOperand(OperandVector &Operands);
79
80public:
81 enum RISCVMatchResultTy {
82 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
83#define GET_OPERAND_DIAGNOSTIC_TYPES
84#include "RISCVGenAsmMatcher.inc"
85#undef GET_OPERAND_DIAGNOSTIC_TYPES
86 };
87
Alex Bradbury9d3f1252017-09-28 08:26:24 +000088 static bool classifySymbolRef(const MCExpr *Expr,
89 RISCVMCExpr::VariantKind &Kind,
90 int64_t &Addend);
91
Alex Bradbury04f06d92017-08-08 14:43:36 +000092 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
93 const MCInstrInfo &MII, const MCTargetOptions &Options)
Oliver Stannard4191b9e2017-10-11 09:17:43 +000094 : MCTargetAsmParser(Options, STI, MII) {
Alex Bradbury04f06d92017-08-08 14:43:36 +000095 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
96 }
97};
98
99/// RISCVOperand - Instances of this class represent a parsed machine
100/// instruction
101struct RISCVOperand : public MCParsedAsmOperand {
102
103 enum KindTy {
104 Token,
105 Register,
106 Immediate,
107 } Kind;
108
Alex Bradburya6e62482017-12-07 10:53:48 +0000109 bool IsRV64;
110
Alex Bradbury04f06d92017-08-08 14:43:36 +0000111 struct RegOp {
112 unsigned RegNum;
113 };
114
115 struct ImmOp {
116 const MCExpr *Val;
117 };
118
119 SMLoc StartLoc, EndLoc;
120 union {
121 StringRef Tok;
122 RegOp Reg;
123 ImmOp Imm;
124 };
125
126 RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
127
128public:
129 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() {
130 Kind = o.Kind;
Alex Bradburya6e62482017-12-07 10:53:48 +0000131 IsRV64 = o.IsRV64;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000132 StartLoc = o.StartLoc;
133 EndLoc = o.EndLoc;
134 switch (Kind) {
135 case Register:
136 Reg = o.Reg;
137 break;
138 case Immediate:
139 Imm = o.Imm;
140 break;
141 case Token:
142 Tok = o.Tok;
143 break;
144 }
145 }
146
147 bool isToken() const override { return Kind == Token; }
148 bool isReg() const override { return Kind == Register; }
149 bool isImm() const override { return Kind == Immediate; }
150 bool isMem() const override { return false; }
151
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000152 bool evaluateConstantImm(int64_t &Imm, RISCVMCExpr::VariantKind &VK) const {
153 const MCExpr *Val = getImm();
154 bool Ret = false;
155 if (auto *RE = dyn_cast<RISCVMCExpr>(Val)) {
156 Ret = RE->evaluateAsConstant(Imm);
157 VK = RE->getKind();
158 } else if (auto CE = dyn_cast<MCConstantExpr>(Val)) {
159 Ret = true;
160 VK = RISCVMCExpr::VK_RISCV_None;
161 Imm = CE->getValue();
162 }
163 return Ret;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000164 }
165
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000166 // True if operand is a symbol with no modifiers, or a constant with no
167 // modifiers and isShiftedInt<N-1, 1>(Op).
168 template <int N> bool isBareSimmNLsb0() const {
169 int64_t Imm;
170 RISCVMCExpr::VariantKind VK;
Alex Bradbury3c941e72017-10-19 16:22:51 +0000171 if (!isImm())
172 return false;
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000173 bool IsConstantImm = evaluateConstantImm(Imm, VK);
174 bool IsValid;
175 if (!IsConstantImm)
176 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
177 else
178 IsValid = isShiftedInt<N - 1, 1>(Imm);
179 return IsValid && VK == RISCVMCExpr::VK_RISCV_None;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000180 }
181
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000182 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td
183
184 /// Return true if the operand is a valid for the fence instruction e.g.
185 /// ('iorw').
186 bool isFenceArg() const {
187 if (!isImm())
188 return false;
189 const MCExpr *Val = getImm();
190 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
191 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
192 return false;
193
194 StringRef Str = SVal->getSymbol().getName();
195 // Letters must be unique, taken from 'iorw', and in ascending order. This
196 // holds as long as each individual character is one of 'iorw' and is
197 // greater than the previous character.
198 char Prev = '\0';
199 for (char c : Str) {
200 if (c != 'i' && c != 'o' && c != 'r' && c != 'w')
201 return false;
202 if (c <= Prev)
203 return false;
204 Prev = c;
205 }
206 return true;
207 }
208
Alex Bradbury0d6cf902017-12-07 10:26:05 +0000209 /// Return true if the operand is a valid floating point rounding mode.
210 bool isFRMArg() const {
211 if (!isImm())
212 return false;
213 const MCExpr *Val = getImm();
214 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
215 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
216 return false;
217
218 StringRef Str = SVal->getSymbol().getName();
219
220 return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid;
221 }
222
Alex Bradbury480b7bc2018-04-17 21:56:40 +0000223 bool isImmXLen() const {
224 int64_t Imm;
225 RISCVMCExpr::VariantKind VK;
226 if (!isImm())
227 return false;
228 bool IsConstantImm = evaluateConstantImm(Imm, VK);
229 // Given only Imm, ensuring that the actually specified constant is either
230 // a signed or unsigned 64-bit number is unfortunately impossible.
231 bool IsInRange = isRV64() ? true : isInt<32>(Imm) || isUInt<32>(Imm);
232 return IsConstantImm && IsInRange && VK == RISCVMCExpr::VK_RISCV_None;
233 }
234
Alex Bradburya6e62482017-12-07 10:53:48 +0000235 bool isUImmLog2XLen() const {
236 int64_t Imm;
237 RISCVMCExpr::VariantKind VK;
238 if (!isImm())
239 return false;
240 if (!evaluateConstantImm(Imm, VK) || VK != RISCVMCExpr::VK_RISCV_None)
241 return false;
242 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
243 }
244
Alex Bradbury0ad4c262017-12-15 10:20:51 +0000245 bool isUImmLog2XLenNonZero() const {
246 int64_t Imm;
247 RISCVMCExpr::VariantKind VK;
248 if (!isImm())
249 return false;
250 if (!evaluateConstantImm(Imm, VK) || VK != RISCVMCExpr::VK_RISCV_None)
251 return false;
252 if (Imm == 0)
253 return false;
254 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
255 }
256
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000257 bool isUImm5() const {
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000258 int64_t Imm;
259 RISCVMCExpr::VariantKind VK;
Alex Bradbury3c941e72017-10-19 16:22:51 +0000260 if (!isImm())
261 return false;
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000262 bool IsConstantImm = evaluateConstantImm(Imm, VK);
263 return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000264 }
265
Alex Bradbury60714f92017-12-13 09:32:55 +0000266 bool isUImm5NonZero() const {
267 int64_t Imm;
268 RISCVMCExpr::VariantKind VK;
269 if (!isImm())
270 return false;
271 bool IsConstantImm = evaluateConstantImm(Imm, VK);
272 return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) &&
273 VK == RISCVMCExpr::VK_RISCV_None;
274 }
275
Alex Bradbury581d6b02017-12-13 09:41:21 +0000276 bool isSImm6() const {
277 RISCVMCExpr::VariantKind VK;
278 int64_t Imm;
279 bool IsValid;
280 bool IsConstantImm = evaluateConstantImm(Imm, VK);
281 if (!IsConstantImm)
282 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
283 else
284 IsValid = isInt<6>(Imm);
285 return IsValid &&
286 (VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO);
287 }
288
Shiva Chenb22c1d22018-02-02 02:43:23 +0000289 bool isSImm6NonZero() const {
290 RISCVMCExpr::VariantKind VK;
291 int64_t Imm;
292 bool IsValid;
293 bool IsConstantImm = evaluateConstantImm(Imm, VK);
294 if (!IsConstantImm)
295 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
296 else
297 IsValid = ((Imm != 0) && isInt<6>(Imm));
298 return IsValid &&
299 (VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO);
300 }
301
Shiva Chen7c172422018-02-22 15:02:28 +0000302 bool isCLUIImm() const {
Alex Bradbury60714f92017-12-13 09:32:55 +0000303 int64_t Imm;
304 RISCVMCExpr::VariantKind VK;
305 bool IsConstantImm = evaluateConstantImm(Imm, VK);
Shiva Chen7c172422018-02-22 15:02:28 +0000306 return IsConstantImm && (Imm != 0) &&
307 (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) &&
308 VK == RISCVMCExpr::VK_RISCV_None;
Alex Bradbury60714f92017-12-13 09:32:55 +0000309 }
310
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000311 bool isUImm7Lsb00() const {
312 int64_t Imm;
313 RISCVMCExpr::VariantKind VK;
314 bool IsConstantImm = evaluateConstantImm(Imm, VK);
315 return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
316 VK == RISCVMCExpr::VK_RISCV_None;
317 }
318
319 bool isUImm8Lsb00() const {
320 int64_t Imm;
321 RISCVMCExpr::VariantKind VK;
322 bool IsConstantImm = evaluateConstantImm(Imm, VK);
323 return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
324 VK == RISCVMCExpr::VK_RISCV_None;
325 }
326
327 bool isUImm8Lsb000() const {
328 int64_t Imm;
329 RISCVMCExpr::VariantKind VK;
330 bool IsConstantImm = evaluateConstantImm(Imm, VK);
331 return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
332 VK == RISCVMCExpr::VK_RISCV_None;
333 }
334
Alex Bradburyf8f4b902017-12-07 13:19:57 +0000335 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); }
336
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000337 bool isUImm9Lsb000() const {
338 int64_t Imm;
339 RISCVMCExpr::VariantKind VK;
340 bool IsConstantImm = evaluateConstantImm(Imm, VK);
341 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
342 VK == RISCVMCExpr::VK_RISCV_None;
343 }
344
Alex Bradbury60714f92017-12-13 09:32:55 +0000345 bool isUImm10Lsb00NonZero() const {
346 int64_t Imm;
347 RISCVMCExpr::VariantKind VK;
348 bool IsConstantImm = evaluateConstantImm(Imm, VK);
349 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) &&
350 VK == RISCVMCExpr::VK_RISCV_None;
351 }
352
Alex Bradbury04f06d92017-08-08 14:43:36 +0000353 bool isSImm12() const {
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000354 RISCVMCExpr::VariantKind VK;
355 int64_t Imm;
356 bool IsValid;
Alex Bradbury3c941e72017-10-19 16:22:51 +0000357 if (!isImm())
358 return false;
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000359 bool IsConstantImm = evaluateConstantImm(Imm, VK);
360 if (!IsConstantImm)
361 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
362 else
363 IsValid = isInt<12>(Imm);
Ahmed Charles646ab872018-02-06 00:55:23 +0000364 return IsValid && (VK == RISCVMCExpr::VK_RISCV_None ||
365 VK == RISCVMCExpr::VK_RISCV_LO ||
366 VK == RISCVMCExpr::VK_RISCV_PCREL_LO);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000367 }
368
Alex Bradburyf8f4b902017-12-07 13:19:57 +0000369 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); }
370
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000371 bool isUImm12() const {
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000372 int64_t Imm;
373 RISCVMCExpr::VariantKind VK;
Alex Bradbury3c941e72017-10-19 16:22:51 +0000374 if (!isImm())
375 return false;
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000376 bool IsConstantImm = evaluateConstantImm(Imm, VK);
377 return IsConstantImm && isUInt<12>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000378 }
379
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000380 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000381
Shiva Chenb22c1d22018-02-02 02:43:23 +0000382 bool isSImm10Lsb0000NonZero() const {
Alex Bradbury60714f92017-12-13 09:32:55 +0000383 int64_t Imm;
384 RISCVMCExpr::VariantKind VK;
385 bool IsConstantImm = evaluateConstantImm(Imm, VK);
Shiva Chenb22c1d22018-02-02 02:43:23 +0000386 return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) &&
Alex Bradbury60714f92017-12-13 09:32:55 +0000387 VK == RISCVMCExpr::VK_RISCV_None;
388 }
389
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000390 bool isUImm20() const {
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000391 RISCVMCExpr::VariantKind VK;
392 int64_t Imm;
393 bool IsValid;
Alex Bradbury3c941e72017-10-19 16:22:51 +0000394 if (!isImm())
395 return false;
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000396 bool IsConstantImm = evaluateConstantImm(Imm, VK);
397 if (!IsConstantImm)
398 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm);
399 else
400 IsValid = isUInt<20>(Imm);
401 return IsValid && (VK == RISCVMCExpr::VK_RISCV_None ||
402 VK == RISCVMCExpr::VK_RISCV_HI ||
403 VK == RISCVMCExpr::VK_RISCV_PCREL_HI);
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000404 }
405
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000406 bool isSImm21Lsb0() const { return isBareSimmNLsb0<21>(); }
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000407
Alex Bradbury04f06d92017-08-08 14:43:36 +0000408 /// getStartLoc - Gets location of the first token of this operand
409 SMLoc getStartLoc() const override { return StartLoc; }
410 /// getEndLoc - Gets location of the last token of this operand
411 SMLoc getEndLoc() const override { return EndLoc; }
Alex Bradburya6e62482017-12-07 10:53:48 +0000412 /// True if this operand is for an RV64 instruction
413 bool isRV64() const { return IsRV64; }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000414
415 unsigned getReg() const override {
416 assert(Kind == Register && "Invalid type access!");
417 return Reg.RegNum;
418 }
419
420 const MCExpr *getImm() const {
421 assert(Kind == Immediate && "Invalid type access!");
422 return Imm.Val;
423 }
424
425 StringRef getToken() const {
426 assert(Kind == Token && "Invalid type access!");
427 return Tok;
428 }
429
430 void print(raw_ostream &OS) const override {
431 switch (Kind) {
432 case Immediate:
433 OS << *getImm();
434 break;
435 case Register:
436 OS << "<register x";
437 OS << getReg() << ">";
438 break;
439 case Token:
440 OS << "'" << getToken() << "'";
441 break;
442 }
443 }
444
Alex Bradburya6e62482017-12-07 10:53:48 +0000445 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S,
446 bool IsRV64) {
Alex Bradbury04f06d92017-08-08 14:43:36 +0000447 auto Op = make_unique<RISCVOperand>(Token);
448 Op->Tok = Str;
449 Op->StartLoc = S;
450 Op->EndLoc = S;
Alex Bradburya6e62482017-12-07 10:53:48 +0000451 Op->IsRV64 = IsRV64;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000452 return Op;
453 }
454
455 static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
Alex Bradburya6e62482017-12-07 10:53:48 +0000456 SMLoc E, bool IsRV64) {
Alex Bradbury04f06d92017-08-08 14:43:36 +0000457 auto Op = make_unique<RISCVOperand>(Register);
458 Op->Reg.RegNum = RegNo;
459 Op->StartLoc = S;
460 Op->EndLoc = E;
Alex Bradburya6e62482017-12-07 10:53:48 +0000461 Op->IsRV64 = IsRV64;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000462 return Op;
463 }
464
465 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S,
Alex Bradburya6e62482017-12-07 10:53:48 +0000466 SMLoc E, bool IsRV64) {
Alex Bradbury04f06d92017-08-08 14:43:36 +0000467 auto Op = make_unique<RISCVOperand>(Immediate);
468 Op->Imm.Val = Val;
469 Op->StartLoc = S;
470 Op->EndLoc = E;
Alex Bradburya6e62482017-12-07 10:53:48 +0000471 Op->IsRV64 = IsRV64;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000472 return Op;
473 }
474
475 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
476 assert(Expr && "Expr shouldn't be null!");
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000477 int64_t Imm = 0;
478 bool IsConstant = false;
479 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
480 IsConstant = RE->evaluateAsConstant(Imm);
481 } else if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
482 IsConstant = true;
483 Imm = CE->getValue();
484 }
485
486 if (IsConstant)
487 Inst.addOperand(MCOperand::createImm(Imm));
Alex Bradbury04f06d92017-08-08 14:43:36 +0000488 else
489 Inst.addOperand(MCOperand::createExpr(Expr));
490 }
491
492 // Used by the TableGen Code
493 void addRegOperands(MCInst &Inst, unsigned N) const {
494 assert(N == 1 && "Invalid number of operands!");
495 Inst.addOperand(MCOperand::createReg(getReg()));
496 }
497
498 void addImmOperands(MCInst &Inst, unsigned N) const {
499 assert(N == 1 && "Invalid number of operands!");
500 addExpr(Inst, getImm());
501 }
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000502
503 void addFenceArgOperands(MCInst &Inst, unsigned N) const {
504 assert(N == 1 && "Invalid number of operands!");
505 // isFenceArg has validated the operand, meaning this cast is safe
506 auto SE = cast<MCSymbolRefExpr>(getImm());
507
508 unsigned Imm = 0;
509 for (char c : SE->getSymbol().getName()) {
510 switch (c) {
511 default: llvm_unreachable("FenceArg must contain only [iorw]");
512 case 'i': Imm |= RISCVFenceField::I; break;
513 case 'o': Imm |= RISCVFenceField::O; break;
514 case 'r': Imm |= RISCVFenceField::R; break;
515 case 'w': Imm |= RISCVFenceField::W; break;
516 }
517 }
518 Inst.addOperand(MCOperand::createImm(Imm));
519 }
Alex Bradbury0d6cf902017-12-07 10:26:05 +0000520
521 // Returns the rounding mode represented by this RISCVOperand. Should only
522 // be called after checking isFRMArg.
523 RISCVFPRndMode::RoundingMode getRoundingMode() const {
524 // isFRMArg has validated the operand, meaning this cast is safe.
525 auto SE = cast<MCSymbolRefExpr>(getImm());
526 RISCVFPRndMode::RoundingMode FRM =
527 RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName());
528 assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode");
529 return FRM;
530 }
531
532 void addFRMArgOperands(MCInst &Inst, unsigned N) const {
533 assert(N == 1 && "Invalid number of operands!");
534 Inst.addOperand(MCOperand::createImm(getRoundingMode()));
535 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000536};
537} // end anonymous namespace.
538
539#define GET_REGISTER_MATCHER
540#define GET_MATCHER_IMPLEMENTATION
Alex Bradbury04f06d92017-08-08 14:43:36 +0000541#include "RISCVGenAsmMatcher.inc"
542
Alex Bradbury7bc2a952017-12-07 10:46:23 +0000543// Return the matching FPR64 register for the given FPR32.
544// FIXME: Ideally this function could be removed in favour of using
545// information from TableGen.
546unsigned convertFPR32ToFPR64(unsigned Reg) {
547 switch (Reg) {
548 default:
549 llvm_unreachable("Not a recognised FPR32 register");
550 case RISCV::F0_32: return RISCV::F0_64;
551 case RISCV::F1_32: return RISCV::F1_64;
552 case RISCV::F2_32: return RISCV::F2_64;
553 case RISCV::F3_32: return RISCV::F3_64;
554 case RISCV::F4_32: return RISCV::F4_64;
555 case RISCV::F5_32: return RISCV::F5_64;
556 case RISCV::F6_32: return RISCV::F6_64;
557 case RISCV::F7_32: return RISCV::F7_64;
558 case RISCV::F8_32: return RISCV::F8_64;
559 case RISCV::F9_32: return RISCV::F9_64;
560 case RISCV::F10_32: return RISCV::F10_64;
561 case RISCV::F11_32: return RISCV::F11_64;
562 case RISCV::F12_32: return RISCV::F12_64;
563 case RISCV::F13_32: return RISCV::F13_64;
564 case RISCV::F14_32: return RISCV::F14_64;
565 case RISCV::F15_32: return RISCV::F15_64;
566 case RISCV::F16_32: return RISCV::F16_64;
567 case RISCV::F17_32: return RISCV::F17_64;
568 case RISCV::F18_32: return RISCV::F18_64;
569 case RISCV::F19_32: return RISCV::F19_64;
570 case RISCV::F20_32: return RISCV::F20_64;
571 case RISCV::F21_32: return RISCV::F21_64;
572 case RISCV::F22_32: return RISCV::F22_64;
573 case RISCV::F23_32: return RISCV::F23_64;
574 case RISCV::F24_32: return RISCV::F24_64;
575 case RISCV::F25_32: return RISCV::F25_64;
576 case RISCV::F26_32: return RISCV::F26_64;
577 case RISCV::F27_32: return RISCV::F27_64;
578 case RISCV::F28_32: return RISCV::F28_64;
579 case RISCV::F29_32: return RISCV::F29_64;
580 case RISCV::F30_32: return RISCV::F30_64;
581 case RISCV::F31_32: return RISCV::F31_64;
582 }
583}
584
585unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
586 unsigned Kind) {
587 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp);
588 if (!Op.isReg())
589 return Match_InvalidOperand;
590
591 unsigned Reg = Op.getReg();
592 bool IsRegFPR32 =
593 RISCVMCRegisterClasses[RISCV::FPR32RegClassID].contains(Reg);
Alex Bradbury60714f92017-12-13 09:32:55 +0000594 bool IsRegFPR32C =
595 RISCVMCRegisterClasses[RISCV::FPR32CRegClassID].contains(Reg);
Alex Bradbury7bc2a952017-12-07 10:46:23 +0000596
597 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
Alex Bradbury60714f92017-12-13 09:32:55 +0000598 // register from FPR32 to FPR64 or FPR32C to FPR64C if necessary.
599 if ((IsRegFPR32 && Kind == MCK_FPR64) ||
600 (IsRegFPR32C && Kind == MCK_FPR64C)) {
Alex Bradbury7bc2a952017-12-07 10:46:23 +0000601 Op.Reg.RegNum = convertFPR32ToFPR64(Reg);
602 return Match_Success;
603 }
604 return Match_InvalidOperand;
605}
606
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000607bool RISCVAsmParser::generateImmOutOfRangeError(
Alex Bradbury480b7bc2018-04-17 21:56:40 +0000608 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000609 Twine Msg = "immediate must be an integer in the range") {
610 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
611 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
612}
613
Alex Bradbury04f06d92017-08-08 14:43:36 +0000614bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
615 OperandVector &Operands,
616 MCStreamer &Out,
617 uint64_t &ErrorInfo,
618 bool MatchingInlineAsm) {
619 MCInst Inst;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000620
621 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) {
622 default:
623 break;
Alex Bradbury480b7bc2018-04-17 21:56:40 +0000624 case Match_Success:
625 return processInstruction(Inst, IDLoc, Out);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000626 case Match_MissingFeature:
627 return Error(IDLoc, "instruction use requires an option to be enabled");
628 case Match_MnemonicFail:
629 return Error(IDLoc, "unrecognized instruction mnemonic");
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000630 case Match_InvalidOperand: {
631 SMLoc ErrorLoc = IDLoc;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000632 if (ErrorInfo != ~0U) {
633 if (ErrorInfo >= Operands.size())
634 return Error(ErrorLoc, "too few operands for instruction");
635
636 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
637 if (ErrorLoc == SMLoc())
638 ErrorLoc = IDLoc;
639 }
640 return Error(ErrorLoc, "invalid operand for instruction");
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000641 }
Alex Bradbury480b7bc2018-04-17 21:56:40 +0000642 case Match_InvalidImmXLen:
643 if (isRV64()) {
644 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
645 return Error(ErrorLoc, "operand must be a constant 64-bit integer");
646 }
647 return generateImmOutOfRangeError(Operands, ErrorInfo,
648 std::numeric_limits<int32_t>::min(),
649 std::numeric_limits<uint32_t>::max());
Alex Bradburya6e62482017-12-07 10:53:48 +0000650 case Match_InvalidUImmLog2XLen:
651 if (isRV64())
652 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
653 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
Alex Bradbury0ad4c262017-12-15 10:20:51 +0000654 case Match_InvalidUImmLog2XLenNonZero:
655 if (isRV64())
656 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
657 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000658 case Match_InvalidUImm5:
659 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
Alex Bradbury581d6b02017-12-13 09:41:21 +0000660 case Match_InvalidSImm6:
661 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
662 (1 << 5) - 1);
Shiva Chenb22c1d22018-02-02 02:43:23 +0000663 case Match_InvalidSImm6NonZero:
664 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
665 (1 << 5) - 1,
666 "immediate must be non-zero in the range");
Shiva Chen7c172422018-02-22 15:02:28 +0000667 case Match_InvalidCLUIImm:
668 return generateImmOutOfRangeError(
669 Operands, ErrorInfo, 1, (1 << 5) - 1,
670 "immediate must be in [0xfffe0, 0xfffff] or");
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000671 case Match_InvalidUImm7Lsb00:
672 return generateImmOutOfRangeError(
673 Operands, ErrorInfo, 0, (1 << 7) - 4,
674 "immediate must be a multiple of 4 bytes in the range");
675 case Match_InvalidUImm8Lsb00:
676 return generateImmOutOfRangeError(
677 Operands, ErrorInfo, 0, (1 << 8) - 4,
678 "immediate must be a multiple of 4 bytes in the range");
679 case Match_InvalidUImm8Lsb000:
680 return generateImmOutOfRangeError(
681 Operands, ErrorInfo, 0, (1 << 8) - 8,
682 "immediate must be a multiple of 8 bytes in the range");
Alex Bradburyf8f4b902017-12-07 13:19:57 +0000683 case Match_InvalidSImm9Lsb0:
684 return generateImmOutOfRangeError(
685 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
686 "immediate must be a multiple of 2 bytes in the range");
Alex Bradbury9f6aec42017-12-07 12:50:32 +0000687 case Match_InvalidUImm9Lsb000:
688 return generateImmOutOfRangeError(
689 Operands, ErrorInfo, 0, (1 << 9) - 8,
690 "immediate must be a multiple of 8 bytes in the range");
Alex Bradbury60714f92017-12-13 09:32:55 +0000691 case Match_InvalidUImm10Lsb00NonZero:
692 return generateImmOutOfRangeError(
693 Operands, ErrorInfo, 4, (1 << 10) - 4,
694 "immediate must be a multiple of 4 bytes in the range");
Shiva Chenb22c1d22018-02-02 02:43:23 +0000695 case Match_InvalidSImm10Lsb0000NonZero:
Alex Bradbury60714f92017-12-13 09:32:55 +0000696 return generateImmOutOfRangeError(
697 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
Shiva Chenb22c1d22018-02-02 02:43:23 +0000698 "immediate must be a multiple of 16 bytes and non-zero in the range");
Alex Bradbury04f06d92017-08-08 14:43:36 +0000699 case Match_InvalidSImm12:
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000700 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
701 (1 << 11) - 1);
Alex Bradburyf8f4b902017-12-07 13:19:57 +0000702 case Match_InvalidSImm12Lsb0:
703 return generateImmOutOfRangeError(
704 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
705 "immediate must be a multiple of 2 bytes in the range");
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000706 case Match_InvalidUImm12:
707 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1);
708 case Match_InvalidSImm13Lsb0:
709 return generateImmOutOfRangeError(
710 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
711 "immediate must be a multiple of 2 bytes in the range");
712 case Match_InvalidUImm20:
713 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
714 case Match_InvalidSImm21Lsb0:
715 return generateImmOutOfRangeError(
716 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
717 "immediate must be a multiple of 2 bytes in the range");
718 case Match_InvalidFenceArg: {
Alex Bradbury04f06d92017-08-08 14:43:36 +0000719 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000720 return Error(
721 ErrorLoc,
722 "operand must be formed of letters selected in-order from 'iorw'");
723 }
Alex Bradbury0d6cf902017-12-07 10:26:05 +0000724 case Match_InvalidFRMArg: {
725 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
726 return Error(
727 ErrorLoc,
728 "operand must be a valid floating point rounding mode mnemonic");
729 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000730 }
731
732 llvm_unreachable("Unknown match type detected!");
733}
734
735bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
736 SMLoc &EndLoc) {
737 const AsmToken &Tok = getParser().getTok();
738 StartLoc = Tok.getLoc();
739 EndLoc = Tok.getEndLoc();
740 RegNo = 0;
741 StringRef Name = getLexer().getTok().getIdentifier();
742
743 if (!MatchRegisterName(Name) || !MatchRegisterAltName(Name)) {
744 getParser().Lex(); // Eat identifier token.
745 return false;
746 }
747
748 return Error(StartLoc, "invalid register name");
749}
750
Alex Bradbury8c345c52017-11-09 15:00:03 +0000751OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands,
752 bool AllowParens) {
753 SMLoc FirstS = getLoc();
754 bool HadParens = false;
755 AsmToken Buf[2];
756
757 // If this a parenthesised register name is allowed, parse it atomically
758 if (AllowParens && getLexer().is(AsmToken::LParen)) {
759 size_t ReadCount = getLexer().peekTokens(Buf);
760 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
761 HadParens = true;
762 getParser().Lex(); // Eat '('
763 }
764 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000765
766 switch (getLexer().getKind()) {
767 default:
768 return MatchOperand_NoMatch;
769 case AsmToken::Identifier:
770 StringRef Name = getLexer().getTok().getIdentifier();
771 unsigned RegNo = MatchRegisterName(Name);
772 if (RegNo == 0) {
773 RegNo = MatchRegisterAltName(Name);
Alex Bradbury8c345c52017-11-09 15:00:03 +0000774 if (RegNo == 0) {
775 if (HadParens)
776 getLexer().UnLex(Buf[0]);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000777 return MatchOperand_NoMatch;
Alex Bradbury8c345c52017-11-09 15:00:03 +0000778 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000779 }
Alex Bradbury8c345c52017-11-09 15:00:03 +0000780 if (HadParens)
Alex Bradburya6e62482017-12-07 10:53:48 +0000781 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64()));
Alex Bradbury8c345c52017-11-09 15:00:03 +0000782 SMLoc S = getLoc();
783 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
Alex Bradbury04f06d92017-08-08 14:43:36 +0000784 getLexer().Lex();
Alex Bradburya6e62482017-12-07 10:53:48 +0000785 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
Alex Bradbury04f06d92017-08-08 14:43:36 +0000786 }
Alex Bradbury8c345c52017-11-09 15:00:03 +0000787
788 if (HadParens) {
789 getParser().Lex(); // Eat ')'
Alex Bradburya6e62482017-12-07 10:53:48 +0000790 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
Alex Bradbury8c345c52017-11-09 15:00:03 +0000791 }
792
Alex Bradbury04f06d92017-08-08 14:43:36 +0000793 return MatchOperand_Success;
794}
795
796OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) {
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000797 SMLoc S = getLoc();
798 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
799 const MCExpr *Res;
800
Alex Bradbury04f06d92017-08-08 14:43:36 +0000801 switch (getLexer().getKind()) {
802 default:
803 return MatchOperand_NoMatch;
804 case AsmToken::LParen:
805 case AsmToken::Minus:
806 case AsmToken::Plus:
807 case AsmToken::Integer:
808 case AsmToken::String:
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000809 if (getParser().parseExpression(Res))
810 return MatchOperand_ParseFail;
811 break;
812 case AsmToken::Identifier: {
813 StringRef Identifier;
814 if (getParser().parseIdentifier(Identifier))
815 return MatchOperand_ParseFail;
816 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
817 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
Alex Bradbury04f06d92017-08-08 14:43:36 +0000818 break;
819 }
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000820 case AsmToken::Percent:
821 return parseOperandWithModifier(Operands);
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000822 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000823
Alex Bradburya6e62482017-12-07 10:53:48 +0000824 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000825 return MatchOperand_Success;
826}
827
828OperandMatchResultTy
829RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
830 SMLoc S = getLoc();
831 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
832
833 if (getLexer().getKind() != AsmToken::Percent) {
834 Error(getLoc(), "expected '%' for operand modifier");
835 return MatchOperand_ParseFail;
836 }
837
838 getParser().Lex(); // Eat '%'
839
840 if (getLexer().getKind() != AsmToken::Identifier) {
841 Error(getLoc(), "expected valid identifier for operand modifier");
842 return MatchOperand_ParseFail;
843 }
844 StringRef Identifier = getParser().getTok().getIdentifier();
845 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier);
846 if (VK == RISCVMCExpr::VK_RISCV_Invalid) {
847 Error(getLoc(), "unrecognized operand modifier");
848 return MatchOperand_ParseFail;
849 }
850
851 getParser().Lex(); // Eat the identifier
852 if (getLexer().getKind() != AsmToken::LParen) {
853 Error(getLoc(), "expected '('");
854 return MatchOperand_ParseFail;
855 }
856 getParser().Lex(); // Eat '('
857
858 const MCExpr *SubExpr;
859 if (getParser().parseParenExpression(SubExpr, E)) {
860 return MatchOperand_ParseFail;
861 }
862
863 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext());
Alex Bradburya6e62482017-12-07 10:53:48 +0000864 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000865 return MatchOperand_Success;
866}
867
868OperandMatchResultTy
869RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
870 if (getLexer().isNot(AsmToken::LParen)) {
871 Error(getLoc(), "expected '('");
Alex Bradbury04f06d92017-08-08 14:43:36 +0000872 return MatchOperand_ParseFail;
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000873 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000874
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000875 getParser().Lex(); // Eat '('
Alex Bradburya6e62482017-12-07 10:53:48 +0000876 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64()));
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000877
878 if (parseRegister(Operands) != MatchOperand_Success) {
879 Error(getLoc(), "expected register");
880 return MatchOperand_ParseFail;
881 }
882
883 if (getLexer().isNot(AsmToken::RParen)) {
884 Error(getLoc(), "expected ')'");
885 return MatchOperand_ParseFail;
886 }
887
888 getParser().Lex(); // Eat ')'
Alex Bradburya6e62482017-12-07 10:53:48 +0000889 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000890
Alex Bradbury04f06d92017-08-08 14:43:36 +0000891 return MatchOperand_Success;
892}
893
894/// Looks at a token type and creates the relevant operand
895/// from this information, adding to Operands.
896/// If operand was parsed, returns false, else true.
897bool RISCVAsmParser::parseOperand(OperandVector &Operands) {
898 // Attempt to parse token as register
Alex Bradbury8c345c52017-11-09 15:00:03 +0000899 if (parseRegister(Operands, true) == MatchOperand_Success)
Alex Bradbury04f06d92017-08-08 14:43:36 +0000900 return false;
901
902 // Attempt to parse token as an immediate
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000903 if (parseImmediate(Operands) == MatchOperand_Success) {
904 // Parse memory base register if present
905 if (getLexer().is(AsmToken::LParen))
906 return parseMemOpBaseReg(Operands) != MatchOperand_Success;
Alex Bradbury04f06d92017-08-08 14:43:36 +0000907 return false;
Alex Bradbury6758ecb2017-09-17 14:27:35 +0000908 }
Alex Bradbury04f06d92017-08-08 14:43:36 +0000909
910 // Finally we have exhausted all options and must declare defeat.
911 Error(getLoc(), "unknown operand");
912 return true;
913}
914
915bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
916 StringRef Name, SMLoc NameLoc,
917 OperandVector &Operands) {
918 // First operand is token for instruction
Alex Bradburya6e62482017-12-07 10:53:48 +0000919 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64()));
Alex Bradbury04f06d92017-08-08 14:43:36 +0000920
921 // If there are no more operands, then finish
922 if (getLexer().is(AsmToken::EndOfStatement))
923 return false;
924
925 // Parse first operand
926 if (parseOperand(Operands))
927 return true;
928
929 // Parse until end of statement, consuming commas between operands
930 while (getLexer().is(AsmToken::Comma)) {
931 // Consume comma token
932 getLexer().Lex();
933
934 // Parse next operand
935 if (parseOperand(Operands))
936 return true;
937 }
938
939 if (getLexer().isNot(AsmToken::EndOfStatement)) {
940 SMLoc Loc = getLexer().getLoc();
941 getParser().eatToEndOfStatement();
942 return Error(Loc, "unexpected token");
943 }
944
945 getParser().Lex(); // Consume the EndOfStatement.
946 return false;
947}
948
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000949bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,
950 RISCVMCExpr::VariantKind &Kind,
951 int64_t &Addend) {
952 Kind = RISCVMCExpr::VK_RISCV_None;
953 Addend = 0;
954
955 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
956 Kind = RE->getKind();
957 Expr = RE->getSubExpr();
958 }
959
960 // It's a simple symbol reference or constant with no addend.
961 if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr))
962 return true;
963
964 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr);
965 if (!BE)
966 return false;
967
968 if (!isa<MCSymbolRefExpr>(BE->getLHS()))
969 return false;
970
971 if (BE->getOpcode() != MCBinaryExpr::Add &&
972 BE->getOpcode() != MCBinaryExpr::Sub)
973 return false;
974
975 // We are able to support the subtraction of two symbol references
976 if (BE->getOpcode() == MCBinaryExpr::Sub &&
977 isa<MCSymbolRefExpr>(BE->getRHS()))
978 return true;
979
Hiroshi Inoue9ff23802018-04-09 04:37:53 +0000980 // See if the addend is a constant, otherwise there's more going
Alex Bradbury9d3f1252017-09-28 08:26:24 +0000981 // on here than we can deal with.
982 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS());
983 if (!AddendExpr)
984 return false;
985
986 Addend = AddendExpr->getValue();
987 if (BE->getOpcode() == MCBinaryExpr::Sub)
988 Addend = -Addend;
989
990 // It's some symbol reference + a constant addend
991 return Kind != RISCVMCExpr::VK_RISCV_Invalid;
992}
993
Alex Bradbury480b7bc2018-04-17 21:56:40 +0000994bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
995 MCStreamer &Out) {
996 Inst.setLoc(IDLoc);
997
998 switch (Inst.getOpcode()) {
999 case RISCV::PseudoLI: {
1000 auto Reg = Inst.getOperand(0).getReg();
1001 int64_t Imm = Inst.getOperand(1).getImm();
1002 // On RV32 the immediate here can either be a signed or an unsigned
1003 // 32-bit number. Sign extension has to be performed to ensure that Imm
1004 // represents the expected signed 64-bit number.
1005 if (!isRV64())
1006 Imm = SignExtend64<32>(Imm);
1007 emitRISCVLoadImm(Reg, Imm, Out, STI);
1008 return false;
1009 }
1010 }
1011
1012 MCInst CInst;
1013 bool Res = compressInst(CInst, Inst, getSTI(), Out.getContext());
1014 CInst.setLoc(IDLoc);
1015 Out.EmitInstruction((Res ? CInst : Inst), getSTI());
1016 return false;
1017}
1018
Alex Bradbury04f06d92017-08-08 14:43:36 +00001019bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { return true; }
1020
1021extern "C" void LLVMInitializeRISCVAsmParser() {
1022 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target());
1023 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target());
1024}