Bug Summary

File:llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
Warning:line 1982, column 11
Called C++ object pointer is null

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 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/build-llvm/lib/Target/RISCV/AsmParser -resource-dir /usr/lib/llvm-13/lib/clang/13.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/build-llvm/lib/Target/RISCV/AsmParser -I /build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser -I /build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV -I /build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/build-llvm/lib/Target/RISCV -I /build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/build-llvm/include -I /build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/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/c++/6.3.0/backward -internal-isystem /usr/lib/llvm-13/lib/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../x86_64-linux-gnu/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-13~++20210413100635+64c24f493e5f/build-llvm/lib/Target/RISCV/AsmParser -fdebug-prefix-map=/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f=. -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 -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2021-04-14-063029-18377-1 -x c++ /build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp

/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/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/RISCVBaseInfo.h"
11#include "MCTargetDesc/RISCVInstPrinter.h"
12#include "MCTargetDesc/RISCVMCExpr.h"
13#include "MCTargetDesc/RISCVMCTargetDesc.h"
14#include "MCTargetDesc/RISCVMatInt.h"
15#include "MCTargetDesc/RISCVTargetStreamer.h"
16#include "TargetInfo/RISCVTargetInfo.h"
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/SmallBitVector.h"
19#include "llvm/ADT/SmallString.h"
20#include "llvm/ADT/SmallVector.h"
21#include "llvm/ADT/Statistic.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 // Helper to emit pseudo vmsge{u}.vx instruction.
132 void emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, MCStreamer &Out);
133
134 // Checks that a PseudoAddTPRel is using x4/tp in its second input operand.
135 // Enforcing this using a restricted register class for the second input
136 // operand of PseudoAddTPRel results in a poor diagnostic due to the fact
137 // 'add' is an overloaded mnemonic.
138 bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands);
139
140 // Check instruction constraints.
141 bool validateInstruction(MCInst &Inst, OperandVector &Operands);
142
143 /// Helper for processing MC instructions that have been successfully matched
144 /// by MatchAndEmitInstruction. Modifications to the emitted instructions,
145 /// like the expansion of pseudo instructions (e.g., "li"), can be performed
146 /// in this method.
147 bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,
148 MCStreamer &Out);
149
150// Auto-generated instruction matching functions
151#define GET_ASSEMBLER_HEADER
152#include "RISCVGenAsmMatcher.inc"
153
154 OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands);
155 OperandMatchResultTy parseImmediate(OperandVector &Operands);
156 OperandMatchResultTy parseRegister(OperandVector &Operands,
157 bool AllowParens = false);
158 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands);
159 OperandMatchResultTy parseAtomicMemOp(OperandVector &Operands);
160 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands);
161 OperandMatchResultTy parseBareSymbol(OperandVector &Operands);
162 OperandMatchResultTy parseCallSymbol(OperandVector &Operands);
163 OperandMatchResultTy parsePseudoJumpSymbol(OperandVector &Operands);
164 OperandMatchResultTy parseJALOffset(OperandVector &Operands);
165 OperandMatchResultTy parseVTypeI(OperandVector &Operands);
166 OperandMatchResultTy parseMaskReg(OperandVector &Operands);
167
168 bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
169
170 bool parseDirectiveOption();
171 bool parseDirectiveAttribute();
172
173 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
174 if (!(getSTI().getFeatureBits()[Feature])) {
175 MCSubtargetInfo &STI = copySTI();
176 setAvailableFeatures(
177 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
178 }
179 }
180
181 bool getFeatureBits(uint64_t Feature) {
182 return getSTI().getFeatureBits()[Feature];
183 }
184
185 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
186 if (getSTI().getFeatureBits()[Feature]) {
187 MCSubtargetInfo &STI = copySTI();
188 setAvailableFeatures(
189 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
190 }
191 }
192
193 void pushFeatureBits() {
194 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 195, __PRETTY_FUNCTION__))
195 "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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 195, __PRETTY_FUNCTION__))
;
196 FeatureBitStack.push_back(getSTI().getFeatureBits());
197 ParserOptionsStack.push_back(ParserOptions);
198 }
199
200 bool popFeatureBits() {
201 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 202, __PRETTY_FUNCTION__))
202 "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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 202, __PRETTY_FUNCTION__))
;
203 if (FeatureBitStack.empty())
204 return true;
205
206 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
207 copySTI().setFeatureBits(FeatureBits);
208 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
209
210 ParserOptions = ParserOptionsStack.pop_back_val();
211
212 return false;
213 }
214
215 std::unique_ptr<RISCVOperand> defaultMaskRegOp() const;
216
217public:
218 enum RISCVMatchResultTy {
219 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
220#define GET_OPERAND_DIAGNOSTIC_TYPES
221#include "RISCVGenAsmMatcher.inc"
222#undef GET_OPERAND_DIAGNOSTIC_TYPES
223 };
224
225 static bool classifySymbolRef(const MCExpr *Expr,
226 RISCVMCExpr::VariantKind &Kind);
227
228 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
229 const MCInstrInfo &MII, const MCTargetOptions &Options)
230 : MCTargetAsmParser(Options, STI, MII) {
231 Parser.addAliasForDirective(".half", ".2byte");
232 Parser.addAliasForDirective(".hword", ".2byte");
233 Parser.addAliasForDirective(".word", ".4byte");
234 Parser.addAliasForDirective(".dword", ".8byte");
235 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
236
237 auto ABIName = StringRef(Options.ABIName);
238 if (ABIName.endswith("f") &&
239 !getSTI().getFeatureBits()[RISCV::FeatureStdExtF]) {
240 errs() << "Hard-float 'f' ABI can't be used for a target that "
241 "doesn't support the F instruction set extension (ignoring "
242 "target-abi)\n";
243 } else if (ABIName.endswith("d") &&
244 !getSTI().getFeatureBits()[RISCV::FeatureStdExtD]) {
245 errs() << "Hard-float 'd' ABI can't be used for a target that "
246 "doesn't support the D instruction set extension (ignoring "
247 "target-abi)\n";
248 }
249
250 const MCObjectFileInfo *MOFI = Parser.getContext().getObjectFileInfo();
251 ParserOptions.IsPicEnabled = MOFI->isPositionIndependent();
252 }
253};
254
255/// RISCVOperand - Instances of this class represent a parsed machine
256/// instruction
257struct RISCVOperand : public MCParsedAsmOperand {
258
259 enum class KindTy {
260 Token,
261 Register,
262 Immediate,
263 SystemRegister,
264 VType,
265 } Kind;
266
267 bool IsRV64;
268
269 struct RegOp {
270 MCRegister RegNum;
271 };
272
273 struct ImmOp {
274 const MCExpr *Val;
275 };
276
277 struct SysRegOp {
278 const char *Data;
279 unsigned Length;
280 unsigned Encoding;
281 // FIXME: Add the Encoding parsed fields as needed for checks,
282 // e.g.: read/write or user/supervisor/machine privileges.
283 };
284
285 struct VTypeOp {
286 unsigned Val;
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 isSImm5() const {
517 if (!isImm())
518 return false;
519 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
520 int64_t Imm;
521 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
522 return IsConstantImm && isInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
523 }
524
525 bool isSImm6() const {
526 if (!isImm())
527 return false;
528 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
529 int64_t Imm;
530 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
531 return IsConstantImm && isInt<6>(Imm) &&
532 VK == RISCVMCExpr::VK_RISCV_None;
533 }
534
535 bool isSImm6NonZero() 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) && (Imm != 0) &&
542 VK == RISCVMCExpr::VK_RISCV_None;
543 }
544
545 bool isCLUIImm() const {
546 if (!isImm())
547 return false;
548 int64_t Imm;
549 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
550 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
551 return IsConstantImm && (Imm != 0) &&
552 (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) &&
553 VK == RISCVMCExpr::VK_RISCV_None;
554 }
555
556 bool isUImm7Lsb00() const {
557 if (!isImm())
558 return false;
559 int64_t Imm;
560 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
561 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
562 return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
563 VK == RISCVMCExpr::VK_RISCV_None;
564 }
565
566 bool isUImm8Lsb00() 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<6, 2>(Imm) &&
573 VK == RISCVMCExpr::VK_RISCV_None;
574 }
575
576 bool isUImm8Lsb000() 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<5, 3>(Imm) &&
583 VK == RISCVMCExpr::VK_RISCV_None;
584 }
585
586 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); }
587
588 bool isUImm9Lsb000() const {
589 if (!isImm())
590 return false;
591 int64_t Imm;
592 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
593 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
594 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
595 VK == RISCVMCExpr::VK_RISCV_None;
596 }
597
598 bool isUImm10Lsb00NonZero() 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<8, 2>(Imm) && (Imm != 0) &&
605 VK == RISCVMCExpr::VK_RISCV_None;
606 }
607
608 bool isSImm12() const {
609 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
610 int64_t Imm;
611 bool IsValid;
612 if (!isImm())
613 return false;
614 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
615 if (!IsConstantImm)
616 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
617 else
618 IsValid = isInt<12>(Imm);
619 return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) ||
620 VK == RISCVMCExpr::VK_RISCV_LO ||
621 VK == RISCVMCExpr::VK_RISCV_PCREL_LO ||
622 VK == RISCVMCExpr::VK_RISCV_TPREL_LO);
623 }
624
625 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); }
626
627 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
628
629 bool isSImm10Lsb0000NonZero() const {
630 if (!isImm())
631 return false;
632 int64_t Imm;
633 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
634 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
635 return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) &&
636 VK == RISCVMCExpr::VK_RISCV_None;
637 }
638
639 bool isUImm20LUI() const {
640 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
641 int64_t Imm;
642 bool IsValid;
643 if (!isImm())
644 return false;
645 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
646 if (!IsConstantImm) {
647 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
648 return IsValid && (VK == RISCVMCExpr::VK_RISCV_HI ||
649 VK == RISCVMCExpr::VK_RISCV_TPREL_HI);
650 } else {
651 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
652 VK == RISCVMCExpr::VK_RISCV_HI ||
653 VK == RISCVMCExpr::VK_RISCV_TPREL_HI);
654 }
655 }
656
657 bool isUImm20AUIPC() const {
658 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
659 int64_t Imm;
660 bool IsValid;
661 if (!isImm())
662 return false;
663 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
664 if (!IsConstantImm) {
665 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
666 return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
667 VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
668 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
669 VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI);
670 } else {
671 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
672 VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
673 VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
674 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
675 VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI);
676 }
677 }
678
679 bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); }
680
681 bool isImmZero() const {
682 if (!isImm())
683 return false;
684 int64_t Imm;
685 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
686 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
687 return IsConstantImm && (Imm == 0) && VK == RISCVMCExpr::VK_RISCV_None;
688 }
689
690 bool isSImm5Plus1() const {
691 if (!isImm())
692 return false;
693 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
694 int64_t Imm;
695 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
696 return IsConstantImm && isInt<5>(Imm - 1) &&
697 VK == RISCVMCExpr::VK_RISCV_None;
698 }
699
700 /// getStartLoc - Gets location of the first token of this operand
701 SMLoc getStartLoc() const override { return StartLoc; }
702 /// getEndLoc - Gets location of the last token of this operand
703 SMLoc getEndLoc() const override { return EndLoc; }
704 /// True if this operand is for an RV64 instruction
705 bool isRV64() const { return IsRV64; }
706
707 unsigned getReg() const override {
708 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 708, __PRETTY_FUNCTION__))
;
709 return Reg.RegNum.id();
710 }
711
712 StringRef getSysReg() const {
713 assert(Kind == KindTy::SystemRegister && "Invalid type access!")((Kind == KindTy::SystemRegister && "Invalid type access!"
) ? static_cast<void> (0) : __assert_fail ("Kind == KindTy::SystemRegister && \"Invalid type access!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 713, __PRETTY_FUNCTION__))
;
714 return StringRef(SysReg.Data, SysReg.Length);
715 }
716
717 const MCExpr *getImm() const {
718 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 718, __PRETTY_FUNCTION__))
;
719 return Imm.Val;
720 }
721
722 StringRef getToken() const {
723 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 723, __PRETTY_FUNCTION__))
;
724 return Tok;
725 }
726
727 unsigned getVType() const {
728 assert(Kind == KindTy::VType && "Invalid type access!")((Kind == KindTy::VType && "Invalid type access!") ? static_cast
<void> (0) : __assert_fail ("Kind == KindTy::VType && \"Invalid type access!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 728, __PRETTY_FUNCTION__))
;
729 return VType.Val;
730 }
731
732 void print(raw_ostream &OS) const override {
733 auto RegName = [](unsigned Reg) {
734 if (Reg)
735 return RISCVInstPrinter::getRegisterName(Reg);
736 else
737 return "noreg";
738 };
739
740 switch (Kind) {
741 case KindTy::Immediate:
742 OS << *getImm();
743 break;
744 case KindTy::Register:
745 OS << "<register " << RegName(getReg()) << ">";
746 break;
747 case KindTy::Token:
748 OS << "'" << getToken() << "'";
749 break;
750 case KindTy::SystemRegister:
751 OS << "<sysreg: " << getSysReg() << '>';
752 break;
753 case KindTy::VType:
754 OS << "<vtype: ";
755 RISCVVType::printVType(getVType(), OS);
756 OS << '>';
757 break;
758 }
759 }
760
761 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S,
762 bool IsRV64) {
763 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
764 Op->Tok = Str;
765 Op->StartLoc = S;
766 Op->EndLoc = S;
767 Op->IsRV64 = IsRV64;
768 return Op;
769 }
770
771 static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S,
772 SMLoc E, bool IsRV64) {
773 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
774 Op->Reg.RegNum = RegNo;
775 Op->StartLoc = S;
776 Op->EndLoc = E;
777 Op->IsRV64 = IsRV64;
778 return Op;
779 }
780
781 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S,
782 SMLoc E, bool IsRV64) {
783 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
784 Op->Imm.Val = Val;
785 Op->StartLoc = S;
786 Op->EndLoc = E;
787 Op->IsRV64 = IsRV64;
788 return Op;
789 }
790
791 static std::unique_ptr<RISCVOperand>
792 createSysReg(StringRef Str, SMLoc S, unsigned Encoding, bool IsRV64) {
793 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
794 Op->SysReg.Data = Str.data();
795 Op->SysReg.Length = Str.size();
796 Op->SysReg.Encoding = Encoding;
797 Op->StartLoc = S;
798 Op->IsRV64 = IsRV64;
799 return Op;
800 }
801
802 static std::unique_ptr<RISCVOperand> createVType(unsigned VTypeI, SMLoc S,
803 bool IsRV64) {
804 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
805 Op->VType.Val = VTypeI;
806 Op->StartLoc = S;
807 Op->IsRV64 = IsRV64;
808 return Op;
809 }
810
811 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
812 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 812, __PRETTY_FUNCTION__))
;
813 int64_t Imm = 0;
814 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
815 bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
816
817 if (IsConstant)
818 Inst.addOperand(MCOperand::createImm(Imm));
819 else
820 Inst.addOperand(MCOperand::createExpr(Expr));
821 }
822
823 // Used by the TableGen Code
824 void addRegOperands(MCInst &Inst, unsigned N) const {
825 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 825, __PRETTY_FUNCTION__))
;
826 Inst.addOperand(MCOperand::createReg(getReg()));
827 }
828
829 void addImmOperands(MCInst &Inst, unsigned N) const {
830 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 830, __PRETTY_FUNCTION__))
;
831 addExpr(Inst, getImm());
832 }
833
834 void addFenceArgOperands(MCInst &Inst, unsigned N) const {
835 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 835, __PRETTY_FUNCTION__))
;
836 // isFenceArg has validated the operand, meaning this cast is safe
837 auto SE = cast<MCSymbolRefExpr>(getImm());
838
839 unsigned Imm = 0;
840 for (char c : SE->getSymbol().getName()) {
841 switch (c) {
842 default:
843 llvm_unreachable("FenceArg must contain only [iorw]")::llvm::llvm_unreachable_internal("FenceArg must contain only [iorw]"
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 843)
;
844 case 'i': Imm |= RISCVFenceField::I; break;
845 case 'o': Imm |= RISCVFenceField::O; break;
846 case 'r': Imm |= RISCVFenceField::R; break;
847 case 'w': Imm |= RISCVFenceField::W; break;
848 }
849 }
850 Inst.addOperand(MCOperand::createImm(Imm));
851 }
852
853 void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
854 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 854, __PRETTY_FUNCTION__))
;
855 Inst.addOperand(MCOperand::createImm(SysReg.Encoding));
856 }
857
858 void addVTypeIOperands(MCInst &Inst, unsigned N) const {
859 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 859, __PRETTY_FUNCTION__))
;
860 Inst.addOperand(MCOperand::createImm(getVType()));
861 }
862
863 // Returns the rounding mode represented by this RISCVOperand. Should only
864 // be called after checking isFRMArg.
865 RISCVFPRndMode::RoundingMode getRoundingMode() const {
866 // isFRMArg has validated the operand, meaning this cast is safe.
867 auto SE = cast<MCSymbolRefExpr>(getImm());
868 RISCVFPRndMode::RoundingMode FRM =
869 RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName());
870 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 870, __PRETTY_FUNCTION__))
;
871 return FRM;
872 }
873
874 void addFRMArgOperands(MCInst &Inst, unsigned N) const {
875 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 875, __PRETTY_FUNCTION__))
;
876 Inst.addOperand(MCOperand::createImm(getRoundingMode()));
877 }
878};
879} // end anonymous namespace.
880
881#define GET_REGISTER_MATCHER
882#define GET_SUBTARGET_FEATURE_NAME
883#define GET_MATCHER_IMPLEMENTATION
884#define GET_MNEMONIC_SPELL_CHECKER
885#include "RISCVGenAsmMatcher.inc"
886
887static MCRegister convertFPR64ToFPR16(MCRegister Reg) {
888 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 888, __PRETTY_FUNCTION__))
;
889 return Reg - RISCV::F0_D + RISCV::F0_H;
890}
891
892static MCRegister convertFPR64ToFPR32(MCRegister Reg) {
893 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 893, __PRETTY_FUNCTION__))
;
894 return Reg - RISCV::F0_D + RISCV::F0_F;
895}
896
897static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg,
898 unsigned Kind) {
899 unsigned RegClassID;
900 if (Kind == MCK_VRM2)
901 RegClassID = RISCV::VRM2RegClassID;
902 else if (Kind == MCK_VRM4)
903 RegClassID = RISCV::VRM4RegClassID;
904 else if (Kind == MCK_VRM8)
905 RegClassID = RISCV::VRM8RegClassID;
906 else
907 return 0;
908 return RI.getMatchingSuperReg(Reg, RISCV::sub_vrm1_0,
909 &RISCVMCRegisterClasses[RegClassID]);
910}
911
912unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
913 unsigned Kind) {
914 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp);
915 if (!Op.isReg())
916 return Match_InvalidOperand;
917
918 MCRegister Reg = Op.getReg();
919 bool IsRegFPR64 =
920 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(Reg);
921 bool IsRegFPR64C =
922 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(Reg);
923 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(Reg);
924
925 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
926 // register from FPR64 to FPR32 or FPR64C to FPR32C if necessary.
927 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
928 (IsRegFPR64C && Kind == MCK_FPR32C)) {
929 Op.Reg.RegNum = convertFPR64ToFPR32(Reg);
930 return Match_Success;
931 }
932 // As the parser couldn't differentiate an FPR16 from an FPR64, coerce the
933 // register from FPR64 to FPR16 if necessary.
934 if (IsRegFPR64 && Kind == MCK_FPR16) {
935 Op.Reg.RegNum = convertFPR64ToFPR16(Reg);
936 return Match_Success;
937 }
938 // As the parser couldn't differentiate an VRM2/VRM4/VRM8 from an VR, coerce
939 // the register from VR to VRM2/VRM4/VRM8 if necessary.
940 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
941 Op.Reg.RegNum = convertVRToVRMx(*getContext().getRegisterInfo(), Reg, Kind);
942 if (Op.Reg.RegNum == 0)
943 return Match_InvalidOperand;
944 return Match_Success;
945 }
946 return Match_InvalidOperand;
947}
948
949bool RISCVAsmParser::generateImmOutOfRangeError(
950 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
951 Twine Msg = "immediate must be an integer in the range") {
952 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
953 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
954}
955
956static std::string RISCVMnemonicSpellCheck(StringRef S,
957 const FeatureBitset &FBS,
958 unsigned VariantID = 0);
959
960bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
961 OperandVector &Operands,
962 MCStreamer &Out,
963 uint64_t &ErrorInfo,
964 bool MatchingInlineAsm) {
965 MCInst Inst;
966 FeatureBitset MissingFeatures;
967
968 auto Result =
969 MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
970 MatchingInlineAsm);
971 switch (Result) {
972 default:
973 break;
974 case Match_Success:
975 if (validateInstruction(Inst, Operands))
976 return true;
977 return processInstruction(Inst, IDLoc, Operands, Out);
978 case Match_MissingFeature: {
979 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 979, __PRETTY_FUNCTION__))
;
980 bool FirstFeature = true;
981 std::string Msg = "instruction requires the following:";
982 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
983 if (MissingFeatures[i]) {
984 Msg += FirstFeature ? " " : ", ";
985 Msg += getSubtargetFeatureName(i);
986 FirstFeature = false;
987 }
988 }
989 return Error(IDLoc, Msg);
990 }
991 case Match_MnemonicFail: {
992 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
993 std::string Suggestion = RISCVMnemonicSpellCheck(
994 ((RISCVOperand &)*Operands[0]).getToken(), FBS);
995 return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);
996 }
997 case Match_InvalidOperand: {
998 SMLoc ErrorLoc = IDLoc;
999 if (ErrorInfo != ~0U) {
1000 if (ErrorInfo >= Operands.size())
1001 return Error(ErrorLoc, "too few operands for instruction");
1002
1003 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1004 if (ErrorLoc == SMLoc())
1005 ErrorLoc = IDLoc;
1006 }
1007 return Error(ErrorLoc, "invalid operand for instruction");
1008 }
1009 }
1010
1011 // Handle the case when the error message is of specific type
1012 // other than the generic Match_InvalidOperand, and the
1013 // corresponding operand is missing.
1014 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1015 SMLoc ErrorLoc = IDLoc;
1016 if (ErrorInfo != ~0U && ErrorInfo >= Operands.size())
1017 return Error(ErrorLoc, "too few operands for instruction");
1018 }
1019
1020 switch(Result) {
1021 default:
1022 break;
1023 case Match_InvalidImmXLenLI:
1024 if (isRV64()) {
1025 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1026 return Error(ErrorLoc, "operand must be a constant 64-bit integer");
1027 }
1028 return generateImmOutOfRangeError(Operands, ErrorInfo,
1029 std::numeric_limits<int32_t>::min(),
1030 std::numeric_limits<uint32_t>::max());
1031 case Match_InvalidImmZero: {
1032 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1033 return Error(ErrorLoc, "immediate must be zero");
1034 }
1035 case Match_InvalidUImmLog2XLen:
1036 if (isRV64())
1037 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1038 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1039 case Match_InvalidUImmLog2XLenNonZero:
1040 if (isRV64())
1041 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
1042 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1043 case Match_InvalidUImmLog2XLenHalf:
1044 if (isRV64())
1045 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1046 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1047 case Match_InvalidUImm5:
1048 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1049 case Match_InvalidSImm5:
1050 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),
1051 (1 << 4) - 1);
1052 case Match_InvalidSImm6:
1053 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
1054 (1 << 5) - 1);
1055 case Match_InvalidSImm6NonZero:
1056 return generateImmOutOfRangeError(
1057 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1058 "immediate must be non-zero in the range");
1059 case Match_InvalidCLUIImm:
1060 return generateImmOutOfRangeError(
1061 Operands, ErrorInfo, 1, (1 << 5) - 1,
1062 "immediate must be in [0xfffe0, 0xfffff] or");
1063 case Match_InvalidUImm7Lsb00:
1064 return generateImmOutOfRangeError(
1065 Operands, ErrorInfo, 0, (1 << 7) - 4,
1066 "immediate must be a multiple of 4 bytes in the range");
1067 case Match_InvalidUImm8Lsb00:
1068 return generateImmOutOfRangeError(
1069 Operands, ErrorInfo, 0, (1 << 8) - 4,
1070 "immediate must be a multiple of 4 bytes in the range");
1071 case Match_InvalidUImm8Lsb000:
1072 return generateImmOutOfRangeError(
1073 Operands, ErrorInfo, 0, (1 << 8) - 8,
1074 "immediate must be a multiple of 8 bytes in the range");
1075 case Match_InvalidSImm9Lsb0:
1076 return generateImmOutOfRangeError(
1077 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1078 "immediate must be a multiple of 2 bytes in the range");
1079 case Match_InvalidUImm9Lsb000:
1080 return generateImmOutOfRangeError(
1081 Operands, ErrorInfo, 0, (1 << 9) - 8,
1082 "immediate must be a multiple of 8 bytes in the range");
1083 case Match_InvalidUImm10Lsb00NonZero:
1084 return generateImmOutOfRangeError(
1085 Operands, ErrorInfo, 4, (1 << 10) - 4,
1086 "immediate must be a multiple of 4 bytes in the range");
1087 case Match_InvalidSImm10Lsb0000NonZero:
1088 return generateImmOutOfRangeError(
1089 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1090 "immediate must be a multiple of 16 bytes and non-zero in the range");
1091 case Match_InvalidSImm12:
1092 return generateImmOutOfRangeError(
1093 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1094 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1095 "integer in the range");
1096 case Match_InvalidSImm12Lsb0:
1097 return generateImmOutOfRangeError(
1098 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1099 "immediate must be a multiple of 2 bytes in the range");
1100 case Match_InvalidSImm13Lsb0:
1101 return generateImmOutOfRangeError(
1102 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1103 "immediate must be a multiple of 2 bytes in the range");
1104 case Match_InvalidUImm20LUI:
1105 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1,
1106 "operand must be a symbol with "
1107 "%hi/%tprel_hi modifier or an integer in "
1108 "the range");
1109 case Match_InvalidUImm20AUIPC:
1110 return generateImmOutOfRangeError(
1111 Operands, ErrorInfo, 0, (1 << 20) - 1,
1112 "operand must be a symbol with a "
1113 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1114 "an integer in the range");
1115 case Match_InvalidSImm21Lsb0JAL:
1116 return generateImmOutOfRangeError(
1117 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1118 "immediate must be a multiple of 2 bytes in the range");
1119 case Match_InvalidCSRSystemRegister: {
1120 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
1121 "operand must be a valid system register "
1122 "name or an integer in the range");
1123 }
1124 case Match_InvalidFenceArg: {
1125 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1126 return Error(
1127 ErrorLoc,
1128 "operand must be formed of letters selected in-order from 'iorw'");
1129 }
1130 case Match_InvalidFRMArg: {
1131 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1132 return Error(
1133 ErrorLoc,
1134 "operand must be a valid floating point rounding mode mnemonic");
1135 }
1136 case Match_InvalidBareSymbol: {
1137 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1138 return Error(ErrorLoc, "operand must be a bare symbol name");
1139 }
1140 case Match_InvalidPseudoJumpSymbol: {
1141 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1142 return Error(ErrorLoc, "operand must be a valid jump target");
1143 }
1144 case Match_InvalidCallSymbol: {
1145 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1146 return Error(ErrorLoc, "operand must be a bare symbol name");
1147 }
1148 case Match_InvalidTPRelAddSymbol: {
1149 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1150 return Error(ErrorLoc, "operand must be a symbol with %tprel_add modifier");
1151 }
1152 case Match_InvalidVTypeI: {
1153 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1154 return Error(
1155 ErrorLoc,
1156 "operand must be "
1157 "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
1158 }
1159 case Match_InvalidVMaskRegister: {
1160 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1161 return Error(ErrorLoc, "operand must be v0.t");
1162 }
1163 case Match_InvalidSImm5Plus1: {
1164 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,
1165 (1 << 4),
1166 "immediate must be in the range");
1167 }
1168 }
1169
1170 llvm_unreachable("Unknown match type detected!")::llvm::llvm_unreachable_internal("Unknown match type detected!"
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 1170)
;
1171}
1172
1173// Attempts to match Name as a register (either using the default name or
1174// alternative ABI names), setting RegNo to the matching register. Upon
1175// failure, returns true and sets RegNo to 0. If IsRV32E then registers
1176// x16-x31 will be rejected.
1177static bool matchRegisterNameHelper(bool IsRV32E, MCRegister &RegNo,
1178 StringRef Name) {
1179 RegNo = MatchRegisterName(Name);
1180 // The 16-/32- and 64-bit FPRs have the same asm name. Check that the initial
1181 // match always matches the 64-bit variant, and not the 16/32-bit one.
1182 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 1182, __PRETTY_FUNCTION__))
;
1183 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 1183, __PRETTY_FUNCTION__))
;
1184 // The default FPR register class is based on the tablegen enum ordering.
1185 static_assert(RISCV::F0_D < RISCV::F0_H, "FPR matching must be updated");
1186 static_assert(RISCV::F0_D < RISCV::F0_F, "FPR matching must be updated");
1187 if (RegNo == RISCV::NoRegister)
1188 RegNo = MatchRegisterAltName(Name);
1189 if (IsRV32E && RegNo >= RISCV::X16 && RegNo <= RISCV::X31)
1190 RegNo = RISCV::NoRegister;
1191 return RegNo == RISCV::NoRegister;
1192}
1193
1194bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1195 SMLoc &EndLoc) {
1196 if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success)
1197 return Error(StartLoc, "invalid register name");
1198 return false;
1199}
1200
1201OperandMatchResultTy RISCVAsmParser::tryParseRegister(unsigned &RegNo,
1202 SMLoc &StartLoc,
1203 SMLoc &EndLoc) {
1204 const AsmToken &Tok = getParser().getTok();
1205 StartLoc = Tok.getLoc();
1206 EndLoc = Tok.getEndLoc();
1207 RegNo = 0;
1208 StringRef Name = getLexer().getTok().getIdentifier();
1209
1210 if (matchRegisterNameHelper(isRV32E(), (MCRegister &)RegNo, Name))
1211 return MatchOperand_NoMatch;
1212
1213 getParser().Lex(); // Eat identifier token.
1214 return MatchOperand_Success;
1215}
1216
1217OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands,
1218 bool AllowParens) {
1219 SMLoc FirstS = getLoc();
1220 bool HadParens = false;
1221 AsmToken LParen;
1222
1223 // If this is an LParen and a parenthesised register name is allowed, parse it
1224 // atomically.
1225 if (AllowParens && getLexer().is(AsmToken::LParen)) {
1226 AsmToken Buf[2];
1227 size_t ReadCount = getLexer().peekTokens(Buf);
1228 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
1229 HadParens = true;
1230 LParen = getParser().getTok();
1231 getParser().Lex(); // Eat '('
1232 }
1233 }
1234
1235 switch (getLexer().getKind()) {
1236 default:
1237 if (HadParens)
1238 getLexer().UnLex(LParen);
1239 return MatchOperand_NoMatch;
1240 case AsmToken::Identifier:
1241 StringRef Name = getLexer().getTok().getIdentifier();
1242 MCRegister RegNo;
1243 matchRegisterNameHelper(isRV32E(), RegNo, Name);
1244
1245 if (RegNo == RISCV::NoRegister) {
1246 if (HadParens)
1247 getLexer().UnLex(LParen);
1248 return MatchOperand_NoMatch;
1249 }
1250 if (HadParens)
1251 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64()));
1252 SMLoc S = getLoc();
1253 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1254 getLexer().Lex();
1255 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
1256 }
1257
1258 if (HadParens) {
1259 getParser().Lex(); // Eat ')'
1260 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
1261 }
1262
1263 return MatchOperand_Success;
1264}
1265
1266OperandMatchResultTy
1267RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
1268 SMLoc S = getLoc();
1269 const MCExpr *Res;
1270
1271 switch (getLexer().getKind()) {
1272 default:
1273 return MatchOperand_NoMatch;
1274 case AsmToken::LParen:
1275 case AsmToken::Minus:
1276 case AsmToken::Plus:
1277 case AsmToken::Exclaim:
1278 case AsmToken::Tilde:
1279 case AsmToken::Integer:
1280 case AsmToken::String: {
1281 if (getParser().parseExpression(Res))
1282 return MatchOperand_ParseFail;
1283
1284 auto *CE = dyn_cast<MCConstantExpr>(Res);
1285 if (CE) {
1286 int64_t Imm = CE->getValue();
1287 if (isUInt<12>(Imm)) {
1288 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
1289 // Accept an immediate representing a named or un-named Sys Reg
1290 // if the range is valid, regardless of the required features.
1291 Operands.push_back(RISCVOperand::createSysReg(
1292 SysReg ? SysReg->Name : "", S, Imm, isRV64()));
1293 return MatchOperand_Success;
1294 }
1295 }
1296
1297 Twine Msg = "immediate must be an integer in the range";
1298 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1299 return MatchOperand_ParseFail;
1300 }
1301 case AsmToken::Identifier: {
1302 StringRef Identifier;
1303 if (getParser().parseIdentifier(Identifier))
1304 return MatchOperand_ParseFail;
1305
1306 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1307 if (!SysReg)
1308 SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
1309 // Accept a named Sys Reg if the required features are present.
1310 if (SysReg) {
1311 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) {
1312 Error(S, "system register use requires an option to be enabled");
1313 return MatchOperand_ParseFail;
1314 }
1315 Operands.push_back(RISCVOperand::createSysReg(
1316 Identifier, S, SysReg->Encoding, isRV64()));
1317 return MatchOperand_Success;
1318 }
1319
1320 Twine Msg = "operand must be a valid system register name "
1321 "or an integer in the range";
1322 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1323 return MatchOperand_ParseFail;
1324 }
1325 case AsmToken::Percent: {
1326 // Discard operand with modifier.
1327 Twine Msg = "immediate must be an integer in the range";
1328 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1329 return MatchOperand_ParseFail;
1330 }
1331 }
1332
1333 return MatchOperand_NoMatch;
1334}
1335
1336OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) {
1337 SMLoc S = getLoc();
1338 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1339 const MCExpr *Res;
1340
1341 switch (getLexer().getKind()) {
1342 default:
1343 return MatchOperand_NoMatch;
1344 case AsmToken::LParen:
1345 case AsmToken::Dot:
1346 case AsmToken::Minus:
1347 case AsmToken::Plus:
1348 case AsmToken::Exclaim:
1349 case AsmToken::Tilde:
1350 case AsmToken::Integer:
1351 case AsmToken::String:
1352 case AsmToken::Identifier:
1353 if (getParser().parseExpression(Res))
1354 return MatchOperand_ParseFail;
1355 break;
1356 case AsmToken::Percent:
1357 return parseOperandWithModifier(Operands);
1358 }
1359
1360 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1361 return MatchOperand_Success;
1362}
1363
1364OperandMatchResultTy
1365RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
1366 SMLoc S = getLoc();
1367 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1368
1369 if (getLexer().getKind() != AsmToken::Percent) {
1370 Error(getLoc(), "expected '%' for operand modifier");
1371 return MatchOperand_ParseFail;
1372 }
1373
1374 getParser().Lex(); // Eat '%'
1375
1376 if (getLexer().getKind() != AsmToken::Identifier) {
1377 Error(getLoc(), "expected valid identifier for operand modifier");
1378 return MatchOperand_ParseFail;
1379 }
1380 StringRef Identifier = getParser().getTok().getIdentifier();
1381 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier);
1382 if (VK == RISCVMCExpr::VK_RISCV_Invalid) {
1383 Error(getLoc(), "unrecognized operand modifier");
1384 return MatchOperand_ParseFail;
1385 }
1386
1387 getParser().Lex(); // Eat the identifier
1388 if (getLexer().getKind() != AsmToken::LParen) {
1389 Error(getLoc(), "expected '('");
1390 return MatchOperand_ParseFail;
1391 }
1392 getParser().Lex(); // Eat '('
1393
1394 const MCExpr *SubExpr;
1395 if (getParser().parseParenExpression(SubExpr, E)) {
1396 return MatchOperand_ParseFail;
1397 }
1398
1399 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext());
1400 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
1401 return MatchOperand_Success;
1402}
1403
1404OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) {
1405 SMLoc S = getLoc();
1406 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1407 const MCExpr *Res;
1408
1409 if (getLexer().getKind() != AsmToken::Identifier)
1410 return MatchOperand_NoMatch;
1411
1412 StringRef Identifier;
1413 AsmToken Tok = getLexer().getTok();
1414
1415 if (getParser().parseIdentifier(Identifier))
1416 return MatchOperand_ParseFail;
1417
1418 if (Identifier.consume_back("@plt")) {
1419 Error(getLoc(), "'@plt' operand not valid for instruction");
1420 return MatchOperand_ParseFail;
1421 }
1422
1423 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1424
1425 if (Sym->isVariable()) {
1426 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
1427 if (!isa<MCSymbolRefExpr>(V)) {
1428 getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
1429 return MatchOperand_NoMatch;
1430 }
1431 Res = V;
1432 } else
1433 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1434
1435 MCBinaryExpr::Opcode Opcode;
1436 switch (getLexer().getKind()) {
1437 default:
1438 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1439 return MatchOperand_Success;
1440 case AsmToken::Plus:
1441 Opcode = MCBinaryExpr::Add;
1442 break;
1443 case AsmToken::Minus:
1444 Opcode = MCBinaryExpr::Sub;
1445 break;
1446 }
1447
1448 const MCExpr *Expr;
1449 if (getParser().parseExpression(Expr))
1450 return MatchOperand_ParseFail;
1451 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
1452 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1453 return MatchOperand_Success;
1454}
1455
1456OperandMatchResultTy RISCVAsmParser::parseCallSymbol(OperandVector &Operands) {
1457 SMLoc S = getLoc();
1458 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1459 const MCExpr *Res;
1460
1461 if (getLexer().getKind() != AsmToken::Identifier)
1462 return MatchOperand_NoMatch;
1463
1464 // Avoid parsing the register in `call rd, foo` as a call symbol.
1465 if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement)
1466 return MatchOperand_NoMatch;
1467
1468 StringRef Identifier;
1469 if (getParser().parseIdentifier(Identifier))
1470 return MatchOperand_ParseFail;
1471
1472 RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_CALL;
1473 if (Identifier.consume_back("@plt"))
1474 Kind = RISCVMCExpr::VK_RISCV_CALL_PLT;
1475
1476 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1477 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
1478 Res = RISCVMCExpr::create(Res, Kind, getContext());
1479 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1480 return MatchOperand_Success;
1481}
1482
1483OperandMatchResultTy
1484RISCVAsmParser::parsePseudoJumpSymbol(OperandVector &Operands) {
1485 SMLoc S = getLoc();
1486 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1487 const MCExpr *Res;
1488
1489 if (getParser().parseExpression(Res))
1490 return MatchOperand_ParseFail;
1491
1492 if (Res->getKind() != MCExpr::ExprKind::SymbolRef ||
1493 cast<MCSymbolRefExpr>(Res)->getKind() ==
1494 MCSymbolRefExpr::VariantKind::VK_PLT) {
1495 Error(S, "operand must be a valid jump target");
1496 return MatchOperand_ParseFail;
1497 }
1498
1499 Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext());
1500 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1501 return MatchOperand_Success;
1502}
1503
1504OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) {
1505 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo`
1506 // both being acceptable forms. When parsing `jal ra, foo` this function
1507 // will be called for the `ra` register operand in an attempt to match the
1508 // single-operand alias. parseJALOffset must fail for this case. It would
1509 // seem logical to try parse the operand using parseImmediate and return
1510 // NoMatch if the next token is a comma (meaning we must be parsing a jal in
1511 // the second form rather than the first). We can't do this as there's no
1512 // way of rewinding the lexer state. Instead, return NoMatch if this operand
1513 // is an identifier and is followed by a comma.
1514 if (getLexer().is(AsmToken::Identifier) &&
1515 getLexer().peekTok().is(AsmToken::Comma))
1516 return MatchOperand_NoMatch;
1517
1518 return parseImmediate(Operands);
1519}
1520
1521OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) {
1522 SMLoc S = getLoc();
1523 if (getLexer().isNot(AsmToken::Identifier))
1524 return MatchOperand_NoMatch;
1525
1526 SmallVector<AsmToken, 7> VTypeIElements;
1527 // Put all the tokens for vtypei operand into VTypeIElements vector.
1528 while (getLexer().isNot(AsmToken::EndOfStatement)) {
1529 VTypeIElements.push_back(getLexer().getTok());
1530 getLexer().Lex();
1531 if (getLexer().is(AsmToken::EndOfStatement))
1532 break;
1533 if (getLexer().isNot(AsmToken::Comma))
1534 goto MatchFail;
1535 AsmToken Comma = getLexer().getTok();
1536 VTypeIElements.push_back(Comma);
1537 getLexer().Lex();
1538 }
1539
1540 if (VTypeIElements.size() == 7) {
1541 // The VTypeIElements layout is:
1542 // SEW comma LMUL comma TA comma MA
1543 // 0 1 2 3 4 5 6
1544 StringRef Name = VTypeIElements[0].getIdentifier();
1545 if (!Name.consume_front("e"))
1546 goto MatchFail;
1547 unsigned Sew;
1548 if (Name.getAsInteger(10, Sew))
1549 goto MatchFail;
1550 if (!RISCVVType::isValidSEW(Sew))
1551 goto MatchFail;
1552
1553 Name = VTypeIElements[2].getIdentifier();
1554 if (!Name.consume_front("m"))
1555 goto MatchFail;
1556 // "m" or "mf"
1557 bool Fractional = Name.consume_front("f");
1558 unsigned Lmul;
1559 if (Name.getAsInteger(10, Lmul))
1560 goto MatchFail;
1561 if (!RISCVVType::isValidLMUL(Lmul, Fractional))
1562 goto MatchFail;
1563
1564 // ta or tu
1565 Name = VTypeIElements[4].getIdentifier();
1566 bool TailAgnostic;
1567 if (Name == "ta")
1568 TailAgnostic = true;
1569 else if (Name == "tu")
1570 TailAgnostic = false;
1571 else
1572 goto MatchFail;
1573
1574 // ma or mu
1575 Name = VTypeIElements[6].getIdentifier();
1576 bool MaskAgnostic;
1577 if (Name == "ma")
1578 MaskAgnostic = true;
1579 else if (Name == "mu")
1580 MaskAgnostic = false;
1581 else
1582 goto MatchFail;
1583
1584 unsigned SewLog2 = Log2_32(Sew / 8);
1585 unsigned LmulLog2 = Log2_32(Lmul);
1586 RISCVVSEW VSEW = static_cast<RISCVVSEW>(SewLog2);
1587 RISCVVLMUL VLMUL =
1588 static_cast<RISCVVLMUL>(Fractional ? 8 - LmulLog2 : LmulLog2);
1589
1590 unsigned VTypeI =
1591 RISCVVType::encodeVTYPE(VLMUL, VSEW, TailAgnostic, MaskAgnostic);
1592 Operands.push_back(RISCVOperand::createVType(VTypeI, S, isRV64()));
1593 return MatchOperand_Success;
1594 }
1595
1596// If NoMatch, unlex all the tokens that comprise a vtypei operand
1597MatchFail:
1598 while (!VTypeIElements.empty())
1599 getLexer().UnLex(VTypeIElements.pop_back_val());
1600 return MatchOperand_NoMatch;
1601}
1602
1603OperandMatchResultTy RISCVAsmParser::parseMaskReg(OperandVector &Operands) {
1604 switch (getLexer().getKind()) {
1605 default:
1606 return MatchOperand_NoMatch;
1607 case AsmToken::Identifier:
1608 StringRef Name = getLexer().getTok().getIdentifier();
1609 if (!Name.consume_back(".t")) {
1610 Error(getLoc(), "expected '.t' suffix");
1611 return MatchOperand_ParseFail;
1612 }
1613 MCRegister RegNo;
1614 matchRegisterNameHelper(isRV32E(), RegNo, Name);
1615
1616 if (RegNo == RISCV::NoRegister)
1617 return MatchOperand_NoMatch;
1618 if (RegNo != RISCV::V0)
1619 return MatchOperand_NoMatch;
1620 SMLoc S = getLoc();
1621 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1);
1622 getLexer().Lex();
1623 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64()));
1624 }
1625
1626 return MatchOperand_Success;
1627}
1628
1629OperandMatchResultTy
1630RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
1631 if (getLexer().isNot(AsmToken::LParen)) {
1632 Error(getLoc(), "expected '('");
1633 return MatchOperand_ParseFail;
1634 }
1635
1636 getParser().Lex(); // Eat '('
1637 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64()));
1638
1639 if (parseRegister(Operands) != MatchOperand_Success) {
1640 Error(getLoc(), "expected register");
1641 return MatchOperand_ParseFail;
1642 }
1643
1644 if (getLexer().isNot(AsmToken::RParen)) {
1645 Error(getLoc(), "expected ')'");
1646 return MatchOperand_ParseFail;
1647 }
1648
1649 getParser().Lex(); // Eat ')'
1650 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
1651
1652 return MatchOperand_Success;
1653}
1654
1655OperandMatchResultTy RISCVAsmParser::parseAtomicMemOp(OperandVector &Operands) {
1656 // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand"
1657 // as one of their register operands, such as `(a0)`. This just denotes that
1658 // the register (in this case `a0`) contains a memory address.
1659 //
1660 // Normally, we would be able to parse these by putting the parens into the
1661 // instruction string. However, GNU as also accepts a zero-offset memory
1662 // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed
1663 // with parseImmediate followed by parseMemOpBaseReg, but these instructions
1664 // do not accept an immediate operand, and we do not want to add a "dummy"
1665 // operand that is silently dropped.
1666 //
1667 // Instead, we use this custom parser. This will: allow (and discard) an
1668 // offset if it is zero; require (and discard) parentheses; and add only the
1669 // parsed register operand to `Operands`.
1670 //
1671 // These operands are printed with RISCVInstPrinter::printAtomicMemOp, which
1672 // will only print the register surrounded by parentheses (which GNU as also
1673 // uses as its canonical representation for these operands).
1674 std::unique_ptr<RISCVOperand> OptionalImmOp;
1675
1676 if (getLexer().isNot(AsmToken::LParen)) {
1677 // Parse an Integer token. We do not accept arbritrary constant expressions
1678 // in the offset field (because they may include parens, which complicates
1679 // parsing a lot).
1680 int64_t ImmVal;
1681 SMLoc ImmStart = getLoc();
1682 if (getParser().parseIntToken(ImmVal,
1683 "expected '(' or optional integer offset"))
1684 return MatchOperand_ParseFail;
1685
1686 // Create a RISCVOperand for checking later (so the error messages are
1687 // nicer), but we don't add it to Operands.
1688 SMLoc ImmEnd = getLoc();
1689 OptionalImmOp =
1690 RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()),
1691 ImmStart, ImmEnd, isRV64());
1692 }
1693
1694 if (getLexer().isNot(AsmToken::LParen)) {
1695 Error(getLoc(), OptionalImmOp ? "expected '(' after optional integer offset"
1696 : "expected '(' or optional integer offset");
1697 return MatchOperand_ParseFail;
1698 }
1699 getParser().Lex(); // Eat '('
1700
1701 if (parseRegister(Operands) != MatchOperand_Success) {
1702 Error(getLoc(), "expected register");
1703 return MatchOperand_ParseFail;
1704 }
1705
1706 if (getLexer().isNot(AsmToken::RParen)) {
1707 Error(getLoc(), "expected ')'");
1708 return MatchOperand_ParseFail;
1709 }
1710 getParser().Lex(); // Eat ')'
1711
1712 // Deferred Handling of non-zero offsets. This makes the error messages nicer.
1713 if (OptionalImmOp && !OptionalImmOp->isImmZero()) {
1714 Error(OptionalImmOp->getStartLoc(), "optional integer offset must be 0",
1715 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
1716 return MatchOperand_ParseFail;
1717 }
1718
1719 return MatchOperand_Success;
1720}
1721
1722/// Looks at a token type and creates the relevant operand from this
1723/// information, adding to Operands. If operand was parsed, returns false, else
1724/// true.
1725bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1726 // Check if the current operand has a custom associated parser, if so, try to
1727 // custom parse the operand, or fallback to the general approach.
1728 OperandMatchResultTy Result =
1729 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
1730 if (Result == MatchOperand_Success)
1731 return false;
1732 if (Result == MatchOperand_ParseFail)
1733 return true;
1734
1735 // Attempt to parse token as a register.
1736 if (parseRegister(Operands, true) == MatchOperand_Success)
1737 return false;
1738
1739 // Attempt to parse token as an immediate
1740 if (parseImmediate(Operands) == MatchOperand_Success) {
1741 // Parse memory base register if present
1742 if (getLexer().is(AsmToken::LParen))
1743 return parseMemOpBaseReg(Operands) != MatchOperand_Success;
1744 return false;
1745 }
1746
1747 // Finally we have exhausted all options and must declare defeat.
1748 Error(getLoc(), "unknown operand");
1749 return true;
1750}
1751
1752bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
1753 StringRef Name, SMLoc NameLoc,
1754 OperandVector &Operands) {
1755 // Ensure that if the instruction occurs when relaxation is enabled,
1756 // relocations are forced for the file. Ideally this would be done when there
1757 // is enough information to reliably determine if the instruction itself may
1758 // cause relaxations. Unfortunately instruction processing stage occurs in the
1759 // same pass as relocation emission, so it's too late to set a 'sticky bit'
1760 // for the entire file.
1761 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) {
1762 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
1763 if (Assembler != nullptr) {
1764 RISCVAsmBackend &MAB =
1765 static_cast<RISCVAsmBackend &>(Assembler->getBackend());
1766 MAB.setForceRelocs();
1767 }
1768 }
1769
1770 // First operand is token for instruction
1771 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64()));
1772
1773 // If there are no more operands, then finish
1774 if (getLexer().is(AsmToken::EndOfStatement))
1775 return false;
1776
1777 // Parse first operand
1778 if (parseOperand(Operands, Name))
1779 return true;
1780
1781 // Parse until end of statement, consuming commas between operands
1782 unsigned OperandIdx = 1;
1783 while (getLexer().is(AsmToken::Comma)) {
1784 // Consume comma token
1785 getLexer().Lex();
1786
1787 // Parse next operand
1788 if (parseOperand(Operands, Name))
1789 return true;
1790
1791 ++OperandIdx;
1792 }
1793
1794 if (getLexer().isNot(AsmToken::EndOfStatement)) {
1795 SMLoc Loc = getLexer().getLoc();
1796 getParser().eatToEndOfStatement();
1797 return Error(Loc, "unexpected token");
1798 }
1799
1800 getParser().Lex(); // Consume the EndOfStatement.
1801 return false;
1802}
1803
1804bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,
1805 RISCVMCExpr::VariantKind &Kind) {
1806 Kind = RISCVMCExpr::VK_RISCV_None;
1807
1808 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
1809 Kind = RE->getKind();
1810 Expr = RE->getSubExpr();
1811 }
1812
1813 MCValue Res;
1814 MCFixup Fixup;
1815 if (Expr->evaluateAsRelocatable(Res, nullptr, &Fixup))
1816 return Res.getRefKind() == RISCVMCExpr::VK_RISCV_None;
1817 return false;
1818}
1819
1820bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) {
1821 // This returns false if this function recognizes the directive
1822 // regardless of whether it is successfully handles or reports an
1823 // error. Otherwise it returns true to give the generic parser a
1824 // chance at recognizing it.
1825 StringRef IDVal = DirectiveID.getString();
1826
1827 if (IDVal == ".option")
1828 return parseDirectiveOption();
1829 else if (IDVal == ".attribute")
1830 return parseDirectiveAttribute();
1831
1832 return true;
1833}
1834
1835bool RISCVAsmParser::parseDirectiveOption() {
1836 MCAsmParser &Parser = getParser();
1837 // Get the option token.
1838 AsmToken Tok = Parser.getTok();
1839 // At the moment only identifiers are supported.
1840 if (Tok.isNot(AsmToken::Identifier))
1841 return Error(Parser.getTok().getLoc(),
1842 "unexpected token, expected identifier");
1843
1844 StringRef Option = Tok.getIdentifier();
1845
1846 if (Option == "push") {
1847 getTargetStreamer().emitDirectiveOptionPush();
1848
1849 Parser.Lex();
1850 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1851 return Error(Parser.getTok().getLoc(),
1852 "unexpected token, expected end of statement");
1853
1854 pushFeatureBits();
1855 return false;
1856 }
1857
1858 if (Option == "pop") {
1859 SMLoc StartLoc = Parser.getTok().getLoc();
1860 getTargetStreamer().emitDirectiveOptionPop();
1861
1862 Parser.Lex();
1863 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1864 return Error(Parser.getTok().getLoc(),
1865 "unexpected token, expected end of statement");
1866
1867 if (popFeatureBits())
1868 return Error(StartLoc, ".option pop with no .option push");
1869
1870 return false;
1871 }
1872
1873 if (Option == "rvc") {
1874 getTargetStreamer().emitDirectiveOptionRVC();
1875
1876 Parser.Lex();
1877 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1878 return Error(Parser.getTok().getLoc(),
1879 "unexpected token, expected end of statement");
1880
1881 setFeatureBits(RISCV::FeatureStdExtC, "c");
1882 return false;
1883 }
1884
1885 if (Option == "norvc") {
1886 getTargetStreamer().emitDirectiveOptionNoRVC();
1887
1888 Parser.Lex();
1889 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1890 return Error(Parser.getTok().getLoc(),
1891 "unexpected token, expected end of statement");
1892
1893 clearFeatureBits(RISCV::FeatureStdExtC, "c");
1894 return false;
1895 }
1896
1897 if (Option == "pic") {
1898 getTargetStreamer().emitDirectiveOptionPIC();
1899
1900 Parser.Lex();
1901 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1902 return Error(Parser.getTok().getLoc(),
1903 "unexpected token, expected end of statement");
1904
1905 ParserOptions.IsPicEnabled = true;
1906 return false;
1907 }
1908
1909 if (Option == "nopic") {
1910 getTargetStreamer().emitDirectiveOptionNoPIC();
1911
1912 Parser.Lex();
1913 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1914 return Error(Parser.getTok().getLoc(),
1915 "unexpected token, expected end of statement");
1916
1917 ParserOptions.IsPicEnabled = false;
1918 return false;
1919 }
1920
1921 if (Option == "relax") {
1922 getTargetStreamer().emitDirectiveOptionRelax();
1923
1924 Parser.Lex();
1925 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1926 return Error(Parser.getTok().getLoc(),
1927 "unexpected token, expected end of statement");
1928
1929 setFeatureBits(RISCV::FeatureRelax, "relax");
1930 return false;
1931 }
1932
1933 if (Option == "norelax") {
1934 getTargetStreamer().emitDirectiveOptionNoRelax();
1935
1936 Parser.Lex();
1937 if (Parser.getTok().isNot(AsmToken::EndOfStatement))
1938 return Error(Parser.getTok().getLoc(),
1939 "unexpected token, expected end of statement");
1940
1941 clearFeatureBits(RISCV::FeatureRelax, "relax");
1942 return false;
1943 }
1944
1945 // Unknown option.
1946 Warning(Parser.getTok().getLoc(),
1947 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or "
1948 "'norelax'");
1949 Parser.eatToEndOfStatement();
1950 return false;
1951}
1952
1953/// parseDirectiveAttribute
1954/// ::= .attribute expression ',' ( expression | "string" )
1955/// ::= .attribute identifier ',' ( expression | "string" )
1956bool RISCVAsmParser::parseDirectiveAttribute() {
1957 MCAsmParser &Parser = getParser();
1958 int64_t Tag;
1959 SMLoc TagLoc;
1960 TagLoc = Parser.getTok().getLoc();
1961 if (Parser.getTok().is(AsmToken::Identifier)) {
1
Calling 'AsmToken::is'
4
Returning from 'AsmToken::is'
5
Taking false branch
1962 StringRef Name = Parser.getTok().getIdentifier();
1963 Optional<unsigned> Ret =
1964 ELFAttrs::attrTypeFromString(Name, RISCVAttrs::RISCVAttributeTags);
1965 if (!Ret.hasValue()) {
1966 Error(TagLoc, "attribute name not recognised: " + Name);
1967 return false;
1968 }
1969 Tag = Ret.getValue();
1970 Parser.Lex();
1971 } else {
1972 const MCExpr *AttrExpr;
1973
1974 TagLoc = Parser.getTok().getLoc();
1975 if (Parser.parseExpression(AttrExpr))
6
Assuming the condition is false
7
Taking false branch
1976 return true;
1977
1978 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
8
Assuming 'AttrExpr' is not a 'MCConstantExpr'
9
'CE' initialized to a null pointer value
1979 if (check(!CE, TagLoc, "expected numeric constant"))
10
Assuming the condition is false
11
Taking false branch
1980 return true;
1981
1982 Tag = CE->getValue();
12
Called C++ object pointer is null
1983 }
1984
1985 if (Parser.parseToken(AsmToken::Comma, "comma expected"))
1986 return true;
1987
1988 StringRef StringValue;
1989 int64_t IntegerValue = 0;
1990 bool IsIntegerValue = true;
1991
1992 // RISC-V attributes have a string value if the tag number is odd
1993 // and an integer value if the tag number is even.
1994 if (Tag % 2)
1995 IsIntegerValue = false;
1996
1997 SMLoc ValueExprLoc = Parser.getTok().getLoc();
1998 if (IsIntegerValue) {
1999 const MCExpr *ValueExpr;
2000 if (Parser.parseExpression(ValueExpr))
2001 return true;
2002
2003 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
2004 if (!CE)
2005 return Error(ValueExprLoc, "expected numeric constant");
2006 IntegerValue = CE->getValue();
2007 } else {
2008 if (Parser.getTok().isNot(AsmToken::String))
2009 return Error(Parser.getTok().getLoc(), "expected string constant");
2010
2011 StringValue = Parser.getTok().getStringContents();
2012 Parser.Lex();
2013 }
2014
2015 if (Parser.parseToken(AsmToken::EndOfStatement,
2016 "unexpected token in '.attribute' directive"))
2017 return true;
2018
2019 if (Tag == RISCVAttrs::ARCH) {
2020 StringRef Arch = StringValue;
2021 if (Arch.consume_front("rv32"))
2022 clearFeatureBits(RISCV::Feature64Bit, "64bit");
2023 else if (Arch.consume_front("rv64"))
2024 setFeatureBits(RISCV::Feature64Bit, "64bit");
2025 else
2026 return Error(ValueExprLoc, "bad arch string " + Arch);
2027
2028 // .attribute arch overrides the current architecture, so unset all
2029 // currently enabled extensions
2030 clearFeatureBits(RISCV::FeatureRV32E, "e");
2031 clearFeatureBits(RISCV::FeatureStdExtM, "m");
2032 clearFeatureBits(RISCV::FeatureStdExtA, "a");
2033 clearFeatureBits(RISCV::FeatureStdExtF, "f");
2034 clearFeatureBits(RISCV::FeatureStdExtD, "d");
2035 clearFeatureBits(RISCV::FeatureStdExtC, "c");
2036 clearFeatureBits(RISCV::FeatureStdExtB, "experimental-b");
2037 clearFeatureBits(RISCV::FeatureStdExtV, "experimental-v");
2038 clearFeatureBits(RISCV::FeatureExtZfh, "experimental-zfh");
2039 clearFeatureBits(RISCV::FeatureExtZba, "experimental-zba");
2040 clearFeatureBits(RISCV::FeatureExtZbb, "experimental-zbb");
2041 clearFeatureBits(RISCV::FeatureExtZbc, "experimental-zbc");
2042 clearFeatureBits(RISCV::FeatureExtZbe, "experimental-zbe");
2043 clearFeatureBits(RISCV::FeatureExtZbf, "experimental-zbf");
2044 clearFeatureBits(RISCV::FeatureExtZbm, "experimental-zbm");
2045 clearFeatureBits(RISCV::FeatureExtZbp, "experimental-zbp");
2046 clearFeatureBits(RISCV::FeatureExtZbproposedc, "experimental-zbproposedc");
2047 clearFeatureBits(RISCV::FeatureExtZbr, "experimental-zbr");
2048 clearFeatureBits(RISCV::FeatureExtZbs, "experimental-zbs");
2049 clearFeatureBits(RISCV::FeatureExtZbt, "experimental-zbt");
2050 clearFeatureBits(RISCV::FeatureExtZvamo, "experimental-zvamo");
2051 clearFeatureBits(RISCV::FeatureStdExtZvlsseg, "experimental-zvlsseg");
2052
2053 while (!Arch.empty()) {
2054 bool DropFirst = true;
2055 if (Arch[0] == 'i')
2056 clearFeatureBits(RISCV::FeatureRV32E, "e");
2057 else if (Arch[0] == 'e')
2058 setFeatureBits(RISCV::FeatureRV32E, "e");
2059 else if (Arch[0] == 'g') {
2060 clearFeatureBits(RISCV::FeatureRV32E, "e");
2061 setFeatureBits(RISCV::FeatureStdExtM, "m");
2062 setFeatureBits(RISCV::FeatureStdExtA, "a");
2063 setFeatureBits(RISCV::FeatureStdExtF, "f");
2064 setFeatureBits(RISCV::FeatureStdExtD, "d");
2065 } else if (Arch[0] == 'm')
2066 setFeatureBits(RISCV::FeatureStdExtM, "m");
2067 else if (Arch[0] == 'a')
2068 setFeatureBits(RISCV::FeatureStdExtA, "a");
2069 else if (Arch[0] == 'f')
2070 setFeatureBits(RISCV::FeatureStdExtF, "f");
2071 else if (Arch[0] == 'd') {
2072 setFeatureBits(RISCV::FeatureStdExtF, "f");
2073 setFeatureBits(RISCV::FeatureStdExtD, "d");
2074 } else if (Arch[0] == 'c') {
2075 setFeatureBits(RISCV::FeatureStdExtC, "c");
2076 } else if (Arch[0] == 'b') {
2077 setFeatureBits(RISCV::FeatureStdExtB, "experimental-b");
2078 } else if (Arch[0] == 'v') {
2079 setFeatureBits(RISCV::FeatureStdExtV, "experimental-v");
2080 } else if (Arch[0] == 's' || Arch[0] == 'x' || Arch[0] == 'z') {
2081 StringRef Ext =
2082 Arch.take_until([](char c) { return ::isdigit(c) || c == '_'; });
2083 if (Ext == "zba")
2084 setFeatureBits(RISCV::FeatureExtZba, "experimental-zba");
2085 else if (Ext == "zbb")
2086 setFeatureBits(RISCV::FeatureExtZbb, "experimental-zbb");
2087 else if (Ext == "zbc")
2088 setFeatureBits(RISCV::FeatureExtZbc, "experimental-zbc");
2089 else if (Ext == "zbe")
2090 setFeatureBits(RISCV::FeatureExtZbe, "experimental-zbe");
2091 else if (Ext == "zbf")
2092 setFeatureBits(RISCV::FeatureExtZbf, "experimental-zbf");
2093 else if (Ext == "zbm")
2094 setFeatureBits(RISCV::FeatureExtZbm, "experimental-zbm");
2095 else if (Ext == "zbp")
2096 setFeatureBits(RISCV::FeatureExtZbp, "experimental-zbp");
2097 else if (Ext == "zbproposedc")
2098 setFeatureBits(RISCV::FeatureExtZbproposedc,
2099 "experimental-zbproposedc");
2100 else if (Ext == "zbr")
2101 setFeatureBits(RISCV::FeatureExtZbr, "experimental-zbr");
2102 else if (Ext == "zbs")
2103 setFeatureBits(RISCV::FeatureExtZbs, "experimental-zbs");
2104 else if (Ext == "zbt")
2105 setFeatureBits(RISCV::FeatureExtZbt, "experimental-zbt");
2106 else if (Ext == "zfh")
2107 setFeatureBits(RISCV::FeatureExtZfh, "experimental-zfh");
2108 else if (Ext == "zvamo")
2109 setFeatureBits(RISCV::FeatureExtZvamo, "experimental-zvamo");
2110 else if (Ext == "zvlsseg")
2111 setFeatureBits(RISCV::FeatureStdExtZvlsseg, "experimental-zvlsseg");
2112 else
2113 return Error(ValueExprLoc, "bad arch string " + Ext);
2114 Arch = Arch.drop_until([](char c) { return ::isdigit(c) || c == '_'; });
2115 DropFirst = false;
2116 } else
2117 return Error(ValueExprLoc, "bad arch string " + Arch);
2118
2119 if (DropFirst)
2120 Arch = Arch.drop_front(1);
2121 int major = 0;
2122 int minor = 0;
2123 Arch.consumeInteger(10, major);
2124 Arch.consume_front("p");
2125 Arch.consumeInteger(10, minor);
2126 Arch = Arch.drop_while([](char c) { return c == '_'; });
2127 }
2128 }
2129
2130 if (IsIntegerValue)
2131 getTargetStreamer().emitAttribute(Tag, IntegerValue);
2132 else {
2133 if (Tag != RISCVAttrs::ARCH) {
2134 getTargetStreamer().emitTextAttribute(Tag, StringValue);
2135 } else {
2136 std::string formalArchStr = "rv32";
2137 if (getFeatureBits(RISCV::Feature64Bit))
2138 formalArchStr = "rv64";
2139 if (getFeatureBits(RISCV::FeatureRV32E))
2140 formalArchStr = (Twine(formalArchStr) + "e1p9").str();
2141 else
2142 formalArchStr = (Twine(formalArchStr) + "i2p0").str();
2143
2144 if (getFeatureBits(RISCV::FeatureStdExtM))
2145 formalArchStr = (Twine(formalArchStr) + "_m2p0").str();
2146 if (getFeatureBits(RISCV::FeatureStdExtA))
2147 formalArchStr = (Twine(formalArchStr) + "_a2p0").str();
2148 if (getFeatureBits(RISCV::FeatureStdExtF))
2149 formalArchStr = (Twine(formalArchStr) + "_f2p0").str();
2150 if (getFeatureBits(RISCV::FeatureStdExtD))
2151 formalArchStr = (Twine(formalArchStr) + "_d2p0").str();
2152 if (getFeatureBits(RISCV::FeatureStdExtC))
2153 formalArchStr = (Twine(formalArchStr) + "_c2p0").str();
2154 if (getFeatureBits(RISCV::FeatureStdExtB))
2155 formalArchStr = (Twine(formalArchStr) + "_b0p93").str();
2156 if (getFeatureBits(RISCV::FeatureStdExtV))
2157 formalArchStr = (Twine(formalArchStr) + "_v0p10").str();
2158 if (getFeatureBits(RISCV::FeatureExtZfh))
2159 formalArchStr = (Twine(formalArchStr) + "_zfh0p1").str();
2160 if (getFeatureBits(RISCV::FeatureExtZba))
2161 formalArchStr = (Twine(formalArchStr) + "_zba0p93").str();
2162 if (getFeatureBits(RISCV::FeatureExtZbb))
2163 formalArchStr = (Twine(formalArchStr) + "_zbb0p93").str();
2164 if (getFeatureBits(RISCV::FeatureExtZbc))
2165 formalArchStr = (Twine(formalArchStr) + "_zbc0p93").str();
2166 if (getFeatureBits(RISCV::FeatureExtZbe))
2167 formalArchStr = (Twine(formalArchStr) + "_zbe0p93").str();
2168 if (getFeatureBits(RISCV::FeatureExtZbf))
2169 formalArchStr = (Twine(formalArchStr) + "_zbf0p93").str();
2170 if (getFeatureBits(RISCV::FeatureExtZbm))
2171 formalArchStr = (Twine(formalArchStr) + "_zbm0p93").str();
2172 if (getFeatureBits(RISCV::FeatureExtZbp))
2173 formalArchStr = (Twine(formalArchStr) + "_zbp0p93").str();
2174 if (getFeatureBits(RISCV::FeatureExtZbproposedc))
2175 formalArchStr = (Twine(formalArchStr) + "_zbproposedc0p93").str();
2176 if (getFeatureBits(RISCV::FeatureExtZbr))
2177 formalArchStr = (Twine(formalArchStr) + "_zbr0p93").str();
2178 if (getFeatureBits(RISCV::FeatureExtZbs))
2179 formalArchStr = (Twine(formalArchStr) + "_zbs0p93").str();
2180 if (getFeatureBits(RISCV::FeatureExtZbt))
2181 formalArchStr = (Twine(formalArchStr) + "_zbt0p93").str();
2182 if (getFeatureBits(RISCV::FeatureExtZvamo))
2183 formalArchStr = (Twine(formalArchStr) + "_zvamo0p10").str();
2184 if (getFeatureBits(RISCV::FeatureStdExtZvlsseg))
2185 formalArchStr = (Twine(formalArchStr) + "_zvlsseg0p10").str();
2186
2187 getTargetStreamer().emitTextAttribute(Tag, formalArchStr);
2188 }
2189 }
2190
2191 return false;
2192}
2193
2194void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
2195 MCInst CInst;
2196 bool Res = compressInst(CInst, Inst, getSTI(), S.getContext());
2197 if (Res)
2198 ++RISCVNumInstrsCompressed;
2199 S.emitInstruction((Res ? CInst : Inst), getSTI());
2200}
2201
2202void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t Value,
2203 MCStreamer &Out) {
2204 RISCVMatInt::InstSeq Seq = RISCVMatInt::generateInstSeq(Value, isRV64());
2205
2206 MCRegister SrcReg = RISCV::X0;
2207 for (RISCVMatInt::Inst &Inst : Seq) {
2208 if (Inst.Opc == RISCV::LUI) {
2209 emitToStreamer(
2210 Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm));
2211 } else {
2212 emitToStreamer(
2213 Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm(
2214 Inst.Imm));
2215 }
2216
2217 // Only the first instruction has X0 as its source.
2218 SrcReg = DestReg;
2219 }
2220}
2221
2222void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
2223 const MCExpr *Symbol,
2224 RISCVMCExpr::VariantKind VKHi,
2225 unsigned SecondOpcode, SMLoc IDLoc,
2226 MCStreamer &Out) {
2227 // A pair of instructions for PC-relative addressing; expands to
2228 // TmpLabel: AUIPC TmpReg, VKHi(symbol)
2229 // OP DestReg, TmpReg, %pcrel_lo(TmpLabel)
2230 MCContext &Ctx = getContext();
2231
2232 MCSymbol *TmpLabel = Ctx.createNamedTempSymbol("pcrel_hi");
2233 Out.emitLabel(TmpLabel);
2234
2235 const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx);
2236 emitToStreamer(
2237 Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi));
2238
2239 const MCExpr *RefToLinkTmpLabel =
2240 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx),
2241 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx);
2242
2243 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
2244 .addOperand(DestReg)
2245 .addOperand(TmpReg)
2246 .addExpr(RefToLinkTmpLabel));
2247}
2248
2249void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
2250 MCStreamer &Out) {
2251 // The load local address pseudo-instruction "lla" is used in PC-relative
2252 // addressing of local symbols:
2253 // lla rdest, symbol
2254 // expands to
2255 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
2256 // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
2257 MCOperand DestReg = Inst.getOperand(0);
2258 const MCExpr *Symbol = Inst.getOperand(1).getExpr();
2259 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
2260 RISCV::ADDI, IDLoc, Out);
2261}
2262
2263void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
2264 MCStreamer &Out) {
2265 // The load address pseudo-instruction "la" is used in PC-relative and
2266 // GOT-indirect addressing of global symbols:
2267 // la rdest, symbol
2268 // expands to either (for non-PIC)
2269 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
2270 // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
2271 // or (for PIC)
2272 // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol)
2273 // Lx rdest, %pcrel_lo(TmpLabel)(rdest)
2274 MCOperand DestReg = Inst.getOperand(0);
2275 const MCExpr *Symbol = Inst.getOperand(1).getExpr();
2276 unsigned SecondOpcode;
2277 RISCVMCExpr::VariantKind VKHi;
2278 if (ParserOptions.IsPicEnabled) {
2279 SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
2280 VKHi = RISCVMCExpr::VK_RISCV_GOT_HI;
2281 } else {
2282 SecondOpcode = RISCV::ADDI;
2283 VKHi = RISCVMCExpr::VK_RISCV_PCREL_HI;
2284 }
2285 emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out);
2286}
2287
2288void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
2289 MCStreamer &Out) {
2290 // The load TLS IE address pseudo-instruction "la.tls.ie" is used in
2291 // initial-exec TLS model addressing of global symbols:
2292 // la.tls.ie rdest, symbol
2293 // expands to
2294 // TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol)
2295 // Lx rdest, %pcrel_lo(TmpLabel)(rdest)
2296 MCOperand DestReg = Inst.getOperand(0);
2297 const MCExpr *Symbol = Inst.getOperand(1).getExpr();
2298 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
2299 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GOT_HI,
2300 SecondOpcode, IDLoc, Out);
2301}
2302
2303void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
2304 MCStreamer &Out) {
2305 // The load TLS GD address pseudo-instruction "la.tls.gd" is used in
2306 // global-dynamic TLS model addressing of global symbols:
2307 // la.tls.gd rdest, symbol
2308 // expands to
2309 // TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol)
2310 // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
2311 MCOperand DestReg = Inst.getOperand(0);
2312 const MCExpr *Symbol = Inst.getOperand(1).getExpr();
2313 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GD_HI,
2314 RISCV::ADDI, IDLoc, Out);
2315}
2316
2317void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode,
2318 SMLoc IDLoc, MCStreamer &Out,
2319 bool HasTmpReg) {
2320 // The load/store pseudo-instruction does a pc-relative load with
2321 // a symbol.
2322 //
2323 // The expansion looks like this
2324 //
2325 // TmpLabel: AUIPC tmp, %pcrel_hi(symbol)
2326 // [S|L]X rd, %pcrel_lo(TmpLabel)(tmp)
2327 MCOperand DestReg = Inst.getOperand(0);
2328 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
2329 unsigned TmpRegOpIdx = HasTmpReg ? 1 : 0;
2330 MCOperand TmpReg = Inst.getOperand(TmpRegOpIdx);
2331 const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr();
2332 emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
2333 Opcode, IDLoc, Out);
2334}
2335
2336void RISCVAsmParser::emitPseudoExtend(MCInst &Inst, bool SignExtend,
2337 int64_t Width, SMLoc IDLoc,
2338 MCStreamer &Out) {
2339 // The sign/zero extend pseudo-instruction does two shifts, with the shift
2340 // amounts dependent on the XLEN.
2341 //
2342 // The expansion looks like this
2343 //
2344 // SLLI rd, rs, XLEN - Width
2345 // SR[A|R]I rd, rd, XLEN - Width
2346 MCOperand DestReg = Inst.getOperand(0);
2347 MCOperand SourceReg = Inst.getOperand(1);
2348
2349 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
2350 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
2351
2352 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 2352, __PRETTY_FUNCTION__))
;
2353
2354 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
2355 .addOperand(DestReg)
2356 .addOperand(SourceReg)
2357 .addImm(ShAmt));
2358
2359 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
2360 .addOperand(DestReg)
2361 .addOperand(DestReg)
2362 .addImm(ShAmt));
2363}
2364
2365void RISCVAsmParser::emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,
2366 MCStreamer &Out) {
2367 if (Inst.getNumOperands() == 3) {
2368 // unmasked va >= x
2369 //
2370 // pseudoinstruction: vmsge{u}.vx vd, va, x
2371 // expansion: vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd
2372 emitToStreamer(Out, MCInstBuilder(Opcode)
2373 .addOperand(Inst.getOperand(0))
2374 .addOperand(Inst.getOperand(1))
2375 .addOperand(Inst.getOperand(2))
2376 .addReg(RISCV::NoRegister));
2377 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
2378 .addOperand(Inst.getOperand(0))
2379 .addOperand(Inst.getOperand(0))
2380 .addOperand(Inst.getOperand(0)));
2381 } else if (Inst.getNumOperands() == 4) {
2382 // masked va >= x, vd != v0
2383 //
2384 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t
2385 // expansion: vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0
2386 assert(Inst.getOperand(0).getReg() != RISCV::V0 &&((Inst.getOperand(0).getReg() != RISCV::V0 && "The destination register should not be V0."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).getReg() != RISCV::V0 && \"The destination register should not be V0.\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 2387, __PRETTY_FUNCTION__))
2387 "The destination register should not be V0.")((Inst.getOperand(0).getReg() != RISCV::V0 && "The destination register should not be V0."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).getReg() != RISCV::V0 && \"The destination register should not be V0.\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 2387, __PRETTY_FUNCTION__))
;
2388 emitToStreamer(Out, MCInstBuilder(Opcode)
2389 .addOperand(Inst.getOperand(0))
2390 .addOperand(Inst.getOperand(1))
2391 .addOperand(Inst.getOperand(2))
2392 .addOperand(Inst.getOperand(3)));
2393 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
2394 .addOperand(Inst.getOperand(0))
2395 .addOperand(Inst.getOperand(0))
2396 .addReg(RISCV::V0));
2397 } else if (Inst.getNumOperands() == 5) {
2398 // masked va >= x, vd == v0
2399 //
2400 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt
2401 // expansion: vmslt{u}.vx vt, va, x; vmandnot.mm vd, vd, vt
2402 assert(Inst.getOperand(0).getReg() == RISCV::V0 &&((Inst.getOperand(0).getReg() == RISCV::V0 && "The destination register should be V0."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).getReg() == RISCV::V0 && \"The destination register should be V0.\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 2403, __PRETTY_FUNCTION__))
2403 "The destination register should be V0.")((Inst.getOperand(0).getReg() == RISCV::V0 && "The destination register should be V0."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(0).getReg() == RISCV::V0 && \"The destination register should be V0.\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 2403, __PRETTY_FUNCTION__))
;
2404 assert(Inst.getOperand(1).getReg() != RISCV::V0 &&((Inst.getOperand(1).getReg() != RISCV::V0 && "The temporary vector register should not be V0."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(1).getReg() != RISCV::V0 && \"The temporary vector register should not be V0.\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 2405, __PRETTY_FUNCTION__))
2405 "The temporary vector register should not be V0.")((Inst.getOperand(1).getReg() != RISCV::V0 && "The temporary vector register should not be V0."
) ? static_cast<void> (0) : __assert_fail ("Inst.getOperand(1).getReg() != RISCV::V0 && \"The temporary vector register should not be V0.\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 2405, __PRETTY_FUNCTION__))
;
2406 emitToStreamer(Out, MCInstBuilder(Opcode)
2407 .addOperand(Inst.getOperand(1))
2408 .addOperand(Inst.getOperand(2))
2409 .addOperand(Inst.getOperand(3))
2410 .addOperand(Inst.getOperand(4)));
2411 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDNOT_MM)
2412 .addOperand(Inst.getOperand(0))
2413 .addOperand(Inst.getOperand(0))
2414 .addOperand(Inst.getOperand(1)));
2415 }
2416}
2417
2418bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
2419 OperandVector &Operands) {
2420 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 2420, __PRETTY_FUNCTION__))
;
2421 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-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 2421, __PRETTY_FUNCTION__))
;
2422 if (Inst.getOperand(2).getReg() != RISCV::X4) {
2423 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
2424 return Error(ErrorLoc, "the second input operand must be tp/x4 when using "
2425 "%tprel_add modifier");
2426 }
2427
2428 return false;
2429}
2430
2431std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp() const {
2432 return RISCVOperand::createReg(RISCV::NoRegister, llvm::SMLoc(),
2433 llvm::SMLoc(), isRV64());
2434}
2435
2436bool RISCVAsmParser::validateInstruction(MCInst &Inst,
2437 OperandVector &Operands) {
2438 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
2439 unsigned Constraints =
2440 (MCID.TSFlags & RISCVII::ConstraintMask) >> RISCVII::ConstraintShift;
2441 if (Constraints == RISCVII::NoConstraint)
2442 return false;
2443
2444 unsigned DestReg = Inst.getOperand(0).getReg();
2445 // Operands[1] will be the first operand, DestReg.
2446 SMLoc Loc = Operands[1]->getStartLoc();
2447 if (Constraints & RISCVII::VS2Constraint) {
2448 unsigned CheckReg = Inst.getOperand(1).getReg();
2449 if (DestReg == CheckReg)
2450 return Error(Loc, "The destination vector register group cannot overlap"
2451 " the source vector register group.");
2452 }
2453 if ((Constraints & RISCVII::VS1Constraint) && (Inst.getOperand(2).isReg())) {
2454 unsigned CheckReg = Inst.getOperand(2).getReg();
2455 if (DestReg == CheckReg)
2456 return Error(Loc, "The destination vector register group cannot overlap"
2457 " the source vector register group.");
2458 }
2459 if ((Constraints & RISCVII::VMConstraint) && (DestReg == RISCV::V0)) {
2460 // vadc, vsbc are special cases. These instructions have no mask register.
2461 // The destination register could not be V0.
2462 unsigned Opcode = Inst.getOpcode();
2463 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
2464 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
2465 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
2466 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
2467 Opcode == RISCV::VMERGE_VXM)
2468 return Error(Loc, "The destination vector register group cannot be V0.");
2469
2470 // Regardless masked or unmasked version, the number of operands is the
2471 // same. For example, "viota.m v0, v2" is "viota.m v0, v2, NoRegister"
2472 // actually. We need to check the last operand to ensure whether it is
2473 // masked or not.
2474 unsigned CheckReg = Inst.getOperand(Inst.getNumOperands() - 1).getReg();
2475 assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) &&(((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) &&
"Unexpected register for mask operand") ? static_cast<void
> (0) : __assert_fail ("(CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) && \"Unexpected register for mask operand\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 2476, __PRETTY_FUNCTION__))
2476 "Unexpected register for mask operand")(((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) &&
"Unexpected register for mask operand") ? static_cast<void
> (0) : __assert_fail ("(CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) && \"Unexpected register for mask operand\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp"
, 2476, __PRETTY_FUNCTION__))
;
2477
2478 if (DestReg == CheckReg)
2479 return Error(Loc, "The destination vector register group cannot overlap"
2480 " the mask register.");
2481 }
2482 return false;
2483}
2484
2485bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
2486 OperandVector &Operands,
2487 MCStreamer &Out) {
2488 Inst.setLoc(IDLoc);
2489
2490 switch (Inst.getOpcode()) {
2491 default:
2492 break;
2493 case RISCV::PseudoLI: {
2494 MCRegister Reg = Inst.getOperand(0).getReg();
2495 const MCOperand &Op1 = Inst.getOperand(1);
2496 if (Op1.isExpr()) {
2497 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar.
2498 // Just convert to an addi. This allows compatibility with gas.
2499 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
2500 .addReg(Reg)
2501 .addReg(RISCV::X0)
2502 .addExpr(Op1.getExpr()));
2503 return false;
2504 }
2505 int64_t Imm = Inst.getOperand(1).getImm();
2506 // On RV32 the immediate here can either be a signed or an unsigned
2507 // 32-bit number. Sign extension has to be performed to ensure that Imm
2508 // represents the expected signed 64-bit number.
2509 if (!isRV64())
2510 Imm = SignExtend64<32>(Imm);
2511 emitLoadImm(Reg, Imm, Out);
2512 return false;
2513 }
2514 case RISCV::PseudoLLA:
2515 emitLoadLocalAddress(Inst, IDLoc, Out);
2516 return false;
2517 case RISCV::PseudoLA:
2518 emitLoadAddress(Inst, IDLoc, Out);
2519 return false;
2520 case RISCV::PseudoLA_TLS_IE:
2521 emitLoadTLSIEAddress(Inst, IDLoc, Out);
2522 return false;
2523 case RISCV::PseudoLA_TLS_GD:
2524 emitLoadTLSGDAddress(Inst, IDLoc, Out);
2525 return false;
2526 case RISCV::PseudoLB:
2527 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false);
2528 return false;
2529 case RISCV::PseudoLBU:
2530 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false);
2531 return false;
2532 case RISCV::PseudoLH:
2533 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false);
2534 return false;
2535 case RISCV::PseudoLHU:
2536 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false);
2537 return false;
2538 case RISCV::PseudoLW:
2539 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false);
2540 return false;
2541 case RISCV::PseudoLWU:
2542 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false);
2543 return false;
2544 case RISCV::PseudoLD:
2545 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false);
2546 return false;
2547 case RISCV::PseudoFLH:
2548 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out, /*HasTmpReg=*/true);
2549 return false;
2550 case RISCV::PseudoFLW:
2551 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true);
2552 return false;
2553 case RISCV::PseudoFLD:
2554 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true);
2555 return false;
2556 case RISCV::PseudoSB:
2557 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true);
2558 return false;
2559 case RISCV::PseudoSH:
2560 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true);
2561 return false;
2562 case RISCV::PseudoSW:
2563 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true);
2564 return false;
2565 case RISCV::PseudoSD:
2566 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true);
2567 return false;
2568 case RISCV::PseudoFSH:
2569 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out, /*HasTmpReg=*/true);
2570 return false;
2571 case RISCV::PseudoFSW:
2572 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true);
2573 return false;
2574 case RISCV::PseudoFSD:
2575 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true);
2576 return false;
2577 case RISCV::PseudoAddTPRel:
2578 if (checkPseudoAddTPRel(Inst, Operands))
2579 return true;
2580 break;
2581 case RISCV::PseudoSEXT_B:
2582 emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/8, IDLoc, Out);
2583 return false;
2584 case RISCV::PseudoSEXT_H:
2585 emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/16, IDLoc, Out);
2586 return false;
2587 case RISCV::PseudoZEXT_H:
2588 emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/16, IDLoc, Out);
2589 return false;
2590 case RISCV::PseudoZEXT_W:
2591 emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/32, IDLoc, Out);
2592 return false;
2593 case RISCV::PseudoVMSGEU_VX:
2594 case RISCV::PseudoVMSGEU_VX_M:
2595 case RISCV::PseudoVMSGEU_VX_M_T:
2596 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
2597 return false;
2598 case RISCV::PseudoVMSGE_VX:
2599 case RISCV::PseudoVMSGE_VX_M:
2600 case RISCV::PseudoVMSGE_VX_M_T:
2601 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
2602 return false;
2603 case RISCV::PseudoVMSGE_VI:
2604 case RISCV::PseudoVMSLT_VI: {
2605 // These instructions are signed and so is immediate so we can subtract one
2606 // and change the opcode.
2607 int64_t Imm = Inst.getOperand(2).getImm();
2608 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
2609 : RISCV::VMSLE_VI;
2610 emitToStreamer(Out, MCInstBuilder(Opc)
2611 .addOperand(Inst.getOperand(0))
2612 .addOperand(Inst.getOperand(1))
2613 .addImm(Imm - 1)
2614 .addOperand(Inst.getOperand(3)));
2615 return false;
2616 }
2617 case RISCV::PseudoVMSGEU_VI:
2618 case RISCV::PseudoVMSLTU_VI: {
2619 int64_t Imm = Inst.getOperand(2).getImm();
2620 // Unsigned comparisons are tricky because the immediate is signed. If the
2621 // immediate is 0 we can't just subtract one. vmsltu.vi v0, v1, 0 is always
2622 // false, but vmsle.vi v0, v1, -1 is always true. Instead we use
2623 // vmsne v0, v1, v1 which is always false.
2624 if (Imm == 0) {
2625 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI
2626 ? RISCV::VMSEQ_VV
2627 : RISCV::VMSNE_VV;
2628 emitToStreamer(Out, MCInstBuilder(Opc)
2629 .addOperand(Inst.getOperand(0))
2630 .addOperand(Inst.getOperand(1))
2631 .addOperand(Inst.getOperand(1))
2632 .addOperand(Inst.getOperand(3)));
2633 } else {
2634 // Other immediate values can subtract one like signed.
2635 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI
2636 ? RISCV::VMSGTU_VI
2637 : RISCV::VMSLEU_VI;
2638 emitToStreamer(Out, MCInstBuilder(Opc)
2639 .addOperand(Inst.getOperand(0))
2640 .addOperand(Inst.getOperand(1))
2641 .addImm(Imm - 1)
2642 .addOperand(Inst.getOperand(3)));
2643 }
2644
2645 return false;
2646 }
2647 }
2648
2649 emitToStreamer(Out, Inst);
2650 return false;
2651}
2652
2653extern "C" LLVM_EXTERNAL_VISIBILITY__attribute__ ((visibility("default"))) void LLVMInitializeRISCVAsmParser() {
2654 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target());
2655 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target());
2656}

/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/MC/MCAsmMacro.h

1//===- MCAsmMacro.h - Assembly Macros ---------------------------*- C++ -*-===//
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#ifndef LLVM_MC_MCASMMACRO_H
10#define LLVM_MC_MCASMMACRO_H
11
12#include "llvm/ADT/APInt.h"
13#include "llvm/ADT/StringRef.h"
14#include "llvm/Support/Debug.h"
15#include "llvm/Support/SMLoc.h"
16#include <vector>
17
18namespace llvm {
19
20/// Target independent representation for an assembler token.
21class AsmToken {
22public:
23 enum TokenKind {
24 // Markers
25 Eof, Error,
26
27 // String values.
28 Identifier,
29 String,
30
31 // Integer values.
32 Integer,
33 BigNum, // larger than 64 bits
34
35 // Real values.
36 Real,
37
38 // Comments
39 Comment,
40 HashDirective,
41 // No-value.
42 EndOfStatement,
43 Colon,
44 Space,
45 Plus, Minus, Tilde,
46 Slash, // '/'
47 BackSlash, // '\'
48 LParen, RParen, LBrac, RBrac, LCurly, RCurly,
49 Star, Dot, Comma, Dollar, Equal, EqualEqual,
50
51 Pipe, PipePipe, Caret,
52 Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash,
53 Less, LessEqual, LessLess, LessGreater,
54 Greater, GreaterEqual, GreaterGreater, At, MinusGreater,
55
56 // MIPS unary expression operators such as %neg.
57 PercentCall16, PercentCall_Hi, PercentCall_Lo, PercentDtprel_Hi,
58 PercentDtprel_Lo, PercentGot, PercentGot_Disp, PercentGot_Hi, PercentGot_Lo,
59 PercentGot_Ofst, PercentGot_Page, PercentGottprel, PercentGp_Rel, PercentHi,
60 PercentHigher, PercentHighest, PercentLo, PercentNeg, PercentPcrel_Hi,
61 PercentPcrel_Lo, PercentTlsgd, PercentTlsldm, PercentTprel_Hi,
62 PercentTprel_Lo
63 };
64
65private:
66 TokenKind Kind;
67
68 /// A reference to the entire token contents; this is always a pointer into
69 /// a memory buffer owned by the source manager.
70 StringRef Str;
71
72 APInt IntVal;
73
74public:
75 AsmToken() = default;
76 AsmToken(TokenKind Kind, StringRef Str, APInt IntVal)
77 : Kind(Kind), Str(Str), IntVal(std::move(IntVal)) {}
78 AsmToken(TokenKind Kind, StringRef Str, int64_t IntVal = 0)
79 : Kind(Kind), Str(Str), IntVal(64, IntVal, true) {}
80
81 TokenKind getKind() const { return Kind; }
82 bool is(TokenKind K) const { return Kind == K; }
2
Assuming 'K' is not equal to field 'Kind'
3
Returning zero, which participates in a condition later
83 bool isNot(TokenKind K) const { return Kind != K; }
84
85 SMLoc getLoc() const;
86 SMLoc getEndLoc() const;
87 SMRange getLocRange() const;
88
89 /// Get the contents of a string token (without quotes).
90 StringRef getStringContents() const {
91 assert(Kind == String && "This token isn't a string!")((Kind == String && "This token isn't a string!") ? static_cast
<void> (0) : __assert_fail ("Kind == String && \"This token isn't a string!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/MC/MCAsmMacro.h"
, 91, __PRETTY_FUNCTION__))
;
92 return Str.slice(1, Str.size() - 1);
93 }
94
95 /// Get the identifier string for the current token, which should be an
96 /// identifier or a string. This gets the portion of the string which should
97 /// be used as the identifier, e.g., it does not include the quotes on
98 /// strings.
99 StringRef getIdentifier() const {
100 if (Kind == Identifier)
101 return getString();
102 return getStringContents();
103 }
104
105 /// Get the string for the current token, this includes all characters (for
106 /// example, the quotes on strings) in the token.
107 ///
108 /// The returned StringRef points into the source manager's memory buffer, and
109 /// is safe to store across calls to Lex().
110 StringRef getString() const { return Str; }
111
112 // FIXME: Don't compute this in advance, it makes every token larger, and is
113 // also not generally what we want (it is nicer for recovery etc. to lex 123br
114 // as a single token, then diagnose as an invalid number).
115 int64_t getIntVal() const {
116 assert(Kind == Integer && "This token isn't an integer!")((Kind == Integer && "This token isn't an integer!") ?
static_cast<void> (0) : __assert_fail ("Kind == Integer && \"This token isn't an integer!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/MC/MCAsmMacro.h"
, 116, __PRETTY_FUNCTION__))
;
117 return IntVal.getZExtValue();
118 }
119
120 APInt getAPIntVal() const {
121 assert((Kind == Integer || Kind == BigNum) &&(((Kind == Integer || Kind == BigNum) && "This token isn't an integer!"
) ? static_cast<void> (0) : __assert_fail ("(Kind == Integer || Kind == BigNum) && \"This token isn't an integer!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/MC/MCAsmMacro.h"
, 122, __PRETTY_FUNCTION__))
122 "This token isn't an integer!")(((Kind == Integer || Kind == BigNum) && "This token isn't an integer!"
) ? static_cast<void> (0) : __assert_fail ("(Kind == Integer || Kind == BigNum) && \"This token isn't an integer!\""
, "/build/llvm-toolchain-snapshot-13~++20210413100635+64c24f493e5f/llvm/include/llvm/MC/MCAsmMacro.h"
, 122, __PRETTY_FUNCTION__))
;
123 return IntVal;
124 }
125
126 void dump(raw_ostream &OS) const;
127};
128
129struct MCAsmMacroParameter {
130 StringRef Name;
131 std::vector<AsmToken> Value;
132 bool Required = false;
133 bool Vararg = false;
134
135#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
136 void dump() const { dump(dbgs()); }
137 LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void dump(raw_ostream &OS) const;
138#endif
139};
140
141typedef std::vector<MCAsmMacroParameter> MCAsmMacroParameters;
142struct MCAsmMacro {
143 StringRef Name;
144 StringRef Body;
145 MCAsmMacroParameters Parameters;
146 std::vector<std::string> Locals;
147 bool IsFunction = false;
148
149public:
150 MCAsmMacro(StringRef N, StringRef B, MCAsmMacroParameters P)
151 : Name(N), Body(B), Parameters(std::move(P)) {}
152 MCAsmMacro(StringRef N, StringRef B, MCAsmMacroParameters P,
153 std::vector<std::string> L, bool F)
154 : Name(N), Body(B), Parameters(std::move(P)), Locals(std::move(L)),
155 IsFunction(F) {}
156
157#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
158 void dump() const { dump(dbgs()); }
159 LLVM_DUMP_METHOD__attribute__((noinline)) __attribute__((__used__)) void dump(raw_ostream &OS) const;
160#endif
161};
162} // namespace llvm
163
164#endif