1 //===-- RISCVAsmParser.cpp - Parse RISC-V 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/SmallVector.h"
20 #include "llvm/ADT/Statistic.h"
21 #include "llvm/ADT/StringExtras.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/MCInstrInfo.h"
28 #include "llvm/MC/MCObjectFileInfo.h"
29 #include "llvm/MC/MCParser/MCAsmLexer.h"
30 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
31 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
32 #include "llvm/MC/MCRegisterInfo.h"
33 #include "llvm/MC/MCStreamer.h"
34 #include "llvm/MC/MCSubtargetInfo.h"
35 #include "llvm/MC/MCValue.h"
36 #include "llvm/MC/TargetRegistry.h"
37 #include "llvm/Support/Casting.h"
38 #include "llvm/Support/CommandLine.h"
39 #include "llvm/Support/MathExtras.h"
40 #include "llvm/Support/RISCVAttributes.h"
41 #include "llvm/Support/RISCVISAInfo.h"
42
43 #include <limits>
44
45 using namespace llvm;
46
47 #define DEBUG_TYPE "riscv-asm-parser"
48
49 STATISTIC(RISCVNumInstrsCompressed,
50 "Number of RISC-V Compressed instructions emitted");
51
52 static cl::opt<bool> AddBuildAttributes("riscv-add-build-attributes",
53 cl::init(false));
54
55 namespace llvm {
56 extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures];
57 } // namespace llvm
58
59 namespace {
60 struct RISCVOperand;
61
62 struct ParserOptionsSet {
63 bool IsPicEnabled;
64 };
65
66 class RISCVAsmParser : public MCTargetAsmParser {
67 // This tracks the parsing of the 4 operands that make up the vtype portion
68 // of vset(i)vli instructions which are separated by commas. The state names
69 // represent the next expected operand with Done meaning no other operands are
70 // expected.
71 enum VTypeState {
72 VTypeState_SEW,
73 VTypeState_LMUL,
74 VTypeState_TailPolicy,
75 VTypeState_MaskPolicy,
76 VTypeState_Done,
77 };
78
79 SmallVector<FeatureBitset, 4> FeatureBitStack;
80
81 SmallVector<ParserOptionsSet, 4> ParserOptionsStack;
82 ParserOptionsSet ParserOptions;
83
getLoc() const84 SMLoc getLoc() const { return getParser().getTok().getLoc(); }
isRV64() const85 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); }
isRVE() const86 bool isRVE() const { return getSTI().hasFeature(RISCV::FeatureRVE); }
87
getTargetStreamer()88 RISCVTargetStreamer &getTargetStreamer() {
89 assert(getParser().getStreamer().getTargetStreamer() &&
90 "do not have a target streamer");
91 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
92 return static_cast<RISCVTargetStreamer &>(TS);
93 }
94
95 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
96 unsigned Kind) override;
97 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
98
99 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo,
100 int64_t Lower, int64_t Upper,
101 const Twine &Msg);
102 bool generateImmOutOfRangeError(SMLoc ErrorLoc, int64_t Lower, int64_t Upper,
103 const Twine &Msg);
104
105 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
106 OperandVector &Operands, MCStreamer &Out,
107 uint64_t &ErrorInfo,
108 bool MatchingInlineAsm) override;
109
110 bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
111 ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
112 SMLoc &EndLoc) override;
113
114 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
115 SMLoc NameLoc, OperandVector &Operands) override;
116
117 ParseStatus parseDirective(AsmToken DirectiveID) override;
118
119 bool parseVTypeToken(StringRef Identifier, VTypeState &State, unsigned &Sew,
120 unsigned &Lmul, bool &Fractional, bool &TailAgnostic,
121 bool &MaskAgnostic);
122 bool generateVTypeError(SMLoc ErrorLoc);
123
124 // Helper to actually emit an instruction to the MCStreamer. Also, when
125 // possible, compression of the instruction is performed.
126 void emitToStreamer(MCStreamer &S, const MCInst &Inst);
127
128 // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that
129 // synthesize the desired immedate value into the destination register.
130 void emitLoadImm(MCRegister DestReg, int64_t Value, MCStreamer &Out);
131
132 // Helper to emit a combination of AUIPC and SecondOpcode. Used to implement
133 // helpers such as emitLoadLocalAddress and emitLoadAddress.
134 void emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
135 const MCExpr *Symbol, RISCVMCExpr::VariantKind VKHi,
136 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
137
138 // Helper to emit pseudo instruction "lla" used in PC-rel addressing.
139 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
140
141 // Helper to emit pseudo instruction "lga" used in GOT-rel addressing.
142 void emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
143
144 // Helper to emit pseudo instruction "la" used in GOT/PC-rel addressing.
145 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
146
147 // Helper to emit pseudo instruction "la.tls.ie" used in initial-exec TLS
148 // addressing.
149 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
150
151 // Helper to emit pseudo instruction "la.tls.gd" used in global-dynamic TLS
152 // addressing.
153 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
154
155 // Helper to emit pseudo load/store instruction with a symbol.
156 void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,
157 MCStreamer &Out, bool HasTmpReg);
158
159 // Helper to emit pseudo sign/zero extend instruction.
160 void emitPseudoExtend(MCInst &Inst, bool SignExtend, int64_t Width,
161 SMLoc IDLoc, MCStreamer &Out);
162
163 // Helper to emit pseudo vmsge{u}.vx instruction.
164 void emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, MCStreamer &Out);
165
166 // Checks that a PseudoAddTPRel is using x4/tp in its second input operand.
167 // Enforcing this using a restricted register class for the second input
168 // operand of PseudoAddTPRel results in a poor diagnostic due to the fact
169 // 'add' is an overloaded mnemonic.
170 bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands);
171
172 // Checks that a PseudoTLSDESCCall is using x5/t0 in its output operand.
173 // Enforcing this using a restricted register class for the output
174 // operand of PseudoTLSDESCCall results in a poor diagnostic due to the fact
175 // 'jalr' is an overloaded mnemonic.
176 bool checkPseudoTLSDESCCall(MCInst &Inst, OperandVector &Operands);
177
178 // Check instruction constraints.
179 bool validateInstruction(MCInst &Inst, OperandVector &Operands);
180
181 /// Helper for processing MC instructions that have been successfully matched
182 /// by MatchAndEmitInstruction. Modifications to the emitted instructions,
183 /// like the expansion of pseudo instructions (e.g., "li"), can be performed
184 /// in this method.
185 bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,
186 MCStreamer &Out);
187
188 // Auto-generated instruction matching functions
189 #define GET_ASSEMBLER_HEADER
190 #include "RISCVGenAsmMatcher.inc"
191
192 ParseStatus parseCSRSystemRegister(OperandVector &Operands);
193 ParseStatus parseFPImm(OperandVector &Operands);
194 ParseStatus parseImmediate(OperandVector &Operands);
195 ParseStatus parseRegister(OperandVector &Operands, bool AllowParens = false);
196 ParseStatus parseMemOpBaseReg(OperandVector &Operands);
197 ParseStatus parseZeroOffsetMemOp(OperandVector &Operands);
198 ParseStatus parseOperandWithModifier(OperandVector &Operands);
199 ParseStatus parseBareSymbol(OperandVector &Operands);
200 ParseStatus parseCallSymbol(OperandVector &Operands);
201 ParseStatus parsePseudoJumpSymbol(OperandVector &Operands);
202 ParseStatus parseJALOffset(OperandVector &Operands);
203 ParseStatus parseVTypeI(OperandVector &Operands);
204 ParseStatus parseMaskReg(OperandVector &Operands);
205 ParseStatus parseInsnDirectiveOpcode(OperandVector &Operands);
206 ParseStatus parseInsnCDirectiveOpcode(OperandVector &Operands);
207 ParseStatus parseGPRAsFPR(OperandVector &Operands);
208 template <bool IsRV64Inst> ParseStatus parseGPRPair(OperandVector &Operands);
209 ParseStatus parseGPRPair(OperandVector &Operands, bool IsRV64Inst);
210 ParseStatus parseFRMArg(OperandVector &Operands);
211 ParseStatus parseFenceArg(OperandVector &Operands);
212 ParseStatus parseReglist(OperandVector &Operands);
213 ParseStatus parseRegReg(OperandVector &Operands);
214 ParseStatus parseRetval(OperandVector &Operands);
215 ParseStatus parseZcmpSpimm(OperandVector &Operands);
216
217 bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
218
219 bool parseDirectiveOption();
220 bool parseDirectiveAttribute();
221 bool parseDirectiveInsn(SMLoc L);
222 bool parseDirectiveVariantCC();
223
224 /// Helper to reset target features for a new arch string. It
225 /// also records the new arch string that is expanded by RISCVISAInfo
226 /// and reports error for invalid arch string.
227 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
228 bool FromOptionDirective);
229
setFeatureBits(uint64_t Feature,StringRef FeatureString)230 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
231 if (!(getSTI().hasFeature(Feature))) {
232 MCSubtargetInfo &STI = copySTI();
233 setAvailableFeatures(
234 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
235 }
236 }
237
clearFeatureBits(uint64_t Feature,StringRef FeatureString)238 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
239 if (getSTI().hasFeature(Feature)) {
240 MCSubtargetInfo &STI = copySTI();
241 setAvailableFeatures(
242 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
243 }
244 }
245
pushFeatureBits()246 void pushFeatureBits() {
247 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
248 "These two stacks must be kept synchronized");
249 FeatureBitStack.push_back(getSTI().getFeatureBits());
250 ParserOptionsStack.push_back(ParserOptions);
251 }
252
popFeatureBits()253 bool popFeatureBits() {
254 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
255 "These two stacks must be kept synchronized");
256 if (FeatureBitStack.empty())
257 return true;
258
259 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
260 copySTI().setFeatureBits(FeatureBits);
261 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
262
263 ParserOptions = ParserOptionsStack.pop_back_val();
264
265 return false;
266 }
267
268 std::unique_ptr<RISCVOperand> defaultMaskRegOp() const;
269 std::unique_ptr<RISCVOperand> defaultFRMArgOp() const;
270 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp() const;
271
272 public:
273 enum RISCVMatchResultTy {
274 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
275 Match_RequiresEvenGPRs,
276 #define GET_OPERAND_DIAGNOSTIC_TYPES
277 #include "RISCVGenAsmMatcher.inc"
278 #undef GET_OPERAND_DIAGNOSTIC_TYPES
279 };
280
281 static bool classifySymbolRef(const MCExpr *Expr,
282 RISCVMCExpr::VariantKind &Kind);
283 static bool isSymbolDiff(const MCExpr *Expr);
284
RISCVAsmParser(const MCSubtargetInfo & STI,MCAsmParser & Parser,const MCInstrInfo & MII,const MCTargetOptions & Options)285 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
286 const MCInstrInfo &MII, const MCTargetOptions &Options)
287 : MCTargetAsmParser(Options, STI, MII) {
288 MCAsmParserExtension::Initialize(Parser);
289
290 Parser.addAliasForDirective(".half", ".2byte");
291 Parser.addAliasForDirective(".hword", ".2byte");
292 Parser.addAliasForDirective(".word", ".4byte");
293 Parser.addAliasForDirective(".dword", ".8byte");
294 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
295
296 auto ABIName = StringRef(Options.ABIName);
297 if (ABIName.ends_with("f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
298 errs() << "Hard-float 'f' ABI can't be used for a target that "
299 "doesn't support the F instruction set extension (ignoring "
300 "target-abi)\n";
301 } else if (ABIName.ends_with("d") &&
302 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
303 errs() << "Hard-float 'd' ABI can't be used for a target that "
304 "doesn't support the D instruction set extension (ignoring "
305 "target-abi)\n";
306 }
307
308 // Use computeTargetABI to check if ABIName is valid. If invalid, output
309 // error message.
310 RISCVABI::computeTargetABI(STI.getTargetTriple(), STI.getFeatureBits(),
311 ABIName);
312
313 const MCObjectFileInfo *MOFI = Parser.getContext().getObjectFileInfo();
314 ParserOptions.IsPicEnabled = MOFI->isPositionIndependent();
315
316 if (AddBuildAttributes)
317 getTargetStreamer().emitTargetAttributes(STI, /*EmitStackAlign*/ false);
318 }
319 };
320
321 /// RISCVOperand - Instances of this class represent a parsed machine
322 /// instruction
323 struct RISCVOperand final : public MCParsedAsmOperand {
324
325 enum class KindTy {
326 Token,
327 Register,
328 Immediate,
329 FPImmediate,
330 SystemRegister,
331 VType,
332 FRM,
333 Fence,
334 Rlist,
335 Spimm,
336 RegReg,
337 } Kind;
338
339 struct RegOp {
340 MCRegister RegNum;
341 bool IsGPRAsFPR;
342 };
343
344 struct ImmOp {
345 const MCExpr *Val;
346 bool IsRV64;
347 };
348
349 struct FPImmOp {
350 uint64_t Val;
351 };
352
353 struct SysRegOp {
354 const char *Data;
355 unsigned Length;
356 unsigned Encoding;
357 // FIXME: Add the Encoding parsed fields as needed for checks,
358 // e.g.: read/write or user/supervisor/machine privileges.
359 };
360
361 struct VTypeOp {
362 unsigned Val;
363 };
364
365 struct FRMOp {
366 RISCVFPRndMode::RoundingMode FRM;
367 };
368
369 struct FenceOp {
370 unsigned Val;
371 };
372
373 struct RlistOp {
374 unsigned Val;
375 };
376
377 struct SpimmOp {
378 unsigned Val;
379 };
380
381 struct RegRegOp {
382 MCRegister Reg1;
383 MCRegister Reg2;
384 };
385
386 SMLoc StartLoc, EndLoc;
387 union {
388 StringRef Tok;
389 RegOp Reg;
390 ImmOp Imm;
391 FPImmOp FPImm;
392 struct SysRegOp SysReg;
393 struct VTypeOp VType;
394 struct FRMOp FRM;
395 struct FenceOp Fence;
396 struct RlistOp Rlist;
397 struct SpimmOp Spimm;
398 struct RegRegOp RegReg;
399 };
400
RISCVOperand__anon932ea4f60111::RISCVOperand401 RISCVOperand(KindTy K) : Kind(K) {}
402
403 public:
RISCVOperand__anon932ea4f60111::RISCVOperand404 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() {
405 Kind = o.Kind;
406 StartLoc = o.StartLoc;
407 EndLoc = o.EndLoc;
408 switch (Kind) {
409 case KindTy::Register:
410 Reg = o.Reg;
411 break;
412 case KindTy::Immediate:
413 Imm = o.Imm;
414 break;
415 case KindTy::FPImmediate:
416 FPImm = o.FPImm;
417 break;
418 case KindTy::Token:
419 Tok = o.Tok;
420 break;
421 case KindTy::SystemRegister:
422 SysReg = o.SysReg;
423 break;
424 case KindTy::VType:
425 VType = o.VType;
426 break;
427 case KindTy::FRM:
428 FRM = o.FRM;
429 break;
430 case KindTy::Fence:
431 Fence = o.Fence;
432 break;
433 case KindTy::Rlist:
434 Rlist = o.Rlist;
435 break;
436 case KindTy::Spimm:
437 Spimm = o.Spimm;
438 break;
439 case KindTy::RegReg:
440 RegReg = o.RegReg;
441 break;
442 }
443 }
444
isToken__anon932ea4f60111::RISCVOperand445 bool isToken() const override { return Kind == KindTy::Token; }
isReg__anon932ea4f60111::RISCVOperand446 bool isReg() const override { return Kind == KindTy::Register; }
isV0Reg__anon932ea4f60111::RISCVOperand447 bool isV0Reg() const {
448 return Kind == KindTy::Register && Reg.RegNum == RISCV::V0;
449 }
isAnyReg__anon932ea4f60111::RISCVOperand450 bool isAnyReg() const {
451 return Kind == KindTy::Register &&
452 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum) ||
453 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(Reg.RegNum) ||
454 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(Reg.RegNum));
455 }
isAnyRegC__anon932ea4f60111::RISCVOperand456 bool isAnyRegC() const {
457 return Kind == KindTy::Register &&
458 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
459 Reg.RegNum) ||
460 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
461 Reg.RegNum));
462 }
isImm__anon932ea4f60111::RISCVOperand463 bool isImm() const override { return Kind == KindTy::Immediate; }
isMem__anon932ea4f60111::RISCVOperand464 bool isMem() const override { return false; }
isSystemRegister__anon932ea4f60111::RISCVOperand465 bool isSystemRegister() const { return Kind == KindTy::SystemRegister; }
isRegReg__anon932ea4f60111::RISCVOperand466 bool isRegReg() const { return Kind == KindTy::RegReg; }
isRlist__anon932ea4f60111::RISCVOperand467 bool isRlist() const { return Kind == KindTy::Rlist; }
isSpimm__anon932ea4f60111::RISCVOperand468 bool isSpimm() const { return Kind == KindTy::Spimm; }
469
isGPR__anon932ea4f60111::RISCVOperand470 bool isGPR() const {
471 return Kind == KindTy::Register &&
472 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum);
473 }
474
isGPRAsFPR__anon932ea4f60111::RISCVOperand475 bool isGPRAsFPR() const { return isGPR() && Reg.IsGPRAsFPR; }
476
isGPRPair__anon932ea4f60111::RISCVOperand477 bool isGPRPair() const {
478 return Kind == KindTy::Register &&
479 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
480 Reg.RegNum);
481 }
482
evaluateConstantImm__anon932ea4f60111::RISCVOperand483 static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm,
484 RISCVMCExpr::VariantKind &VK) {
485 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
486 VK = RE->getKind();
487 return RE->evaluateAsConstant(Imm);
488 }
489
490 if (auto CE = dyn_cast<MCConstantExpr>(Expr)) {
491 VK = RISCVMCExpr::VK_RISCV_None;
492 Imm = CE->getValue();
493 return true;
494 }
495
496 return false;
497 }
498
499 // True if operand is a symbol with no modifiers, or a constant with no
500 // modifiers and isShiftedInt<N-1, 1>(Op).
isBareSimmNLsb0__anon932ea4f60111::RISCVOperand501 template <int N> bool isBareSimmNLsb0() const {
502 int64_t Imm;
503 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
504 if (!isImm())
505 return false;
506 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
507 bool IsValid;
508 if (!IsConstantImm)
509 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
510 else
511 IsValid = isShiftedInt<N - 1, 1>(Imm);
512 return IsValid && VK == RISCVMCExpr::VK_RISCV_None;
513 }
514
515 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td
516
isBareSymbol__anon932ea4f60111::RISCVOperand517 bool isBareSymbol() const {
518 int64_t Imm;
519 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
520 // Must be of 'immediate' type but not a constant.
521 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
522 return false;
523 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
524 VK == RISCVMCExpr::VK_RISCV_None;
525 }
526
isCallSymbol__anon932ea4f60111::RISCVOperand527 bool isCallSymbol() const {
528 int64_t Imm;
529 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
530 // Must be of 'immediate' type but not a constant.
531 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
532 return false;
533 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
534 (VK == RISCVMCExpr::VK_RISCV_CALL ||
535 VK == RISCVMCExpr::VK_RISCV_CALL_PLT);
536 }
537
isPseudoJumpSymbol__anon932ea4f60111::RISCVOperand538 bool isPseudoJumpSymbol() const {
539 int64_t Imm;
540 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
541 // Must be of 'immediate' type but not a constant.
542 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
543 return false;
544 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
545 VK == RISCVMCExpr::VK_RISCV_CALL;
546 }
547
isTPRelAddSymbol__anon932ea4f60111::RISCVOperand548 bool isTPRelAddSymbol() const {
549 int64_t Imm;
550 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
551 // Must be of 'immediate' type but not a constant.
552 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
553 return false;
554 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
555 VK == RISCVMCExpr::VK_RISCV_TPREL_ADD;
556 }
557
isTLSDESCCallSymbol__anon932ea4f60111::RISCVOperand558 bool isTLSDESCCallSymbol() const {
559 int64_t Imm;
560 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
561 // Must be of 'immediate' type but not a constant.
562 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK))
563 return false;
564 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
565 VK == RISCVMCExpr::VK_RISCV_TLSDESC_CALL;
566 }
567
isCSRSystemRegister__anon932ea4f60111::RISCVOperand568 bool isCSRSystemRegister() const { return isSystemRegister(); }
569
isVTypeImm__anon932ea4f60111::RISCVOperand570 bool isVTypeImm(unsigned N) const {
571 int64_t Imm;
572 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
573 if (!isImm())
574 return false;
575 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
576 return IsConstantImm && isUIntN(N, Imm) && VK == RISCVMCExpr::VK_RISCV_None;
577 }
578
579 // If the last operand of the vsetvli/vsetvli instruction is a constant
580 // expression, KindTy is Immediate.
isVTypeI10__anon932ea4f60111::RISCVOperand581 bool isVTypeI10() const {
582 if (Kind == KindTy::Immediate)
583 return isVTypeImm(10);
584 return Kind == KindTy::VType;
585 }
isVTypeI11__anon932ea4f60111::RISCVOperand586 bool isVTypeI11() const {
587 if (Kind == KindTy::Immediate)
588 return isVTypeImm(11);
589 return Kind == KindTy::VType;
590 }
591
592 /// Return true if the operand is a valid for the fence instruction e.g.
593 /// ('iorw').
isFenceArg__anon932ea4f60111::RISCVOperand594 bool isFenceArg() const { return Kind == KindTy::Fence; }
595
596 /// Return true if the operand is a valid floating point rounding mode.
isFRMArg__anon932ea4f60111::RISCVOperand597 bool isFRMArg() const { return Kind == KindTy::FRM; }
isFRMArgLegacy__anon932ea4f60111::RISCVOperand598 bool isFRMArgLegacy() const { return Kind == KindTy::FRM; }
isRTZArg__anon932ea4f60111::RISCVOperand599 bool isRTZArg() const { return isFRMArg() && FRM.FRM == RISCVFPRndMode::RTZ; }
600
601 /// Return true if the operand is a valid fli.s floating-point immediate.
isLoadFPImm__anon932ea4f60111::RISCVOperand602 bool isLoadFPImm() const {
603 if (isImm())
604 return isUImm5();
605 if (Kind != KindTy::FPImmediate)
606 return false;
607 int Idx = RISCVLoadFPImm::getLoadFPImm(
608 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
609 // Don't allow decimal version of the minimum value. It is a different value
610 // for each supported data type.
611 return Idx >= 0 && Idx != 1;
612 }
613
isImmXLenLI__anon932ea4f60111::RISCVOperand614 bool isImmXLenLI() const {
615 int64_t Imm;
616 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
617 if (!isImm())
618 return false;
619 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
620 if (VK == RISCVMCExpr::VK_RISCV_LO ||
621 VK == RISCVMCExpr::VK_RISCV_PCREL_LO ||
622 VK == RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO ||
623 VK == RISCVMCExpr::VK_RISCV_TLSDESC_ADD_LO)
624 return true;
625 // Given only Imm, ensuring that the actually specified constant is either
626 // a signed or unsigned 64-bit number is unfortunately impossible.
627 if (IsConstantImm) {
628 return VK == RISCVMCExpr::VK_RISCV_None &&
629 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
630 }
631
632 return RISCVAsmParser::isSymbolDiff(getImm());
633 }
634
isImmXLenLI_Restricted__anon932ea4f60111::RISCVOperand635 bool isImmXLenLI_Restricted() const {
636 int64_t Imm;
637 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
638 if (!isImm())
639 return false;
640 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
641 // 'la imm' supports constant immediates only.
642 return IsConstantImm && (VK == RISCVMCExpr::VK_RISCV_None) &&
643 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
644 }
645
isUImmLog2XLen__anon932ea4f60111::RISCVOperand646 bool isUImmLog2XLen() const {
647 int64_t Imm;
648 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
649 if (!isImm())
650 return false;
651 if (!evaluateConstantImm(getImm(), Imm, VK) ||
652 VK != RISCVMCExpr::VK_RISCV_None)
653 return false;
654 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
655 }
656
isUImmLog2XLenNonZero__anon932ea4f60111::RISCVOperand657 bool isUImmLog2XLenNonZero() const {
658 int64_t Imm;
659 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
660 if (!isImm())
661 return false;
662 if (!evaluateConstantImm(getImm(), Imm, VK) ||
663 VK != RISCVMCExpr::VK_RISCV_None)
664 return false;
665 if (Imm == 0)
666 return false;
667 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
668 }
669
isUImmLog2XLenHalf__anon932ea4f60111::RISCVOperand670 bool isUImmLog2XLenHalf() const {
671 int64_t Imm;
672 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
673 if (!isImm())
674 return false;
675 if (!evaluateConstantImm(getImm(), Imm, VK) ||
676 VK != RISCVMCExpr::VK_RISCV_None)
677 return false;
678 return (isRV64Imm() && isUInt<5>(Imm)) || isUInt<4>(Imm);
679 }
680
IsUImm__anon932ea4f60111::RISCVOperand681 template <unsigned N> bool IsUImm() const {
682 int64_t Imm;
683 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
684 if (!isImm())
685 return false;
686 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
687 return IsConstantImm && isUInt<N>(Imm) && VK == RISCVMCExpr::VK_RISCV_None;
688 }
689
isUImm1__anon932ea4f60111::RISCVOperand690 bool isUImm1() const { return IsUImm<1>(); }
isUImm2__anon932ea4f60111::RISCVOperand691 bool isUImm2() const { return IsUImm<2>(); }
isUImm3__anon932ea4f60111::RISCVOperand692 bool isUImm3() const { return IsUImm<3>(); }
isUImm4__anon932ea4f60111::RISCVOperand693 bool isUImm4() const { return IsUImm<4>(); }
isUImm5__anon932ea4f60111::RISCVOperand694 bool isUImm5() const { return IsUImm<5>(); }
isUImm6__anon932ea4f60111::RISCVOperand695 bool isUImm6() const { return IsUImm<6>(); }
isUImm7__anon932ea4f60111::RISCVOperand696 bool isUImm7() const { return IsUImm<7>(); }
isUImm8__anon932ea4f60111::RISCVOperand697 bool isUImm8() const { return IsUImm<8>(); }
isUImm20__anon932ea4f60111::RISCVOperand698 bool isUImm20() const { return IsUImm<20>(); }
699
isUImm8GE32__anon932ea4f60111::RISCVOperand700 bool isUImm8GE32() const {
701 int64_t Imm;
702 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
703 if (!isImm())
704 return false;
705 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
706 return IsConstantImm && isUInt<8>(Imm) && Imm >= 32 &&
707 VK == RISCVMCExpr::VK_RISCV_None;
708 }
709
isRnumArg__anon932ea4f60111::RISCVOperand710 bool isRnumArg() const {
711 int64_t Imm;
712 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
713 if (!isImm())
714 return false;
715 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
716 return IsConstantImm && Imm >= INT64_C(0) && Imm <= INT64_C(10) &&
717 VK == RISCVMCExpr::VK_RISCV_None;
718 }
719
isRnumArg_0_7__anon932ea4f60111::RISCVOperand720 bool isRnumArg_0_7() const {
721 int64_t Imm;
722 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
723 if (!isImm())
724 return false;
725 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
726 return IsConstantImm && Imm >= INT64_C(0) && Imm <= INT64_C(7) &&
727 VK == RISCVMCExpr::VK_RISCV_None;
728 }
729
isRnumArg_1_10__anon932ea4f60111::RISCVOperand730 bool isRnumArg_1_10() const {
731 int64_t Imm;
732 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
733 if (!isImm())
734 return false;
735 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
736 return IsConstantImm && Imm >= INT64_C(1) && Imm <= INT64_C(10) &&
737 VK == RISCVMCExpr::VK_RISCV_None;
738 }
739
isRnumArg_2_14__anon932ea4f60111::RISCVOperand740 bool isRnumArg_2_14() const {
741 int64_t Imm;
742 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
743 if (!isImm())
744 return false;
745 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
746 return IsConstantImm && Imm >= INT64_C(2) && Imm <= INT64_C(14) &&
747 VK == RISCVMCExpr::VK_RISCV_None;
748 }
749
isSImm5__anon932ea4f60111::RISCVOperand750 bool isSImm5() const {
751 if (!isImm())
752 return false;
753 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
754 int64_t Imm;
755 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
756 return IsConstantImm && isInt<5>(fixImmediateForRV32(Imm, isRV64Imm())) &&
757 VK == RISCVMCExpr::VK_RISCV_None;
758 }
759
isSImm6__anon932ea4f60111::RISCVOperand760 bool isSImm6() const {
761 if (!isImm())
762 return false;
763 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
764 int64_t Imm;
765 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
766 return IsConstantImm && isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
767 VK == RISCVMCExpr::VK_RISCV_None;
768 }
769
isSImm6NonZero__anon932ea4f60111::RISCVOperand770 bool isSImm6NonZero() const {
771 if (!isImm())
772 return false;
773 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
774 int64_t Imm;
775 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
776 return IsConstantImm && Imm != 0 &&
777 isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
778 VK == RISCVMCExpr::VK_RISCV_None;
779 }
780
isCLUIImm__anon932ea4f60111::RISCVOperand781 bool isCLUIImm() const {
782 if (!isImm())
783 return false;
784 int64_t Imm;
785 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
786 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
787 return IsConstantImm && (Imm != 0) &&
788 (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) &&
789 VK == RISCVMCExpr::VK_RISCV_None;
790 }
791
isUImm2Lsb0__anon932ea4f60111::RISCVOperand792 bool isUImm2Lsb0() const {
793 if (!isImm())
794 return false;
795 int64_t Imm;
796 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
797 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
798 return IsConstantImm && isShiftedUInt<1, 1>(Imm) &&
799 VK == RISCVMCExpr::VK_RISCV_None;
800 }
801
isUImm7Lsb00__anon932ea4f60111::RISCVOperand802 bool isUImm7Lsb00() const {
803 if (!isImm())
804 return false;
805 int64_t Imm;
806 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
807 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
808 return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
809 VK == RISCVMCExpr::VK_RISCV_None;
810 }
811
isUImm8Lsb00__anon932ea4f60111::RISCVOperand812 bool isUImm8Lsb00() const {
813 if (!isImm())
814 return false;
815 int64_t Imm;
816 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
817 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
818 return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
819 VK == RISCVMCExpr::VK_RISCV_None;
820 }
821
isUImm8Lsb000__anon932ea4f60111::RISCVOperand822 bool isUImm8Lsb000() const {
823 if (!isImm())
824 return false;
825 int64_t Imm;
826 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
827 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
828 return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
829 VK == RISCVMCExpr::VK_RISCV_None;
830 }
831
isSImm9Lsb0__anon932ea4f60111::RISCVOperand832 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); }
833
isUImm9Lsb000__anon932ea4f60111::RISCVOperand834 bool isUImm9Lsb000() const {
835 if (!isImm())
836 return false;
837 int64_t Imm;
838 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
839 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
840 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
841 VK == RISCVMCExpr::VK_RISCV_None;
842 }
843
isUImm10Lsb00NonZero__anon932ea4f60111::RISCVOperand844 bool isUImm10Lsb00NonZero() const {
845 if (!isImm())
846 return false;
847 int64_t Imm;
848 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
849 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
850 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) &&
851 VK == RISCVMCExpr::VK_RISCV_None;
852 }
853
854 // If this a RV32 and the immediate is a uimm32, sign extend it to 32 bits.
855 // This allows writing 'addi a0, a0, 0xffffffff'.
fixImmediateForRV32__anon932ea4f60111::RISCVOperand856 static int64_t fixImmediateForRV32(int64_t Imm, bool IsRV64Imm) {
857 if (IsRV64Imm || !isUInt<32>(Imm))
858 return Imm;
859 return SignExtend64<32>(Imm);
860 }
861
isSImm12__anon932ea4f60111::RISCVOperand862 bool isSImm12() const {
863 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
864 int64_t Imm;
865 bool IsValid;
866 if (!isImm())
867 return false;
868 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
869 if (!IsConstantImm)
870 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
871 else
872 IsValid = isInt<12>(fixImmediateForRV32(Imm, isRV64Imm()));
873 return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) ||
874 VK == RISCVMCExpr::VK_RISCV_LO ||
875 VK == RISCVMCExpr::VK_RISCV_PCREL_LO ||
876 VK == RISCVMCExpr::VK_RISCV_TPREL_LO ||
877 VK == RISCVMCExpr::VK_RISCV_TLSDESC_LOAD_LO ||
878 VK == RISCVMCExpr::VK_RISCV_TLSDESC_ADD_LO);
879 }
880
isSImm12Lsb0__anon932ea4f60111::RISCVOperand881 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); }
882
isSImm12Lsb00000__anon932ea4f60111::RISCVOperand883 bool isSImm12Lsb00000() const {
884 if (!isImm())
885 return false;
886 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
887 int64_t Imm;
888 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
889 return IsConstantImm && isShiftedInt<7, 5>(Imm) &&
890 VK == RISCVMCExpr::VK_RISCV_None;
891 }
892
isSImm13Lsb0__anon932ea4f60111::RISCVOperand893 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
894
isSImm10Lsb0000NonZero__anon932ea4f60111::RISCVOperand895 bool isSImm10Lsb0000NonZero() const {
896 if (!isImm())
897 return false;
898 int64_t Imm;
899 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
900 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
901 return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) &&
902 VK == RISCVMCExpr::VK_RISCV_None;
903 }
904
isUImm20LUI__anon932ea4f60111::RISCVOperand905 bool isUImm20LUI() const {
906 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
907 int64_t Imm;
908 bool IsValid;
909 if (!isImm())
910 return false;
911 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
912 if (!IsConstantImm) {
913 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
914 return IsValid && (VK == RISCVMCExpr::VK_RISCV_HI ||
915 VK == RISCVMCExpr::VK_RISCV_TPREL_HI);
916 } else {
917 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
918 VK == RISCVMCExpr::VK_RISCV_HI ||
919 VK == RISCVMCExpr::VK_RISCV_TPREL_HI);
920 }
921 }
922
isUImm20AUIPC__anon932ea4f60111::RISCVOperand923 bool isUImm20AUIPC() const {
924 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
925 int64_t Imm;
926 bool IsValid;
927 if (!isImm())
928 return false;
929 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
930 if (!IsConstantImm) {
931 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
932 return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
933 VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
934 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
935 VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI ||
936 VK == RISCVMCExpr::VK_RISCV_TLSDESC_HI);
937 }
938
939 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None ||
940 VK == RISCVMCExpr::VK_RISCV_PCREL_HI ||
941 VK == RISCVMCExpr::VK_RISCV_GOT_HI ||
942 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI ||
943 VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI ||
944 VK == RISCVMCExpr::VK_RISCV_TLSDESC_HI);
945 }
946
isSImm21Lsb0JAL__anon932ea4f60111::RISCVOperand947 bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); }
948
isImmZero__anon932ea4f60111::RISCVOperand949 bool isImmZero() const {
950 if (!isImm())
951 return false;
952 int64_t Imm;
953 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
954 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
955 return IsConstantImm && (Imm == 0) && VK == RISCVMCExpr::VK_RISCV_None;
956 }
957
isSImm5Plus1__anon932ea4f60111::RISCVOperand958 bool isSImm5Plus1() const {
959 if (!isImm())
960 return false;
961 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
962 int64_t Imm;
963 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
964 return IsConstantImm &&
965 isInt<5>(fixImmediateForRV32(Imm, isRV64Imm()) - 1) &&
966 VK == RISCVMCExpr::VK_RISCV_None;
967 }
968
969 /// getStartLoc - Gets location of the first token of this operand
getStartLoc__anon932ea4f60111::RISCVOperand970 SMLoc getStartLoc() const override { return StartLoc; }
971 /// getEndLoc - Gets location of the last token of this operand
getEndLoc__anon932ea4f60111::RISCVOperand972 SMLoc getEndLoc() const override { return EndLoc; }
973 /// True if this operand is for an RV64 instruction
isRV64Imm__anon932ea4f60111::RISCVOperand974 bool isRV64Imm() const {
975 assert(Kind == KindTy::Immediate && "Invalid type access!");
976 return Imm.IsRV64;
977 }
978
getReg__anon932ea4f60111::RISCVOperand979 unsigned getReg() const override {
980 assert(Kind == KindTy::Register && "Invalid type access!");
981 return Reg.RegNum.id();
982 }
983
getSysReg__anon932ea4f60111::RISCVOperand984 StringRef getSysReg() const {
985 assert(Kind == KindTy::SystemRegister && "Invalid type access!");
986 return StringRef(SysReg.Data, SysReg.Length);
987 }
988
getImm__anon932ea4f60111::RISCVOperand989 const MCExpr *getImm() const {
990 assert(Kind == KindTy::Immediate && "Invalid type access!");
991 return Imm.Val;
992 }
993
getFPConst__anon932ea4f60111::RISCVOperand994 uint64_t getFPConst() const {
995 assert(Kind == KindTy::FPImmediate && "Invalid type access!");
996 return FPImm.Val;
997 }
998
getToken__anon932ea4f60111::RISCVOperand999 StringRef getToken() const {
1000 assert(Kind == KindTy::Token && "Invalid type access!");
1001 return Tok;
1002 }
1003
getVType__anon932ea4f60111::RISCVOperand1004 unsigned getVType() const {
1005 assert(Kind == KindTy::VType && "Invalid type access!");
1006 return VType.Val;
1007 }
1008
getFRM__anon932ea4f60111::RISCVOperand1009 RISCVFPRndMode::RoundingMode getFRM() const {
1010 assert(Kind == KindTy::FRM && "Invalid type access!");
1011 return FRM.FRM;
1012 }
1013
getFence__anon932ea4f60111::RISCVOperand1014 unsigned getFence() const {
1015 assert(Kind == KindTy::Fence && "Invalid type access!");
1016 return Fence.Val;
1017 }
1018
print__anon932ea4f60111::RISCVOperand1019 void print(raw_ostream &OS) const override {
1020 auto RegName = [](MCRegister Reg) {
1021 if (Reg)
1022 return RISCVInstPrinter::getRegisterName(Reg);
1023 else
1024 return "noreg";
1025 };
1026
1027 switch (Kind) {
1028 case KindTy::Immediate:
1029 OS << *getImm();
1030 break;
1031 case KindTy::FPImmediate:
1032 break;
1033 case KindTy::Register:
1034 OS << "<register " << RegName(getReg()) << ">";
1035 break;
1036 case KindTy::Token:
1037 OS << "'" << getToken() << "'";
1038 break;
1039 case KindTy::SystemRegister:
1040 OS << "<sysreg: " << getSysReg() << '>';
1041 break;
1042 case KindTy::VType:
1043 OS << "<vtype: ";
1044 RISCVVType::printVType(getVType(), OS);
1045 OS << '>';
1046 break;
1047 case KindTy::FRM:
1048 OS << "<frm: ";
1049 roundingModeToString(getFRM());
1050 OS << '>';
1051 break;
1052 case KindTy::Fence:
1053 OS << "<fence: ";
1054 OS << getFence();
1055 OS << '>';
1056 break;
1057 case KindTy::Rlist:
1058 OS << "<rlist: ";
1059 RISCVZC::printRlist(Rlist.Val, OS);
1060 OS << '>';
1061 break;
1062 case KindTy::Spimm:
1063 OS << "<Spimm: ";
1064 RISCVZC::printSpimm(Spimm.Val, OS);
1065 OS << '>';
1066 break;
1067 case KindTy::RegReg:
1068 OS << "<RegReg: Reg1 " << RegName(RegReg.Reg1);
1069 OS << " Reg2 " << RegName(RegReg.Reg2);
1070 break;
1071 }
1072 }
1073
createToken__anon932ea4f60111::RISCVOperand1074 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1075 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1076 Op->Tok = Str;
1077 Op->StartLoc = S;
1078 Op->EndLoc = S;
1079 return Op;
1080 }
1081
1082 static std::unique_ptr<RISCVOperand>
createReg__anon932ea4f60111::RISCVOperand1083 createReg(unsigned RegNo, SMLoc S, SMLoc E, bool IsGPRAsFPR = false) {
1084 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1085 Op->Reg.RegNum = RegNo;
1086 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1087 Op->StartLoc = S;
1088 Op->EndLoc = E;
1089 return Op;
1090 }
1091
createImm__anon932ea4f60111::RISCVOperand1092 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S,
1093 SMLoc E, bool IsRV64) {
1094 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
1095 Op->Imm.Val = Val;
1096 Op->Imm.IsRV64 = IsRV64;
1097 Op->StartLoc = S;
1098 Op->EndLoc = E;
1099 return Op;
1100 }
1101
createFPImm__anon932ea4f60111::RISCVOperand1102 static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) {
1103 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1104 Op->FPImm.Val = Val;
1105 Op->StartLoc = S;
1106 Op->EndLoc = S;
1107 return Op;
1108 }
1109
createSysReg__anon932ea4f60111::RISCVOperand1110 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1111 unsigned Encoding) {
1112 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1113 Op->SysReg.Data = Str.data();
1114 Op->SysReg.Length = Str.size();
1115 Op->SysReg.Encoding = Encoding;
1116 Op->StartLoc = S;
1117 Op->EndLoc = S;
1118 return Op;
1119 }
1120
1121 static std::unique_ptr<RISCVOperand>
createFRMArg__anon932ea4f60111::RISCVOperand1122 createFRMArg(RISCVFPRndMode::RoundingMode FRM, SMLoc S) {
1123 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1124 Op->FRM.FRM = FRM;
1125 Op->StartLoc = S;
1126 Op->EndLoc = S;
1127 return Op;
1128 }
1129
createFenceArg__anon932ea4f60111::RISCVOperand1130 static std::unique_ptr<RISCVOperand> createFenceArg(unsigned Val, SMLoc S) {
1131 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1132 Op->Fence.Val = Val;
1133 Op->StartLoc = S;
1134 Op->EndLoc = S;
1135 return Op;
1136 }
1137
createVType__anon932ea4f60111::RISCVOperand1138 static std::unique_ptr<RISCVOperand> createVType(unsigned VTypeI, SMLoc S) {
1139 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1140 Op->VType.Val = VTypeI;
1141 Op->StartLoc = S;
1142 Op->EndLoc = S;
1143 return Op;
1144 }
1145
createRlist__anon932ea4f60111::RISCVOperand1146 static std::unique_ptr<RISCVOperand> createRlist(unsigned RlistEncode,
1147 SMLoc S) {
1148 auto Op = std::make_unique<RISCVOperand>(KindTy::Rlist);
1149 Op->Rlist.Val = RlistEncode;
1150 Op->StartLoc = S;
1151 return Op;
1152 }
1153
createRegReg__anon932ea4f60111::RISCVOperand1154 static std::unique_ptr<RISCVOperand> createRegReg(unsigned Reg1No,
1155 unsigned Reg2No, SMLoc S) {
1156 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1157 Op->RegReg.Reg1 = Reg1No;
1158 Op->RegReg.Reg2 = Reg2No;
1159 Op->StartLoc = S;
1160 Op->EndLoc = S;
1161 return Op;
1162 }
1163
createSpimm__anon932ea4f60111::RISCVOperand1164 static std::unique_ptr<RISCVOperand> createSpimm(unsigned Spimm, SMLoc S) {
1165 auto Op = std::make_unique<RISCVOperand>(KindTy::Spimm);
1166 Op->Spimm.Val = Spimm;
1167 Op->StartLoc = S;
1168 return Op;
1169 }
1170
addExpr__anon932ea4f60111::RISCVOperand1171 static void addExpr(MCInst &Inst, const MCExpr *Expr, bool IsRV64Imm) {
1172 assert(Expr && "Expr shouldn't be null!");
1173 int64_t Imm = 0;
1174 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
1175 bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
1176
1177 if (IsConstant)
1178 Inst.addOperand(
1179 MCOperand::createImm(fixImmediateForRV32(Imm, IsRV64Imm)));
1180 else
1181 Inst.addOperand(MCOperand::createExpr(Expr));
1182 }
1183
1184 // Used by the TableGen Code
addRegOperands__anon932ea4f60111::RISCVOperand1185 void addRegOperands(MCInst &Inst, unsigned N) const {
1186 assert(N == 1 && "Invalid number of operands!");
1187 Inst.addOperand(MCOperand::createReg(getReg()));
1188 }
1189
addImmOperands__anon932ea4f60111::RISCVOperand1190 void addImmOperands(MCInst &Inst, unsigned N) const {
1191 assert(N == 1 && "Invalid number of operands!");
1192 addExpr(Inst, getImm(), isRV64Imm());
1193 }
1194
addFPImmOperands__anon932ea4f60111::RISCVOperand1195 void addFPImmOperands(MCInst &Inst, unsigned N) const {
1196 assert(N == 1 && "Invalid number of operands!");
1197 if (isImm()) {
1198 addExpr(Inst, getImm(), isRV64Imm());
1199 return;
1200 }
1201
1202 int Imm = RISCVLoadFPImm::getLoadFPImm(
1203 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1204 Inst.addOperand(MCOperand::createImm(Imm));
1205 }
1206
addFenceArgOperands__anon932ea4f60111::RISCVOperand1207 void addFenceArgOperands(MCInst &Inst, unsigned N) const {
1208 assert(N == 1 && "Invalid number of operands!");
1209 Inst.addOperand(MCOperand::createImm(Fence.Val));
1210 }
1211
addCSRSystemRegisterOperands__anon932ea4f60111::RISCVOperand1212 void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const {
1213 assert(N == 1 && "Invalid number of operands!");
1214 Inst.addOperand(MCOperand::createImm(SysReg.Encoding));
1215 }
1216
1217 // Support non-canonical syntax:
1218 // "vsetivli rd, uimm, 0xabc" or "vsetvli rd, rs1, 0xabc"
1219 // "vsetivli rd, uimm, (0xc << N)" or "vsetvli rd, rs1, (0xc << N)"
addVTypeIOperands__anon932ea4f60111::RISCVOperand1220 void addVTypeIOperands(MCInst &Inst, unsigned N) const {
1221 assert(N == 1 && "Invalid number of operands!");
1222 int64_t Imm = 0;
1223 if (Kind == KindTy::Immediate) {
1224 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
1225 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
1226 (void)IsConstantImm;
1227 assert(IsConstantImm && "Invalid VTypeI Operand!");
1228 } else {
1229 Imm = getVType();
1230 }
1231 Inst.addOperand(MCOperand::createImm(Imm));
1232 }
1233
addRlistOperands__anon932ea4f60111::RISCVOperand1234 void addRlistOperands(MCInst &Inst, unsigned N) const {
1235 assert(N == 1 && "Invalid number of operands!");
1236 Inst.addOperand(MCOperand::createImm(Rlist.Val));
1237 }
1238
addRegRegOperands__anon932ea4f60111::RISCVOperand1239 void addRegRegOperands(MCInst &Inst, unsigned N) const {
1240 assert(N == 1 && "Invalid number of operands!");
1241 Inst.addOperand(MCOperand::createReg(RegReg.Reg1));
1242 Inst.addOperand(MCOperand::createReg(RegReg.Reg2));
1243 }
1244
addSpimmOperands__anon932ea4f60111::RISCVOperand1245 void addSpimmOperands(MCInst &Inst, unsigned N) const {
1246 assert(N == 1 && "Invalid number of operands!");
1247 Inst.addOperand(MCOperand::createImm(Spimm.Val));
1248 }
1249
addFRMArgOperands__anon932ea4f60111::RISCVOperand1250 void addFRMArgOperands(MCInst &Inst, unsigned N) const {
1251 assert(N == 1 && "Invalid number of operands!");
1252 Inst.addOperand(MCOperand::createImm(getFRM()));
1253 }
1254 };
1255 } // end anonymous namespace.
1256
1257 #define GET_REGISTER_MATCHER
1258 #define GET_SUBTARGET_FEATURE_NAME
1259 #define GET_MATCHER_IMPLEMENTATION
1260 #define GET_MNEMONIC_SPELL_CHECKER
1261 #include "RISCVGenAsmMatcher.inc"
1262
convertFPR64ToFPR16(MCRegister Reg)1263 static MCRegister convertFPR64ToFPR16(MCRegister Reg) {
1264 assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register");
1265 return Reg - RISCV::F0_D + RISCV::F0_H;
1266 }
1267
convertFPR64ToFPR32(MCRegister Reg)1268 static MCRegister convertFPR64ToFPR32(MCRegister Reg) {
1269 assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register");
1270 return Reg - RISCV::F0_D + RISCV::F0_F;
1271 }
1272
convertVRToVRMx(const MCRegisterInfo & RI,MCRegister Reg,unsigned Kind)1273 static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg,
1274 unsigned Kind) {
1275 unsigned RegClassID;
1276 if (Kind == MCK_VRM2)
1277 RegClassID = RISCV::VRM2RegClassID;
1278 else if (Kind == MCK_VRM4)
1279 RegClassID = RISCV::VRM4RegClassID;
1280 else if (Kind == MCK_VRM8)
1281 RegClassID = RISCV::VRM8RegClassID;
1282 else
1283 return 0;
1284 return RI.getMatchingSuperReg(Reg, RISCV::sub_vrm1_0,
1285 &RISCVMCRegisterClasses[RegClassID]);
1286 }
1287
validateTargetOperandClass(MCParsedAsmOperand & AsmOp,unsigned Kind)1288 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
1289 unsigned Kind) {
1290 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp);
1291 if (!Op.isReg())
1292 return Match_InvalidOperand;
1293
1294 MCRegister Reg = Op.getReg();
1295 bool IsRegFPR64 =
1296 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(Reg);
1297 bool IsRegFPR64C =
1298 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(Reg);
1299 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(Reg);
1300
1301 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
1302 // register from FPR64 to FPR32 or FPR64C to FPR32C if necessary.
1303 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1304 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1305 Op.Reg.RegNum = convertFPR64ToFPR32(Reg);
1306 return Match_Success;
1307 }
1308 // As the parser couldn't differentiate an FPR16 from an FPR64, coerce the
1309 // register from FPR64 to FPR16 if necessary.
1310 if (IsRegFPR64 && Kind == MCK_FPR16) {
1311 Op.Reg.RegNum = convertFPR64ToFPR16(Reg);
1312 return Match_Success;
1313 }
1314 // As the parser couldn't differentiate an VRM2/VRM4/VRM8 from an VR, coerce
1315 // the register from VR to VRM2/VRM4/VRM8 if necessary.
1316 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1317 Op.Reg.RegNum = convertVRToVRMx(*getContext().getRegisterInfo(), Reg, Kind);
1318 if (Op.Reg.RegNum == 0)
1319 return Match_InvalidOperand;
1320 return Match_Success;
1321 }
1322 return Match_InvalidOperand;
1323 }
1324
checkTargetMatchPredicate(MCInst & Inst)1325 unsigned RISCVAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1326 const MCInstrDesc &MCID = MII.get(Inst.getOpcode());
1327
1328 for (unsigned I = 0; I < MCID.NumOperands; ++I) {
1329 if (MCID.operands()[I].RegClass == RISCV::GPRPairRegClassID) {
1330 const auto &Op = Inst.getOperand(I);
1331 assert(Op.isReg());
1332
1333 MCRegister Reg = Op.getReg();
1334 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(Reg))
1335 continue;
1336
1337 // FIXME: We should form a paired register during parsing/matching.
1338 if (((Reg.id() - RISCV::X0) & 1) != 0)
1339 return Match_RequiresEvenGPRs;
1340 }
1341 }
1342
1343 return Match_Success;
1344 }
1345
generateImmOutOfRangeError(SMLoc ErrorLoc,int64_t Lower,int64_t Upper,const Twine & Msg="immediate must be an integer in the range")1346 bool RISCVAsmParser::generateImmOutOfRangeError(
1347 SMLoc ErrorLoc, int64_t Lower, int64_t Upper,
1348 const Twine &Msg = "immediate must be an integer in the range") {
1349 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]");
1350 }
1351
generateImmOutOfRangeError(OperandVector & Operands,uint64_t ErrorInfo,int64_t Lower,int64_t Upper,const Twine & Msg="immediate must be an integer in the range")1352 bool RISCVAsmParser::generateImmOutOfRangeError(
1353 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper,
1354 const Twine &Msg = "immediate must be an integer in the range") {
1355 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1356 return generateImmOutOfRangeError(ErrorLoc, Lower, Upper, Msg);
1357 }
1358
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)1359 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1360 OperandVector &Operands,
1361 MCStreamer &Out,
1362 uint64_t &ErrorInfo,
1363 bool MatchingInlineAsm) {
1364 MCInst Inst;
1365 FeatureBitset MissingFeatures;
1366
1367 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1368 MatchingInlineAsm);
1369 switch (Result) {
1370 default:
1371 break;
1372 case Match_Success:
1373 if (validateInstruction(Inst, Operands))
1374 return true;
1375 return processInstruction(Inst, IDLoc, Operands, Out);
1376 case Match_MissingFeature: {
1377 assert(MissingFeatures.any() && "Unknown missing features!");
1378 bool FirstFeature = true;
1379 std::string Msg = "instruction requires the following:";
1380 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) {
1381 if (MissingFeatures[i]) {
1382 Msg += FirstFeature ? " " : ", ";
1383 Msg += getSubtargetFeatureName(i);
1384 FirstFeature = false;
1385 }
1386 }
1387 return Error(IDLoc, Msg);
1388 }
1389 case Match_MnemonicFail: {
1390 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1391 std::string Suggestion = RISCVMnemonicSpellCheck(
1392 ((RISCVOperand &)*Operands[0]).getToken(), FBS, 0);
1393 return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion);
1394 }
1395 case Match_InvalidOperand: {
1396 SMLoc ErrorLoc = IDLoc;
1397 if (ErrorInfo != ~0ULL) {
1398 if (ErrorInfo >= Operands.size())
1399 return Error(ErrorLoc, "too few operands for instruction");
1400
1401 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1402 if (ErrorLoc == SMLoc())
1403 ErrorLoc = IDLoc;
1404 }
1405 return Error(ErrorLoc, "invalid operand for instruction");
1406 }
1407 }
1408
1409 // Handle the case when the error message is of specific type
1410 // other than the generic Match_InvalidOperand, and the
1411 // corresponding operand is missing.
1412 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1413 SMLoc ErrorLoc = IDLoc;
1414 if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.size())
1415 return Error(ErrorLoc, "too few operands for instruction");
1416 }
1417
1418 switch (Result) {
1419 default:
1420 break;
1421 case Match_RequiresEvenGPRs:
1422 return Error(IDLoc,
1423 "double precision floating point operands must use even "
1424 "numbered X register");
1425 case Match_InvalidImmXLenLI:
1426 if (isRV64()) {
1427 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1428 return Error(ErrorLoc, "operand must be a constant 64-bit integer");
1429 }
1430 return generateImmOutOfRangeError(Operands, ErrorInfo,
1431 std::numeric_limits<int32_t>::min(),
1432 std::numeric_limits<uint32_t>::max());
1433 case Match_InvalidImmXLenLI_Restricted:
1434 if (isRV64()) {
1435 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1436 return Error(ErrorLoc, "operand either must be a constant 64-bit integer "
1437 "or a bare symbol name");
1438 }
1439 return generateImmOutOfRangeError(
1440 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1441 std::numeric_limits<uint32_t>::max(),
1442 "operand either must be a bare symbol name or an immediate integer in "
1443 "the range");
1444 case Match_InvalidImmZero: {
1445 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1446 return Error(ErrorLoc, "immediate must be zero");
1447 }
1448 case Match_InvalidUImmLog2XLen:
1449 if (isRV64())
1450 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1451 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1452 case Match_InvalidUImmLog2XLenNonZero:
1453 if (isRV64())
1454 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
1455 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1456 case Match_InvalidUImmLog2XLenHalf:
1457 if (isRV64())
1458 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1459 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1460 case Match_InvalidUImm1:
1461 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
1462 case Match_InvalidUImm2:
1463 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
1464 case Match_InvalidUImm2Lsb0:
1465 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 2,
1466 "immediate must be one of");
1467 case Match_InvalidUImm3:
1468 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
1469 case Match_InvalidUImm4:
1470 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1471 case Match_InvalidUImm5:
1472 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1473 case Match_InvalidUImm6:
1474 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1475 case Match_InvalidUImm7:
1476 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
1477 case Match_InvalidUImm8:
1478 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
1479 case Match_InvalidUImm8GE32:
1480 return generateImmOutOfRangeError(Operands, ErrorInfo, 32, (1 << 8) - 1);
1481 case Match_InvalidSImm5:
1482 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),
1483 (1 << 4) - 1);
1484 case Match_InvalidSImm6:
1485 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
1486 (1 << 5) - 1);
1487 case Match_InvalidSImm6NonZero:
1488 return generateImmOutOfRangeError(
1489 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1490 "immediate must be non-zero in the range");
1491 case Match_InvalidCLUIImm:
1492 return generateImmOutOfRangeError(
1493 Operands, ErrorInfo, 1, (1 << 5) - 1,
1494 "immediate must be in [0xfffe0, 0xfffff] or");
1495 case Match_InvalidUImm7Lsb00:
1496 return generateImmOutOfRangeError(
1497 Operands, ErrorInfo, 0, (1 << 7) - 4,
1498 "immediate must be a multiple of 4 bytes in the range");
1499 case Match_InvalidUImm8Lsb00:
1500 return generateImmOutOfRangeError(
1501 Operands, ErrorInfo, 0, (1 << 8) - 4,
1502 "immediate must be a multiple of 4 bytes in the range");
1503 case Match_InvalidUImm8Lsb000:
1504 return generateImmOutOfRangeError(
1505 Operands, ErrorInfo, 0, (1 << 8) - 8,
1506 "immediate must be a multiple of 8 bytes in the range");
1507 case Match_InvalidSImm9Lsb0:
1508 return generateImmOutOfRangeError(
1509 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1510 "immediate must be a multiple of 2 bytes in the range");
1511 case Match_InvalidUImm9Lsb000:
1512 return generateImmOutOfRangeError(
1513 Operands, ErrorInfo, 0, (1 << 9) - 8,
1514 "immediate must be a multiple of 8 bytes in the range");
1515 case Match_InvalidUImm10Lsb00NonZero:
1516 return generateImmOutOfRangeError(
1517 Operands, ErrorInfo, 4, (1 << 10) - 4,
1518 "immediate must be a multiple of 4 bytes in the range");
1519 case Match_InvalidSImm10Lsb0000NonZero:
1520 return generateImmOutOfRangeError(
1521 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1522 "immediate must be a multiple of 16 bytes and non-zero in the range");
1523 case Match_InvalidSImm12:
1524 return generateImmOutOfRangeError(
1525 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1526 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1527 "integer in the range");
1528 case Match_InvalidSImm12Lsb0:
1529 return generateImmOutOfRangeError(
1530 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1531 "immediate must be a multiple of 2 bytes in the range");
1532 case Match_InvalidSImm12Lsb00000:
1533 return generateImmOutOfRangeError(
1534 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32,
1535 "immediate must be a multiple of 32 bytes in the range");
1536 case Match_InvalidSImm13Lsb0:
1537 return generateImmOutOfRangeError(
1538 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1539 "immediate must be a multiple of 2 bytes in the range");
1540 case Match_InvalidUImm20LUI:
1541 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1,
1542 "operand must be a symbol with "
1543 "%hi/%tprel_hi modifier or an integer in "
1544 "the range");
1545 case Match_InvalidUImm20:
1546 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
1547 case Match_InvalidUImm20AUIPC:
1548 return generateImmOutOfRangeError(
1549 Operands, ErrorInfo, 0, (1 << 20) - 1,
1550 "operand must be a symbol with a "
1551 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1552 "an integer in the range");
1553 case Match_InvalidSImm21Lsb0JAL:
1554 return generateImmOutOfRangeError(
1555 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1556 "immediate must be a multiple of 2 bytes in the range");
1557 case Match_InvalidCSRSystemRegister: {
1558 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
1559 "operand must be a valid system register "
1560 "name or an integer in the range");
1561 }
1562 case Match_InvalidLoadFPImm: {
1563 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1564 return Error(ErrorLoc, "operand must be a valid floating-point constant");
1565 }
1566 case Match_InvalidBareSymbol: {
1567 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1568 return Error(ErrorLoc, "operand must be a bare symbol name");
1569 }
1570 case Match_InvalidPseudoJumpSymbol: {
1571 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1572 return Error(ErrorLoc, "operand must be a valid jump target");
1573 }
1574 case Match_InvalidCallSymbol: {
1575 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1576 return Error(ErrorLoc, "operand must be a bare symbol name");
1577 }
1578 case Match_InvalidTPRelAddSymbol: {
1579 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1580 return Error(ErrorLoc, "operand must be a symbol with %tprel_add modifier");
1581 }
1582 case Match_InvalidTLSDESCCallSymbol: {
1583 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1584 return Error(ErrorLoc,
1585 "operand must be a symbol with %tlsdesc_call modifier");
1586 }
1587 case Match_InvalidRTZArg: {
1588 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1589 return Error(ErrorLoc, "operand must be 'rtz' floating-point rounding mode");
1590 }
1591 case Match_InvalidVTypeI: {
1592 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1593 return generateVTypeError(ErrorLoc);
1594 }
1595 case Match_InvalidVMaskRegister: {
1596 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1597 return Error(ErrorLoc, "operand must be v0.t");
1598 }
1599 case Match_InvalidSImm5Plus1: {
1600 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,
1601 (1 << 4),
1602 "immediate must be in the range");
1603 }
1604 case Match_InvalidRlist: {
1605 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1606 return Error(
1607 ErrorLoc,
1608 "operand must be {ra [, s0[-sN]]} or {x1 [, x8[-x9][, x18[-xN]]]}");
1609 }
1610 case Match_InvalidSpimm: {
1611 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1612 return Error(
1613 ErrorLoc,
1614 "stack adjustment is invalid for this instruction and register list; "
1615 "refer to Zc spec for a detailed range of stack adjustment");
1616 }
1617 case Match_InvalidRnumArg: {
1618 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
1619 }
1620 case Match_InvalidRegReg: {
1621 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1622 return Error(ErrorLoc, "operands must be register and register");
1623 }
1624 }
1625
1626 llvm_unreachable("Unknown match type detected!");
1627 }
1628
1629 // Attempts to match Name as a register (either using the default name or
1630 // alternative ABI names), setting RegNo to the matching register. Upon
1631 // failure, returns a non-valid MCRegister. If IsRVE, then registers x16-x31
1632 // will be rejected.
matchRegisterNameHelper(bool IsRVE,StringRef Name)1633 static MCRegister matchRegisterNameHelper(bool IsRVE, StringRef Name) {
1634 MCRegister Reg = MatchRegisterName(Name);
1635 // The 16-/32- and 64-bit FPRs have the same asm name. Check that the initial
1636 // match always matches the 64-bit variant, and not the 16/32-bit one.
1637 assert(!(Reg >= RISCV::F0_H && Reg <= RISCV::F31_H));
1638 assert(!(Reg >= RISCV::F0_F && Reg <= RISCV::F31_F));
1639 // The default FPR register class is based on the tablegen enum ordering.
1640 static_assert(RISCV::F0_D < RISCV::F0_H, "FPR matching must be updated");
1641 static_assert(RISCV::F0_D < RISCV::F0_F, "FPR matching must be updated");
1642 if (!Reg)
1643 Reg = MatchRegisterAltName(Name);
1644 if (IsRVE && Reg >= RISCV::X16 && Reg <= RISCV::X31)
1645 Reg = RISCV::NoRegister;
1646 return Reg;
1647 }
1648
parseRegister(MCRegister & Reg,SMLoc & StartLoc,SMLoc & EndLoc)1649 bool RISCVAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
1650 SMLoc &EndLoc) {
1651 if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())
1652 return Error(StartLoc, "invalid register name");
1653 return false;
1654 }
1655
tryParseRegister(MCRegister & Reg,SMLoc & StartLoc,SMLoc & EndLoc)1656 ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
1657 SMLoc &EndLoc) {
1658 const AsmToken &Tok = getParser().getTok();
1659 StartLoc = Tok.getLoc();
1660 EndLoc = Tok.getEndLoc();
1661 StringRef Name = getLexer().getTok().getIdentifier();
1662
1663 Reg = matchRegisterNameHelper(isRVE(), Name);
1664 if (!Reg)
1665 return ParseStatus::NoMatch;
1666
1667 getParser().Lex(); // Eat identifier token.
1668 return ParseStatus::Success;
1669 }
1670
parseRegister(OperandVector & Operands,bool AllowParens)1671 ParseStatus RISCVAsmParser::parseRegister(OperandVector &Operands,
1672 bool AllowParens) {
1673 SMLoc FirstS = getLoc();
1674 bool HadParens = false;
1675 AsmToken LParen;
1676
1677 // If this is an LParen and a parenthesised register name is allowed, parse it
1678 // atomically.
1679 if (AllowParens && getLexer().is(AsmToken::LParen)) {
1680 AsmToken Buf[2];
1681 size_t ReadCount = getLexer().peekTokens(Buf);
1682 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) {
1683 HadParens = true;
1684 LParen = getParser().getTok();
1685 getParser().Lex(); // Eat '('
1686 }
1687 }
1688
1689 switch (getLexer().getKind()) {
1690 default:
1691 if (HadParens)
1692 getLexer().UnLex(LParen);
1693 return ParseStatus::NoMatch;
1694 case AsmToken::Identifier:
1695 StringRef Name = getLexer().getTok().getIdentifier();
1696 MCRegister RegNo = matchRegisterNameHelper(isRVE(), Name);
1697
1698 if (!RegNo) {
1699 if (HadParens)
1700 getLexer().UnLex(LParen);
1701 return ParseStatus::NoMatch;
1702 }
1703 if (HadParens)
1704 Operands.push_back(RISCVOperand::createToken("(", FirstS));
1705 SMLoc S = getLoc();
1706 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size());
1707 getLexer().Lex();
1708 Operands.push_back(RISCVOperand::createReg(RegNo, S, E));
1709 }
1710
1711 if (HadParens) {
1712 getParser().Lex(); // Eat ')'
1713 Operands.push_back(RISCVOperand::createToken(")", getLoc()));
1714 }
1715
1716 return ParseStatus::Success;
1717 }
1718
parseInsnDirectiveOpcode(OperandVector & Operands)1719 ParseStatus RISCVAsmParser::parseInsnDirectiveOpcode(OperandVector &Operands) {
1720 SMLoc S = getLoc();
1721 SMLoc E;
1722 const MCExpr *Res;
1723
1724 switch (getLexer().getKind()) {
1725 default:
1726 return ParseStatus::NoMatch;
1727 case AsmToken::LParen:
1728 case AsmToken::Minus:
1729 case AsmToken::Plus:
1730 case AsmToken::Exclaim:
1731 case AsmToken::Tilde:
1732 case AsmToken::Integer:
1733 case AsmToken::String: {
1734 if (getParser().parseExpression(Res, E))
1735 return ParseStatus::Failure;
1736
1737 auto *CE = dyn_cast<MCConstantExpr>(Res);
1738 if (CE) {
1739 int64_t Imm = CE->getValue();
1740 if (isUInt<7>(Imm)) {
1741 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1742 return ParseStatus::Success;
1743 }
1744 }
1745
1746 break;
1747 }
1748 case AsmToken::Identifier: {
1749 StringRef Identifier;
1750 if (getParser().parseIdentifier(Identifier))
1751 return ParseStatus::Failure;
1752
1753 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1754 if (Opcode) {
1755 assert(isUInt<7>(Opcode->Value) && (Opcode->Value & 0x3) == 3 &&
1756 "Unexpected opcode");
1757 Res = MCConstantExpr::create(Opcode->Value, getContext());
1758 E = SMLoc::getFromPointer(S.getPointer() + Identifier.size());
1759 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1760 return ParseStatus::Success;
1761 }
1762
1763 break;
1764 }
1765 case AsmToken::Percent:
1766 break;
1767 }
1768
1769 return generateImmOutOfRangeError(
1770 S, 0, 127,
1771 "opcode must be a valid opcode name or an immediate in the range");
1772 }
1773
parseInsnCDirectiveOpcode(OperandVector & Operands)1774 ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(OperandVector &Operands) {
1775 SMLoc S = getLoc();
1776 SMLoc E;
1777 const MCExpr *Res;
1778
1779 switch (getLexer().getKind()) {
1780 default:
1781 return ParseStatus::NoMatch;
1782 case AsmToken::LParen:
1783 case AsmToken::Minus:
1784 case AsmToken::Plus:
1785 case AsmToken::Exclaim:
1786 case AsmToken::Tilde:
1787 case AsmToken::Integer:
1788 case AsmToken::String: {
1789 if (getParser().parseExpression(Res, E))
1790 return ParseStatus::Failure;
1791
1792 auto *CE = dyn_cast<MCConstantExpr>(Res);
1793 if (CE) {
1794 int64_t Imm = CE->getValue();
1795 if (Imm >= 0 && Imm <= 2) {
1796 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1797 return ParseStatus::Success;
1798 }
1799 }
1800
1801 break;
1802 }
1803 case AsmToken::Identifier: {
1804 StringRef Identifier;
1805 if (getParser().parseIdentifier(Identifier))
1806 return ParseStatus::Failure;
1807
1808 unsigned Opcode;
1809 if (Identifier == "C0")
1810 Opcode = 0;
1811 else if (Identifier == "C1")
1812 Opcode = 1;
1813 else if (Identifier == "C2")
1814 Opcode = 2;
1815 else
1816 break;
1817
1818 Res = MCConstantExpr::create(Opcode, getContext());
1819 E = SMLoc::getFromPointer(S.getPointer() + Identifier.size());
1820 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1821 return ParseStatus::Success;
1822 }
1823 case AsmToken::Percent: {
1824 // Discard operand with modifier.
1825 break;
1826 }
1827 }
1828
1829 return generateImmOutOfRangeError(
1830 S, 0, 2,
1831 "opcode must be a valid opcode name or an immediate in the range");
1832 }
1833
parseCSRSystemRegister(OperandVector & Operands)1834 ParseStatus RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) {
1835 SMLoc S = getLoc();
1836 const MCExpr *Res;
1837
1838 switch (getLexer().getKind()) {
1839 default:
1840 return ParseStatus::NoMatch;
1841 case AsmToken::LParen:
1842 case AsmToken::Minus:
1843 case AsmToken::Plus:
1844 case AsmToken::Exclaim:
1845 case AsmToken::Tilde:
1846 case AsmToken::Integer:
1847 case AsmToken::String: {
1848 if (getParser().parseExpression(Res))
1849 return ParseStatus::Failure;
1850
1851 auto *CE = dyn_cast<MCConstantExpr>(Res);
1852 if (CE) {
1853 int64_t Imm = CE->getValue();
1854 if (isUInt<12>(Imm)) {
1855 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
1856 // Accept an immediate representing a named or un-named Sys Reg
1857 // if the range is valid, regardless of the required features.
1858 Operands.push_back(
1859 RISCVOperand::createSysReg(SysReg ? SysReg->Name : "", S, Imm));
1860 return ParseStatus::Success;
1861 }
1862 }
1863
1864 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1865 }
1866 case AsmToken::Identifier: {
1867 StringRef Identifier;
1868 if (getParser().parseIdentifier(Identifier))
1869 return ParseStatus::Failure;
1870
1871 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1872 if (!SysReg)
1873 SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
1874 if (!SysReg)
1875 if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
1876 Warning(S, "'" + Identifier + "' is a deprecated alias for '" +
1877 SysReg->Name + "'");
1878
1879 // Accept a named Sys Reg if the required features are present.
1880 if (SysReg) {
1881 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits()))
1882 return Error(S, "system register use requires an option to be enabled");
1883 Operands.push_back(
1884 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
1885 return ParseStatus::Success;
1886 }
1887
1888 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
1889 "operand must be a valid system register "
1890 "name or an integer in the range");
1891 }
1892 case AsmToken::Percent: {
1893 // Discard operand with modifier.
1894 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1895 }
1896 }
1897
1898 return ParseStatus::NoMatch;
1899 }
1900
parseFPImm(OperandVector & Operands)1901 ParseStatus RISCVAsmParser::parseFPImm(OperandVector &Operands) {
1902 SMLoc S = getLoc();
1903
1904 // Parse special floats (inf/nan/min) representation.
1905 if (getTok().is(AsmToken::Identifier)) {
1906 StringRef Identifier = getTok().getIdentifier();
1907 if (Identifier.compare_insensitive("inf") == 0) {
1908 Operands.push_back(
1909 RISCVOperand::createImm(MCConstantExpr::create(30, getContext()), S,
1910 getTok().getEndLoc(), isRV64()));
1911 } else if (Identifier.compare_insensitive("nan") == 0) {
1912 Operands.push_back(
1913 RISCVOperand::createImm(MCConstantExpr::create(31, getContext()), S,
1914 getTok().getEndLoc(), isRV64()));
1915 } else if (Identifier.compare_insensitive("min") == 0) {
1916 Operands.push_back(
1917 RISCVOperand::createImm(MCConstantExpr::create(1, getContext()), S,
1918 getTok().getEndLoc(), isRV64()));
1919 } else {
1920 return TokError("invalid floating point literal");
1921 }
1922
1923 Lex(); // Eat the token.
1924
1925 return ParseStatus::Success;
1926 }
1927
1928 // Handle negation, as that still comes through as a separate token.
1929 bool IsNegative = parseOptionalToken(AsmToken::Minus);
1930
1931 const AsmToken &Tok = getTok();
1932 if (!Tok.is(AsmToken::Real))
1933 return TokError("invalid floating point immediate");
1934
1935 // Parse FP representation.
1936 APFloat RealVal(APFloat::IEEEdouble());
1937 auto StatusOrErr =
1938 RealVal.convertFromString(Tok.getString(), APFloat::rmTowardZero);
1939 if (errorToBool(StatusOrErr.takeError()))
1940 return TokError("invalid floating point representation");
1941
1942 if (IsNegative)
1943 RealVal.changeSign();
1944
1945 Operands.push_back(RISCVOperand::createFPImm(
1946 RealVal.bitcastToAPInt().getZExtValue(), S));
1947
1948 Lex(); // Eat the token.
1949
1950 return ParseStatus::Success;
1951 }
1952
parseImmediate(OperandVector & Operands)1953 ParseStatus RISCVAsmParser::parseImmediate(OperandVector &Operands) {
1954 SMLoc S = getLoc();
1955 SMLoc E;
1956 const MCExpr *Res;
1957
1958 switch (getLexer().getKind()) {
1959 default:
1960 return ParseStatus::NoMatch;
1961 case AsmToken::LParen:
1962 case AsmToken::Dot:
1963 case AsmToken::Minus:
1964 case AsmToken::Plus:
1965 case AsmToken::Exclaim:
1966 case AsmToken::Tilde:
1967 case AsmToken::Integer:
1968 case AsmToken::String:
1969 case AsmToken::Identifier:
1970 if (getParser().parseExpression(Res, E))
1971 return ParseStatus::Failure;
1972 break;
1973 case AsmToken::Percent:
1974 return parseOperandWithModifier(Operands);
1975 }
1976
1977 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
1978 return ParseStatus::Success;
1979 }
1980
parseOperandWithModifier(OperandVector & Operands)1981 ParseStatus RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) {
1982 SMLoc S = getLoc();
1983 SMLoc E;
1984
1985 if (parseToken(AsmToken::Percent, "expected '%' for operand modifier"))
1986 return ParseStatus::Failure;
1987
1988 if (getLexer().getKind() != AsmToken::Identifier)
1989 return Error(getLoc(), "expected valid identifier for operand modifier");
1990 StringRef Identifier = getParser().getTok().getIdentifier();
1991 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier);
1992 if (VK == RISCVMCExpr::VK_RISCV_Invalid)
1993 return Error(getLoc(), "unrecognized operand modifier");
1994
1995 getParser().Lex(); // Eat the identifier
1996 if (parseToken(AsmToken::LParen, "expected '('"))
1997 return ParseStatus::Failure;
1998
1999 const MCExpr *SubExpr;
2000 if (getParser().parseParenExpression(SubExpr, E))
2001 return ParseStatus::Failure;
2002
2003 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext());
2004 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64()));
2005 return ParseStatus::Success;
2006 }
2007
parseBareSymbol(OperandVector & Operands)2008 ParseStatus RISCVAsmParser::parseBareSymbol(OperandVector &Operands) {
2009 SMLoc S = getLoc();
2010 const MCExpr *Res;
2011
2012 if (getLexer().getKind() != AsmToken::Identifier)
2013 return ParseStatus::NoMatch;
2014
2015 StringRef Identifier;
2016 AsmToken Tok = getLexer().getTok();
2017
2018 if (getParser().parseIdentifier(Identifier))
2019 return ParseStatus::Failure;
2020
2021 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Identifier.size());
2022
2023 if (Identifier.consume_back("@plt"))
2024 return Error(getLoc(), "'@plt' operand not valid for instruction");
2025
2026 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
2027
2028 if (Sym->isVariable()) {
2029 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false);
2030 if (!isa<MCSymbolRefExpr>(V)) {
2031 getLexer().UnLex(Tok); // Put back if it's not a bare symbol.
2032 return ParseStatus::NoMatch;
2033 }
2034 Res = V;
2035 } else
2036 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
2037
2038 MCBinaryExpr::Opcode Opcode;
2039 switch (getLexer().getKind()) {
2040 default:
2041 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
2042 return ParseStatus::Success;
2043 case AsmToken::Plus:
2044 Opcode = MCBinaryExpr::Add;
2045 getLexer().Lex();
2046 break;
2047 case AsmToken::Minus:
2048 Opcode = MCBinaryExpr::Sub;
2049 getLexer().Lex();
2050 break;
2051 }
2052
2053 const MCExpr *Expr;
2054 if (getParser().parseExpression(Expr, E))
2055 return ParseStatus::Failure;
2056 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext());
2057 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
2058 return ParseStatus::Success;
2059 }
2060
parseCallSymbol(OperandVector & Operands)2061 ParseStatus RISCVAsmParser::parseCallSymbol(OperandVector &Operands) {
2062 SMLoc S = getLoc();
2063 const MCExpr *Res;
2064
2065 if (getLexer().getKind() != AsmToken::Identifier)
2066 return ParseStatus::NoMatch;
2067
2068 // Avoid parsing the register in `call rd, foo` as a call symbol.
2069 if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement)
2070 return ParseStatus::NoMatch;
2071
2072 StringRef Identifier;
2073 if (getParser().parseIdentifier(Identifier))
2074 return ParseStatus::Failure;
2075
2076 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Identifier.size());
2077
2078 RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_CALL_PLT;
2079 (void)Identifier.consume_back("@plt");
2080
2081 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
2082 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
2083 Res = RISCVMCExpr::create(Res, Kind, getContext());
2084 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
2085 return ParseStatus::Success;
2086 }
2087
parsePseudoJumpSymbol(OperandVector & Operands)2088 ParseStatus RISCVAsmParser::parsePseudoJumpSymbol(OperandVector &Operands) {
2089 SMLoc S = getLoc();
2090 SMLoc E;
2091 const MCExpr *Res;
2092
2093 if (getParser().parseExpression(Res, E))
2094 return ParseStatus::Failure;
2095
2096 if (Res->getKind() != MCExpr::ExprKind::SymbolRef ||
2097 cast<MCSymbolRefExpr>(Res)->getKind() ==
2098 MCSymbolRefExpr::VariantKind::VK_PLT)
2099 return Error(S, "operand must be a valid jump target");
2100
2101 Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext());
2102 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64()));
2103 return ParseStatus::Success;
2104 }
2105
parseJALOffset(OperandVector & Operands)2106 ParseStatus RISCVAsmParser::parseJALOffset(OperandVector &Operands) {
2107 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo`
2108 // both being acceptable forms. When parsing `jal ra, foo` this function
2109 // will be called for the `ra` register operand in an attempt to match the
2110 // single-operand alias. parseJALOffset must fail for this case. It would
2111 // seem logical to try parse the operand using parseImmediate and return
2112 // NoMatch if the next token is a comma (meaning we must be parsing a jal in
2113 // the second form rather than the first). We can't do this as there's no
2114 // way of rewinding the lexer state. Instead, return NoMatch if this operand
2115 // is an identifier and is followed by a comma.
2116 if (getLexer().is(AsmToken::Identifier) &&
2117 getLexer().peekTok().is(AsmToken::Comma))
2118 return ParseStatus::NoMatch;
2119
2120 return parseImmediate(Operands);
2121 }
2122
parseVTypeToken(StringRef Identifier,VTypeState & State,unsigned & Sew,unsigned & Lmul,bool & Fractional,bool & TailAgnostic,bool & MaskAgnostic)2123 bool RISCVAsmParser::parseVTypeToken(StringRef Identifier, VTypeState &State,
2124 unsigned &Sew, unsigned &Lmul,
2125 bool &Fractional, bool &TailAgnostic,
2126 bool &MaskAgnostic) {
2127 switch (State) {
2128 case VTypeState_SEW:
2129 if (!Identifier.consume_front("e"))
2130 break;
2131 if (Identifier.getAsInteger(10, Sew))
2132 break;
2133 if (!RISCVVType::isValidSEW(Sew))
2134 break;
2135 State = VTypeState_LMUL;
2136 return false;
2137 case VTypeState_LMUL: {
2138 if (!Identifier.consume_front("m"))
2139 break;
2140 Fractional = Identifier.consume_front("f");
2141 if (Identifier.getAsInteger(10, Lmul))
2142 break;
2143 if (!RISCVVType::isValidLMUL(Lmul, Fractional))
2144 break;
2145 State = VTypeState_TailPolicy;
2146 return false;
2147 }
2148 case VTypeState_TailPolicy:
2149 if (Identifier == "ta")
2150 TailAgnostic = true;
2151 else if (Identifier == "tu")
2152 TailAgnostic = false;
2153 else
2154 break;
2155 State = VTypeState_MaskPolicy;
2156 return false;
2157 case VTypeState_MaskPolicy:
2158 if (Identifier == "ma")
2159 MaskAgnostic = true;
2160 else if (Identifier == "mu")
2161 MaskAgnostic = false;
2162 else
2163 break;
2164 State = VTypeState_Done;
2165 return false;
2166 case VTypeState_Done:
2167 // Extra token?
2168 break;
2169 }
2170
2171 return true;
2172 }
2173
parseVTypeI(OperandVector & Operands)2174 ParseStatus RISCVAsmParser::parseVTypeI(OperandVector &Operands) {
2175 SMLoc S = getLoc();
2176
2177 unsigned Sew = 0;
2178 unsigned Lmul = 0;
2179 bool Fractional = false;
2180 bool TailAgnostic = false;
2181 bool MaskAgnostic = false;
2182
2183 VTypeState State = VTypeState_SEW;
2184
2185 if (getLexer().isNot(AsmToken::Identifier))
2186 return ParseStatus::NoMatch;
2187
2188 StringRef Identifier = getTok().getIdentifier();
2189
2190 if (parseVTypeToken(Identifier, State, Sew, Lmul, Fractional, TailAgnostic,
2191 MaskAgnostic))
2192 return ParseStatus::NoMatch;
2193
2194 getLexer().Lex();
2195
2196 while (parseOptionalToken(AsmToken::Comma)) {
2197 if (getLexer().isNot(AsmToken::Identifier))
2198 break;
2199
2200 Identifier = getTok().getIdentifier();
2201
2202 if (parseVTypeToken(Identifier, State, Sew, Lmul, Fractional, TailAgnostic,
2203 MaskAgnostic))
2204 break;
2205
2206 getLexer().Lex();
2207 }
2208
2209 if (getLexer().is(AsmToken::EndOfStatement) && State == VTypeState_Done) {
2210 RISCVII::VLMUL VLMUL = RISCVVType::encodeLMUL(Lmul, Fractional);
2211
2212 unsigned VTypeI =
2213 RISCVVType::encodeVTYPE(VLMUL, Sew, TailAgnostic, MaskAgnostic);
2214 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2215 return ParseStatus::Success;
2216 }
2217
2218 return generateVTypeError(S);
2219 }
2220
generateVTypeError(SMLoc ErrorLoc)2221 bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2222 return Error(
2223 ErrorLoc,
2224 "operand must be "
2225 "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2226 }
2227
parseMaskReg(OperandVector & Operands)2228 ParseStatus RISCVAsmParser::parseMaskReg(OperandVector &Operands) {
2229 if (getLexer().isNot(AsmToken::Identifier))
2230 return ParseStatus::NoMatch;
2231
2232 StringRef Name = getLexer().getTok().getIdentifier();
2233 if (!Name.consume_back(".t"))
2234 return Error(getLoc(), "expected '.t' suffix");
2235 MCRegister RegNo = matchRegisterNameHelper(isRVE(), Name);
2236
2237 if (!RegNo)
2238 return ParseStatus::NoMatch;
2239 if (RegNo != RISCV::V0)
2240 return ParseStatus::NoMatch;
2241 SMLoc S = getLoc();
2242 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size());
2243 getLexer().Lex();
2244 Operands.push_back(RISCVOperand::createReg(RegNo, S, E));
2245 return ParseStatus::Success;
2246 }
2247
parseGPRAsFPR(OperandVector & Operands)2248 ParseStatus RISCVAsmParser::parseGPRAsFPR(OperandVector &Operands) {
2249 if (getLexer().isNot(AsmToken::Identifier))
2250 return ParseStatus::NoMatch;
2251
2252 StringRef Name = getLexer().getTok().getIdentifier();
2253 MCRegister RegNo = matchRegisterNameHelper(isRVE(), Name);
2254
2255 if (!RegNo)
2256 return ParseStatus::NoMatch;
2257 SMLoc S = getLoc();
2258 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size());
2259 getLexer().Lex();
2260 Operands.push_back(RISCVOperand::createReg(
2261 RegNo, S, E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2262 return ParseStatus::Success;
2263 }
2264
2265 template <bool IsRV64>
parseGPRPair(OperandVector & Operands)2266 ParseStatus RISCVAsmParser::parseGPRPair(OperandVector &Operands) {
2267 return parseGPRPair(Operands, IsRV64);
2268 }
2269
parseGPRPair(OperandVector & Operands,bool IsRV64Inst)2270 ParseStatus RISCVAsmParser::parseGPRPair(OperandVector &Operands,
2271 bool IsRV64Inst) {
2272 // If this is not an RV64 GPRPair instruction, don't parse as a GPRPair on
2273 // RV64 as it will prevent matching the RV64 version of the same instruction
2274 // that doesn't use a GPRPair.
2275 // If this is an RV64 GPRPair instruction, there is no RV32 version so we can
2276 // still parse as a pair.
2277 if (!IsRV64Inst && isRV64())
2278 return ParseStatus::NoMatch;
2279
2280 if (getLexer().isNot(AsmToken::Identifier))
2281 return ParseStatus::NoMatch;
2282
2283 StringRef Name = getLexer().getTok().getIdentifier();
2284 MCRegister RegNo = matchRegisterNameHelper(isRVE(), Name);
2285
2286 if (!RegNo)
2287 return ParseStatus::NoMatch;
2288
2289 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(RegNo))
2290 return ParseStatus::NoMatch;
2291
2292 if ((RegNo - RISCV::X0) & 1)
2293 return TokError("register must be even");
2294
2295 SMLoc S = getLoc();
2296 SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size());
2297 getLexer().Lex();
2298
2299 const MCRegisterInfo *RI = getContext().getRegisterInfo();
2300 unsigned Pair = RI->getMatchingSuperReg(
2301 RegNo, RISCV::sub_gpr_even,
2302 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2303 Operands.push_back(RISCVOperand::createReg(Pair, S, E));
2304 return ParseStatus::Success;
2305 }
2306
parseFRMArg(OperandVector & Operands)2307 ParseStatus RISCVAsmParser::parseFRMArg(OperandVector &Operands) {
2308 if (getLexer().isNot(AsmToken::Identifier))
2309 return TokError(
2310 "operand must be a valid floating point rounding mode mnemonic");
2311
2312 StringRef Str = getLexer().getTok().getIdentifier();
2313 RISCVFPRndMode::RoundingMode FRM = RISCVFPRndMode::stringToRoundingMode(Str);
2314
2315 if (FRM == RISCVFPRndMode::Invalid)
2316 return TokError(
2317 "operand must be a valid floating point rounding mode mnemonic");
2318
2319 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2320 Lex(); // Eat identifier token.
2321 return ParseStatus::Success;
2322 }
2323
parseFenceArg(OperandVector & Operands)2324 ParseStatus RISCVAsmParser::parseFenceArg(OperandVector &Operands) {
2325 const AsmToken &Tok = getLexer().getTok();
2326
2327 if (Tok.is(AsmToken::Integer)) {
2328 if (Tok.getIntVal() != 0)
2329 goto ParseFail;
2330
2331 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2332 Lex();
2333 return ParseStatus::Success;
2334 }
2335
2336 if (Tok.is(AsmToken::Identifier)) {
2337 StringRef Str = Tok.getIdentifier();
2338
2339 // Letters must be unique, taken from 'iorw', and in ascending order. This
2340 // holds as long as each individual character is one of 'iorw' and is
2341 // greater than the previous character.
2342 unsigned Imm = 0;
2343 bool Valid = true;
2344 char Prev = '\0';
2345 for (char c : Str) {
2346 switch (c) {
2347 default:
2348 Valid = false;
2349 break;
2350 case 'i':
2351 Imm |= RISCVFenceField::I;
2352 break;
2353 case 'o':
2354 Imm |= RISCVFenceField::O;
2355 break;
2356 case 'r':
2357 Imm |= RISCVFenceField::R;
2358 break;
2359 case 'w':
2360 Imm |= RISCVFenceField::W;
2361 break;
2362 }
2363
2364 if (c <= Prev) {
2365 Valid = false;
2366 break;
2367 }
2368 Prev = c;
2369 }
2370
2371 if (!Valid)
2372 goto ParseFail;
2373
2374 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2375 Lex();
2376 return ParseStatus::Success;
2377 }
2378
2379 ParseFail:
2380 return TokError("operand must be formed of letters selected in-order from "
2381 "'iorw' or be 0");
2382 }
2383
parseMemOpBaseReg(OperandVector & Operands)2384 ParseStatus RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) {
2385 if (parseToken(AsmToken::LParen, "expected '('"))
2386 return ParseStatus::Failure;
2387 Operands.push_back(RISCVOperand::createToken("(", getLoc()));
2388
2389 if (!parseRegister(Operands).isSuccess())
2390 return Error(getLoc(), "expected register");
2391
2392 if (parseToken(AsmToken::RParen, "expected ')'"))
2393 return ParseStatus::Failure;
2394 Operands.push_back(RISCVOperand::createToken(")", getLoc()));
2395
2396 return ParseStatus::Success;
2397 }
2398
parseZeroOffsetMemOp(OperandVector & Operands)2399 ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(OperandVector &Operands) {
2400 // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand"
2401 // as one of their register operands, such as `(a0)`. This just denotes that
2402 // the register (in this case `a0`) contains a memory address.
2403 //
2404 // Normally, we would be able to parse these by putting the parens into the
2405 // instruction string. However, GNU as also accepts a zero-offset memory
2406 // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed
2407 // with parseImmediate followed by parseMemOpBaseReg, but these instructions
2408 // do not accept an immediate operand, and we do not want to add a "dummy"
2409 // operand that is silently dropped.
2410 //
2411 // Instead, we use this custom parser. This will: allow (and discard) an
2412 // offset if it is zero; require (and discard) parentheses; and add only the
2413 // parsed register operand to `Operands`.
2414 //
2415 // These operands are printed with RISCVInstPrinter::printZeroOffsetMemOp,
2416 // which will only print the register surrounded by parentheses (which GNU as
2417 // also uses as its canonical representation for these operands).
2418 std::unique_ptr<RISCVOperand> OptionalImmOp;
2419
2420 if (getLexer().isNot(AsmToken::LParen)) {
2421 // Parse an Integer token. We do not accept arbritrary constant expressions
2422 // in the offset field (because they may include parens, which complicates
2423 // parsing a lot).
2424 int64_t ImmVal;
2425 SMLoc ImmStart = getLoc();
2426 if (getParser().parseIntToken(ImmVal,
2427 "expected '(' or optional integer offset"))
2428 return ParseStatus::Failure;
2429
2430 // Create a RISCVOperand for checking later (so the error messages are
2431 // nicer), but we don't add it to Operands.
2432 SMLoc ImmEnd = getLoc();
2433 OptionalImmOp =
2434 RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()),
2435 ImmStart, ImmEnd, isRV64());
2436 }
2437
2438 if (parseToken(AsmToken::LParen,
2439 OptionalImmOp ? "expected '(' after optional integer offset"
2440 : "expected '(' or optional integer offset"))
2441 return ParseStatus::Failure;
2442
2443 if (!parseRegister(Operands).isSuccess())
2444 return Error(getLoc(), "expected register");
2445
2446 if (parseToken(AsmToken::RParen, "expected ')'"))
2447 return ParseStatus::Failure;
2448
2449 // Deferred Handling of non-zero offsets. This makes the error messages nicer.
2450 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2451 return Error(
2452 OptionalImmOp->getStartLoc(), "optional integer offset must be 0",
2453 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2454
2455 return ParseStatus::Success;
2456 }
2457
parseRegReg(OperandVector & Operands)2458 ParseStatus RISCVAsmParser::parseRegReg(OperandVector &Operands) {
2459 // RR : a2(a1)
2460 if (getLexer().getKind() != AsmToken::Identifier)
2461 return ParseStatus::NoMatch;
2462
2463 StringRef RegName = getLexer().getTok().getIdentifier();
2464 MCRegister Reg = matchRegisterNameHelper(isRVE(), RegName);
2465 if (!Reg)
2466 return Error(getLoc(), "invalid register");
2467 getLexer().Lex();
2468
2469 if (parseToken(AsmToken::LParen, "expected '(' or invalid operand"))
2470 return ParseStatus::Failure;
2471
2472 if (getLexer().getKind() != AsmToken::Identifier)
2473 return Error(getLoc(), "expected register");
2474
2475 StringRef Reg2Name = getLexer().getTok().getIdentifier();
2476 MCRegister Reg2 = matchRegisterNameHelper(isRVE(), Reg2Name);
2477 if (!Reg2)
2478 return Error(getLoc(), "invalid register");
2479 getLexer().Lex();
2480
2481 if (parseToken(AsmToken::RParen, "expected ')'"))
2482 return ParseStatus::Failure;
2483
2484 Operands.push_back(RISCVOperand::createRegReg(Reg, Reg2, getLoc()));
2485
2486 return ParseStatus::Success;
2487 }
2488
parseReglist(OperandVector & Operands)2489 ParseStatus RISCVAsmParser::parseReglist(OperandVector &Operands) {
2490 // Rlist: {ra [, s0[-sN]]}
2491 // XRlist: {x1 [, x8[-x9][, x18[-xN]]]}
2492 SMLoc S = getLoc();
2493
2494 if (parseToken(AsmToken::LCurly, "register list must start with '{'"))
2495 return ParseStatus::Failure;
2496
2497 bool IsEABI = isRVE();
2498
2499 if (getLexer().isNot(AsmToken::Identifier))
2500 return Error(getLoc(), "register list must start from 'ra' or 'x1'");
2501
2502 StringRef RegName = getLexer().getTok().getIdentifier();
2503 MCRegister RegStart = matchRegisterNameHelper(IsEABI, RegName);
2504 MCRegister RegEnd;
2505 if (RegStart != RISCV::X1)
2506 return Error(getLoc(), "register list must start from 'ra' or 'x1'");
2507 getLexer().Lex();
2508
2509 // parse case like ,s0
2510 if (parseOptionalToken(AsmToken::Comma)) {
2511 if (getLexer().isNot(AsmToken::Identifier))
2512 return Error(getLoc(), "invalid register");
2513 StringRef RegName = getLexer().getTok().getIdentifier();
2514 RegStart = matchRegisterNameHelper(IsEABI, RegName);
2515 if (!RegStart)
2516 return Error(getLoc(), "invalid register");
2517 if (RegStart != RISCV::X8)
2518 return Error(getLoc(),
2519 "continuous register list must start from 's0' or 'x8'");
2520 getLexer().Lex(); // eat reg
2521 }
2522
2523 // parse case like -s1
2524 if (parseOptionalToken(AsmToken::Minus)) {
2525 StringRef EndName = getLexer().getTok().getIdentifier();
2526 // FIXME: the register mapping and checks of EABI is wrong
2527 RegEnd = matchRegisterNameHelper(IsEABI, EndName);
2528 if (!RegEnd)
2529 return Error(getLoc(), "invalid register");
2530 if (IsEABI && RegEnd != RISCV::X9)
2531 return Error(getLoc(), "contiguous register list of EABI can only be "
2532 "'s0-s1' or 'x8-x9' pair");
2533 getLexer().Lex();
2534 }
2535
2536 if (!IsEABI) {
2537 // parse extra part like ', x18[-x20]' for XRegList
2538 if (parseOptionalToken(AsmToken::Comma)) {
2539 if (RegEnd != RISCV::X9)
2540 return Error(
2541 getLoc(),
2542 "first contiguous registers pair of register list must be 'x8-x9'");
2543
2544 // parse ', x18' for extra part
2545 if (getLexer().isNot(AsmToken::Identifier))
2546 return Error(getLoc(), "invalid register");
2547 StringRef EndName = getLexer().getTok().getIdentifier();
2548 if (MatchRegisterName(EndName) != RISCV::X18)
2549 return Error(getLoc(),
2550 "second contiguous registers pair of register list "
2551 "must start from 'x18'");
2552 getLexer().Lex();
2553
2554 // parse '-x20' for extra part
2555 if (parseOptionalToken(AsmToken::Minus)) {
2556 if (getLexer().isNot(AsmToken::Identifier))
2557 return Error(getLoc(), "invalid register");
2558 EndName = getLexer().getTok().getIdentifier();
2559 if (MatchRegisterName(EndName) == RISCV::NoRegister)
2560 return Error(getLoc(), "invalid register");
2561 getLexer().Lex();
2562 }
2563 RegEnd = MatchRegisterName(EndName);
2564 }
2565 }
2566
2567 if (RegEnd == RISCV::X26)
2568 return Error(getLoc(), "invalid register list, {ra, s0-s10} or {x1, x8-x9, "
2569 "x18-x26} is not supported");
2570
2571 if (parseToken(AsmToken::RCurly, "register list must end with '}'"))
2572 return ParseStatus::Failure;
2573
2574 if (RegEnd == RISCV::NoRegister)
2575 RegEnd = RegStart;
2576
2577 auto Encode = RISCVZC::encodeRlist(RegEnd, IsEABI);
2578 if (Encode == 16)
2579 return Error(S, "invalid register list");
2580 Operands.push_back(RISCVOperand::createRlist(Encode, S));
2581
2582 return ParseStatus::Success;
2583 }
2584
parseZcmpSpimm(OperandVector & Operands)2585 ParseStatus RISCVAsmParser::parseZcmpSpimm(OperandVector &Operands) {
2586 (void)parseOptionalToken(AsmToken::Minus);
2587
2588 SMLoc S = getLoc();
2589 int64_t StackAdjustment = getLexer().getTok().getIntVal();
2590 unsigned Spimm = 0;
2591 unsigned RlistVal = static_cast<RISCVOperand *>(Operands[1].get())->Rlist.Val;
2592
2593 bool IsEABI = isRVE();
2594 if (!RISCVZC::getSpimm(RlistVal, Spimm, StackAdjustment, isRV64(), IsEABI))
2595 return ParseStatus::NoMatch;
2596 Operands.push_back(RISCVOperand::createSpimm(Spimm << 4, S));
2597 getLexer().Lex();
2598 return ParseStatus::Success;
2599 }
2600
2601 /// Looks at a token type and creates the relevant operand from this
2602 /// information, adding to Operands. If operand was parsed, returns false, else
2603 /// true.
parseOperand(OperandVector & Operands,StringRef Mnemonic)2604 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2605 // Check if the current operand has a custom associated parser, if so, try to
2606 // custom parse the operand, or fallback to the general approach.
2607 ParseStatus Result =
2608 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true);
2609 if (Result.isSuccess())
2610 return false;
2611 if (Result.isFailure())
2612 return true;
2613
2614 // Attempt to parse token as a register.
2615 if (parseRegister(Operands, true).isSuccess())
2616 return false;
2617
2618 // Attempt to parse token as an immediate
2619 if (parseImmediate(Operands).isSuccess()) {
2620 // Parse memory base register if present
2621 if (getLexer().is(AsmToken::LParen))
2622 return !parseMemOpBaseReg(Operands).isSuccess();
2623 return false;
2624 }
2625
2626 // Finally we have exhausted all options and must declare defeat.
2627 Error(getLoc(), "unknown operand");
2628 return true;
2629 }
2630
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)2631 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info,
2632 StringRef Name, SMLoc NameLoc,
2633 OperandVector &Operands) {
2634 // Ensure that if the instruction occurs when relaxation is enabled,
2635 // relocations are forced for the file. Ideally this would be done when there
2636 // is enough information to reliably determine if the instruction itself may
2637 // cause relaxations. Unfortunately instruction processing stage occurs in the
2638 // same pass as relocation emission, so it's too late to set a 'sticky bit'
2639 // for the entire file.
2640 if (getSTI().hasFeature(RISCV::FeatureRelax)) {
2641 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
2642 if (Assembler != nullptr) {
2643 RISCVAsmBackend &MAB =
2644 static_cast<RISCVAsmBackend &>(Assembler->getBackend());
2645 MAB.setForceRelocs();
2646 }
2647 }
2648
2649 // First operand is token for instruction
2650 Operands.push_back(RISCVOperand::createToken(Name, NameLoc));
2651
2652 // If there are no more operands, then finish
2653 if (getLexer().is(AsmToken::EndOfStatement)) {
2654 getParser().Lex(); // Consume the EndOfStatement.
2655 return false;
2656 }
2657
2658 // Parse first operand
2659 if (parseOperand(Operands, Name))
2660 return true;
2661
2662 // Parse until end of statement, consuming commas between operands
2663 while (parseOptionalToken(AsmToken::Comma)) {
2664 // Parse next operand
2665 if (parseOperand(Operands, Name))
2666 return true;
2667 }
2668
2669 if (getParser().parseEOL("unexpected token")) {
2670 getParser().eatToEndOfStatement();
2671 return true;
2672 }
2673 return false;
2674 }
2675
classifySymbolRef(const MCExpr * Expr,RISCVMCExpr::VariantKind & Kind)2676 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr,
2677 RISCVMCExpr::VariantKind &Kind) {
2678 Kind = RISCVMCExpr::VK_RISCV_None;
2679
2680 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
2681 Kind = RE->getKind();
2682 Expr = RE->getSubExpr();
2683 }
2684
2685 MCValue Res;
2686 MCFixup Fixup;
2687 if (Expr->evaluateAsRelocatable(Res, nullptr, &Fixup))
2688 return Res.getRefKind() == RISCVMCExpr::VK_RISCV_None;
2689 return false;
2690 }
2691
isSymbolDiff(const MCExpr * Expr)2692 bool RISCVAsmParser::isSymbolDiff(const MCExpr *Expr) {
2693 MCValue Res;
2694 MCFixup Fixup;
2695 if (Expr->evaluateAsRelocatable(Res, nullptr, &Fixup)) {
2696 return Res.getRefKind() == RISCVMCExpr::VK_RISCV_None && Res.getSymA() &&
2697 Res.getSymB();
2698 }
2699 return false;
2700 }
2701
parseDirective(AsmToken DirectiveID)2702 ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
2703 StringRef IDVal = DirectiveID.getString();
2704
2705 if (IDVal == ".option")
2706 return parseDirectiveOption();
2707 if (IDVal == ".attribute")
2708 return parseDirectiveAttribute();
2709 if (IDVal == ".insn")
2710 return parseDirectiveInsn(DirectiveID.getLoc());
2711 if (IDVal == ".variant_cc")
2712 return parseDirectiveVariantCC();
2713
2714 return ParseStatus::NoMatch;
2715 }
2716
resetToArch(StringRef Arch,SMLoc Loc,std::string & Result,bool FromOptionDirective)2717 bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
2718 bool FromOptionDirective) {
2719 for (auto Feature : RISCVFeatureKV)
2720 if (llvm::RISCVISAInfo::isSupportedExtensionFeature(Feature.Key))
2721 clearFeatureBits(Feature.Value, Feature.Key);
2722
2723 auto ParseResult = llvm::RISCVISAInfo::parseArchString(
2724 Arch, /*EnableExperimentalExtension=*/true,
2725 /*ExperimentalExtensionVersionCheck=*/true);
2726 if (!ParseResult) {
2727 std::string Buffer;
2728 raw_string_ostream OutputErrMsg(Buffer);
2729 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
2730 OutputErrMsg << "invalid arch name '" << Arch << "', "
2731 << ErrMsg.getMessage();
2732 });
2733
2734 return Error(Loc, OutputErrMsg.str());
2735 }
2736 auto &ISAInfo = *ParseResult;
2737
2738 for (auto Feature : RISCVFeatureKV)
2739 if (ISAInfo->hasExtension(Feature.Key))
2740 setFeatureBits(Feature.Value, Feature.Key);
2741
2742 if (FromOptionDirective) {
2743 if (ISAInfo->getXLen() == 32 && isRV64())
2744 return Error(Loc, "bad arch string switching from rv64 to rv32");
2745 else if (ISAInfo->getXLen() == 64 && !isRV64())
2746 return Error(Loc, "bad arch string switching from rv32 to rv64");
2747 }
2748
2749 if (ISAInfo->getXLen() == 32)
2750 clearFeatureBits(RISCV::Feature64Bit, "64bit");
2751 else if (ISAInfo->getXLen() == 64)
2752 setFeatureBits(RISCV::Feature64Bit, "64bit");
2753 else
2754 return Error(Loc, "bad arch string " + Arch);
2755
2756 Result = ISAInfo->toString();
2757 return false;
2758 }
2759
parseDirectiveOption()2760 bool RISCVAsmParser::parseDirectiveOption() {
2761 MCAsmParser &Parser = getParser();
2762 // Get the option token.
2763 AsmToken Tok = Parser.getTok();
2764
2765 // At the moment only identifiers are supported.
2766 if (parseToken(AsmToken::Identifier, "expected identifier"))
2767 return true;
2768
2769 StringRef Option = Tok.getIdentifier();
2770
2771 if (Option == "push") {
2772 if (Parser.parseEOL())
2773 return true;
2774
2775 getTargetStreamer().emitDirectiveOptionPush();
2776 pushFeatureBits();
2777 return false;
2778 }
2779
2780 if (Option == "pop") {
2781 SMLoc StartLoc = Parser.getTok().getLoc();
2782 if (Parser.parseEOL())
2783 return true;
2784
2785 getTargetStreamer().emitDirectiveOptionPop();
2786 if (popFeatureBits())
2787 return Error(StartLoc, ".option pop with no .option push");
2788
2789 return false;
2790 }
2791
2792 if (Option == "arch") {
2793 SmallVector<RISCVOptionArchArg> Args;
2794 do {
2795 if (Parser.parseComma())
2796 return true;
2797
2798 RISCVOptionArchArgType Type;
2799 if (parseOptionalToken(AsmToken::Plus))
2800 Type = RISCVOptionArchArgType::Plus;
2801 else if (parseOptionalToken(AsmToken::Minus))
2802 Type = RISCVOptionArchArgType::Minus;
2803 else if (!Args.empty())
2804 return Error(Parser.getTok().getLoc(),
2805 "unexpected token, expected + or -");
2806 else
2807 Type = RISCVOptionArchArgType::Full;
2808
2809 if (Parser.getTok().isNot(AsmToken::Identifier))
2810 return Error(Parser.getTok().getLoc(),
2811 "unexpected token, expected identifier");
2812
2813 StringRef Arch = Parser.getTok().getString();
2814 SMLoc Loc = Parser.getTok().getLoc();
2815 Parser.Lex();
2816
2817 if (Type == RISCVOptionArchArgType::Full) {
2818 std::string Result;
2819 if (resetToArch(Arch, Loc, Result, true))
2820 return true;
2821
2822 Args.emplace_back(Type, Result);
2823 break;
2824 }
2825
2826 ArrayRef<SubtargetFeatureKV> KVArray(RISCVFeatureKV);
2827 auto Ext = llvm::lower_bound(KVArray, Arch);
2828 if (Ext == KVArray.end() || StringRef(Ext->Key) != Arch ||
2829 !RISCVISAInfo::isSupportedExtension(Arch)) {
2830 if (isDigit(Arch.back()))
2831 return Error(
2832 Loc,
2833 "Extension version number parsing not currently implemented");
2834 return Error(Loc, "unknown extension feature");
2835 }
2836
2837 Args.emplace_back(Type, Ext->Key);
2838
2839 if (Type == RISCVOptionArchArgType::Plus) {
2840 FeatureBitset OldFeatureBits = STI->getFeatureBits();
2841
2842 setFeatureBits(Ext->Value, Ext->Key);
2843 auto ParseResult = RISCVFeatures::parseFeatureBits(isRV64(), STI->getFeatureBits());
2844 if (!ParseResult) {
2845 copySTI().setFeatureBits(OldFeatureBits);
2846 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
2847
2848 std::string Buffer;
2849 raw_string_ostream OutputErrMsg(Buffer);
2850 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
2851 OutputErrMsg << ErrMsg.getMessage();
2852 });
2853
2854 return Error(Loc, OutputErrMsg.str());
2855 }
2856 } else {
2857 assert(Type == RISCVOptionArchArgType::Minus);
2858 // It is invalid to disable an extension that there are other enabled
2859 // extensions depend on it.
2860 // TODO: Make use of RISCVISAInfo to handle this
2861 for (auto Feature : KVArray) {
2862 if (getSTI().hasFeature(Feature.Value) &&
2863 Feature.Implies.test(Ext->Value))
2864 return Error(Loc,
2865 Twine("Can't disable ") + Ext->Key + " extension, " +
2866 Feature.Key + " extension requires " + Ext->Key +
2867 " extension be enabled");
2868 }
2869
2870 clearFeatureBits(Ext->Value, Ext->Key);
2871 }
2872 } while (Parser.getTok().isNot(AsmToken::EndOfStatement));
2873
2874 if (Parser.parseEOL())
2875 return true;
2876
2877 getTargetStreamer().emitDirectiveOptionArch(Args);
2878 return false;
2879 }
2880
2881 if (Option == "rvc") {
2882 if (Parser.parseEOL())
2883 return true;
2884
2885 getTargetStreamer().emitDirectiveOptionRVC();
2886 setFeatureBits(RISCV::FeatureStdExtC, "c");
2887 return false;
2888 }
2889
2890 if (Option == "norvc") {
2891 if (Parser.parseEOL())
2892 return true;
2893
2894 getTargetStreamer().emitDirectiveOptionNoRVC();
2895 clearFeatureBits(RISCV::FeatureStdExtC, "c");
2896 clearFeatureBits(RISCV::FeatureStdExtZca, "+zca");
2897 return false;
2898 }
2899
2900 if (Option == "pic") {
2901 if (Parser.parseEOL())
2902 return true;
2903
2904 getTargetStreamer().emitDirectiveOptionPIC();
2905 ParserOptions.IsPicEnabled = true;
2906 return false;
2907 }
2908
2909 if (Option == "nopic") {
2910 if (Parser.parseEOL())
2911 return true;
2912
2913 getTargetStreamer().emitDirectiveOptionNoPIC();
2914 ParserOptions.IsPicEnabled = false;
2915 return false;
2916 }
2917
2918 if (Option == "relax") {
2919 if (Parser.parseEOL())
2920 return true;
2921
2922 getTargetStreamer().emitDirectiveOptionRelax();
2923 setFeatureBits(RISCV::FeatureRelax, "relax");
2924 return false;
2925 }
2926
2927 if (Option == "norelax") {
2928 if (Parser.parseEOL())
2929 return true;
2930
2931 getTargetStreamer().emitDirectiveOptionNoRelax();
2932 clearFeatureBits(RISCV::FeatureRelax, "relax");
2933 return false;
2934 }
2935
2936 // Unknown option.
2937 Warning(Parser.getTok().getLoc(), "unknown option, expected 'push', 'pop', "
2938 "'rvc', 'norvc', 'arch', 'relax' or "
2939 "'norelax'");
2940 Parser.eatToEndOfStatement();
2941 return false;
2942 }
2943
2944 /// parseDirectiveAttribute
2945 /// ::= .attribute expression ',' ( expression | "string" )
2946 /// ::= .attribute identifier ',' ( expression | "string" )
parseDirectiveAttribute()2947 bool RISCVAsmParser::parseDirectiveAttribute() {
2948 MCAsmParser &Parser = getParser();
2949 int64_t Tag;
2950 SMLoc TagLoc;
2951 TagLoc = Parser.getTok().getLoc();
2952 if (Parser.getTok().is(AsmToken::Identifier)) {
2953 StringRef Name = Parser.getTok().getIdentifier();
2954 std::optional<unsigned> Ret =
2955 ELFAttrs::attrTypeFromString(Name, RISCVAttrs::getRISCVAttributeTags());
2956 if (!Ret)
2957 return Error(TagLoc, "attribute name not recognised: " + Name);
2958 Tag = *Ret;
2959 Parser.Lex();
2960 } else {
2961 const MCExpr *AttrExpr;
2962
2963 TagLoc = Parser.getTok().getLoc();
2964 if (Parser.parseExpression(AttrExpr))
2965 return true;
2966
2967 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr);
2968 if (check(!CE, TagLoc, "expected numeric constant"))
2969 return true;
2970
2971 Tag = CE->getValue();
2972 }
2973
2974 if (Parser.parseComma())
2975 return true;
2976
2977 StringRef StringValue;
2978 int64_t IntegerValue = 0;
2979 bool IsIntegerValue = true;
2980
2981 // RISC-V attributes have a string value if the tag number is odd
2982 // and an integer value if the tag number is even.
2983 if (Tag % 2)
2984 IsIntegerValue = false;
2985
2986 SMLoc ValueExprLoc = Parser.getTok().getLoc();
2987 if (IsIntegerValue) {
2988 const MCExpr *ValueExpr;
2989 if (Parser.parseExpression(ValueExpr))
2990 return true;
2991
2992 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr);
2993 if (!CE)
2994 return Error(ValueExprLoc, "expected numeric constant");
2995 IntegerValue = CE->getValue();
2996 } else {
2997 if (Parser.getTok().isNot(AsmToken::String))
2998 return Error(Parser.getTok().getLoc(), "expected string constant");
2999
3000 StringValue = Parser.getTok().getStringContents();
3001 Parser.Lex();
3002 }
3003
3004 if (Parser.parseEOL())
3005 return true;
3006
3007 if (IsIntegerValue)
3008 getTargetStreamer().emitAttribute(Tag, IntegerValue);
3009 else if (Tag != RISCVAttrs::ARCH)
3010 getTargetStreamer().emitTextAttribute(Tag, StringValue);
3011 else {
3012 std::string Result;
3013 if (resetToArch(StringValue, ValueExprLoc, Result, false))
3014 return true;
3015
3016 // Then emit the arch string.
3017 getTargetStreamer().emitTextAttribute(Tag, Result);
3018 }
3019
3020 return false;
3021 }
3022
isValidInsnFormat(StringRef Format,bool AllowC)3023 bool isValidInsnFormat(StringRef Format, bool AllowC) {
3024 return StringSwitch<bool>(Format)
3025 .Cases("r", "r4", "i", "b", "sb", "u", "j", "uj", "s", true)
3026 .Cases("cr", "ci", "ciw", "css", "cl", "cs", "ca", "cb", "cj", AllowC)
3027 .Default(false);
3028 }
3029
3030 /// parseDirectiveInsn
3031 /// ::= .insn [ format encoding, (operands (, operands)*) ]
parseDirectiveInsn(SMLoc L)3032 bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3033 MCAsmParser &Parser = getParser();
3034
3035 // Expect instruction format as identifier.
3036 StringRef Format;
3037 SMLoc ErrorLoc = Parser.getTok().getLoc();
3038 if (Parser.parseIdentifier(Format))
3039 return Error(ErrorLoc, "expected instruction format");
3040
3041 bool AllowC = getSTI().hasFeature(RISCV::FeatureStdExtC) ||
3042 getSTI().hasFeature(RISCV::FeatureStdExtZca);
3043 if (!isValidInsnFormat(Format, AllowC))
3044 return Error(ErrorLoc, "invalid instruction format");
3045
3046 std::string FormatName = (".insn_" + Format).str();
3047
3048 ParseInstructionInfo Info;
3049 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> Operands;
3050
3051 if (ParseInstruction(Info, FormatName, L, Operands))
3052 return true;
3053
3054 unsigned Opcode;
3055 uint64_t ErrorInfo;
3056 return MatchAndEmitInstruction(L, Opcode, Operands, Parser.getStreamer(),
3057 ErrorInfo,
3058 /*MatchingInlineAsm=*/false);
3059 }
3060
3061 /// parseDirectiveVariantCC
3062 /// ::= .variant_cc symbol
parseDirectiveVariantCC()3063 bool RISCVAsmParser::parseDirectiveVariantCC() {
3064 StringRef Name;
3065 if (getParser().parseIdentifier(Name))
3066 return TokError("expected symbol name");
3067 if (parseEOL())
3068 return true;
3069 getTargetStreamer().emitDirectiveVariantCC(
3070 *getContext().getOrCreateSymbol(Name));
3071 return false;
3072 }
3073
emitToStreamer(MCStreamer & S,const MCInst & Inst)3074 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) {
3075 MCInst CInst;
3076 bool Res = RISCVRVC::compress(CInst, Inst, getSTI());
3077 if (Res)
3078 ++RISCVNumInstrsCompressed;
3079 S.emitInstruction((Res ? CInst : Inst), getSTI());
3080 }
3081
emitLoadImm(MCRegister DestReg,int64_t Value,MCStreamer & Out)3082 void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t Value,
3083 MCStreamer &Out) {
3084 RISCVMatInt::InstSeq Seq = RISCVMatInt::generateInstSeq(Value, getSTI());
3085
3086 MCRegister SrcReg = RISCV::X0;
3087 for (const RISCVMatInt::Inst &Inst : Seq) {
3088 switch (Inst.getOpndKind()) {
3089 case RISCVMatInt::Imm:
3090 emitToStreamer(Out,
3091 MCInstBuilder(Inst.getOpcode()).addReg(DestReg).addImm(Inst.getImm()));
3092 break;
3093 case RISCVMatInt::RegX0:
3094 emitToStreamer(
3095 Out, MCInstBuilder(Inst.getOpcode()).addReg(DestReg).addReg(SrcReg).addReg(
3096 RISCV::X0));
3097 break;
3098 case RISCVMatInt::RegReg:
3099 emitToStreamer(
3100 Out, MCInstBuilder(Inst.getOpcode()).addReg(DestReg).addReg(SrcReg).addReg(
3101 SrcReg));
3102 break;
3103 case RISCVMatInt::RegImm:
3104 emitToStreamer(
3105 Out, MCInstBuilder(Inst.getOpcode()).addReg(DestReg).addReg(SrcReg).addImm(
3106 Inst.getImm()));
3107 break;
3108 }
3109
3110 // Only the first instruction has X0 as its source.
3111 SrcReg = DestReg;
3112 }
3113 }
3114
emitAuipcInstPair(MCOperand DestReg,MCOperand TmpReg,const MCExpr * Symbol,RISCVMCExpr::VariantKind VKHi,unsigned SecondOpcode,SMLoc IDLoc,MCStreamer & Out)3115 void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg,
3116 const MCExpr *Symbol,
3117 RISCVMCExpr::VariantKind VKHi,
3118 unsigned SecondOpcode, SMLoc IDLoc,
3119 MCStreamer &Out) {
3120 // A pair of instructions for PC-relative addressing; expands to
3121 // TmpLabel: AUIPC TmpReg, VKHi(symbol)
3122 // OP DestReg, TmpReg, %pcrel_lo(TmpLabel)
3123 MCContext &Ctx = getContext();
3124
3125 MCSymbol *TmpLabel = Ctx.createNamedTempSymbol("pcrel_hi");
3126 Out.emitLabel(TmpLabel);
3127
3128 const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx);
3129 emitToStreamer(
3130 Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi));
3131
3132 const MCExpr *RefToLinkTmpLabel =
3133 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx),
3134 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx);
3135
3136 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3137 .addOperand(DestReg)
3138 .addOperand(TmpReg)
3139 .addExpr(RefToLinkTmpLabel));
3140 }
3141
emitLoadLocalAddress(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)3142 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3143 MCStreamer &Out) {
3144 // The load local address pseudo-instruction "lla" is used in PC-relative
3145 // addressing of local symbols:
3146 // lla rdest, symbol
3147 // expands to
3148 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
3149 // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
3150 MCOperand DestReg = Inst.getOperand(0);
3151 const MCExpr *Symbol = Inst.getOperand(1).getExpr();
3152 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
3153 RISCV::ADDI, IDLoc, Out);
3154 }
3155
emitLoadGlobalAddress(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)3156 void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3157 MCStreamer &Out) {
3158 // The load global address pseudo-instruction "lga" is used in GOT-indirect
3159 // addressing of global symbols:
3160 // lga rdest, symbol
3161 // expands to
3162 // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol)
3163 // Lx rdest, %pcrel_lo(TmpLabel)(rdest)
3164 MCOperand DestReg = Inst.getOperand(0);
3165 const MCExpr *Symbol = Inst.getOperand(1).getExpr();
3166 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3167 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_GOT_HI,
3168 SecondOpcode, IDLoc, Out);
3169 }
3170
emitLoadAddress(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)3171 void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3172 MCStreamer &Out) {
3173 // The load address pseudo-instruction "la" is used in PC-relative and
3174 // GOT-indirect addressing of global symbols:
3175 // la rdest, symbol
3176 // is an alias for either (for non-PIC)
3177 // lla rdest, symbol
3178 // or (for PIC)
3179 // lga rdest, symbol
3180 if (ParserOptions.IsPicEnabled)
3181 emitLoadGlobalAddress(Inst, IDLoc, Out);
3182 else
3183 emitLoadLocalAddress(Inst, IDLoc, Out);
3184 }
3185
emitLoadTLSIEAddress(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)3186 void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3187 MCStreamer &Out) {
3188 // The load TLS IE address pseudo-instruction "la.tls.ie" is used in
3189 // initial-exec TLS model addressing of global symbols:
3190 // la.tls.ie rdest, symbol
3191 // expands to
3192 // TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol)
3193 // Lx rdest, %pcrel_lo(TmpLabel)(rdest)
3194 MCOperand DestReg = Inst.getOperand(0);
3195 const MCExpr *Symbol = Inst.getOperand(1).getExpr();
3196 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3197 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GOT_HI,
3198 SecondOpcode, IDLoc, Out);
3199 }
3200
emitLoadTLSGDAddress(MCInst & Inst,SMLoc IDLoc,MCStreamer & Out)3201 void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3202 MCStreamer &Out) {
3203 // The load TLS GD address pseudo-instruction "la.tls.gd" is used in
3204 // global-dynamic TLS model addressing of global symbols:
3205 // la.tls.gd rdest, symbol
3206 // expands to
3207 // TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol)
3208 // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
3209 MCOperand DestReg = Inst.getOperand(0);
3210 const MCExpr *Symbol = Inst.getOperand(1).getExpr();
3211 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GD_HI,
3212 RISCV::ADDI, IDLoc, Out);
3213 }
3214
emitLoadStoreSymbol(MCInst & Inst,unsigned Opcode,SMLoc IDLoc,MCStreamer & Out,bool HasTmpReg)3215 void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode,
3216 SMLoc IDLoc, MCStreamer &Out,
3217 bool HasTmpReg) {
3218 // The load/store pseudo-instruction does a pc-relative load with
3219 // a symbol.
3220 //
3221 // The expansion looks like this
3222 //
3223 // TmpLabel: AUIPC tmp, %pcrel_hi(symbol)
3224 // [S|L]X rd, %pcrel_lo(TmpLabel)(tmp)
3225 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3226 MCOperand DestReg = Inst.getOperand(DestRegOpIdx);
3227 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3228 MCOperand TmpReg = Inst.getOperand(0);
3229 const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr();
3230 emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI,
3231 Opcode, IDLoc, Out);
3232 }
3233
emitPseudoExtend(MCInst & Inst,bool SignExtend,int64_t Width,SMLoc IDLoc,MCStreamer & Out)3234 void RISCVAsmParser::emitPseudoExtend(MCInst &Inst, bool SignExtend,
3235 int64_t Width, SMLoc IDLoc,
3236 MCStreamer &Out) {
3237 // The sign/zero extend pseudo-instruction does two shifts, with the shift
3238 // amounts dependent on the XLEN.
3239 //
3240 // The expansion looks like this
3241 //
3242 // SLLI rd, rs, XLEN - Width
3243 // SR[A|R]I rd, rd, XLEN - Width
3244 MCOperand DestReg = Inst.getOperand(0);
3245 MCOperand SourceReg = Inst.getOperand(1);
3246
3247 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3248 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3249
3250 assert(ShAmt > 0 && "Shift amount must be non-zero.");
3251
3252 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3253 .addOperand(DestReg)
3254 .addOperand(SourceReg)
3255 .addImm(ShAmt));
3256
3257 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3258 .addOperand(DestReg)
3259 .addOperand(DestReg)
3260 .addImm(ShAmt));
3261 }
3262
emitVMSGE(MCInst & Inst,unsigned Opcode,SMLoc IDLoc,MCStreamer & Out)3263 void RISCVAsmParser::emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,
3264 MCStreamer &Out) {
3265 if (Inst.getNumOperands() == 3) {
3266 // unmasked va >= x
3267 //
3268 // pseudoinstruction: vmsge{u}.vx vd, va, x
3269 // expansion: vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd
3270 emitToStreamer(Out, MCInstBuilder(Opcode)
3271 .addOperand(Inst.getOperand(0))
3272 .addOperand(Inst.getOperand(1))
3273 .addOperand(Inst.getOperand(2))
3274 .addReg(RISCV::NoRegister));
3275 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
3276 .addOperand(Inst.getOperand(0))
3277 .addOperand(Inst.getOperand(0))
3278 .addOperand(Inst.getOperand(0)));
3279 } else if (Inst.getNumOperands() == 4) {
3280 // masked va >= x, vd != v0
3281 //
3282 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t
3283 // expansion: vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0
3284 assert(Inst.getOperand(0).getReg() != RISCV::V0 &&
3285 "The destination register should not be V0.");
3286 emitToStreamer(Out, MCInstBuilder(Opcode)
3287 .addOperand(Inst.getOperand(0))
3288 .addOperand(Inst.getOperand(1))
3289 .addOperand(Inst.getOperand(2))
3290 .addOperand(Inst.getOperand(3)));
3291 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
3292 .addOperand(Inst.getOperand(0))
3293 .addOperand(Inst.getOperand(0))
3294 .addReg(RISCV::V0));
3295 } else if (Inst.getNumOperands() == 5 &&
3296 Inst.getOperand(0).getReg() == RISCV::V0) {
3297 // masked va >= x, vd == v0
3298 //
3299 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt
3300 // expansion: vmslt{u}.vx vt, va, x; vmandn.mm vd, vd, vt
3301 assert(Inst.getOperand(0).getReg() == RISCV::V0 &&
3302 "The destination register should be V0.");
3303 assert(Inst.getOperand(1).getReg() != RISCV::V0 &&
3304 "The temporary vector register should not be V0.");
3305 emitToStreamer(Out, MCInstBuilder(Opcode)
3306 .addOperand(Inst.getOperand(1))
3307 .addOperand(Inst.getOperand(2))
3308 .addOperand(Inst.getOperand(3))
3309 .addReg(RISCV::NoRegister));
3310 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3311 .addOperand(Inst.getOperand(0))
3312 .addOperand(Inst.getOperand(0))
3313 .addOperand(Inst.getOperand(1)));
3314 } else if (Inst.getNumOperands() == 5) {
3315 // masked va >= x, any vd
3316 //
3317 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt
3318 // expansion: vmslt{u}.vx vt, va, x; vmandn.mm vt, v0, vt;
3319 // vmandn.mm vd, vd, v0; vmor.mm vd, vt, vd
3320 assert(Inst.getOperand(1).getReg() != RISCV::V0 &&
3321 "The temporary vector register should not be V0.");
3322 emitToStreamer(Out, MCInstBuilder(Opcode)
3323 .addOperand(Inst.getOperand(1))
3324 .addOperand(Inst.getOperand(2))
3325 .addOperand(Inst.getOperand(3))
3326 .addReg(RISCV::NoRegister));
3327 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3328 .addOperand(Inst.getOperand(1))
3329 .addReg(RISCV::V0)
3330 .addOperand(Inst.getOperand(1)));
3331 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3332 .addOperand(Inst.getOperand(0))
3333 .addOperand(Inst.getOperand(0))
3334 .addReg(RISCV::V0));
3335 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
3336 .addOperand(Inst.getOperand(0))
3337 .addOperand(Inst.getOperand(1))
3338 .addOperand(Inst.getOperand(0)));
3339 }
3340 }
3341
checkPseudoAddTPRel(MCInst & Inst,OperandVector & Operands)3342 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
3343 OperandVector &Operands) {
3344 assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction");
3345 assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind");
3346 if (Inst.getOperand(2).getReg() != RISCV::X4) {
3347 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3348 return Error(ErrorLoc, "the second input operand must be tp/x4 when using "
3349 "%tprel_add modifier");
3350 }
3351
3352 return false;
3353 }
3354
checkPseudoTLSDESCCall(MCInst & Inst,OperandVector & Operands)3355 bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
3356 OperandVector &Operands) {
3357 assert(Inst.getOpcode() == RISCV::PseudoTLSDESCCall && "Invalid instruction");
3358 assert(Inst.getOperand(0).isReg() && "Unexpected operand kind");
3359 if (Inst.getOperand(0).getReg() != RISCV::X5) {
3360 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3361 return Error(ErrorLoc, "the output operand must be t0/x5 when using "
3362 "%tlsdesc_call modifier");
3363 }
3364
3365 return false;
3366 }
3367
defaultMaskRegOp() const3368 std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp() const {
3369 return RISCVOperand::createReg(RISCV::NoRegister, llvm::SMLoc(),
3370 llvm::SMLoc());
3371 }
3372
defaultFRMArgOp() const3373 std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp() const {
3374 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3375 llvm::SMLoc());
3376 }
3377
defaultFRMArgLegacyOp() const3378 std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp() const {
3379 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3380 llvm::SMLoc());
3381 }
3382
validateInstruction(MCInst & Inst,OperandVector & Operands)3383 bool RISCVAsmParser::validateInstruction(MCInst &Inst,
3384 OperandVector &Operands) {
3385 unsigned Opcode = Inst.getOpcode();
3386
3387 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3388 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3389 unsigned DestReg = Inst.getOperand(0).getReg();
3390 unsigned TempReg = Inst.getOperand(1).getReg();
3391 if (DestReg == TempReg) {
3392 SMLoc Loc = Operands.back()->getStartLoc();
3393 return Error(Loc, "The temporary vector register cannot be the same as "
3394 "the destination register.");
3395 }
3396 }
3397
3398 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3399 Opcode == RISCV::TH_LWD) {
3400 unsigned Rd1 = Inst.getOperand(0).getReg();
3401 unsigned Rd2 = Inst.getOperand(1).getReg();
3402 unsigned Rs1 = Inst.getOperand(2).getReg();
3403 // The encoding with rd1 == rd2 == rs1 is reserved for XTHead load pair.
3404 if (Rs1 == Rd1 && Rs1 == Rd2) {
3405 SMLoc Loc = Operands[1]->getStartLoc();
3406 return Error(Loc, "The source register and destination registers "
3407 "cannot be equal.");
3408 }
3409 }
3410
3411 if (Opcode == RISCV::CM_MVSA01) {
3412 unsigned Rd1 = Inst.getOperand(0).getReg();
3413 unsigned Rd2 = Inst.getOperand(1).getReg();
3414 if (Rd1 == Rd2) {
3415 SMLoc Loc = Operands[1]->getStartLoc();
3416 return Error(Loc, "'rs1' and 'rs2' must be different.");
3417 }
3418 }
3419
3420 bool IsTHeadMemPair32 = (Opcode == RISCV::TH_LWD ||
3421 Opcode == RISCV::TH_LWUD || Opcode == RISCV::TH_SWD);
3422 bool IsTHeadMemPair64 = (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_SDD);
3423 // The last operand of XTHeadMemPair instructions must be constant 3 or 4
3424 // depending on the data width.
3425 if (IsTHeadMemPair32 && Inst.getOperand(4).getImm() != 3) {
3426 SMLoc Loc = Operands.back()->getStartLoc();
3427 return Error(Loc, "Operand must be constant 3.");
3428 } else if (IsTHeadMemPair64 && Inst.getOperand(4).getImm() != 4) {
3429 SMLoc Loc = Operands.back()->getStartLoc();
3430 return Error(Loc, "Operand must be constant 4.");
3431 }
3432
3433 const MCInstrDesc &MCID = MII.get(Opcode);
3434 if (!(MCID.TSFlags & RISCVII::ConstraintMask))
3435 return false;
3436
3437 if (Opcode == RISCV::VC_V_XVW || Opcode == RISCV::VC_V_IVW ||
3438 Opcode == RISCV::VC_V_FVW || Opcode == RISCV::VC_V_VVW) {
3439 // Operands Opcode, Dst, uimm, Dst, Rs2, Rs1 for VC_V_XVW.
3440 unsigned VCIXDst = Inst.getOperand(0).getReg();
3441 SMLoc VCIXDstLoc = Operands[2]->getStartLoc();
3442 if (MCID.TSFlags & RISCVII::VS1Constraint) {
3443 unsigned VCIXRs1 = Inst.getOperand(Inst.getNumOperands() - 1).getReg();
3444 if (VCIXDst == VCIXRs1)
3445 return Error(VCIXDstLoc, "The destination vector register group cannot"
3446 " overlap the source vector register group.");
3447 }
3448 if (MCID.TSFlags & RISCVII::VS2Constraint) {
3449 unsigned VCIXRs2 = Inst.getOperand(Inst.getNumOperands() - 2).getReg();
3450 if (VCIXDst == VCIXRs2)
3451 return Error(VCIXDstLoc, "The destination vector register group cannot"
3452 " overlap the source vector register group.");
3453 }
3454 return false;
3455 }
3456
3457 unsigned DestReg = Inst.getOperand(0).getReg();
3458 unsigned Offset = 0;
3459 int TiedOp = MCID.getOperandConstraint(1, MCOI::TIED_TO);
3460 if (TiedOp == 0)
3461 Offset = 1;
3462
3463 // Operands[1] will be the first operand, DestReg.
3464 SMLoc Loc = Operands[1]->getStartLoc();
3465 if (MCID.TSFlags & RISCVII::VS2Constraint) {
3466 unsigned CheckReg = Inst.getOperand(Offset + 1).getReg();
3467 if (DestReg == CheckReg)
3468 return Error(Loc, "The destination vector register group cannot overlap"
3469 " the source vector register group.");
3470 }
3471 if ((MCID.TSFlags & RISCVII::VS1Constraint) && Inst.getOperand(Offset + 2).isReg()) {
3472 unsigned CheckReg = Inst.getOperand(Offset + 2).getReg();
3473 if (DestReg == CheckReg)
3474 return Error(Loc, "The destination vector register group cannot overlap"
3475 " the source vector register group.");
3476 }
3477 if ((MCID.TSFlags & RISCVII::VMConstraint) && (DestReg == RISCV::V0)) {
3478 // vadc, vsbc are special cases. These instructions have no mask register.
3479 // The destination register could not be V0.
3480 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
3481 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
3482 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
3483 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
3484 Opcode == RISCV::VMERGE_VXM)
3485 return Error(Loc, "The destination vector register group cannot be V0.");
3486
3487 // Regardless masked or unmasked version, the number of operands is the
3488 // same. For example, "viota.m v0, v2" is "viota.m v0, v2, NoRegister"
3489 // actually. We need to check the last operand to ensure whether it is
3490 // masked or not.
3491 unsigned CheckReg = Inst.getOperand(Inst.getNumOperands() - 1).getReg();
3492 assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) &&
3493 "Unexpected register for mask operand");
3494
3495 if (DestReg == CheckReg)
3496 return Error(Loc, "The destination vector register group cannot overlap"
3497 " the mask register.");
3498 }
3499 return false;
3500 }
3501
processInstruction(MCInst & Inst,SMLoc IDLoc,OperandVector & Operands,MCStreamer & Out)3502 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
3503 OperandVector &Operands,
3504 MCStreamer &Out) {
3505 Inst.setLoc(IDLoc);
3506
3507 switch (Inst.getOpcode()) {
3508 default:
3509 break;
3510 case RISCV::PseudoLLAImm:
3511 case RISCV::PseudoLAImm:
3512 case RISCV::PseudoLI: {
3513 MCRegister Reg = Inst.getOperand(0).getReg();
3514 const MCOperand &Op1 = Inst.getOperand(1);
3515 if (Op1.isExpr()) {
3516 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar.
3517 // Just convert to an addi. This allows compatibility with gas.
3518 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
3519 .addReg(Reg)
3520 .addReg(RISCV::X0)
3521 .addExpr(Op1.getExpr()));
3522 return false;
3523 }
3524 int64_t Imm = Inst.getOperand(1).getImm();
3525 // On RV32 the immediate here can either be a signed or an unsigned
3526 // 32-bit number. Sign extension has to be performed to ensure that Imm
3527 // represents the expected signed 64-bit number.
3528 if (!isRV64())
3529 Imm = SignExtend64<32>(Imm);
3530 emitLoadImm(Reg, Imm, Out);
3531 return false;
3532 }
3533 case RISCV::PseudoLLA:
3534 emitLoadLocalAddress(Inst, IDLoc, Out);
3535 return false;
3536 case RISCV::PseudoLGA:
3537 emitLoadGlobalAddress(Inst, IDLoc, Out);
3538 return false;
3539 case RISCV::PseudoLA:
3540 emitLoadAddress(Inst, IDLoc, Out);
3541 return false;
3542 case RISCV::PseudoLA_TLS_IE:
3543 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3544 return false;
3545 case RISCV::PseudoLA_TLS_GD:
3546 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3547 return false;
3548 case RISCV::PseudoLB:
3549 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false);
3550 return false;
3551 case RISCV::PseudoLBU:
3552 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false);
3553 return false;
3554 case RISCV::PseudoLH:
3555 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false);
3556 return false;
3557 case RISCV::PseudoLHU:
3558 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false);
3559 return false;
3560 case RISCV::PseudoLW:
3561 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false);
3562 return false;
3563 case RISCV::PseudoLWU:
3564 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false);
3565 return false;
3566 case RISCV::PseudoLD:
3567 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false);
3568 return false;
3569 case RISCV::PseudoFLH:
3570 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out, /*HasTmpReg=*/true);
3571 return false;
3572 case RISCV::PseudoFLW:
3573 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true);
3574 return false;
3575 case RISCV::PseudoFLD:
3576 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true);
3577 return false;
3578 case RISCV::PseudoSB:
3579 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true);
3580 return false;
3581 case RISCV::PseudoSH:
3582 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true);
3583 return false;
3584 case RISCV::PseudoSW:
3585 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true);
3586 return false;
3587 case RISCV::PseudoSD:
3588 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true);
3589 return false;
3590 case RISCV::PseudoFSH:
3591 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out, /*HasTmpReg=*/true);
3592 return false;
3593 case RISCV::PseudoFSW:
3594 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true);
3595 return false;
3596 case RISCV::PseudoFSD:
3597 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true);
3598 return false;
3599 case RISCV::PseudoAddTPRel:
3600 if (checkPseudoAddTPRel(Inst, Operands))
3601 return true;
3602 break;
3603 case RISCV::PseudoTLSDESCCall:
3604 if (checkPseudoTLSDESCCall(Inst, Operands))
3605 return true;
3606 break;
3607 case RISCV::PseudoSEXT_B:
3608 emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/8, IDLoc, Out);
3609 return false;
3610 case RISCV::PseudoSEXT_H:
3611 emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/16, IDLoc, Out);
3612 return false;
3613 case RISCV::PseudoZEXT_H:
3614 emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/16, IDLoc, Out);
3615 return false;
3616 case RISCV::PseudoZEXT_W:
3617 emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/32, IDLoc, Out);
3618 return false;
3619 case RISCV::PseudoVMSGEU_VX:
3620 case RISCV::PseudoVMSGEU_VX_M:
3621 case RISCV::PseudoVMSGEU_VX_M_T:
3622 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
3623 return false;
3624 case RISCV::PseudoVMSGE_VX:
3625 case RISCV::PseudoVMSGE_VX_M:
3626 case RISCV::PseudoVMSGE_VX_M_T:
3627 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
3628 return false;
3629 case RISCV::PseudoVMSGE_VI:
3630 case RISCV::PseudoVMSLT_VI: {
3631 // These instructions are signed and so is immediate so we can subtract one
3632 // and change the opcode.
3633 int64_t Imm = Inst.getOperand(2).getImm();
3634 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
3635 : RISCV::VMSLE_VI;
3636 emitToStreamer(Out, MCInstBuilder(Opc)
3637 .addOperand(Inst.getOperand(0))
3638 .addOperand(Inst.getOperand(1))
3639 .addImm(Imm - 1)
3640 .addOperand(Inst.getOperand(3)));
3641 return false;
3642 }
3643 case RISCV::PseudoVMSGEU_VI:
3644 case RISCV::PseudoVMSLTU_VI: {
3645 int64_t Imm = Inst.getOperand(2).getImm();
3646 // Unsigned comparisons are tricky because the immediate is signed. If the
3647 // immediate is 0 we can't just subtract one. vmsltu.vi v0, v1, 0 is always
3648 // false, but vmsle.vi v0, v1, -1 is always true. Instead we use
3649 // vmsne v0, v1, v1 which is always false.
3650 if (Imm == 0) {
3651 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI
3652 ? RISCV::VMSEQ_VV
3653 : RISCV::VMSNE_VV;
3654 emitToStreamer(Out, MCInstBuilder(Opc)
3655 .addOperand(Inst.getOperand(0))
3656 .addOperand(Inst.getOperand(1))
3657 .addOperand(Inst.getOperand(1))
3658 .addOperand(Inst.getOperand(3)));
3659 } else {
3660 // Other immediate values can subtract one like signed.
3661 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI
3662 ? RISCV::VMSGTU_VI
3663 : RISCV::VMSLEU_VI;
3664 emitToStreamer(Out, MCInstBuilder(Opc)
3665 .addOperand(Inst.getOperand(0))
3666 .addOperand(Inst.getOperand(1))
3667 .addImm(Imm - 1)
3668 .addOperand(Inst.getOperand(3)));
3669 }
3670
3671 return false;
3672 }
3673 }
3674
3675 emitToStreamer(Out, Inst);
3676 return false;
3677 }
3678
LLVMInitializeRISCVAsmParser()3679 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser() {
3680 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target());
3681 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target());
3682 }
3683