Bug Summary

File:llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Warning:line 2364, column 17
The right operand of '==' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name RISCVAsmParser.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-12/lib/clang/12.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/build-llvm/lib/Target/RISCV/AsmParser -I /build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser -I /build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV -I /build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/build-llvm/lib/Target/RISCV -I /build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/build-llvm/include -I /build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-12/lib/clang/12.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/build-llvm/lib/Target/RISCV/AsmParser -fdebug-prefix-map=/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734=. -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-12-11-210320-5824-1 -x c++ /build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
1//===-- RISCVAsmParser.cpp - Parse RISCV assembly to MCInst instructions --===//
2//
3// 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
6//
7//===----------------------------------------------------------------------===//
8
9#include "MCTargetDesc/RISCVAsmBackend.h"
10#include "MCTargetDesc/RISCVMCExpr.h"
11#include "MCTargetDesc/RISCVMCTargetDesc.h"
12#include "MCTargetDesc/RISCVTargetStreamer.h"
13#include "TargetInfo/RISCVTargetInfo.h"
14#include "Utils/RISCVBaseInfo.h"
15#include "Utils/RISCVMatInt.h"
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/ADT/SmallBitVector.h"
18#include "llvm/ADT/SmallString.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/ADT/Statistic.h"
21#include "llvm/ADT/StringSwitch.h"
22#include "llvm/MC/MCAssembler.h"
23#include "llvm/MC/MCContext.h"
24#include "llvm/MC/MCExpr.h"
25#include "llvm/MC/MCInst.h"
26#include "llvm/MC/MCInstBuilder.h"
27#include "llvm/MC/MCObjectFileInfo.h"
28#include "llvm/MC/MCParser/MCAsmLexer.h"
29#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
30#include "llvm/MC/MCParser/MCTargetAsmParser.h"
31#include "llvm/MC/MCRegisterInfo.h"
32#include "llvm/MC/MCStreamer.h"
33#include "llvm/MC/MCSubtargetInfo.h"
34#include "llvm/MC/MCValue.h"
35#include "llvm/Support/Casting.h"
36#include "llvm/Support/MathExtras.h"
37#include "llvm/Support/RISCVAttributes.h"
38#include "llvm/Support/TargetRegistry.h"
39
40#include <limits>
41
42using namespace llvm;
43
44#define DEBUG_TYPE"riscv-asm-parser" "riscv-asm-parser"
45
46// Include the auto-generated portion of the compress emitter.
47#define GEN_COMPRESS_INSTR
48#include "RISCVGenCompressInstEmitter.inc"
49
50STATISTIC(RISCVNumInstrsCompressed,static llvm::Statistic RISCVNumInstrsCompressed = {"riscv-asm-parser"
, "RISCVNumInstrsCompressed", "Number of RISC-V Compressed instructions emitted"
}
51 "Number of RISC-V Compressed instructions emitted")static llvm::Statistic RISCVNumInstrsCompressed = {"riscv-asm-parser"
, "RISCVNumInstrsCompressed", "Number of RISC-V Compressed instructions emitted"
}
;
52
53namespace {
54struct RISCVOperand;
55
56struct ParserOptionsSet {
57 bool IsPicEnabled;
58};
59
60class RISCVAsmParser : public MCTargetAsmParser {
61 SmallVector<FeatureBitset, 4> FeatureBitStack;
62
63 SmallVector<ParserOptionsSet, 4> ParserOptionsStack;
64 ParserOptionsSet ParserOptions;
65
66 SMLoc getLoc() const { return getParser().getTok().getLoc(); }
67 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
68 bool isRV32E() const { return getSTI().hasFeature(RISCV::FeatureRV32E); }
69
70 RISCVTargetStreamer &getTargetStreamer() {
71 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
72 return static_cast<RISCVTargetStreamer &>(TS);
73 }
74
75 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
76 unsigned Kind) override;
77
78 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
79 int64_t Lower, int64_t Upper, Twine Msg);
80
81 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
82 OperandVector &Operands, MCStreamer &Out,
83 uint64_t &ErrorInfo,
84 bool MatchingInlineAsm) override;
85
86 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
87 OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc,
88 SMLoc &EndLoc) override;
89
90 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
91 SMLoc NameLoc, OperandVector &Operands) override;
92
93 bool ParseDirective(AsmToken DirectiveID) override;
94
95 // Helper to actually emit an instruction to the MCStreamer. Also, when
96 // possible, compression of the instruction is performed.
97 void emitToStreamer(MCStreamer &S, const MCInst &Inst);
98
99 // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that
100 // synthesize the desired immedate value into the destination register.
101 void emitLoadImm(MCRegister DestReg, int64_t Value, MCStreamer &Out);
102
103 // Helper to emit a combination of AUIPC and SecondOpcode. Used to implement
104 // helpers such as emitLoadLocalAddress and emitLoadAddress.
105 void emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
106 const MCExpr *Symbol, RISCVMCExpr::VariantKind VKHi,
107 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
108
109 // Helper to emit pseudo instruction "lla" used in PC-rel addressing.
110 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
111
112 // Helper to emit pseudo instruction "la" used in GOT/PC-rel addressing.
113 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
114
115 // Helper to emit pseudo instruction "la.tls.ie" used in initial-exec TLS
116 // addressing.
117 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
118
119 // Helper to emit pseudo instruction "la.tls.gd" used in global-dynamic TLS
120 // addressing.
121 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
122
123 // Helper to emit pseudo load/store instruction with a symbol.
124 void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,
125 MCStreamer &Out, bool HasTmpReg);
126
127 // Helper to emit pseudo sign/zero extend instruction.
128 void emitPseudoExtend(MCInst &Inst, bool SignExtend, int64_t Width,
129 SMLoc IDLoc, MCStreamer &Out);
130
131 // Checks that a PseudoAddTPRel is using x4/tp in its second input operand.
132 // Enforcing this using a restricted register class for the second input
133 // operand of PseudoAddTPRel results in a poor diagnostic due to the fact
134 // 'add' is an overloaded mnemonic.
135 bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands);
136
137 // Check instruction constraints.
138 bool validateInstruction(MCInst &Inst, OperandVector &Operands);
139
140 /// Helper for processing MC instructions that have been successfully matched
141 /// by MatchAndEmitInstruction. Modifications to the emitted instructions,
142 /// like the expansion of pseudo instructions (e.g., "li"), can be performed
143 /// in this method.
144 bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,
145 MCStreamer &Out);
146
147// Auto-generated instruction matching functions
148#define GET_ASSEMBLER_HEADER
149#include "RISCVGenAsmMatcher.inc"
150
151 OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands);
152 OperandMatchResultTy parseImmediate(OperandVector &Operands);
153 OperandMatchResultTy parseRegister(OperandVector &Operands,
154 bool AllowParens = false);
155 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
156 OperandMatchResultTy parseAtomicMemOp(OperandVector &Operands);
157 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
158 OperandMatchResultTy parseBareSymbol(OperandVector &Operands);
159 OperandMatchResultTy parseCallSymbol(OperandVector &Operands);
160 OperandMatchResultTy parsePseudoJumpSymbol(OperandVector &Operands);
161 OperandMatchResultTy parseJALOffset(OperandVector &Operands);
162 OperandMatchResultTy parseVTypeI(OperandVector &Operands);
163 OperandMatchResultTy parseMaskReg(OperandVector &Operands);
164
165 bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
166
167 bool parseDirectiveOption();
168 bool parseDirectiveAttribute();
169
170 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
171 if (!(getSTI().getFeatureBits()[Feature])) {
172 MCSubtargetInfo &STI = copySTI();
173 setAvailableFeatures(
174 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
175 }
176 }
177
178 bool getFeatureBits(uint64_t Feature) {
179 return getSTI().getFeatureBits()[Feature];
180 }
181
182 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
183 if (getSTI().getFeatureBits()[Feature]) {
184 MCSubtargetInfo &STI = copySTI();
185 setAvailableFeatures(
186 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
187 }
188 }
189
190 void pushFeatureBits() {
191 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&((FeatureBitStack.size() == ParserOptionsStack.size() &&
"These two stacks must be kept synchronized") ? static_cast<
void> (0) : __assert_fail ("FeatureBitStack.size() == ParserOptionsStack.size() && \"These two stacks must be kept synchronized\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 192, __PRETTY_FUNCTION__))
192 "These two stacks must be kept synchronized")((FeatureBitStack.size() == ParserOptionsStack.size() &&
"These two stacks must be kept synchronized") ? static_cast<
void> (0) : __assert_fail ("FeatureBitStack.size() == ParserOptionsStack.size() && \"These two stacks must be kept synchronized\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 192, __PRETTY_FUNCTION__))
;
193 FeatureBitStack.push_back(getSTI().getFeatureBits());
194 ParserOptionsStack.push_back(ParserOptions);
195 }
196
197 bool popFeatureBits() {
198 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&((FeatureBitStack.size() == ParserOptionsStack.size() &&
"These two stacks must be kept synchronized") ? static_cast<
void> (0) : __assert_fail ("FeatureBitStack.size() == ParserOptionsStack.size() && \"These two stacks must be kept synchronized\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 199, __PRETTY_FUNCTION__))
199 "These two stacks must be kept synchronized")((FeatureBitStack.size() == ParserOptionsStack.size() &&
"These two stacks must be kept synchronized") ? static_cast<
void> (0) : __assert_fail ("FeatureBitStack.size() == ParserOptionsStack.size() && \"These two stacks must be kept synchronized\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 199, __PRETTY_FUNCTION__))
;
200 if (FeatureBitStack.empty())
201 return true;
202
203 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
204 copySTI().setFeatureBits(FeatureBits);
205 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
206
207 ParserOptions = ParserOptionsStack.pop_back_val();
208
209 return false;
210 }
211
212 std::unique_ptr<RISCVOperand> defaultMaskRegOp() const;
213
214public:
215 enum RISCVMatchResultTy {
216 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
217#define GET_OPERAND_DIAGNOSTIC_TYPES
218#include "RISCVGenAsmMatcher.inc"
219#undef GET_OPERAND_DIAGNOSTIC_TYPES
220 };
221
222 static bool classifySymbolRef(const MCExpr *Expr,
223 RISCVMCExpr::VariantKind &Kind);
224
225 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
226 const MCInstrInfo &MII, const MCTargetOptions &Options)
227 : MCTargetAsmParser(Options, STI, MII) {
228 Parser.addAliasForDirective(".half", ".2byte");
229 Parser.addAliasForDirective(".hword", ".2byte");
230 Parser.addAliasForDirective(".word", ".4byte");
231 Parser.addAliasForDirective(".dword", ".8byte");
232 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
233
234 auto ABIName = StringRef(Options.ABIName);
235 if (ABIName.endswith("f") &&
236 !getSTI().getFeatureBits()[RISCV::FeatureStdExtF]) {
237 errs() << "Hard-float 'f' ABI can't be used for a target that "
238 "doesn't support the F instruction set extension (ignoring "
239 "target-abi)\n";
240 } else if (ABIName.endswith("d") &&
241 !getSTI().getFeatureBits()[RISCV::FeatureStdExtD]) {
242 errs() << "Hard-float 'd' ABI can't be used for a target that "
243 "doesn't support the D instruction set extension (ignoring "
244 "target-abi)\n";
245 }
246
247 const MCObjectFileInfo *MOFI = Parser.getContext().getObjectFileInfo();
248 ParserOptions.IsPicEnabled = MOFI->isPositionIndependent();
249 }
250};
251
252/// RISCVOperand - Instances of this class represent a parsed machine
253/// instruction
254struct RISCVOperand : public MCParsedAsmOperand {
255
256 enum class KindTy {
257 Token,
258 Register,
259 Immediate,
260 SystemRegister,
261 VType,
262 } Kind;
263
264 bool IsRV64;
265
266 struct RegOp {
267 MCRegister RegNum;
268 };
269
270 struct ImmOp {
271 const MCExpr *Val;
272 };
273
274 struct SysRegOp {
275 const char *Data;
276 unsigned Length;
277 unsigned Encoding;
278 // FIXME: Add the Encoding parsed fields as needed for checks,
279 // e.g.: read/write or user/supervisor/machine privileges.
280 };
281
282 struct VTypeOp {
283 RISCVVSEW Sew;
284 RISCVVLMUL Lmul;
285 bool TailAgnostic;
286 bool MaskAgnostic;
287 };
288
289 SMLoc StartLoc, EndLoc;
290 union {
291 StringRef Tok;
292 RegOp Reg;
293 ImmOp Imm;
294 struct SysRegOp SysReg;
295 struct VTypeOp VType;
296 };
297
298 RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
299
300public:
301 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() {
302 Kind = o.Kind;
303 IsRV64 = o.IsRV64;
304 StartLoc = o.StartLoc;
305 EndLoc = o.EndLoc;
306 switch (Kind) {
307 case KindTy::Register:
308 Reg = o.Reg;
309 break;
310 case KindTy::Immediate:
311 Imm = o.Imm;
312 break;
313 case KindTy::Token:
314 Tok = o.Tok;
315 break;
316 case KindTy::SystemRegister:
317 SysReg = o.SysReg;
318 break;
319 case KindTy::VType:
320 VType = o.VType;
321 break;
322 }
323 }
324
325 bool isToken() const override { return Kind == KindTy::Token; }
326 bool isReg() const override { return Kind == KindTy::Register; }
327 bool isV0Reg() const {
328 return Kind == KindTy::Register && Reg.RegNum == RISCV::V0;
329 }
330 bool isImm() const override { return Kind == KindTy::Immediate; }
331 bool isMem() const override { return false; }
332 bool isSystemRegister() const { return Kind == KindTy::SystemRegister; }
333 bool isVType() const { return Kind == KindTy::VType; }
334
335 bool isGPR() const {
336 return Kind == KindTy::Register &&
337 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum);
338 }
339
340 static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
341 RISCVMCExpr::VariantKind &VK) {
342 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
343 VK = RE->getKind();
344 return RE->evaluateAsConstant(Imm);
345 }
346
347 if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
348 VK = RISCVMCExpr::VK_RISCV_None;
349 Imm = CE->getValue();
350 return true;
351 }
352
353 return false;
354 }
355
356 // True if operand is a symbol with no modifiers, or a constant with no
357 // modifiers and isShiftedInt<N-1, 1>(Op).
358 template <int N> bool isBareSimmNLsb0() const {
359 int64_t Imm;
360 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
361 if (!isImm())
362 return false;
363 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
364 bool IsValid;
365 if (!IsConstantImm)
366 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
367 else
368 IsValid = isShiftedInt<N - 1, 1>(Imm);
369 return IsValid && VK == RISCVMCExpr::VK_RISCV_None;
370 }
371
372 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td
373
374 bool isBareSymbol() const {
375 int64_t Imm;
376 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
377 // Must be of 'immediate' type but not a constant.
378 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
379 return false;
380 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
381 VK == RISCVMCExpr::VK_RISCV_None;
382 }
383
384 bool isCallSymbol() const {
385 int64_t Imm;
386 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
387 // Must be of 'immediate' type but not a constant.
388 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
389 return false;
390 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
391 (VK == RISCVMCExpr::VK_RISCV_CALL ||
392 VK == RISCVMCExpr::VK_RISCV_CALL_PLT);
393 }
394
395 bool isPseudoJumpSymbol() const {
396 int64_t Imm;
397 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
398 // Must be of 'immediate' type but not a constant.
399 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
400 return false;
401 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
402 VK == RISCVMCExpr::VK_RISCV_CALL;
403 }
404
405 bool isTPRelAddSymbol() const {
406 int64_t Imm;
407 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
408 // Must be of 'immediate' type but not a constant.
409 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
410 return false;
411 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
412 VK == RISCVMCExpr::VK_RISCV_TPREL_ADD;
413 }
414
415 bool isCSRSystemRegister() const { return isSystemRegister(); }
416
417 bool isVTypeI() const { return isVType(); }
418
419 /// Return true if the operand is a valid for the fence instruction e.g.
420 /// ('iorw').
421 bool isFenceArg() const {
422 if (!isImm())
423 return false;
424 const MCExpr *Val = getImm();
425 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
426 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
427 return false;
428
429 StringRef Str = SVal->getSymbol().getName();
430 // Letters must be unique, taken from 'iorw', and in ascending order. This
431 // holds as long as each individual character is one of 'iorw' and is
432 // greater than the previous character.
433 char Prev = '\0';
434 for (char c : Str) {
435 if (c != 'i' && c != 'o' && c != 'r' && c != 'w')
436 return false;
437 if (c <= Prev)
438 return false;
439 Prev = c;
440 }
441 return true;
442 }
443
444 /// Return true if the operand is a valid floating point rounding mode.
445 bool isFRMArg() const {
446 if (!isImm())
447 return false;
448 const MCExpr *Val = getImm();
449 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
450 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
451 return false;
452
453 StringRef Str = SVal->getSymbol().getName();
454
455 return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid;
456 }
457
458 bool isImmXLenLI() const {
459 int64_t Imm;
460 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
461 if (!isImm())
462 return false;
463 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
464 if (VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO)
465 return true;
466 // Given only Imm, ensuring that the actually specified constant is either
467 // a signed or unsigned 64-bit number is unfortunately impossible.
468 return IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None &&
469 (isRV64() || (isInt<32>(Imm) || isUInt<32>(Imm)));
470 }
471
472 bool isUImmLog2XLen() const {
473 int64_t Imm;
474 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
475 if (!isImm())
476 return false;
477 if (!evaluateConstantImm(getImm(), Imm, VK) ||
478 VK != RISCVMCExpr::VK_RISCV_None)
479 return false;
480 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
481 }
482
483 bool isUImmLog2XLenNonZero() const {
484 int64_t Imm;
485 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
486 if (!isImm())
487 return false;
488 if (!evaluateConstantImm(getImm(), Imm, VK) ||
489 VK != RISCVMCExpr::VK_RISCV_None)
490 return false;
491 if (Imm == 0)
492 return false;
493 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm);
494 }
495
496 bool isUImmLog2XLenHalf() const {
497 int64_t Imm;
498 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
499 if (!isImm())
500 return false;
501 if (!evaluateConstantImm(getImm(), Imm, VK) ||
502 VK != RISCVMCExpr::VK_RISCV_None)
503 return false;
504 return (isRV64() && isUInt<5>(Imm)) || isUInt<4>(Imm);
505 }
506
507 bool isUImm5() const {
508 int64_t Imm;
509 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
510 if (!isImm())
511 return false;
512 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
513 return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
514 }
515
516 bool isUImm5NonZero() const {
517 int64_t Imm;
518 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
519 if (!isImm())
520 return false;
521 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
522 return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) &&
523 VK == RISCVMCExpr::VK_RISCV_None;
524 }
525
526 bool isSImm5() const {
527 if (!isImm())
528 return false;
529 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
530 int64_t Imm;
531 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
532 return IsConstantImm && isInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
533 }
534
535 bool isSImm6() const {
536 if (!isImm())
537 return false;
538 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
539 int64_t Imm;
540 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
541 return IsConstantImm && isInt<6>(Imm) &&
542 VK == RISCVMCExpr::VK_RISCV_None;
543 }
544
545 bool isSImm6NonZero() const {
546 if (!isImm())
547 return false;
548 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
549 int64_t Imm;
550 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
551 return IsConstantImm && isInt<6>(Imm) && (Imm != 0) &&
552 VK == RISCVMCExpr::VK_RISCV_None;
553 }
554
555 bool isCLUIImm() const {
556 if (!isImm())
557 return false;
558 int64_t Imm;
559 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
560 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
561 return IsConstantImm && (Imm != 0) &&
562 (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) &&
563 VK == RISCVMCExpr::VK_RISCV_None;
564 }
565
566 bool isUImm7Lsb00() const {
567 if (!isImm())
568 return false;
569 int64_t Imm;
570 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
571 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
572 return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
573 VK == RISCVMCExpr::VK_RISCV_None;
574 }
575
576 bool isUImm8Lsb00() const {
577 if (!isImm())
578 return false;
579 int64_t Imm;
580 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
581 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
582 return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
583 VK == RISCVMCExpr::VK_RISCV_None;
584 }
585
586 bool isUImm8Lsb000() const {
587 if (!isImm())
588 return false;
589 int64_t Imm;
590 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
591 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
592 return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
593 VK == RISCVMCExpr::VK_RISCV_None;
594 }
595
596 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); }
597
598 bool isUImm9Lsb000() const {
599 if (!isImm())
600 return false;
601 int64_t Imm;
602 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
603 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
604 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
605 VK == RISCVMCExpr::VK_RISCV_None;
606 }
607
608 bool isUImm10Lsb00NonZero() const {
609 if (!isImm())
610 return false;
611 int64_t Imm;
612 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
613 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
614 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) &&
615 VK == RISCVMCExpr::VK_RISCV_None;
616 }
617
618 bool isSImm12() const {
619 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
620 int64_t Imm;
621 bool IsValid;
622 if (!isImm())
623 return false;
624 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
625 if (!IsConstantImm)
626 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
627 else
628 IsValid = isInt<12>(Imm);
629 return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) ||
630 VK == RISCVMCExpr::VK_RISCV_LO ||
631 VK == RISCVMCExpr::VK_RISCV_PCREL_LO ||
632 VK == RISCVMCExpr::VK_RISCV_TPREL_LO);
633 }
634
635 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); }
636
637 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
638
639 bool isSImm10Lsb0000NonZero() const {
640 if (!isImm())
641 return false;
642 int64_t Imm;
643 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
644 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
645 return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) &&
646 VK == RISCVMCExpr::VK_RISCV_None;
647 }
648
649 bool isUImm20LUI() const {
650 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
651 int64_t Imm;
652 bool IsValid;
653 if (!isImm())
654 return false;
655 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
656 if (!IsConstantImm) {
657 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
658 return IsValid && (VK == RISCVMCExpr::VK_RISCV_HI ||
659 VK == RISCVMCExpr::VK_RISCV_TPREL_HI);
660 } else {
661 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
662 VK == RISCVMCExpr::VK_RISCV_HI ||
663 VK == RISCVMCExpr::VK_RISCV_TPREL_HI);
664 }
665 }
666
667 bool isUImm20AUIPC() const {
668 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
669 int64_t Imm;
670 bool IsValid;
671 if (!isImm())
672 return false;
673 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
674 if (!IsConstantImm) {
675 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
676 return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
677 VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
678 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
679 VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI);
680 } else {
681 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
682 VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
683 VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
684 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
685 VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI);
686 }
687 }
688
689 bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); }
690
691 bool isImmZero() const {
692 if (!isImm())
693 return false;
694 int64_t Imm;
695 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
696 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
697 return IsConstantImm && (Imm == 0) && VK == RISCVMCExpr::VK_RISCV_None;
698 }
699
700 bool isSImm5Plus1() const {
701 if (!isImm())
702 return false;
703 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
704 int64_t Imm;
705 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
706 return IsConstantImm && isInt<5>(Imm - 1) &&
707 VK == RISCVMCExpr::VK_RISCV_None;
708 }
709
710 /// getStartLoc - Gets location of the first token of this operand
711 SMLoc getStartLoc() const override { return StartLoc; }
712 /// getEndLoc - Gets location of the last token of this operand
713 SMLoc getEndLoc() const override { return EndLoc; }
714 /// True if this operand is for an RV64 instruction
715 bool isRV64() const { return IsRV64; }
716
717 unsigned getReg() const override {
718 assert(Kind == KindTy::Register && "Invalid type access!")((Kind == KindTy::Register && "Invalid type access!")
? static_cast<void> (0) : __assert_fail ("Kind == KindTy::Register && \"Invalid type access!\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 718, __PRETTY_FUNCTION__))
;
719 return Reg.RegNum.id();
720 }
721
722 StringRef getSysReg() const {
723 assert(Kind == KindTy::SystemRegister && "Invalid access!")((Kind == KindTy::SystemRegister && "Invalid access!"
) ? static_cast<void> (0) : __assert_fail ("Kind == KindTy::SystemRegister && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 723, __PRETTY_FUNCTION__))
;
724 return StringRef(SysReg.Data, SysReg.Length);
725 }
726
727 const MCExpr *getImm() const {
728 assert(Kind == KindTy::Immediate && "Invalid type access!")((Kind == KindTy::Immediate && "Invalid type access!"
) ? static_cast<void> (0) : __assert_fail ("Kind == KindTy::Immediate && \"Invalid type access!\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 728, __PRETTY_FUNCTION__))
;
729 return Imm.Val;
730 }
731
732 StringRef getToken() const {
733 assert(Kind == KindTy::Token && "Invalid type access!")((Kind == KindTy::Token && "Invalid type access!") ? static_cast
<void> (0) : __assert_fail ("Kind == KindTy::Token && \"Invalid type access!\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 733, __PRETTY_FUNCTION__))
;
734 return Tok;
735 }
736
737 static StringRef getSEWStr(RISCVVSEW Sew) {
738 switch (Sew) {
739 case RISCVVSEW::SEW_8:
740 return "e8";
741 case RISCVVSEW::SEW_16:
742 return "e16";
743 case RISCVVSEW::SEW_32:
744 return "e32";
745 case RISCVVSEW::SEW_64:
746 return "e64";
747 case RISCVVSEW::SEW_128:
748 return "e128";
749 case RISCVVSEW::SEW_256:
750 return "e256";
751 case RISCVVSEW::SEW_512:
752 return "e512";
753 case RISCVVSEW::SEW_1024:
754 return "e1024";
755 }
756 llvm_unreachable("Unknown SEW.")::llvm::llvm_unreachable_internal("Unknown SEW.", "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 756)
;
757 }
758
759 static StringRef getLMULStr(RISCVVLMUL Lmul) {
760 switch (Lmul) {
761 case RISCVVLMUL::LMUL_1:
762 return "m1";
763 case RISCVVLMUL::LMUL_2:
764 return "m2";
765 case RISCVVLMUL::LMUL_4:
766 return "m4";
767 case RISCVVLMUL::LMUL_8:
768 return "m8";
769 case RISCVVLMUL::LMUL_F2:
770 return "mf2";
771 case RISCVVLMUL::LMUL_F4:
772 return "mf4";
773 case RISCVVLMUL::LMUL_F8:
774 return "mf8";
775 }
776 llvm_unreachable("Unknown LMUL.")::llvm::llvm_unreachable_internal("Unknown LMUL.", "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 776)
;
777 }
778
779 StringRef getVType(SmallString<32> &Buf) const {
780 assert(Kind == KindTy::VType && "Invalid access!")((Kind == KindTy::VType && "Invalid access!") ? static_cast
<void> (0) : __assert_fail ("Kind == KindTy::VType && \"Invalid access!\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 780, __PRETTY_FUNCTION__))
;
781 Buf.append(getSEWStr(VType.Sew));
782 Buf.append(",");
783 Buf.append(getLMULStr(VType.Lmul));
784
785 return Buf.str();
786 }
787
788 void print(raw_ostream &OS) const override {
789 switch (Kind) {
790 case KindTy::Immediate:
791 OS << *getImm();
792 break;
793 case KindTy::Register:
794 OS << "<register x";
795 OS << getReg() << ">";
796 break;
797 case KindTy::Token:
798 OS << "'" << getToken() << "'";
799 break;
800 case KindTy::SystemRegister:
801 OS << "<sysreg: " << getSysReg() << '>';
802 break;
803 case KindTy::VType:
804 SmallString<32> VTypeBuf;
805 OS << "<vtype: " << getVType(VTypeBuf) << '>';
806 break;
807 }
808 }
809
810 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S,
811 bool IsRV64) {
812 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
813 Op->Tok = Str;
814 Op->StartLoc = S;
815 Op->EndLoc = S;
816 Op->IsRV64 = IsRV64;
817 return Op;
818 }
819
820 static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
821 SMLoc E, bool IsRV64) {
822 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
823 Op->Reg.RegNum = RegNo;
824 Op->StartLoc = S;
825 Op->EndLoc = E;
826 Op->IsRV64 = IsRV64;
827 return Op;
828 }
829
830 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S,
831 SMLoc E, bool IsRV64) {
832 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
833 Op->Imm.Val = Val;
834 Op->StartLoc = S;
835 Op->EndLoc = E;
836 Op->IsRV64 = IsRV64;
837 return Op;
838 }
839
840 static std::unique_ptr<RISCVOperand>
841 createSysReg(StringRef Str, SMLoc S, unsigned Encoding, bool IsRV64) {
842 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
843 Op->SysReg.Data = Str.data();
844 Op->SysReg.Length = Str.size();
845 Op->SysReg.Encoding = Encoding;
846 Op->StartLoc = S;
847 Op->IsRV64 = IsRV64;
848 return Op;
849 }
850
851 static std::unique_ptr<RISCVOperand>
852 createVType(unsigned Sew, unsigned Lmul, bool Fractional, bool TailAgnostic,
853 bool MaskAgnostic, SMLoc S, bool IsRV64) {
854 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
855 unsigned SewLog2 = Log2_32(Sew / 8);
856 unsigned LmulLog2 = Log2_32(Lmul);
857 Op->VType.Sew = static_cast<RISCVVSEW>(SewLog2);
858 if (Fractional) {
859 unsigned Flmul = 8 - LmulLog2;
860 Op->VType.Lmul = static_cast<RISCVVLMUL>(Flmul);
861 } else {
862 Op->VType.Lmul = static_cast<RISCVVLMUL>(LmulLog2);
863 }
864 Op->VType.TailAgnostic = TailAgnostic;
865 Op->VType.MaskAgnostic = MaskAgnostic;
866 Op->StartLoc = S;
867 Op->IsRV64 = IsRV64;
868 return Op;
869 }
870
871 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
872 assert(Expr && "Expr shouldn't be null!")((Expr && "Expr shouldn't be null!") ? static_cast<
void> (0) : __assert_fail ("Expr && \"Expr shouldn't be null!\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 872, __PRETTY_FUNCTION__))
;
873 int64_t Imm = 0;
874 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
875 bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
876
877 if (IsConstant)
878 Inst.addOperand(MCOperand::createImm(Imm));
879 else
880 Inst.addOperand(MCOperand::createExpr(Expr));
881 }
882
883 // Used by the TableGen Code
884 void addRegOperands(MCInst &Inst, unsigned N) const {
885 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 885, __PRETTY_FUNCTION__))
;
886 Inst.addOperand(MCOperand::createReg(getReg()));
887 }
888
889 void addImmOperands(MCInst &Inst, unsigned N) const {
890 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 890, __PRETTY_FUNCTION__))
;
891 addExpr(Inst, getImm());
892 }
893
894 void addSImm5Plus1Operands(MCInst &Inst, unsigned N) const {
895 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 895, __PRETTY_FUNCTION__))
;
896 int64_t Imm = 0;
897 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
898 bool IsConstant = evaluateConstantImm(getImm(), Imm, VK);
899 assert(IsConstant && "Expect constant value!")((IsConstant && "Expect constant value!") ? static_cast
<void> (0) : __assert_fail ("IsConstant && \"Expect constant value!\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 899, __PRETTY_FUNCTION__))
;
900 (void)IsConstant;
901 Inst.addOperand(MCOperand::createImm(Imm - 1));
902 }
903
904 void addFenceArgOperands(MCInst &Inst, unsigned N) const {
905 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 905, __PRETTY_FUNCTION__))
;
906 // isFenceArg has validated the operand, meaning this cast is safe
907 auto SE = cast<MCSymbolRefExpr>(getImm());
908
909 unsigned Imm = 0;
910 for (char c : SE->getSymbol().getName()) {
911 switch (c) {
912 default:
913 llvm_unreachable("FenceArg must contain only [iorw]")::llvm::llvm_unreachable_internal("FenceArg must contain only [iorw]"
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 913)
;
914 case 'i': Imm |= RISCVFenceField::I; break;
915 case 'o': Imm |= RISCVFenceField::O; break;
916 case 'r': Imm |= RISCVFenceField::R; break;
917 case 'w': Imm |= RISCVFenceField::W; break;
918 }
919 }
920 Inst.addOperand(MCOperand::createImm(Imm));
921 }
922
923 void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
924 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 924, __PRETTY_FUNCTION__))
;
925 Inst.addOperand(MCOperand::createImm(SysReg.Encoding));
926 }
927
928 void addVTypeIOperands(MCInst &Inst, unsigned N) const {
929 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 929, __PRETTY_FUNCTION__))
;
930 unsigned VTypeI = RISCVVType::encodeVTYPE(
931 VType.Lmul, VType.Sew, VType.TailAgnostic, VType.MaskAgnostic);
932 Inst.addOperand(MCOperand::createImm(VTypeI));
933 }
934
935 // Returns the rounding mode represented by this RISCVOperand. Should only
936 // be called after checking isFRMArg.
937 RISCVFPRndMode::RoundingMode getRoundingMode() const {
938 // isFRMArg has validated the operand, meaning this cast is safe.
939 auto SE = cast<MCSymbolRefExpr>(getImm());
940 RISCVFPRndMode::RoundingMode FRM =
941 RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName());
942 assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode")((FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode"
) ? static_cast<void> (0) : __assert_fail ("FRM != RISCVFPRndMode::Invalid && \"Invalid rounding mode\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 942, __PRETTY_FUNCTION__))
;
943 return FRM;
944 }
945
946 void addFRMArgOperands(MCInst &Inst, unsigned N) const {
947 assert(N == 1 && "Invalid number of operands!")((N == 1 && "Invalid number of operands!") ? static_cast
<void> (0) : __assert_fail ("N == 1 && \"Invalid number of operands!\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 947, __PRETTY_FUNCTION__))
;
948 Inst.addOperand(MCOperand::createImm(getRoundingMode()));
949 }
950};
951} // end anonymous namespace.
952
953#define GET_REGISTER_MATCHER
954#define GET_SUBTARGET_FEATURE_NAME
955#define GET_MATCHER_IMPLEMENTATION
956#define GET_MNEMONIC_SPELL_CHECKER
957#include "RISCVGenAsmMatcher.inc"
958
959static MCRegister convertFPR64ToFPR16(MCRegister Reg) {
960 assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register")((Reg >= RISCV::F0_D && Reg <= RISCV::F31_D &&
"Invalid register") ? static_cast<void> (0) : __assert_fail
("Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && \"Invalid register\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 960, __PRETTY_FUNCTION__))
;
961 return Reg - RISCV::F0_D + RISCV::F0_H;
962}
963
964static MCRegister convertFPR64ToFPR32(MCRegister Reg) {
965 assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register")((Reg >= RISCV::F0_D && Reg <= RISCV::F31_D &&
"Invalid register") ? static_cast<void> (0) : __assert_fail
("Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && \"Invalid register\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 965, __PRETTY_FUNCTION__))
;
966 return Reg - RISCV::F0_D + RISCV::F0_F;
967}
968
969unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
970 unsigned Kind) {
971 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp);
972 if (!Op.isReg())
973 return Match_InvalidOperand;
974
975 MCRegister Reg = Op.getReg();
976 bool IsRegFPR64 =
977 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(Reg);
978 bool IsRegFPR64C =
979 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(Reg);
980
981 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
982 // register from FPR64 to FPR32 or FPR64C to FPR32C if necessary.
983 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
984 (IsRegFPR64C && Kind == MCK_FPR32C)) {
985 Op.Reg.RegNum = convertFPR64ToFPR32(Reg);
986 return Match_Success;
987 }
988 // As the parser couldn't differentiate an FPR16 from an FPR64, coerce the
989 // register from FPR64 to FPR16 if necessary.
990 if (IsRegFPR64 && Kind == MCK_FPR16) {
991 Op.Reg.RegNum = convertFPR64ToFPR16(Reg);
992 return Match_Success;
993 }
994 return Match_InvalidOperand;
995}
996
997bool RISCVAsmParser::generateImmOutOfRangeError(
998 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
999 Twine Msg = "immediate must be an integer in the range") {
1000 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1001 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
1002}
1003
1004static std::string RISCVMnemonicSpellCheck(StringRef S,
1005 const FeatureBitset &FBS,
1006 unsigned VariantID = 0);
1007
1008bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1009 OperandVector &Operands,
1010 MCStreamer &Out,
1011 uint64_t &ErrorInfo,
1012 bool MatchingInlineAsm) {
1013 MCInst Inst;
1014 FeatureBitset MissingFeatures;
1015
1016 auto Result =
1017 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1018 MatchingInlineAsm);
1019 switch (Result) {
1
Control jumps to 'case Match_Success:' at line 1022
1020 default:
1021 break;
1022 case Match_Success:
1023 if (validateInstruction(Inst, Operands))
2
Calling 'RISCVAsmParser::validateInstruction'
1024 return true;
1025 return processInstruction(Inst, IDLoc, Operands, Out);
1026 case Match_MissingFeature: {
1027 assert(MissingFeatures.any() && "Unknown missing features!")((MissingFeatures.any() && "Unknown missing features!"
) ? static_cast<void> (0) : __assert_fail ("MissingFeatures.any() && \"Unknown missing features!\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 1027, __PRETTY_FUNCTION__))
;
1028 bool FirstFeature = true;
1029 std::string Msg = "instruction requires the following:";
1030 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
1031 if (MissingFeatures[i]) {
1032 Msg += FirstFeature ? " " : ", ";
1033 Msg += getSubtargetFeatureName(i);
1034 FirstFeature = false;
1035 }
1036 }
1037 return Error(IDLoc, Msg);
1038 }
1039 case Match_MnemonicFail: {
1040 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1041 std::string Suggestion = RISCVMnemonicSpellCheck(
1042 ((RISCVOperand &)*Operands[0]).getToken(), FBS);
1043 return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);
1044 }
1045 case Match_InvalidOperand: {
1046 SMLoc ErrorLoc = IDLoc;
1047 if (ErrorInfo != ~0U) {
1048 if (ErrorInfo >= Operands.size())
1049 return Error(ErrorLoc, "too few operands for instruction");
1050
1051 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1052 if (ErrorLoc == SMLoc())
1053 ErrorLoc = IDLoc;
1054 }
1055 return Error(ErrorLoc, "invalid operand for instruction");
1056 }
1057 }
1058
1059 // Handle the case when the error message is of specific type
1060 // other than the generic Match_InvalidOperand, and the
1061 // corresponding operand is missing.
1062 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1063 SMLoc ErrorLoc = IDLoc;
1064 if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
1065 return Error(ErrorLoc, "too few operands for instruction");
1066 }
1067
1068 switch(Result) {
1069 default:
1070 break;
1071 case Match_InvalidImmXLenLI:
1072 if (isRV64()) {
1073 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1074 return Error(ErrorLoc, "operand must be a constant 64-bit integer");
1075 }
1076 return generateImmOutOfRangeError(Operands, ErrorInfo,
1077 std::numeric_limits<int32_t>::min(),
1078 std::numeric_limits<uint32_t>::max());
1079 case Match_InvalidImmZero: {
1080 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1081 return Error(ErrorLoc, "immediate must be zero");
1082 }
1083 case Match_InvalidUImmLog2XLen:
1084 if (isRV64())
1085 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1086 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1087 case Match_InvalidUImmLog2XLenNonZero:
1088 if (isRV64())
1089 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
1090 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1091 case Match_InvalidUImmLog2XLenHalf:
1092 if (isRV64())
1093 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1094 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1095 case Match_InvalidUImm5:
1096 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1097 case Match_InvalidSImm6:
1098 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
1099 (1 << 5) - 1);
1100 case Match_InvalidSImm6NonZero:
1101 return generateImmOutOfRangeError(
1102 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1103 "immediate must be non-zero in the range");
1104 case Match_InvalidCLUIImm:
1105 return generateImmOutOfRangeError(
1106 Operands, ErrorInfo, 1, (1 << 5) - 1,
1107 "immediate must be in [0xfffe0, 0xfffff] or");
1108 case Match_InvalidUImm7Lsb00:
1109 return generateImmOutOfRangeError(
1110 Operands, ErrorInfo, 0, (1 << 7) - 4,
1111 "immediate must be a multiple of 4 bytes in the range");
1112 case Match_InvalidUImm8Lsb00:
1113 return generateImmOutOfRangeError(
1114 Operands, ErrorInfo, 0, (1 << 8) - 4,
1115 "immediate must be a multiple of 4 bytes in the range");
1116 case Match_InvalidUImm8Lsb000:
1117 return generateImmOutOfRangeError(
1118 Operands, ErrorInfo, 0, (1 << 8) - 8,
1119 "immediate must be a multiple of 8 bytes in the range");
1120 case Match_InvalidSImm9Lsb0:
1121 return generateImmOutOfRangeError(
1122 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1123 "immediate must be a multiple of 2 bytes in the range");
1124 case Match_InvalidUImm9Lsb000:
1125 return generateImmOutOfRangeError(
1126 Operands, ErrorInfo, 0, (1 << 9) - 8,
1127 "immediate must be a multiple of 8 bytes in the range");
1128 case Match_InvalidUImm10Lsb00NonZero:
1129 return generateImmOutOfRangeError(
1130 Operands, ErrorInfo, 4, (1 << 10) - 4,
1131 "immediate must be a multiple of 4 bytes in the range");
1132 case Match_InvalidSImm10Lsb0000NonZero:
1133 return generateImmOutOfRangeError(
1134 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1135 "immediate must be a multiple of 16 bytes and non-zero in the range");
1136 case Match_InvalidSImm12:
1137 return generateImmOutOfRangeError(
1138 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1139 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1140 "integer in the range");
1141 case Match_InvalidSImm12Lsb0:
1142 return generateImmOutOfRangeError(
1143 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1144 "immediate must be a multiple of 2 bytes in the range");
1145 case Match_InvalidSImm13Lsb0:
1146 return generateImmOutOfRangeError(
1147 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1148 "immediate must be a multiple of 2 bytes in the range");
1149 case Match_InvalidUImm20LUI:
1150 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1,
1151 "operand must be a symbol with "
1152 "%hi/%tprel_hi modifier or an integer in "
1153 "the range");
1154 case Match_InvalidUImm20AUIPC:
1155 return generateImmOutOfRangeError(
1156 Operands, ErrorInfo, 0, (1 << 20) - 1,
1157 "operand must be a symbol with a "
1158 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1159 "an integer in the range");
1160 case Match_InvalidSImm21Lsb0JAL:
1161 return generateImmOutOfRangeError(
1162 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1163 "immediate must be a multiple of 2 bytes in the range");
1164 case Match_InvalidCSRSystemRegister: {
1165 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
1166 "operand must be a valid system register "
1167 "name or an integer in the range");
1168 }
1169 case Match_InvalidFenceArg: {
1170 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1171 return Error(
1172 ErrorLoc,
1173 "operand must be formed of letters selected in-order from 'iorw'");
1174 }
1175 case Match_InvalidFRMArg: {
1176 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1177 return Error(
1178 ErrorLoc,
1179 "operand must be a valid floating point rounding mode mnemonic");
1180 }
1181 case Match_InvalidBareSymbol: {
1182 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1183 return Error(ErrorLoc, "operand must be a bare symbol name");
1184 }
1185 case Match_InvalidPseudoJumpSymbol: {
1186 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1187 return Error(ErrorLoc, "operand must be a valid jump target");
1188 }
1189 case Match_InvalidCallSymbol: {
1190 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1191 return Error(ErrorLoc, "operand must be a bare symbol name");
1192 }
1193 case Match_InvalidTPRelAddSymbol: {
1194 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1195 return Error(ErrorLoc, "operand must be a symbol with %tprel_add modifier");
1196 }
1197 case Match_InvalidVTypeI: {
1198 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1199 return Error(
1200 ErrorLoc,
1201 "operand must be "
1202 "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
1203 }
1204 case Match_InvalidVMaskRegister: {
1205 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1206 return Error(ErrorLoc, "operand must be v0.t");
1207 }
1208 case Match_InvalidSImm5Plus1: {
1209 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,
1210 (1 << 4),
1211 "immediate must be in the range");
1212 }
1213 }
1214
1215 llvm_unreachable("Unknown match type detected!")::llvm::llvm_unreachable_internal("Unknown match type detected!"
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 1215)
;
1216}
1217
1218// Attempts to match Name as a register (either using the default name or
1219// alternative ABI names), setting RegNo to the matching register. Upon
1220// failure, returns true and sets RegNo to 0. If IsRV32E then registers
1221// x16-x31 will be rejected.
1222static bool matchRegisterNameHelper(bool IsRV32E, MCRegister &RegNo,
1223 StringRef Name) {
1224 RegNo = MatchRegisterName(Name);
1225 // The 16-/32- and 64-bit FPRs have the same asm name. Check that the initial
1226 // match always matches the 64-bit variant, and not the 16/32-bit one.
1227 assert(!(RegNo >= RISCV::F0_H && RegNo <= RISCV::F31_H))((!(RegNo >= RISCV::F0_H && RegNo <= RISCV::F31_H
)) ? static_cast<void> (0) : __assert_fail ("!(RegNo >= RISCV::F0_H && RegNo <= RISCV::F31_H)"
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 1227, __PRETTY_FUNCTION__))
;
1228 assert(!(RegNo >= RISCV::F0_F && RegNo <= RISCV::F31_F))((!(RegNo >= RISCV::F0_F && RegNo <= RISCV::F31_F
)) ? static_cast<void> (0) : __assert_fail ("!(RegNo >= RISCV::F0_F && RegNo <= RISCV::F31_F)"
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 1228, __PRETTY_FUNCTION__))
;
1229 // The default FPR register class is based on the tablegen enum ordering.
1230 static_assert(RISCV::F0_D < RISCV::F0_H, "FPR matching must be updated");
1231 static_assert(RISCV::F0_D < RISCV::F0_F, "FPR matching must be updated");
1232 if (RegNo == RISCV::NoRegister)
1233 RegNo = MatchRegisterAltName(Name);
1234 if (IsRV32E && RegNo >= RISCV::X16 && RegNo <= RISCV::X31)
1235 RegNo = RISCV::NoRegister;
1236 return RegNo == RISCV::NoRegister;
1237}
1238
1239bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1240 SMLoc &EndLoc) {
1241 if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success)
1242 return Error(StartLoc, "invalid register name");
1243 return false;
1244}
1245
1246OperandMatchResultTy RISCVAsmParser::tryParseRegister(unsigned &RegNo,
1247 SMLoc &StartLoc,
1248 SMLoc &EndLoc) {
1249 const AsmToken &Tok = getParser().getTok();
1250 StartLoc = Tok.getLoc();
1251 EndLoc = Tok.getEndLoc();
1252 RegNo = 0;
1253 StringRef Name = getLexer().getTok().getIdentifier();
1254
1255 if (matchRegisterNameHelper(isRV32E(), (MCRegister &)RegNo, Name))
1256 return MatchOperand_NoMatch;
1257
1258 getParser().Lex(); // Eat identifier token.
1259 return MatchOperand_Success;
1260}
1261
1262OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands,
1263 bool AllowParens) {
1264 SMLoc FirstS = getLoc();
1265 bool HadParens = false;
1266 AsmToken LParen;
1267
1268 // If this is an LParen and a parenthesised register name is allowed, parse it
1269 // atomically.
1270 if (AllowParens && getLexer().is(AsmToken::LParen)) {
1271 AsmToken Buf[2];
1272 size_t ReadCount = getLexer().peekTokens(Buf);
1273 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
1274 HadParens = true;
1275 LParen = getParser().getTok();
1276 getParser().Lex(); // Eat '('
1277 }
1278 }
1279
1280 switch (getLexer().getKind()) {
1281 default:
1282 if (HadParens)
1283 getLexer().UnLex(LParen);
1284 return MatchOperand_NoMatch;
1285 case AsmToken::Identifier:
1286 StringRef Name = getLexer().getTok().getIdentifier();
1287 MCRegister RegNo;
1288 matchRegisterNameHelper(isRV32E(), RegNo, Name);
1289
1290 if (RegNo == RISCV::NoRegister) {
1291 if (HadParens)
1292 getLexer().UnLex(LParen);
1293 return MatchOperand_NoMatch;
1294 }
1295 if (HadParens)
1296 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64()));
1297 SMLoc S = getLoc();
1298 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1299 getLexer().Lex();
1300 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
1301 }
1302
1303 if (HadParens) {
1304 getParser().Lex(); // Eat ')'
1305 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
1306 }
1307
1308 return MatchOperand_Success;
1309}
1310
1311OperandMatchResultTy
1312RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
1313 SMLoc S = getLoc();
1314 const MCExpr *Res;
1315
1316 switch (getLexer().getKind()) {
1317 default:
1318 return MatchOperand_NoMatch;
1319 case AsmToken::LParen:
1320 case AsmToken::Minus:
1321 case AsmToken::Plus:
1322 case AsmToken::Exclaim:
1323 case AsmToken::Tilde:
1324 case AsmToken::Integer:
1325 case AsmToken::String: {
1326 if (getParser().parseExpression(Res))
1327 return MatchOperand_ParseFail;
1328
1329 auto *CE = dyn_cast<MCConstantExpr>(Res);
1330 if (CE) {
1331 int64_t Imm = CE->getValue();
1332 if (isUInt<12>(Imm)) {
1333 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
1334 // Accept an immediate representing a named or un-named Sys Reg
1335 // if the range is valid, regardless of the required features.
1336 Operands.push_back(RISCVOperand::createSysReg(
1337 SysReg ? SysReg->Name : "", S, Imm, isRV64()));
1338 return MatchOperand_Success;
1339 }
1340 }
1341
1342 Twine Msg = "immediate must be an integer in the range";
1343 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1344 return MatchOperand_ParseFail;
1345 }
1346 case AsmToken::Identifier: {
1347 StringRef Identifier;
1348 if (getParser().parseIdentifier(Identifier))
1349 return MatchOperand_ParseFail;
1350
1351 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1352 if (!SysReg)
1353 SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
1354 // Accept a named Sys Reg if the required features are present.
1355 if (SysReg) {
1356 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) {
1357 Error(S, "system register use requires an option to be enabled");
1358 return MatchOperand_ParseFail;
1359 }
1360 Operands.push_back(RISCVOperand::createSysReg(
1361 Identifier, S, SysReg->Encoding, isRV64()));
1362 return MatchOperand_Success;
1363 }
1364
1365 Twine Msg = "operand must be a valid system register name "
1366 "or an integer in the range";
1367 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1368 return MatchOperand_ParseFail;
1369 }
1370 case AsmToken::Percent: {
1371 // Discard operand with modifier.
1372 Twine Msg = "immediate must be an integer in the range";
1373 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1374 return MatchOperand_ParseFail;
1375 }
1376 }
1377
1378 return MatchOperand_NoMatch;
1379}
1380
1381OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) {
1382 SMLoc S = getLoc();
1383 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1384 const MCExpr *Res;
1385
1386 switch (getLexer().getKind()) {
1387 default:
1388 return MatchOperand_NoMatch;
1389 case AsmToken::LParen:
1390 case AsmToken::Dot:
1391 case AsmToken::Minus:
1392 case AsmToken::Plus:
1393 case AsmToken::Exclaim:
1394 case AsmToken::Tilde:
1395 case AsmToken::Integer:
1396 case AsmToken::String:
1397 case AsmToken::Identifier:
1398 if (getParser().parseExpression(Res))
1399 return MatchOperand_ParseFail;
1400 break;
1401 case AsmToken::Percent:
1402 return parseOperandWithModifier(Operands);
1403 }
1404
1405 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1406 return MatchOperand_Success;
1407}
1408
1409OperandMatchResultTy
1410RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
1411 SMLoc S = getLoc();
1412 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1413
1414 if (getLexer().getKind() != AsmToken::Percent) {
1415 Error(getLoc(), "expected '%' for operand modifier");
1416 return MatchOperand_ParseFail;
1417 }
1418
1419 getParser().Lex(); // Eat '%'
1420
1421 if (getLexer().getKind() != AsmToken::Identifier) {
1422 Error(getLoc(), "expected valid identifier for operand modifier");
1423 return MatchOperand_ParseFail;
1424 }
1425 StringRef Identifier = getParser().getTok().getIdentifier();
1426 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier);
1427 if (VK == RISCVMCExpr::VK_RISCV_Invalid) {
1428 Error(getLoc(), "unrecognized operand modifier");
1429 return MatchOperand_ParseFail;
1430 }
1431
1432 getParser().Lex(); // Eat the identifier
1433 if (getLexer().getKind() != AsmToken::LParen) {
1434 Error(getLoc(), "expected '('");
1435 return MatchOperand_ParseFail;
1436 }
1437 getParser().Lex(); // Eat '('
1438
1439 const MCExpr *SubExpr;
1440 if (getParser().parseParenExpression(SubExpr, E)) {
1441 return MatchOperand_ParseFail;
1442 }
1443
1444 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext());
1445 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
1446 return MatchOperand_Success;
1447}
1448
1449OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) {
1450 SMLoc S = getLoc();
1451 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1452 const MCExpr *Res;
1453
1454 if (getLexer().getKind() != AsmToken::Identifier)
1455 return MatchOperand_NoMatch;
1456
1457 StringRef Identifier;
1458 AsmToken Tok = getLexer().getTok();
1459
1460 if (getParser().parseIdentifier(Identifier))
1461 return MatchOperand_ParseFail;
1462
1463 if (Identifier.consume_back("@plt")) {
1464 Error(getLoc(), "'@plt' operand not valid for instruction");
1465 return MatchOperand_ParseFail;
1466 }
1467
1468 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1469
1470 if (Sym->isVariable()) {
1471 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1472 if (!isa<MCSymbolRefExpr>(V)) {
1473 getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1474 return MatchOperand_NoMatch;
1475 }
1476 Res = V;
1477 } else
1478 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1479
1480 MCBinaryExpr::Opcode Opcode;
1481 switch (getLexer().getKind()) {
1482 default:
1483 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1484 return MatchOperand_Success;
1485 case AsmToken::Plus:
1486 Opcode = MCBinaryExpr::Add;
1487 break;
1488 case AsmToken::Minus:
1489 Opcode = MCBinaryExpr::Sub;
1490 break;
1491 }
1492
1493 const MCExpr *Expr;
1494 if (getParser().parseExpression(Expr))
1495 return MatchOperand_ParseFail;
1496 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1497 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1498 return MatchOperand_Success;
1499}
1500
1501OperandMatchResultTy RISCVAsmParser::parseCallSymbol(OperandVector &Operands) {
1502 SMLoc S = getLoc();
1503 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1504 const MCExpr *Res;
1505
1506 if (getLexer().getKind() != AsmToken::Identifier)
1507 return MatchOperand_NoMatch;
1508
1509 // Avoid parsing the register in `call rd, foo` as a call symbol.
1510 if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement)
1511 return MatchOperand_NoMatch;
1512
1513 StringRef Identifier;
1514 if (getParser().parseIdentifier(Identifier))
1515 return MatchOperand_ParseFail;
1516
1517 RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_CALL;
1518 if (Identifier.consume_back("@plt"))
1519 Kind = RISCVMCExpr::VK_RISCV_CALL_PLT;
1520
1521 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1522 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1523 Res = RISCVMCExpr::create(Res, Kind, getContext());
1524 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1525 return MatchOperand_Success;
1526}
1527
1528OperandMatchResultTy
1529RISCVAsmParser::parsePseudoJumpSymbol(OperandVector &Operands) {
1530 SMLoc S = getLoc();
1531 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1532 const MCExpr *Res;
1533
1534 if (getParser().parseExpression(Res))
1535 return MatchOperand_ParseFail;
1536
1537 if (Res->getKind() != MCExpr::ExprKind::SymbolRef ||
1538 cast<MCSymbolRefExpr>(Res)->getKind() ==
1539 MCSymbolRefExpr::VariantKind::VK_PLT) {
1540 Error(S, "operand must be a valid jump target");
1541 return MatchOperand_ParseFail;
1542 }
1543
1544 Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext());
1545 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1546 return MatchOperand_Success;
1547}
1548
1549OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) {
1550 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo`
1551 // both being acceptable forms. When parsing `jal ra, foo` this function
1552 // will be called for the `ra` register operand in an attempt to match the
1553 // single-operand alias. parseJALOffset must fail for this case. It would
1554 // seem logical to try parse the operand using parseImmediate and return
1555 // NoMatch if the next token is a comma (meaning we must be parsing a jal in
1556 // the second form rather than the first). We can't do this as there's no
1557 // way of rewinding the lexer state. Instead, return NoMatch if this operand
1558 // is an identifier and is followed by a comma.
1559 if (getLexer().is(AsmToken::Identifier) &&
1560 getLexer().peekTok().is(AsmToken::Comma))
1561 return MatchOperand_NoMatch;
1562
1563 return parseImmediate(Operands);
1564}
1565
1566OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) {
1567 SMLoc S = getLoc();
1568 if (getLexer().getKind() != AsmToken::Identifier)
1569 return MatchOperand_NoMatch;
1570
1571 // Parse "e8,m1,t[a|u],m[a|u]"
1572 StringRef Name = getLexer().getTok().getIdentifier();
1573 if (!Name.consume_front("e"))
1574 return MatchOperand_NoMatch;
1575 unsigned Sew;
1576 if (Name.getAsInteger(10, Sew))
1577 return MatchOperand_NoMatch;
1578 if (!RISCVVType::isValidSEW(Sew))
1579 return MatchOperand_NoMatch;
1580 getLexer().Lex();
1581
1582 if (!getLexer().is(AsmToken::Comma))
1583 return MatchOperand_NoMatch;
1584 getLexer().Lex();
1585
1586 Name = getLexer().getTok().getIdentifier();
1587 if (!Name.consume_front("m"))
1588 return MatchOperand_NoMatch;
1589 // "m" or "mf"
1590 bool Fractional = Name.consume_front("f");
1591 unsigned Lmul;
1592 if (Name.getAsInteger(10, Lmul))
1593 return MatchOperand_NoMatch;
1594 if (!RISCVVType::isValidLMUL(Lmul, Fractional))
1595 return MatchOperand_NoMatch;
1596 getLexer().Lex();
1597
1598 if (!getLexer().is(AsmToken::Comma))
1599 return MatchOperand_NoMatch;
1600 getLexer().Lex();
1601
1602 Name = getLexer().getTok().getIdentifier();
1603 // ta or tu
1604 bool TailAgnostic;
1605 if (Name == "ta")
1606 TailAgnostic = true;
1607 else if (Name == "tu")
1608 TailAgnostic = false;
1609 else
1610 return MatchOperand_NoMatch;
1611 getLexer().Lex();
1612
1613 if (!getLexer().is(AsmToken::Comma))
1614 return MatchOperand_NoMatch;
1615 getLexer().Lex();
1616
1617 Name = getLexer().getTok().getIdentifier();
1618 // ma or mu
1619 bool MaskAgnostic;
1620 if (Name == "ma")
1621 MaskAgnostic = true;
1622 else if (Name == "mu")
1623 MaskAgnostic = false;
1624 else
1625 return MatchOperand_NoMatch;
1626 getLexer().Lex();
1627
1628 if (getLexer().getKind() != AsmToken::EndOfStatement)
1629 return MatchOperand_NoMatch;
1630
1631 Operands.push_back(RISCVOperand::createVType(
1632 Sew, Lmul, Fractional, TailAgnostic, MaskAgnostic, S, isRV64()));
1633
1634 return MatchOperand_Success;
1635}
1636
1637OperandMatchResultTy RISCVAsmParser::parseMaskReg(OperandVector &Operands) {
1638 switch (getLexer().getKind()) {
1639 default:
1640 return MatchOperand_NoMatch;
1641 case AsmToken::Identifier:
1642 StringRef Name = getLexer().getTok().getIdentifier();
1643 if (!Name.consume_back(".t")) {
1644 Error(getLoc(), "expected '.t' suffix");
1645 return MatchOperand_ParseFail;
1646 }
1647 MCRegister RegNo;
1648 matchRegisterNameHelper(isRV32E(), RegNo, Name);
1649
1650 if (RegNo == RISCV::NoRegister)
1651 return MatchOperand_NoMatch;
1652 if (RegNo != RISCV::V0)
1653 return MatchOperand_NoMatch;
1654 SMLoc S = getLoc();
1655 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1656 getLexer().Lex();
1657 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
1658 }
1659
1660 return MatchOperand_Success;
1661}
1662
1663OperandMatchResultTy
1664RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
1665 if (getLexer().isNot(AsmToken::LParen)) {
1666 Error(getLoc(), "expected '('");
1667 return MatchOperand_ParseFail;
1668 }
1669
1670 getParser().Lex(); // Eat '('
1671 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64()));
1672
1673 if (parseRegister(Operands) != MatchOperand_Success) {
1674 Error(getLoc(), "expected register");
1675 return MatchOperand_ParseFail;
1676 }
1677
1678 if (getLexer().isNot(AsmToken::RParen)) {
1679 Error(getLoc(), "expected ')'");
1680 return MatchOperand_ParseFail;
1681 }
1682
1683 getParser().Lex(); // Eat ')'
1684 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
1685
1686 return MatchOperand_Success;
1687}
1688
1689OperandMatchResultTy RISCVAsmParser::parseAtomicMemOp(OperandVector &Operands) {
1690 // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand"
1691 // as one of their register operands, such as `(a0)`. This just denotes that
1692 // the register (in this case `a0`) contains a memory address.
1693 //
1694 // Normally, we would be able to parse these by putting the parens into the
1695 // instruction string. However, GNU as also accepts a zero-offset memory
1696 // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed
1697 // with parseImmediate followed by parseMemOpBaseReg, but these instructions
1698 // do not accept an immediate operand, and we do not want to add a "dummy"
1699 // operand that is silently dropped.
1700 //
1701 // Instead, we use this custom parser. This will: allow (and discard) an
1702 // offset if it is zero; require (and discard) parentheses; and add only the
1703 // parsed register operand to `Operands`.
1704 //
1705 // These operands are printed with RISCVInstPrinter::printAtomicMemOp, which
1706 // will only print the register surrounded by parentheses (which GNU as also
1707 // uses as its canonical representation for these operands).
1708 std::unique_ptr<RISCVOperand> OptionalImmOp;
1709
1710 if (getLexer().isNot(AsmToken::LParen)) {
1711 // Parse an Integer token. We do not accept arbritrary constant expressions
1712 // in the offset field (because they may include parens, which complicates
1713 // parsing a lot).
1714 int64_t ImmVal;
1715 SMLoc ImmStart = getLoc();
1716 if (getParser().parseIntToken(ImmVal,
1717 "expected '(' or optional integer offset"))
1718 return MatchOperand_ParseFail;
1719
1720 // Create a RISCVOperand for checking later (so the error messages are
1721 // nicer), but we don't add it to Operands.
1722 SMLoc ImmEnd = getLoc();
1723 OptionalImmOp =
1724 RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()),
1725 ImmStart, ImmEnd, isRV64());
1726 }
1727
1728 if (getLexer().isNot(AsmToken::LParen)) {
1729 Error(getLoc(), OptionalImmOp ? "expected '(' after optional integer offset"
1730 : "expected '(' or optional integer offset");
1731 return MatchOperand_ParseFail;
1732 }
1733 getParser().Lex(); // Eat '('
1734
1735 if (parseRegister(Operands) != MatchOperand_Success) {
1736 Error(getLoc(), "expected register");
1737 return MatchOperand_ParseFail;
1738 }
1739
1740 if (getLexer().isNot(AsmToken::RParen)) {
1741 Error(getLoc(), "expected ')'");
1742 return MatchOperand_ParseFail;
1743 }
1744 getParser().Lex(); // Eat ')'
1745
1746 // Deferred Handling of non-zero offsets. This makes the error messages nicer.
1747 if (OptionalImmOp && !OptionalImmOp->isImmZero()) {
1748 Error(OptionalImmOp->getStartLoc(), "optional integer offset must be 0",
1749 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
1750 return MatchOperand_ParseFail;
1751 }
1752
1753 return MatchOperand_Success;
1754}
1755
1756/// Looks at a token type and creates the relevant operand from this
1757/// information, adding to Operands. If operand was parsed, returns false, else
1758/// true.
1759bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1760 // Check if the current operand has a custom associated parser, if so, try to
1761 // custom parse the operand, or fallback to the general approach.
1762 OperandMatchResultTy Result =
1763 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
1764 if (Result == MatchOperand_Success)
1765 return false;
1766 if (Result == MatchOperand_ParseFail)
1767 return true;
1768
1769 // Attempt to parse token as a register.
1770 if (parseRegister(Operands, true) == MatchOperand_Success)
1771 return false;
1772
1773 // Attempt to parse token as an immediate
1774 if (parseImmediate(Operands) == MatchOperand_Success) {
1775 // Parse memory base register if present
1776 if (getLexer().is(AsmToken::LParen))
1777 return parseMemOpBaseReg(Operands) != MatchOperand_Success;
1778 return false;
1779 }
1780
1781 // Finally we have exhausted all options and must declare defeat.
1782 Error(getLoc(), "unknown operand");
1783 return true;
1784}
1785
1786bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1787 StringRef Name, SMLoc NameLoc,
1788 OperandVector &Operands) {
1789 // Ensure that if the instruction occurs when relaxation is enabled,
1790 // relocations are forced for the file. Ideally this would be done when there
1791 // is enough information to reliably determine if the instruction itself may
1792 // cause relaxations. Unfortunately instruction processing stage occurs in the
1793 // same pass as relocation emission, so it's too late to set a 'sticky bit'
1794 // for the entire file.
1795 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) {
1796 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
1797 if (Assembler != nullptr) {
1798 RISCVAsmBackend &MAB =
1799 static_cast<RISCVAsmBackend &>(Assembler->getBackend());
1800 MAB.setForceRelocs();
1801 }
1802 }
1803
1804 // First operand is token for instruction
1805 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64()));
1806
1807 // If there are no more operands, then finish
1808 if (getLexer().is(AsmToken::EndOfStatement))
1809 return false;
1810
1811 // Parse first operand
1812 if (parseOperand(Operands, Name))
1813 return true;
1814
1815 // Parse until end of statement, consuming commas between operands
1816 unsigned OperandIdx = 1;
1817 while (getLexer().is(AsmToken::Comma)) {
1818 // Consume comma token
1819 getLexer().Lex();
1820
1821 // Parse next operand
1822 if (parseOperand(Operands, Name))
1823 return true;
1824
1825 ++OperandIdx;
1826 }
1827
1828 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1829 SMLoc Loc = getLexer().getLoc();
1830 getParser().eatToEndOfStatement();
1831 return Error(Loc, "unexpected token");
1832 }
1833
1834 getParser().Lex(); // Consume the EndOfStatement.
1835 return false;
1836}
1837
1838bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,
1839 RISCVMCExpr::VariantKind &Kind) {
1840 Kind = RISCVMCExpr::VK_RISCV_None;
1841
1842 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
1843 Kind = RE->getKind();
1844 Expr = RE->getSubExpr();
1845 }
1846
1847 MCValue Res;
1848 MCFixup Fixup;
1849 if (Expr->evaluateAsRelocatable(Res, nullptr, &Fixup))
1850 return Res.getRefKind() == RISCVMCExpr::VK_RISCV_None;
1851 return false;
1852}
1853
1854bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) {
1855 // This returns false if this function recognizes the directive
1856 // regardless of whether it is successfully handles or reports an
1857 // error. Otherwise it returns true to give the generic parser a
1858 // chance at recognizing it.
1859 StringRef IDVal = DirectiveID.getString();
1860
1861 if (IDVal == ".option")
1862 return parseDirectiveOption();
1863 else if (IDVal == ".attribute")
1864 return parseDirectiveAttribute();
1865
1866 return true;
1867}
1868
1869bool RISCVAsmParser::parseDirectiveOption() {
1870 MCAsmParser &Parser = getParser();
1871 // Get the option token.
1872 AsmToken Tok = Parser.getTok();
1873 // At the moment only identifiers are supported.
1874 if (Tok.isNot(AsmToken::Identifier))
1875 return Error(Parser.getTok().getLoc(),
1876 "unexpected token, expected identifier");
1877
1878 StringRef Option = Tok.getIdentifier();
1879
1880 if (Option == "push") {
1881 getTargetStreamer().emitDirectiveOptionPush();
1882
1883 Parser.Lex();
1884 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1885 return Error(Parser.getTok().getLoc(),
1886 "unexpected token, expected end of statement");
1887
1888 pushFeatureBits();
1889 return false;
1890 }
1891
1892 if (Option == "pop") {
1893 SMLoc StartLoc = Parser.getTok().getLoc();
1894 getTargetStreamer().emitDirectiveOptionPop();
1895
1896 Parser.Lex();
1897 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1898 return Error(Parser.getTok().getLoc(),
1899 "unexpected token, expected end of statement");
1900
1901 if (popFeatureBits())
1902 return Error(StartLoc, ".option pop with no .option push");
1903
1904 return false;
1905 }
1906
1907 if (Option == "rvc") {
1908 getTargetStreamer().emitDirectiveOptionRVC();
1909
1910 Parser.Lex();
1911 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1912 return Error(Parser.getTok().getLoc(),
1913 "unexpected token, expected end of statement");
1914
1915 setFeatureBits(RISCV::FeatureStdExtC, "c");
1916 return false;
1917 }
1918
1919 if (Option == "norvc") {
1920 getTargetStreamer().emitDirectiveOptionNoRVC();
1921
1922 Parser.Lex();
1923 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1924 return Error(Parser.getTok().getLoc(),
1925 "unexpected token, expected end of statement");
1926
1927 clearFeatureBits(RISCV::FeatureStdExtC, "c");
1928 return false;
1929 }
1930
1931 if (Option == "pic") {
1932 getTargetStreamer().emitDirectiveOptionPIC();
1933
1934 Parser.Lex();
1935 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1936 return Error(Parser.getTok().getLoc(),
1937 "unexpected token, expected end of statement");
1938
1939 ParserOptions.IsPicEnabled = true;
1940 return false;
1941 }
1942
1943 if (Option == "nopic") {
1944 getTargetStreamer().emitDirectiveOptionNoPIC();
1945
1946 Parser.Lex();
1947 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1948 return Error(Parser.getTok().getLoc(),
1949 "unexpected token, expected end of statement");
1950
1951 ParserOptions.IsPicEnabled = false;
1952 return false;
1953 }
1954
1955 if (Option == "relax") {
1956 getTargetStreamer().emitDirectiveOptionRelax();
1957
1958 Parser.Lex();
1959 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1960 return Error(Parser.getTok().getLoc(),
1961 "unexpected token, expected end of statement");
1962
1963 setFeatureBits(RISCV::FeatureRelax, "relax");
1964 return false;
1965 }
1966
1967 if (Option == "norelax") {
1968 getTargetStreamer().emitDirectiveOptionNoRelax();
1969
1970 Parser.Lex();
1971 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1972 return Error(Parser.getTok().getLoc(),
1973 "unexpected token, expected end of statement");
1974
1975 clearFeatureBits(RISCV::FeatureRelax, "relax");
1976 return false;
1977 }
1978
1979 // Unknown option.
1980 Warning(Parser.getTok().getLoc(),
1981 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or "
1982 "'norelax'");
1983 Parser.eatToEndOfStatement();
1984 return false;
1985}
1986
1987/// parseDirectiveAttribute
1988/// ::= .attribute expression ',' ( expression | "string" )
1989/// ::= .attribute identifier ',' ( expression | "string" )
1990bool RISCVAsmParser::parseDirectiveAttribute() {
1991 MCAsmParser &Parser = getParser();
1992 int64_t Tag;
1993 SMLoc TagLoc;
1994 TagLoc = Parser.getTok().getLoc();
1995 if (Parser.getTok().is(AsmToken::Identifier)) {
1996 StringRef Name = Parser.getTok().getIdentifier();
1997 Optional<unsigned> Ret =
1998 ELFAttrs::attrTypeFromString(Name, RISCVAttrs::RISCVAttributeTags);
1999 if (!Ret.hasValue()) {
2000 Error(TagLoc, "attribute name not recognised: " + Name);
2001 return false;
2002 }
2003 Tag = Ret.getValue();
2004 Parser.Lex();
2005 } else {
2006 const MCExpr *AttrExpr;
2007
2008 TagLoc = Parser.getTok().getLoc();
2009 if (Parser.parseExpression(AttrExpr))
2010 return true;
2011
2012 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
2013 if (check(!CE, TagLoc, "expected numeric constant"))
2014 return true;
2015
2016 Tag = CE->getValue();
2017 }
2018
2019 if (Parser.parseToken(AsmToken::Comma, "comma expected"))
2020 return true;
2021
2022 StringRef StringValue;
2023 int64_t IntegerValue = 0;
2024 bool IsIntegerValue = true;
2025
2026 // RISC-V attributes have a string value if the tag number is odd
2027 // and an integer value if the tag number is even.
2028 if (Tag % 2)
2029 IsIntegerValue = false;
2030
2031 SMLoc ValueExprLoc = Parser.getTok().getLoc();
2032 if (IsIntegerValue) {
2033 const MCExpr *ValueExpr;
2034 if (Parser.parseExpression(ValueExpr))
2035 return true;
2036
2037 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
2038 if (!CE)
2039 return Error(ValueExprLoc, "expected numeric constant");
2040 IntegerValue = CE->getValue();
2041 } else {
2042 if (Parser.getTok().isNot(AsmToken::String))
2043 return Error(Parser.getTok().getLoc(), "expected string constant");
2044
2045 StringValue = Parser.getTok().getStringContents();
2046 Parser.Lex();
2047 }
2048
2049 if (Parser.parseToken(AsmToken::EndOfStatement,
2050 "unexpected token in '.attribute' directive"))
2051 return true;
2052
2053 if (Tag == RISCVAttrs::ARCH) {
2054 StringRef Arch = StringValue;
2055 if (Arch.consume_front("rv32"))
2056 clearFeatureBits(RISCV::Feature64Bit, "64bit");
2057 else if (Arch.consume_front("rv64"))
2058 setFeatureBits(RISCV::Feature64Bit, "64bit");
2059 else
2060 return Error(ValueExprLoc, "bad arch string " + Arch);
2061
2062 while (!Arch.empty()) {
2063 if (Arch[0] == 'i')
2064 clearFeatureBits(RISCV::FeatureRV32E, "e");
2065 else if (Arch[0] == 'e')
2066 setFeatureBits(RISCV::FeatureRV32E, "e");
2067 else if (Arch[0] == 'g') {
2068 clearFeatureBits(RISCV::FeatureRV32E, "e");
2069 setFeatureBits(RISCV::FeatureStdExtM, "m");
2070 setFeatureBits(RISCV::FeatureStdExtA, "a");
2071 setFeatureBits(RISCV::FeatureStdExtF, "f");
2072 setFeatureBits(RISCV::FeatureStdExtD, "d");
2073 } else if (Arch[0] == 'm')
2074 setFeatureBits(RISCV::FeatureStdExtM, "m");
2075 else if (Arch[0] == 'a')
2076 setFeatureBits(RISCV::FeatureStdExtA, "a");
2077 else if (Arch[0] == 'f')
2078 setFeatureBits(RISCV::FeatureStdExtF, "f");
2079 else if (Arch[0] == 'd') {
2080 setFeatureBits(RISCV::FeatureStdExtF, "f");
2081 setFeatureBits(RISCV::FeatureStdExtD, "d");
2082 } else if (Arch[0] == 'c') {
2083 setFeatureBits(RISCV::FeatureStdExtC, "c");
2084 } else
2085 return Error(ValueExprLoc, "bad arch string " + Arch);
2086
2087 Arch = Arch.drop_front(1);
2088 int major = 0;
2089 int minor = 0;
2090 Arch.consumeInteger(10, major);
2091 Arch.consume_front("p");
2092 Arch.consumeInteger(10, minor);
2093 if (major != 0 || minor != 0) {
2094 Arch = Arch.drop_until([](char c) { return c == '_' || c == '"'; });
2095 Arch = Arch.drop_while([](char c) { return c == '_'; });
2096 }
2097 }
2098 }
2099
2100 if (IsIntegerValue)
2101 getTargetStreamer().emitAttribute(Tag, IntegerValue);
2102 else {
2103 if (Tag != RISCVAttrs::ARCH) {
2104 getTargetStreamer().emitTextAttribute(Tag, StringValue);
2105 } else {
2106 std::string formalArchStr = "rv32";
2107 if (getFeatureBits(RISCV::Feature64Bit))
2108 formalArchStr = "rv64";
2109 if (getFeatureBits(RISCV::FeatureRV32E))
2110 formalArchStr = (Twine(formalArchStr) + "e1p9").str();
2111 else
2112 formalArchStr = (Twine(formalArchStr) + "i2p0").str();
2113
2114 if (getFeatureBits(RISCV::FeatureStdExtM))
2115 formalArchStr = (Twine(formalArchStr) + "_m2p0").str();
2116 if (getFeatureBits(RISCV::FeatureStdExtA))
2117 formalArchStr = (Twine(formalArchStr) + "_a2p0").str();
2118 if (getFeatureBits(RISCV::FeatureStdExtF))
2119 formalArchStr = (Twine(formalArchStr) + "_f2p0").str();
2120 if (getFeatureBits(RISCV::FeatureStdExtD))
2121 formalArchStr = (Twine(formalArchStr) + "_d2p0").str();
2122 if (getFeatureBits(RISCV::FeatureStdExtC))
2123 formalArchStr = (Twine(formalArchStr) + "_c2p0").str();
2124
2125 getTargetStreamer().emitTextAttribute(Tag, formalArchStr);
2126 }
2127 }
2128
2129 return false;
2130}
2131
2132void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
2133 MCInst CInst;
2134 bool Res = compressInst(CInst, Inst, getSTI(), S.getContext());
2135 if (Res)
2136 ++RISCVNumInstrsCompressed;
2137 S.emitInstruction((Res ? CInst : Inst), getSTI());
2138}
2139
2140void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t Value,
2141 MCStreamer &Out) {
2142 RISCVMatInt::InstSeq Seq;
2143 RISCVMatInt::generateInstSeq(Value, isRV64(), Seq);
2144
2145 MCRegister SrcReg = RISCV::X0;
2146 for (RISCVMatInt::Inst &Inst : Seq) {
2147 if (Inst.Opc == RISCV::LUI) {
2148 emitToStreamer(
2149 Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm));
2150 } else {
2151 emitToStreamer(
2152 Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm(
2153 Inst.Imm));
2154 }
2155
2156 // Only the first instruction has X0 as its source.
2157 SrcReg = DestReg;
2158 }
2159}
2160
2161void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
2162 const MCExpr *Symbol,
2163 RISCVMCExpr::VariantKind VKHi,
2164 unsigned SecondOpcode, SMLoc IDLoc,
2165 MCStreamer &Out) {
2166 // A pair of instructions for PC-relative addressing; expands to
2167 // TmpLabel: AUIPC TmpReg, VKHi(symbol)
2168 // OP DestReg, TmpReg, %pcrel_lo(TmpLabel)
2169 MCContext &Ctx = getContext();
2170
2171 MCSymbol *TmpLabel = Ctx.createTempSymbol(
2172 "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false);
2173 Out.emitLabel(TmpLabel);
2174
2175 const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx);
2176 emitToStreamer(
2177 Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi));
2178
2179 const MCExpr *RefToLinkTmpLabel =
2180 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx),
2181 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx);
2182
2183 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
2184 .addOperand(DestReg)
2185 .addOperand(TmpReg)
2186 .addExpr(RefToLinkTmpLabel));
2187}
2188
2189void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
2190 MCStreamer &Out) {
2191 // The load local address pseudo-instruction "lla" is used in PC-relative
2192 // addressing of local symbols:
2193 // lla rdest, symbol
2194 // expands to
2195 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
2196 // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
2197 MCOperand DestReg = Inst.getOperand(0);
2198 const MCExpr *Symbol = Inst.getOperand(1).getExpr();
2199 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
2200 RISCV::ADDI, IDLoc, Out);
2201}
2202
2203void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
2204 MCStreamer &Out) {
2205 // The load address pseudo-instruction "la" is used in PC-relative and
2206 // GOT-indirect addressing of global symbols:
2207 // la rdest, symbol
2208 // expands to either (for non-PIC)
2209 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
2210 // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
2211 // or (for PIC)
2212 // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol)
2213 // Lx rdest, %pcrel_lo(TmpLabel)(rdest)
2214 MCOperand DestReg = Inst.getOperand(0);
2215 const MCExpr *Symbol = Inst.getOperand(1).getExpr();
2216 unsigned SecondOpcode;
2217 RISCVMCExpr::VariantKind VKHi;
2218 if (ParserOptions.IsPicEnabled) {
2219 SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
2220 VKHi = RISCVMCExpr::VK_RISCV_GOT_HI;
2221 } else {
2222 SecondOpcode = RISCV::ADDI;
2223 VKHi = RISCVMCExpr::VK_RISCV_PCREL_HI;
2224 }
2225 emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out);
2226}
2227
2228void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
2229 MCStreamer &Out) {
2230 // The load TLS IE address pseudo-instruction "la.tls.ie" is used in
2231 // initial-exec TLS model addressing of global symbols:
2232 // la.tls.ie rdest, symbol
2233 // expands to
2234 // TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol)
2235 // Lx rdest, %pcrel_lo(TmpLabel)(rdest)
2236 MCOperand DestReg = Inst.getOperand(0);
2237 const MCExpr *Symbol = Inst.getOperand(1).getExpr();
2238 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
2239 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GOT_HI,
2240 SecondOpcode, IDLoc, Out);
2241}
2242
2243void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
2244 MCStreamer &Out) {
2245 // The load TLS GD address pseudo-instruction "la.tls.gd" is used in
2246 // global-dynamic TLS model addressing of global symbols:
2247 // la.tls.gd rdest, symbol
2248 // expands to
2249 // TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol)
2250 // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
2251 MCOperand DestReg = Inst.getOperand(0);
2252 const MCExpr *Symbol = Inst.getOperand(1).getExpr();
2253 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GD_HI,
2254 RISCV::ADDI, IDLoc, Out);
2255}
2256
2257void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode,
2258 SMLoc IDLoc, MCStreamer &Out,
2259 bool HasTmpReg) {
2260 // The load/store pseudo-instruction does a pc-relative load with
2261 // a symbol.
2262 //
2263 // The expansion looks like this
2264 //
2265 // TmpLabel: AUIPC tmp, %pcrel_hi(symbol)
2266 // [S|L]X rd, %pcrel_lo(TmpLabel)(tmp)
2267 MCOperand DestReg = Inst.getOperand(0);
2268 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
2269 unsigned TmpRegOpIdx = HasTmpReg ? 1 : 0;
2270 MCOperand TmpReg = Inst.getOperand(TmpRegOpIdx);
2271 const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr();
2272 emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
2273 Opcode, IDLoc, Out);
2274}
2275
2276void RISCVAsmParser::emitPseudoExtend(MCInst &Inst, bool SignExtend,
2277 int64_t Width, SMLoc IDLoc,
2278 MCStreamer &Out) {
2279 // The sign/zero extend pseudo-instruction does two shifts, with the shift
2280 // amounts dependent on the XLEN.
2281 //
2282 // The expansion looks like this
2283 //
2284 // SLLI rd, rs, XLEN - Width
2285 // SR[A|R]I rd, rd, XLEN - Width
2286 MCOperand DestReg = Inst.getOperand(0);
2287 MCOperand SourceReg = Inst.getOperand(1);
2288
2289 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
2290 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
2291
2292 assert(ShAmt > 0 && "Shift amount must be non-zero.")((ShAmt > 0 && "Shift amount must be non-zero.") ?
static_cast<void> (0) : __assert_fail ("ShAmt > 0 && \"Shift amount must be non-zero.\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 2292, __PRETTY_FUNCTION__))
;
2293
2294 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
2295 .addOperand(DestReg)
2296 .addOperand(SourceReg)
2297 .addImm(ShAmt));
2298
2299 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
2300 .addOperand(DestReg)
2301 .addOperand(DestReg)
2302 .addImm(ShAmt));
2303}
2304
2305bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
2306 OperandVector &Operands) {
2307 assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction")((Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOpcode() == RISCV::PseudoAddTPRel && \"Invalid instruction\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 2307, __PRETTY_FUNCTION__))
;
2308 assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind")((Inst.getOperand(2).isReg() && "Unexpected second operand kind"
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(2).isReg() && \"Unexpected second operand kind\""
, "/build/llvm-toolchain-snapshot-12~++20201211111113+08280c4b734/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 2308, __PRETTY_FUNCTION__))
;
2309 if (Inst.getOperand(2).getReg() != RISCV::X4) {
2310 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
2311 return Error(ErrorLoc, "the second input operand must be tp/x4 when using "
2312 "%tprel_add modifier");
2313 }
2314
2315 return false;
2316}
2317
2318std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp() const {
2319 return RISCVOperand::createReg(RISCV::NoRegister, llvm::SMLoc(),
2320 llvm::SMLoc(), isRV64());
2321}
2322
2323bool RISCVAsmParser::validateInstruction(MCInst &Inst,
2324 OperandVector &Operands) {
2325 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
2326 unsigned TargetFlags =
2327 (MCID.TSFlags >> RISCVII::ConstraintOffset) & RISCVII::ConstraintMask;
2328 if (TargetFlags == RISCVII::NoConstraint)
3
Assuming 'TargetFlags' is not equal to NoConstraint
4
Taking false branch
2329 return false;
2330
2331 unsigned DestReg = Inst.getOperand(0).getReg();
2332 unsigned CheckReg;
5
'CheckReg' declared without an initial value
2333 // Operands[1] will be the first operand, DestReg.
2334 SMLoc Loc = Operands[1]->getStartLoc();
2335 if (TargetFlags & RISCVII::VS2Constraint) {
6
Assuming the condition is false
7
Taking false branch
2336 CheckReg = Inst.getOperand(1).getReg();
2337 if (DestReg == CheckReg)
2338 return Error(Loc, "The destination vector register group cannot overlap"
2339 " the source vector register group.");
2340 }
2341 if ((TargetFlags & RISCVII::VS1Constraint) && (Inst.getOperand(2).isReg())) {
8
Assuming the condition is false
2342 CheckReg = Inst.getOperand(2).getReg();
2343 if (DestReg == CheckReg)
2344 return Error(Loc, "The destination vector register group cannot overlap"
2345 " the source vector register group.");
2346 }
2347 if ((TargetFlags & RISCVII::VMConstraint) && (DestReg == RISCV::V0)) {
9
Assuming the condition is true
10
Assuming 'DestReg' is equal to V0
11
Taking true branch
2348 // vadc, vsbc are special cases. These instructions have no mask register.
2349 // The destination register could not be V0.
2350 unsigned Opcode = Inst.getOpcode();
2351 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
12
Assuming 'Opcode' is not equal to VADC_VVM
13
Assuming 'Opcode' is not equal to VADC_VXM
17
Taking false branch
2352 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
14
Assuming 'Opcode' is not equal to VADC_VIM
15
Assuming 'Opcode' is not equal to VSBC_VVM
2353 Opcode == RISCV::VSBC_VXM)
16
Assuming 'Opcode' is not equal to VSBC_VXM
2354 return Error(Loc, "The destination vector register group cannot be V0.");
2355
2356 // Regardless masked or unmasked version, the number of operands is the
2357 // same. For example, "viota.m v0, v2" is "viota.m v0, v2, NoRegister"
2358 // actually. We need to check the last operand to ensure whether it is
2359 // masked or not.
2360 if ((TargetFlags & RISCVII::OneInput) && (Inst.getNumOperands() == 3))
18
Assuming the condition is false
2361 CheckReg = Inst.getOperand(2).getReg();
2362 else if (Inst.getNumOperands() == 4)
19
Assuming the condition is false
20
Taking false branch
2363 CheckReg = Inst.getOperand(3).getReg();
2364 if (DestReg == CheckReg)
21
The right operand of '==' is a garbage value
2365 return Error(Loc, "The destination vector register group cannot overlap"
2366 " the mask register.");
2367 }
2368 return false;
2369}
2370
2371bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
2372 OperandVector &Operands,
2373 MCStreamer &Out) {
2374 Inst.setLoc(IDLoc);
2375
2376 switch (Inst.getOpcode()) {
2377 default:
2378 break;
2379 case RISCV::PseudoLI: {
2380 MCRegister Reg = Inst.getOperand(0).getReg();
2381 const MCOperand &Op1 = Inst.getOperand(1);
2382 if (Op1.isExpr()) {
2383 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar.
2384 // Just convert to an addi. This allows compatibility with gas.
2385 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
2386 .addReg(Reg)
2387 .addReg(RISCV::X0)
2388 .addExpr(Op1.getExpr()));
2389 return false;
2390 }
2391 int64_t Imm = Inst.getOperand(1).getImm();
2392 // On RV32 the immediate here can either be a signed or an unsigned
2393 // 32-bit number. Sign extension has to be performed to ensure that Imm
2394 // represents the expected signed 64-bit number.
2395 if (!isRV64())
2396 Imm = SignExtend64<32>(Imm);
2397 emitLoadImm(Reg, Imm, Out);
2398 return false;
2399 }
2400 case RISCV::PseudoLLA:
2401 emitLoadLocalAddress(Inst, IDLoc, Out);
2402 return false;
2403 case RISCV::PseudoLA:
2404 emitLoadAddress(Inst, IDLoc, Out);
2405 return false;
2406 case RISCV::PseudoLA_TLS_IE:
2407 emitLoadTLSIEAddress(Inst, IDLoc, Out);
2408 return false;
2409 case RISCV::PseudoLA_TLS_GD:
2410 emitLoadTLSGDAddress(Inst, IDLoc, Out);
2411 return false;
2412 case RISCV::PseudoLB:
2413 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false);
2414 return false;
2415 case RISCV::PseudoLBU:
2416 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false);
2417 return false;
2418 case RISCV::PseudoLH:
2419 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false);
2420 return false;
2421 case RISCV::PseudoLHU:
2422 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false);
2423 return false;
2424 case RISCV::PseudoLW:
2425 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false);
2426 return false;
2427 case RISCV::PseudoLWU:
2428 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false);
2429 return false;
2430 case RISCV::PseudoLD:
2431 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false);
2432 return false;
2433 case RISCV::PseudoFLH:
2434 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out, /*HasTmpReg=*/true);
2435 return false;
2436 case RISCV::PseudoFLW:
2437 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true);
2438 return false;
2439 case RISCV::PseudoFLD:
2440 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true);
2441 return false;
2442 case RISCV::PseudoSB:
2443 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true);
2444 return false;
2445 case RISCV::PseudoSH:
2446 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true);
2447 return false;
2448 case RISCV::PseudoSW:
2449 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true);
2450 return false;
2451 case RISCV::PseudoSD:
2452 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true);
2453 return false;
2454 case RISCV::PseudoFSH:
2455 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out, /*HasTmpReg=*/true);
2456 return false;
2457 case RISCV::PseudoFSW:
2458 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true);
2459 return false;
2460 case RISCV::PseudoFSD:
2461 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true);
2462 return false;
2463 case RISCV::PseudoAddTPRel:
2464 if (checkPseudoAddTPRel(Inst, Operands))
2465 return true;
2466 break;
2467 case RISCV::PseudoSEXT_B:
2468 emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/8, IDLoc, Out);
2469 return false;
2470 case RISCV::PseudoSEXT_H:
2471 emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/16, IDLoc, Out);
2472 return false;
2473 case RISCV::PseudoZEXT_H:
2474 emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/16, IDLoc, Out);
2475 return false;
2476 case RISCV::PseudoZEXT_W:
2477 emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/32, IDLoc, Out);
2478 return false;
2479 }
2480
2481 emitToStreamer(Out, Inst);
2482 return false;
2483}
2484
2485extern "C" LLVM_EXTERNAL_VISIBILITY__attribute__ ((visibility("default"))) void LLVMInitializeRISCVAsmParser() {
2486 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target());
2487 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target());
2488}