1 //===-- RISCVAsmParser.cpp - Parse RISCV assembly to MCInst instructions --===//
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
7 //===----------------------------------------------------------------------===//
9 #include "MCTargetDesc/RISCVAsmBackend.h"
10 #include "MCTargetDesc/RISCVBaseInfo.h"
11 #include "MCTargetDesc/RISCVInstPrinter.h"
12 #include "MCTargetDesc/RISCVMCExpr.h"
13 #include "MCTargetDesc/RISCVMCTargetDesc.h"
14 #include "MCTargetDesc/RISCVMatInt.h"
15 #include "MCTargetDesc/RISCVTargetStreamer.h"
16 #include "TargetInfo/RISCVTargetInfo.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallBitVector.h"
19 #include "llvm/ADT/SmallString.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/Statistic.h"
22 #include "llvm/MC/MCAssembler.h"
23 #include "llvm/MC/MCContext.h"
24 #include "llvm/MC/MCExpr.h"
25 #include "llvm/MC/MCInst.h"
26 #include "llvm/MC/MCInstBuilder.h"
27 #include "llvm/MC/MCObjectFileInfo.h"
28 #include "llvm/MC/MCParser/MCAsmLexer.h"
29 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
30 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
31 #include "llvm/MC/MCRegisterInfo.h"
32 #include "llvm/MC/MCStreamer.h"
33 #include "llvm/MC/MCSubtargetInfo.h"
34 #include "llvm/MC/MCValue.h"
35 #include "llvm/Support/Casting.h"
36 #include "llvm/Support/MathExtras.h"
37 #include "llvm/Support/RISCVAttributes.h"
38 #include "llvm/Support/TargetRegistry.h"
44 #define DEBUG_TYPE "riscv-asm-parser"
46 // Include the auto-generated portion of the compress emitter.
47 #define GEN_COMPRESS_INSTR
48 #include "RISCVGenCompressInstEmitter.inc"
50 STATISTIC(RISCVNumInstrsCompressed
,
51 "Number of RISC-V Compressed instructions emitted");
56 struct ParserOptionsSet
{
60 class RISCVAsmParser
: public MCTargetAsmParser
{
61 SmallVector
<FeatureBitset
, 4> FeatureBitStack
;
63 SmallVector
<ParserOptionsSet
, 4> ParserOptionsStack
;
64 ParserOptionsSet ParserOptions
;
66 SMLoc
getLoc() const { return getParser().getTok().getLoc(); }
67 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit
); }
68 bool isRV32E() const { return getSTI().hasFeature(RISCV::FeatureRV32E
); }
70 RISCVTargetStreamer
&getTargetStreamer() {
71 MCTargetStreamer
&TS
= *getParser().getStreamer().getTargetStreamer();
72 return static_cast<RISCVTargetStreamer
&>(TS
);
75 unsigned validateTargetOperandClass(MCParsedAsmOperand
&Op
,
76 unsigned Kind
) override
;
78 bool generateImmOutOfRangeError(OperandVector
&Operands
, uint64_t ErrorInfo
,
79 int64_t Lower
, int64_t Upper
, Twine Msg
);
81 bool MatchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
82 OperandVector
&Operands
, MCStreamer
&Out
,
84 bool MatchingInlineAsm
) override
;
86 bool ParseRegister(unsigned &RegNo
, SMLoc
&StartLoc
, SMLoc
&EndLoc
) override
;
87 OperandMatchResultTy
tryParseRegister(unsigned &RegNo
, SMLoc
&StartLoc
,
88 SMLoc
&EndLoc
) override
;
90 bool ParseInstruction(ParseInstructionInfo
&Info
, StringRef Name
,
91 SMLoc NameLoc
, OperandVector
&Operands
) override
;
93 bool ParseDirective(AsmToken DirectiveID
) override
;
95 // Helper to actually emit an instruction to the MCStreamer. Also, when
96 // possible, compression of the instruction is performed.
97 void emitToStreamer(MCStreamer
&S
, const MCInst
&Inst
);
99 // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that
100 // synthesize the desired immedate value into the destination register.
101 void emitLoadImm(MCRegister DestReg
, int64_t Value
, MCStreamer
&Out
);
103 // Helper to emit a combination of AUIPC and SecondOpcode. Used to implement
104 // helpers such as emitLoadLocalAddress and emitLoadAddress.
105 void emitAuipcInstPair(MCOperand DestReg
, MCOperand TmpReg
,
106 const MCExpr
*Symbol
, RISCVMCExpr::VariantKind VKHi
,
107 unsigned SecondOpcode
, SMLoc IDLoc
, MCStreamer
&Out
);
109 // Helper to emit pseudo instruction "lla" used in PC-rel addressing.
110 void emitLoadLocalAddress(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
);
112 // Helper to emit pseudo instruction "la" used in GOT/PC-rel addressing.
113 void emitLoadAddress(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
);
115 // Helper to emit pseudo instruction "la.tls.ie" used in initial-exec TLS
117 void emitLoadTLSIEAddress(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
);
119 // Helper to emit pseudo instruction "la.tls.gd" used in global-dynamic TLS
121 void emitLoadTLSGDAddress(MCInst
&Inst
, SMLoc IDLoc
, MCStreamer
&Out
);
123 // Helper to emit pseudo load/store instruction with a symbol.
124 void emitLoadStoreSymbol(MCInst
&Inst
, unsigned Opcode
, SMLoc IDLoc
,
125 MCStreamer
&Out
, bool HasTmpReg
);
127 // Helper to emit pseudo sign/zero extend instruction.
128 void emitPseudoExtend(MCInst
&Inst
, bool SignExtend
, int64_t Width
,
129 SMLoc IDLoc
, MCStreamer
&Out
);
131 // Helper to emit pseudo vmsge{u}.vx instruction.
132 void emitVMSGE(MCInst
&Inst
, unsigned Opcode
, SMLoc IDLoc
, MCStreamer
&Out
);
134 // Checks that a PseudoAddTPRel is using x4/tp in its second input operand.
135 // Enforcing this using a restricted register class for the second input
136 // operand of PseudoAddTPRel results in a poor diagnostic due to the fact
137 // 'add' is an overloaded mnemonic.
138 bool checkPseudoAddTPRel(MCInst
&Inst
, OperandVector
&Operands
);
140 // Check instruction constraints.
141 bool validateInstruction(MCInst
&Inst
, OperandVector
&Operands
);
143 /// Helper for processing MC instructions that have been successfully matched
144 /// by MatchAndEmitInstruction. Modifications to the emitted instructions,
145 /// like the expansion of pseudo instructions (e.g., "li"), can be performed
147 bool processInstruction(MCInst
&Inst
, SMLoc IDLoc
, OperandVector
&Operands
,
150 // Auto-generated instruction matching functions
151 #define GET_ASSEMBLER_HEADER
152 #include "RISCVGenAsmMatcher.inc"
154 OperandMatchResultTy
parseCSRSystemRegister(OperandVector
&Operands
);
155 OperandMatchResultTy
parseImmediate(OperandVector
&Operands
);
156 OperandMatchResultTy
parseRegister(OperandVector
&Operands
,
157 bool AllowParens
= false);
158 OperandMatchResultTy
parseMemOpBaseReg(OperandVector
&Operands
);
159 OperandMatchResultTy
parseAtomicMemOp(OperandVector
&Operands
);
160 OperandMatchResultTy
parseOperandWithModifier(OperandVector
&Operands
);
161 OperandMatchResultTy
parseBareSymbol(OperandVector
&Operands
);
162 OperandMatchResultTy
parseCallSymbol(OperandVector
&Operands
);
163 OperandMatchResultTy
parsePseudoJumpSymbol(OperandVector
&Operands
);
164 OperandMatchResultTy
parseJALOffset(OperandVector
&Operands
);
165 OperandMatchResultTy
parseVTypeI(OperandVector
&Operands
);
166 OperandMatchResultTy
parseMaskReg(OperandVector
&Operands
);
168 bool parseOperand(OperandVector
&Operands
, StringRef Mnemonic
);
170 bool parseDirectiveOption();
171 bool parseDirectiveAttribute();
173 void setFeatureBits(uint64_t Feature
, StringRef FeatureString
) {
174 if (!(getSTI().getFeatureBits()[Feature
])) {
175 MCSubtargetInfo
&STI
= copySTI();
176 setAvailableFeatures(
177 ComputeAvailableFeatures(STI
.ToggleFeature(FeatureString
)));
181 bool getFeatureBits(uint64_t Feature
) {
182 return getSTI().getFeatureBits()[Feature
];
185 void clearFeatureBits(uint64_t Feature
, StringRef FeatureString
) {
186 if (getSTI().getFeatureBits()[Feature
]) {
187 MCSubtargetInfo
&STI
= copySTI();
188 setAvailableFeatures(
189 ComputeAvailableFeatures(STI
.ToggleFeature(FeatureString
)));
193 void pushFeatureBits() {
194 assert(FeatureBitStack
.size() == ParserOptionsStack
.size() &&
195 "These two stacks must be kept synchronized");
196 FeatureBitStack
.push_back(getSTI().getFeatureBits());
197 ParserOptionsStack
.push_back(ParserOptions
);
200 bool popFeatureBits() {
201 assert(FeatureBitStack
.size() == ParserOptionsStack
.size() &&
202 "These two stacks must be kept synchronized");
203 if (FeatureBitStack
.empty())
206 FeatureBitset FeatureBits
= FeatureBitStack
.pop_back_val();
207 copySTI().setFeatureBits(FeatureBits
);
208 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits
));
210 ParserOptions
= ParserOptionsStack
.pop_back_val();
215 std::unique_ptr
<RISCVOperand
> defaultMaskRegOp() const;
218 enum RISCVMatchResultTy
{
219 Match_Dummy
= FIRST_TARGET_MATCH_RESULT_TY
,
220 #define GET_OPERAND_DIAGNOSTIC_TYPES
221 #include "RISCVGenAsmMatcher.inc"
222 #undef GET_OPERAND_DIAGNOSTIC_TYPES
225 static bool classifySymbolRef(const MCExpr
*Expr
,
226 RISCVMCExpr::VariantKind
&Kind
);
228 RISCVAsmParser(const MCSubtargetInfo
&STI
, MCAsmParser
&Parser
,
229 const MCInstrInfo
&MII
, const MCTargetOptions
&Options
)
230 : MCTargetAsmParser(Options
, STI
, MII
) {
231 Parser
.addAliasForDirective(".half", ".2byte");
232 Parser
.addAliasForDirective(".hword", ".2byte");
233 Parser
.addAliasForDirective(".word", ".4byte");
234 Parser
.addAliasForDirective(".dword", ".8byte");
235 setAvailableFeatures(ComputeAvailableFeatures(STI
.getFeatureBits()));
237 auto ABIName
= StringRef(Options
.ABIName
);
238 if (ABIName
.endswith("f") &&
239 !getSTI().getFeatureBits()[RISCV::FeatureStdExtF
]) {
240 errs() << "Hard-float 'f' ABI can't be used for a target that "
241 "doesn't support the F instruction set extension (ignoring "
243 } else if (ABIName
.endswith("d") &&
244 !getSTI().getFeatureBits()[RISCV::FeatureStdExtD
]) {
245 errs() << "Hard-float 'd' ABI can't be used for a target that "
246 "doesn't support the D instruction set extension (ignoring "
250 const MCObjectFileInfo
*MOFI
= Parser
.getContext().getObjectFileInfo();
251 ParserOptions
.IsPicEnabled
= MOFI
->isPositionIndependent();
255 /// RISCVOperand - Instances of this class represent a parsed machine
257 struct RISCVOperand
: public MCParsedAsmOperand
{
281 // FIXME: Add the Encoding parsed fields as needed for checks,
282 // e.g.: read/write or user/supervisor/machine privileges.
289 SMLoc StartLoc
, EndLoc
;
294 struct SysRegOp SysReg
;
295 struct VTypeOp VType
;
298 RISCVOperand(KindTy K
) : MCParsedAsmOperand(), Kind(K
) {}
301 RISCVOperand(const RISCVOperand
&o
) : MCParsedAsmOperand() {
304 StartLoc
= o
.StartLoc
;
307 case KindTy::Register
:
310 case KindTy::Immediate
:
316 case KindTy::SystemRegister
:
325 bool isToken() const override
{ return Kind
== KindTy::Token
; }
326 bool isReg() const override
{ return Kind
== KindTy::Register
; }
327 bool isV0Reg() const {
328 return Kind
== KindTy::Register
&& Reg
.RegNum
== RISCV::V0
;
330 bool isImm() const override
{ return Kind
== KindTy::Immediate
; }
331 bool isMem() const override
{ return false; }
332 bool isSystemRegister() const { return Kind
== KindTy::SystemRegister
; }
333 bool isVType() const { return Kind
== KindTy::VType
; }
336 return Kind
== KindTy::Register
&&
337 RISCVMCRegisterClasses
[RISCV::GPRRegClassID
].contains(Reg
.RegNum
);
340 static bool evaluateConstantImm(const MCExpr
*Expr
, int64_t &Imm
,
341 RISCVMCExpr::VariantKind
&VK
) {
342 if (auto *RE
= dyn_cast
<RISCVMCExpr
>(Expr
)) {
344 return RE
->evaluateAsConstant(Imm
);
347 if (auto CE
= dyn_cast
<MCConstantExpr
>(Expr
)) {
348 VK
= RISCVMCExpr::VK_RISCV_None
;
349 Imm
= CE
->getValue();
356 // True if operand is a symbol with no modifiers, or a constant with no
357 // modifiers and isShiftedInt<N-1, 1>(Op).
358 template <int N
> bool isBareSimmNLsb0() const {
360 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
363 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
366 IsValid
= RISCVAsmParser::classifySymbolRef(getImm(), VK
);
368 IsValid
= isShiftedInt
<N
- 1, 1>(Imm
);
369 return IsValid
&& VK
== RISCVMCExpr::VK_RISCV_None
;
372 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td
374 bool isBareSymbol() const {
376 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
377 // Must be of 'immediate' type but not a constant.
378 if (!isImm() || evaluateConstantImm(getImm(), Imm
, VK
))
380 return RISCVAsmParser::classifySymbolRef(getImm(), VK
) &&
381 VK
== RISCVMCExpr::VK_RISCV_None
;
384 bool isCallSymbol() const {
386 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
387 // Must be of 'immediate' type but not a constant.
388 if (!isImm() || evaluateConstantImm(getImm(), Imm
, VK
))
390 return RISCVAsmParser::classifySymbolRef(getImm(), VK
) &&
391 (VK
== RISCVMCExpr::VK_RISCV_CALL
||
392 VK
== RISCVMCExpr::VK_RISCV_CALL_PLT
);
395 bool isPseudoJumpSymbol() const {
397 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
398 // Must be of 'immediate' type but not a constant.
399 if (!isImm() || evaluateConstantImm(getImm(), Imm
, VK
))
401 return RISCVAsmParser::classifySymbolRef(getImm(), VK
) &&
402 VK
== RISCVMCExpr::VK_RISCV_CALL
;
405 bool isTPRelAddSymbol() const {
407 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
408 // Must be of 'immediate' type but not a constant.
409 if (!isImm() || evaluateConstantImm(getImm(), Imm
, VK
))
411 return RISCVAsmParser::classifySymbolRef(getImm(), VK
) &&
412 VK
== RISCVMCExpr::VK_RISCV_TPREL_ADD
;
415 bool isCSRSystemRegister() const { return isSystemRegister(); }
417 bool isVTypeI() const { return isVType(); }
419 /// Return true if the operand is a valid for the fence instruction e.g.
421 bool isFenceArg() const {
424 const MCExpr
*Val
= getImm();
425 auto *SVal
= dyn_cast
<MCSymbolRefExpr
>(Val
);
426 if (!SVal
|| SVal
->getKind() != MCSymbolRefExpr::VK_None
)
429 StringRef Str
= SVal
->getSymbol().getName();
430 // Letters must be unique, taken from 'iorw', and in ascending order. This
431 // holds as long as each individual character is one of 'iorw' and is
432 // greater than the previous character.
435 if (c
!= 'i' && c
!= 'o' && c
!= 'r' && c
!= 'w')
444 /// Return true if the operand is a valid floating point rounding mode.
445 bool isFRMArg() const {
448 const MCExpr
*Val
= getImm();
449 auto *SVal
= dyn_cast
<MCSymbolRefExpr
>(Val
);
450 if (!SVal
|| SVal
->getKind() != MCSymbolRefExpr::VK_None
)
453 StringRef Str
= SVal
->getSymbol().getName();
455 return RISCVFPRndMode::stringToRoundingMode(Str
) != RISCVFPRndMode::Invalid
;
458 bool isImmXLenLI() const {
460 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
463 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
464 if (VK
== RISCVMCExpr::VK_RISCV_LO
|| VK
== RISCVMCExpr::VK_RISCV_PCREL_LO
)
466 // Given only Imm, ensuring that the actually specified constant is either
467 // a signed or unsigned 64-bit number is unfortunately impossible.
468 return IsConstantImm
&& VK
== RISCVMCExpr::VK_RISCV_None
&&
469 (isRV64() || (isInt
<32>(Imm
) || isUInt
<32>(Imm
)));
472 bool isUImmLog2XLen() const {
474 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
477 if (!evaluateConstantImm(getImm(), Imm
, VK
) ||
478 VK
!= RISCVMCExpr::VK_RISCV_None
)
480 return (isRV64() && isUInt
<6>(Imm
)) || isUInt
<5>(Imm
);
483 bool isUImmLog2XLenNonZero() const {
485 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
488 if (!evaluateConstantImm(getImm(), Imm
, VK
) ||
489 VK
!= RISCVMCExpr::VK_RISCV_None
)
493 return (isRV64() && isUInt
<6>(Imm
)) || isUInt
<5>(Imm
);
496 bool isUImmLog2XLenHalf() const {
498 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
501 if (!evaluateConstantImm(getImm(), Imm
, VK
) ||
502 VK
!= RISCVMCExpr::VK_RISCV_None
)
504 return (isRV64() && isUInt
<5>(Imm
)) || isUInt
<4>(Imm
);
507 bool isUImm5() const {
509 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
512 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
513 return IsConstantImm
&& isUInt
<5>(Imm
) && VK
== RISCVMCExpr::VK_RISCV_None
;
516 bool isSImm5() const {
519 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
521 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
522 return IsConstantImm
&& isInt
<5>(Imm
) && VK
== RISCVMCExpr::VK_RISCV_None
;
525 bool isSImm6() const {
528 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
530 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
531 return IsConstantImm
&& isInt
<6>(Imm
) && VK
== RISCVMCExpr::VK_RISCV_None
;
534 bool isSImm6NonZero() const {
537 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
539 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
540 return IsConstantImm
&& isInt
<6>(Imm
) && (Imm
!= 0) &&
541 VK
== RISCVMCExpr::VK_RISCV_None
;
544 bool isCLUIImm() const {
548 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
549 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
550 return IsConstantImm
&& (Imm
!= 0) &&
551 (isUInt
<5>(Imm
) || (Imm
>= 0xfffe0 && Imm
<= 0xfffff)) &&
552 VK
== RISCVMCExpr::VK_RISCV_None
;
555 bool isUImm7Lsb00() const {
559 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
560 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
561 return IsConstantImm
&& isShiftedUInt
<5, 2>(Imm
) &&
562 VK
== RISCVMCExpr::VK_RISCV_None
;
565 bool isUImm8Lsb00() const {
569 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
570 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
571 return IsConstantImm
&& isShiftedUInt
<6, 2>(Imm
) &&
572 VK
== RISCVMCExpr::VK_RISCV_None
;
575 bool isUImm8Lsb000() const {
579 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
580 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
581 return IsConstantImm
&& isShiftedUInt
<5, 3>(Imm
) &&
582 VK
== RISCVMCExpr::VK_RISCV_None
;
585 bool isSImm9Lsb0() const { return isBareSimmNLsb0
<9>(); }
587 bool isUImm9Lsb000() const {
591 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
592 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
593 return IsConstantImm
&& isShiftedUInt
<6, 3>(Imm
) &&
594 VK
== RISCVMCExpr::VK_RISCV_None
;
597 bool isUImm10Lsb00NonZero() const {
601 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
602 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
603 return IsConstantImm
&& isShiftedUInt
<8, 2>(Imm
) && (Imm
!= 0) &&
604 VK
== RISCVMCExpr::VK_RISCV_None
;
607 bool isSImm12() const {
608 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
613 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
615 IsValid
= RISCVAsmParser::classifySymbolRef(getImm(), VK
);
617 IsValid
= isInt
<12>(Imm
);
618 return IsValid
&& ((IsConstantImm
&& VK
== RISCVMCExpr::VK_RISCV_None
) ||
619 VK
== RISCVMCExpr::VK_RISCV_LO
||
620 VK
== RISCVMCExpr::VK_RISCV_PCREL_LO
||
621 VK
== RISCVMCExpr::VK_RISCV_TPREL_LO
);
624 bool isSImm12Lsb0() const { return isBareSimmNLsb0
<12>(); }
626 bool isSImm13Lsb0() const { return isBareSimmNLsb0
<13>(); }
628 bool isSImm10Lsb0000NonZero() const {
632 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
633 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
634 return IsConstantImm
&& (Imm
!= 0) && isShiftedInt
<6, 4>(Imm
) &&
635 VK
== RISCVMCExpr::VK_RISCV_None
;
638 bool isUImm20LUI() const {
639 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
644 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
645 if (!IsConstantImm
) {
646 IsValid
= RISCVAsmParser::classifySymbolRef(getImm(), VK
);
647 return IsValid
&& (VK
== RISCVMCExpr::VK_RISCV_HI
||
648 VK
== RISCVMCExpr::VK_RISCV_TPREL_HI
);
650 return isUInt
<20>(Imm
) && (VK
== RISCVMCExpr::VK_RISCV_None
||
651 VK
== RISCVMCExpr::VK_RISCV_HI
||
652 VK
== RISCVMCExpr::VK_RISCV_TPREL_HI
);
656 bool isUImm20AUIPC() const {
657 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
662 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
663 if (!IsConstantImm
) {
664 IsValid
= RISCVAsmParser::classifySymbolRef(getImm(), VK
);
665 return IsValid
&& (VK
== RISCVMCExpr::VK_RISCV_PCREL_HI
||
666 VK
== RISCVMCExpr::VK_RISCV_GOT_HI
||
667 VK
== RISCVMCExpr::VK_RISCV_TLS_GOT_HI
||
668 VK
== RISCVMCExpr::VK_RISCV_TLS_GD_HI
);
670 return isUInt
<20>(Imm
) && (VK
== RISCVMCExpr::VK_RISCV_None
||
671 VK
== RISCVMCExpr::VK_RISCV_PCREL_HI
||
672 VK
== RISCVMCExpr::VK_RISCV_GOT_HI
||
673 VK
== RISCVMCExpr::VK_RISCV_TLS_GOT_HI
||
674 VK
== RISCVMCExpr::VK_RISCV_TLS_GD_HI
);
678 bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0
<21>(); }
680 bool isImmZero() const {
684 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
685 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
686 return IsConstantImm
&& (Imm
== 0) && VK
== RISCVMCExpr::VK_RISCV_None
;
689 bool isSImm5Plus1() const {
692 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
694 bool IsConstantImm
= evaluateConstantImm(getImm(), Imm
, VK
);
695 return IsConstantImm
&& isInt
<5>(Imm
- 1) &&
696 VK
== RISCVMCExpr::VK_RISCV_None
;
699 /// getStartLoc - Gets location of the first token of this operand
700 SMLoc
getStartLoc() const override
{ return StartLoc
; }
701 /// getEndLoc - Gets location of the last token of this operand
702 SMLoc
getEndLoc() const override
{ return EndLoc
; }
703 /// True if this operand is for an RV64 instruction
704 bool isRV64() const { return IsRV64
; }
706 unsigned getReg() const override
{
707 assert(Kind
== KindTy::Register
&& "Invalid type access!");
708 return Reg
.RegNum
.id();
711 StringRef
getSysReg() const {
712 assert(Kind
== KindTy::SystemRegister
&& "Invalid type access!");
713 return StringRef(SysReg
.Data
, SysReg
.Length
);
716 const MCExpr
*getImm() const {
717 assert(Kind
== KindTy::Immediate
&& "Invalid type access!");
721 StringRef
getToken() const {
722 assert(Kind
== KindTy::Token
&& "Invalid type access!");
726 unsigned getVType() const {
727 assert(Kind
== KindTy::VType
&& "Invalid type access!");
731 void print(raw_ostream
&OS
) const override
{
732 auto RegName
= [](unsigned Reg
) {
734 return RISCVInstPrinter::getRegisterName(Reg
);
740 case KindTy::Immediate
:
743 case KindTy::Register
:
744 OS
<< "<register " << RegName(getReg()) << ">";
747 OS
<< "'" << getToken() << "'";
749 case KindTy::SystemRegister
:
750 OS
<< "<sysreg: " << getSysReg() << '>';
754 RISCVVType::printVType(getVType(), OS
);
760 static std::unique_ptr
<RISCVOperand
> createToken(StringRef Str
, SMLoc S
,
762 auto Op
= std::make_unique
<RISCVOperand
>(KindTy::Token
);
770 static std::unique_ptr
<RISCVOperand
> createReg(unsigned RegNo
, SMLoc S
,
771 SMLoc E
, bool IsRV64
) {
772 auto Op
= std::make_unique
<RISCVOperand
>(KindTy::Register
);
773 Op
->Reg
.RegNum
= RegNo
;
780 static std::unique_ptr
<RISCVOperand
> createImm(const MCExpr
*Val
, SMLoc S
,
781 SMLoc E
, bool IsRV64
) {
782 auto Op
= std::make_unique
<RISCVOperand
>(KindTy::Immediate
);
790 static std::unique_ptr
<RISCVOperand
>
791 createSysReg(StringRef Str
, SMLoc S
, unsigned Encoding
, bool IsRV64
) {
792 auto Op
= std::make_unique
<RISCVOperand
>(KindTy::SystemRegister
);
793 Op
->SysReg
.Data
= Str
.data();
794 Op
->SysReg
.Length
= Str
.size();
795 Op
->SysReg
.Encoding
= Encoding
;
801 static std::unique_ptr
<RISCVOperand
> createVType(unsigned VTypeI
, SMLoc S
,
803 auto Op
= std::make_unique
<RISCVOperand
>(KindTy::VType
);
804 Op
->VType
.Val
= VTypeI
;
810 void addExpr(MCInst
&Inst
, const MCExpr
*Expr
) const {
811 assert(Expr
&& "Expr shouldn't be null!");
813 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::VK_RISCV_None
;
814 bool IsConstant
= evaluateConstantImm(Expr
, Imm
, VK
);
817 Inst
.addOperand(MCOperand::createImm(Imm
));
819 Inst
.addOperand(MCOperand::createExpr(Expr
));
822 // Used by the TableGen Code
823 void addRegOperands(MCInst
&Inst
, unsigned N
) const {
824 assert(N
== 1 && "Invalid number of operands!");
825 Inst
.addOperand(MCOperand::createReg(getReg()));
828 void addImmOperands(MCInst
&Inst
, unsigned N
) const {
829 assert(N
== 1 && "Invalid number of operands!");
830 addExpr(Inst
, getImm());
833 void addFenceArgOperands(MCInst
&Inst
, unsigned N
) const {
834 assert(N
== 1 && "Invalid number of operands!");
835 // isFenceArg has validated the operand, meaning this cast is safe
836 auto SE
= cast
<MCSymbolRefExpr
>(getImm());
839 for (char c
: SE
->getSymbol().getName()) {
842 llvm_unreachable("FenceArg must contain only [iorw]");
844 Imm
|= RISCVFenceField::I
;
847 Imm
|= RISCVFenceField::O
;
850 Imm
|= RISCVFenceField::R
;
853 Imm
|= RISCVFenceField::W
;
857 Inst
.addOperand(MCOperand::createImm(Imm
));
860 void addCSRSystemRegisterOperands(MCInst
&Inst
, unsigned N
) const {
861 assert(N
== 1 && "Invalid number of operands!");
862 Inst
.addOperand(MCOperand::createImm(SysReg
.Encoding
));
865 void addVTypeIOperands(MCInst
&Inst
, unsigned N
) const {
866 assert(N
== 1 && "Invalid number of operands!");
867 Inst
.addOperand(MCOperand::createImm(getVType()));
870 // Returns the rounding mode represented by this RISCVOperand. Should only
871 // be called after checking isFRMArg.
872 RISCVFPRndMode::RoundingMode
getRoundingMode() const {
873 // isFRMArg has validated the operand, meaning this cast is safe.
874 auto SE
= cast
<MCSymbolRefExpr
>(getImm());
875 RISCVFPRndMode::RoundingMode FRM
=
876 RISCVFPRndMode::stringToRoundingMode(SE
->getSymbol().getName());
877 assert(FRM
!= RISCVFPRndMode::Invalid
&& "Invalid rounding mode");
881 void addFRMArgOperands(MCInst
&Inst
, unsigned N
) const {
882 assert(N
== 1 && "Invalid number of operands!");
883 Inst
.addOperand(MCOperand::createImm(getRoundingMode()));
886 } // end anonymous namespace.
888 #define GET_REGISTER_MATCHER
889 #define GET_SUBTARGET_FEATURE_NAME
890 #define GET_MATCHER_IMPLEMENTATION
891 #define GET_MNEMONIC_SPELL_CHECKER
892 #include "RISCVGenAsmMatcher.inc"
894 static MCRegister
convertFPR64ToFPR16(MCRegister Reg
) {
895 assert(Reg
>= RISCV::F0_D
&& Reg
<= RISCV::F31_D
&& "Invalid register");
896 return Reg
- RISCV::F0_D
+ RISCV::F0_H
;
899 static MCRegister
convertFPR64ToFPR32(MCRegister Reg
) {
900 assert(Reg
>= RISCV::F0_D
&& Reg
<= RISCV::F31_D
&& "Invalid register");
901 return Reg
- RISCV::F0_D
+ RISCV::F0_F
;
904 static MCRegister
convertVRToVRMx(const MCRegisterInfo
&RI
, MCRegister Reg
,
907 if (Kind
== MCK_VRM2
)
908 RegClassID
= RISCV::VRM2RegClassID
;
909 else if (Kind
== MCK_VRM4
)
910 RegClassID
= RISCV::VRM4RegClassID
;
911 else if (Kind
== MCK_VRM8
)
912 RegClassID
= RISCV::VRM8RegClassID
;
915 return RI
.getMatchingSuperReg(Reg
, RISCV::sub_vrm1_0
,
916 &RISCVMCRegisterClasses
[RegClassID
]);
919 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand
&AsmOp
,
921 RISCVOperand
&Op
= static_cast<RISCVOperand
&>(AsmOp
);
923 return Match_InvalidOperand
;
925 MCRegister Reg
= Op
.getReg();
927 RISCVMCRegisterClasses
[RISCV::FPR64RegClassID
].contains(Reg
);
929 RISCVMCRegisterClasses
[RISCV::FPR64CRegClassID
].contains(Reg
);
930 bool IsRegVR
= RISCVMCRegisterClasses
[RISCV::VRRegClassID
].contains(Reg
);
932 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the
933 // register from FPR64 to FPR32 or FPR64C to FPR32C if necessary.
934 if ((IsRegFPR64
&& Kind
== MCK_FPR32
) ||
935 (IsRegFPR64C
&& Kind
== MCK_FPR32C
)) {
936 Op
.Reg
.RegNum
= convertFPR64ToFPR32(Reg
);
937 return Match_Success
;
939 // As the parser couldn't differentiate an FPR16 from an FPR64, coerce the
940 // register from FPR64 to FPR16 if necessary.
941 if (IsRegFPR64
&& Kind
== MCK_FPR16
) {
942 Op
.Reg
.RegNum
= convertFPR64ToFPR16(Reg
);
943 return Match_Success
;
945 // As the parser couldn't differentiate an VRM2/VRM4/VRM8 from an VR, coerce
946 // the register from VR to VRM2/VRM4/VRM8 if necessary.
947 if (IsRegVR
&& (Kind
== MCK_VRM2
|| Kind
== MCK_VRM4
|| Kind
== MCK_VRM8
)) {
948 Op
.Reg
.RegNum
= convertVRToVRMx(*getContext().getRegisterInfo(), Reg
, Kind
);
949 if (Op
.Reg
.RegNum
== 0)
950 return Match_InvalidOperand
;
951 return Match_Success
;
953 return Match_InvalidOperand
;
956 bool RISCVAsmParser::generateImmOutOfRangeError(
957 OperandVector
&Operands
, uint64_t ErrorInfo
, int64_t Lower
, int64_t Upper
,
958 Twine Msg
= "immediate must be an integer in the range") {
959 SMLoc ErrorLoc
= ((RISCVOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
960 return Error(ErrorLoc
, Msg
+ " [" + Twine(Lower
) + ", " + Twine(Upper
) + "]");
963 static std::string
RISCVMnemonicSpellCheck(StringRef S
,
964 const FeatureBitset
&FBS
,
965 unsigned VariantID
= 0);
967 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc
, unsigned &Opcode
,
968 OperandVector
&Operands
,
971 bool MatchingInlineAsm
) {
973 FeatureBitset MissingFeatures
;
975 auto Result
= MatchInstructionImpl(Operands
, Inst
, ErrorInfo
, MissingFeatures
,
981 if (validateInstruction(Inst
, Operands
))
983 return processInstruction(Inst
, IDLoc
, Operands
, Out
);
984 case Match_MissingFeature
: {
985 assert(MissingFeatures
.any() && "Unknown missing features!");
986 bool FirstFeature
= true;
987 std::string Msg
= "instruction requires the following:";
988 for (unsigned i
= 0, e
= MissingFeatures
.size(); i
!= e
; ++i
) {
989 if (MissingFeatures
[i
]) {
990 Msg
+= FirstFeature
? " " : ", ";
991 Msg
+= getSubtargetFeatureName(i
);
992 FirstFeature
= false;
995 return Error(IDLoc
, Msg
);
997 case Match_MnemonicFail
: {
998 FeatureBitset FBS
= ComputeAvailableFeatures(getSTI().getFeatureBits());
999 std::string Suggestion
=
1000 RISCVMnemonicSpellCheck(((RISCVOperand
&)*Operands
[0]).getToken(), FBS
);
1001 return Error(IDLoc
, "unrecognized instruction mnemonic" + Suggestion
);
1003 case Match_InvalidOperand
: {
1004 SMLoc ErrorLoc
= IDLoc
;
1005 if (ErrorInfo
!= ~0U) {
1006 if (ErrorInfo
>= Operands
.size())
1007 return Error(ErrorLoc
, "too few operands for instruction");
1009 ErrorLoc
= ((RISCVOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
1010 if (ErrorLoc
== SMLoc())
1013 return Error(ErrorLoc
, "invalid operand for instruction");
1017 // Handle the case when the error message is of specific type
1018 // other than the generic Match_InvalidOperand, and the
1019 // corresponding operand is missing.
1020 if (Result
> FIRST_TARGET_MATCH_RESULT_TY
) {
1021 SMLoc ErrorLoc
= IDLoc
;
1022 if (ErrorInfo
!= ~0U && ErrorInfo
>= Operands
.size())
1023 return Error(ErrorLoc
, "too few operands for instruction");
1029 case Match_InvalidImmXLenLI
:
1031 SMLoc ErrorLoc
= ((RISCVOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
1032 return Error(ErrorLoc
, "operand must be a constant 64-bit integer");
1034 return generateImmOutOfRangeError(Operands
, ErrorInfo
,
1035 std::numeric_limits
<int32_t>::min(),
1036 std::numeric_limits
<uint32_t>::max());
1037 case Match_InvalidImmZero
: {
1038 SMLoc ErrorLoc
= ((RISCVOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
1039 return Error(ErrorLoc
, "immediate must be zero");
1041 case Match_InvalidUImmLog2XLen
:
1043 return generateImmOutOfRangeError(Operands
, ErrorInfo
, 0, (1 << 6) - 1);
1044 return generateImmOutOfRangeError(Operands
, ErrorInfo
, 0, (1 << 5) - 1);
1045 case Match_InvalidUImmLog2XLenNonZero
:
1047 return generateImmOutOfRangeError(Operands
, ErrorInfo
, 1, (1 << 6) - 1);
1048 return generateImmOutOfRangeError(Operands
, ErrorInfo
, 1, (1 << 5) - 1);
1049 case Match_InvalidUImmLog2XLenHalf
:
1051 return generateImmOutOfRangeError(Operands
, ErrorInfo
, 0, (1 << 5) - 1);
1052 return generateImmOutOfRangeError(Operands
, ErrorInfo
, 0, (1 << 4) - 1);
1053 case Match_InvalidUImm5
:
1054 return generateImmOutOfRangeError(Operands
, ErrorInfo
, 0, (1 << 5) - 1);
1055 case Match_InvalidSImm5
:
1056 return generateImmOutOfRangeError(Operands
, ErrorInfo
, -(1 << 4),
1058 case Match_InvalidSImm6
:
1059 return generateImmOutOfRangeError(Operands
, ErrorInfo
, -(1 << 5),
1061 case Match_InvalidSImm6NonZero
:
1062 return generateImmOutOfRangeError(
1063 Operands
, ErrorInfo
, -(1 << 5), (1 << 5) - 1,
1064 "immediate must be non-zero in the range");
1065 case Match_InvalidCLUIImm
:
1066 return generateImmOutOfRangeError(
1067 Operands
, ErrorInfo
, 1, (1 << 5) - 1,
1068 "immediate must be in [0xfffe0, 0xfffff] or");
1069 case Match_InvalidUImm7Lsb00
:
1070 return generateImmOutOfRangeError(
1071 Operands
, ErrorInfo
, 0, (1 << 7) - 4,
1072 "immediate must be a multiple of 4 bytes in the range");
1073 case Match_InvalidUImm8Lsb00
:
1074 return generateImmOutOfRangeError(
1075 Operands
, ErrorInfo
, 0, (1 << 8) - 4,
1076 "immediate must be a multiple of 4 bytes in the range");
1077 case Match_InvalidUImm8Lsb000
:
1078 return generateImmOutOfRangeError(
1079 Operands
, ErrorInfo
, 0, (1 << 8) - 8,
1080 "immediate must be a multiple of 8 bytes in the range");
1081 case Match_InvalidSImm9Lsb0
:
1082 return generateImmOutOfRangeError(
1083 Operands
, ErrorInfo
, -(1 << 8), (1 << 8) - 2,
1084 "immediate must be a multiple of 2 bytes in the range");
1085 case Match_InvalidUImm9Lsb000
:
1086 return generateImmOutOfRangeError(
1087 Operands
, ErrorInfo
, 0, (1 << 9) - 8,
1088 "immediate must be a multiple of 8 bytes in the range");
1089 case Match_InvalidUImm10Lsb00NonZero
:
1090 return generateImmOutOfRangeError(
1091 Operands
, ErrorInfo
, 4, (1 << 10) - 4,
1092 "immediate must be a multiple of 4 bytes in the range");
1093 case Match_InvalidSImm10Lsb0000NonZero
:
1094 return generateImmOutOfRangeError(
1095 Operands
, ErrorInfo
, -(1 << 9), (1 << 9) - 16,
1096 "immediate must be a multiple of 16 bytes and non-zero in the range");
1097 case Match_InvalidSImm12
:
1098 return generateImmOutOfRangeError(
1099 Operands
, ErrorInfo
, -(1 << 11), (1 << 11) - 1,
1100 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1101 "integer in the range");
1102 case Match_InvalidSImm12Lsb0
:
1103 return generateImmOutOfRangeError(
1104 Operands
, ErrorInfo
, -(1 << 11), (1 << 11) - 2,
1105 "immediate must be a multiple of 2 bytes in the range");
1106 case Match_InvalidSImm13Lsb0
:
1107 return generateImmOutOfRangeError(
1108 Operands
, ErrorInfo
, -(1 << 12), (1 << 12) - 2,
1109 "immediate must be a multiple of 2 bytes in the range");
1110 case Match_InvalidUImm20LUI
:
1111 return generateImmOutOfRangeError(Operands
, ErrorInfo
, 0, (1 << 20) - 1,
1112 "operand must be a symbol with "
1113 "%hi/%tprel_hi modifier or an integer in "
1115 case Match_InvalidUImm20AUIPC
:
1116 return generateImmOutOfRangeError(
1117 Operands
, ErrorInfo
, 0, (1 << 20) - 1,
1118 "operand must be a symbol with a "
1119 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1120 "an integer in the range");
1121 case Match_InvalidSImm21Lsb0JAL
:
1122 return generateImmOutOfRangeError(
1123 Operands
, ErrorInfo
, -(1 << 20), (1 << 20) - 2,
1124 "immediate must be a multiple of 2 bytes in the range");
1125 case Match_InvalidCSRSystemRegister
: {
1126 return generateImmOutOfRangeError(Operands
, ErrorInfo
, 0, (1 << 12) - 1,
1127 "operand must be a valid system register "
1128 "name or an integer in the range");
1130 case Match_InvalidFenceArg
: {
1131 SMLoc ErrorLoc
= ((RISCVOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
1134 "operand must be formed of letters selected in-order from 'iorw'");
1136 case Match_InvalidFRMArg
: {
1137 SMLoc ErrorLoc
= ((RISCVOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
1140 "operand must be a valid floating point rounding mode mnemonic");
1142 case Match_InvalidBareSymbol
: {
1143 SMLoc ErrorLoc
= ((RISCVOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
1144 return Error(ErrorLoc
, "operand must be a bare symbol name");
1146 case Match_InvalidPseudoJumpSymbol
: {
1147 SMLoc ErrorLoc
= ((RISCVOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
1148 return Error(ErrorLoc
, "operand must be a valid jump target");
1150 case Match_InvalidCallSymbol
: {
1151 SMLoc ErrorLoc
= ((RISCVOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
1152 return Error(ErrorLoc
, "operand must be a bare symbol name");
1154 case Match_InvalidTPRelAddSymbol
: {
1155 SMLoc ErrorLoc
= ((RISCVOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
1156 return Error(ErrorLoc
, "operand must be a symbol with %tprel_add modifier");
1158 case Match_InvalidVTypeI
: {
1159 SMLoc ErrorLoc
= ((RISCVOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
1163 "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
1165 case Match_InvalidVMaskRegister
: {
1166 SMLoc ErrorLoc
= ((RISCVOperand
&)*Operands
[ErrorInfo
]).getStartLoc();
1167 return Error(ErrorLoc
, "operand must be v0.t");
1169 case Match_InvalidSImm5Plus1
: {
1170 return generateImmOutOfRangeError(Operands
, ErrorInfo
, -(1 << 4) + 1,
1172 "immediate must be in the range");
1176 llvm_unreachable("Unknown match type detected!");
1179 // Attempts to match Name as a register (either using the default name or
1180 // alternative ABI names), setting RegNo to the matching register. Upon
1181 // failure, returns true and sets RegNo to 0. If IsRV32E then registers
1182 // x16-x31 will be rejected.
1183 static bool matchRegisterNameHelper(bool IsRV32E
, MCRegister
&RegNo
,
1185 RegNo
= MatchRegisterName(Name
);
1186 // The 16-/32- and 64-bit FPRs have the same asm name. Check that the initial
1187 // match always matches the 64-bit variant, and not the 16/32-bit one.
1188 assert(!(RegNo
>= RISCV::F0_H
&& RegNo
<= RISCV::F31_H
));
1189 assert(!(RegNo
>= RISCV::F0_F
&& RegNo
<= RISCV::F31_F
));
1190 // The default FPR register class is based on the tablegen enum ordering.
1191 static_assert(RISCV::F0_D
< RISCV::F0_H
, "FPR matching must be updated");
1192 static_assert(RISCV::F0_D
< RISCV::F0_F
, "FPR matching must be updated");
1193 if (RegNo
== RISCV::NoRegister
)
1194 RegNo
= MatchRegisterAltName(Name
);
1195 if (IsRV32E
&& RegNo
>= RISCV::X16
&& RegNo
<= RISCV::X31
)
1196 RegNo
= RISCV::NoRegister
;
1197 return RegNo
== RISCV::NoRegister
;
1200 bool RISCVAsmParser::ParseRegister(unsigned &RegNo
, SMLoc
&StartLoc
,
1202 if (tryParseRegister(RegNo
, StartLoc
, EndLoc
) != MatchOperand_Success
)
1203 return Error(StartLoc
, "invalid register name");
1207 OperandMatchResultTy
RISCVAsmParser::tryParseRegister(unsigned &RegNo
,
1210 const AsmToken
&Tok
= getParser().getTok();
1211 StartLoc
= Tok
.getLoc();
1212 EndLoc
= Tok
.getEndLoc();
1214 StringRef Name
= getLexer().getTok().getIdentifier();
1216 if (matchRegisterNameHelper(isRV32E(), (MCRegister
&)RegNo
, Name
))
1217 return MatchOperand_NoMatch
;
1219 getParser().Lex(); // Eat identifier token.
1220 return MatchOperand_Success
;
1223 OperandMatchResultTy
RISCVAsmParser::parseRegister(OperandVector
&Operands
,
1225 SMLoc FirstS
= getLoc();
1226 bool HadParens
= false;
1229 // If this is an LParen and a parenthesised register name is allowed, parse it
1231 if (AllowParens
&& getLexer().is(AsmToken::LParen
)) {
1233 size_t ReadCount
= getLexer().peekTokens(Buf
);
1234 if (ReadCount
== 2 && Buf
[1].getKind() == AsmToken::RParen
) {
1236 LParen
= getParser().getTok();
1237 getParser().Lex(); // Eat '('
1241 switch (getLexer().getKind()) {
1244 getLexer().UnLex(LParen
);
1245 return MatchOperand_NoMatch
;
1246 case AsmToken::Identifier
:
1247 StringRef Name
= getLexer().getTok().getIdentifier();
1249 matchRegisterNameHelper(isRV32E(), RegNo
, Name
);
1251 if (RegNo
== RISCV::NoRegister
) {
1253 getLexer().UnLex(LParen
);
1254 return MatchOperand_NoMatch
;
1257 Operands
.push_back(RISCVOperand::createToken("(", FirstS
, isRV64()));
1259 SMLoc E
= SMLoc::getFromPointer(S
.getPointer() - 1);
1261 Operands
.push_back(RISCVOperand::createReg(RegNo
, S
, E
, isRV64()));
1265 getParser().Lex(); // Eat ')'
1266 Operands
.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
1269 return MatchOperand_Success
;
1272 OperandMatchResultTy
1273 RISCVAsmParser::parseCSRSystemRegister(OperandVector
&Operands
) {
1277 switch (getLexer().getKind()) {
1279 return MatchOperand_NoMatch
;
1280 case AsmToken::LParen
:
1281 case AsmToken::Minus
:
1282 case AsmToken::Plus
:
1283 case AsmToken::Exclaim
:
1284 case AsmToken::Tilde
:
1285 case AsmToken::Integer
:
1286 case AsmToken::String
: {
1287 if (getParser().parseExpression(Res
))
1288 return MatchOperand_ParseFail
;
1290 auto *CE
= dyn_cast
<MCConstantExpr
>(Res
);
1292 int64_t Imm
= CE
->getValue();
1293 if (isUInt
<12>(Imm
)) {
1294 auto SysReg
= RISCVSysReg::lookupSysRegByEncoding(Imm
);
1295 // Accept an immediate representing a named or un-named Sys Reg
1296 // if the range is valid, regardless of the required features.
1297 Operands
.push_back(RISCVOperand::createSysReg(
1298 SysReg
? SysReg
->Name
: "", S
, Imm
, isRV64()));
1299 return MatchOperand_Success
;
1303 Twine Msg
= "immediate must be an integer in the range";
1304 Error(S
, Msg
+ " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1305 return MatchOperand_ParseFail
;
1307 case AsmToken::Identifier
: {
1308 StringRef Identifier
;
1309 if (getParser().parseIdentifier(Identifier
))
1310 return MatchOperand_ParseFail
;
1312 auto SysReg
= RISCVSysReg::lookupSysRegByName(Identifier
);
1314 SysReg
= RISCVSysReg::lookupSysRegByAltName(Identifier
);
1316 if ((SysReg
= RISCVSysReg::lookupSysRegByDeprecatedName(Identifier
)))
1317 Warning(S
, "'" + Identifier
+ "' is a deprecated alias for '" +
1318 SysReg
->Name
+ "'");
1320 // Accept a named Sys Reg if the required features are present.
1322 if (!SysReg
->haveRequiredFeatures(getSTI().getFeatureBits())) {
1323 Error(S
, "system register use requires an option to be enabled");
1324 return MatchOperand_ParseFail
;
1326 Operands
.push_back(RISCVOperand::createSysReg(
1327 Identifier
, S
, SysReg
->Encoding
, isRV64()));
1328 return MatchOperand_Success
;
1331 Twine Msg
= "operand must be a valid system register name "
1332 "or an integer in the range";
1333 Error(S
, Msg
+ " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1334 return MatchOperand_ParseFail
;
1336 case AsmToken::Percent
: {
1337 // Discard operand with modifier.
1338 Twine Msg
= "immediate must be an integer in the range";
1339 Error(S
, Msg
+ " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]");
1340 return MatchOperand_ParseFail
;
1344 return MatchOperand_NoMatch
;
1347 OperandMatchResultTy
RISCVAsmParser::parseImmediate(OperandVector
&Operands
) {
1349 SMLoc E
= SMLoc::getFromPointer(S
.getPointer() - 1);
1352 switch (getLexer().getKind()) {
1354 return MatchOperand_NoMatch
;
1355 case AsmToken::LParen
:
1357 case AsmToken::Minus
:
1358 case AsmToken::Plus
:
1359 case AsmToken::Exclaim
:
1360 case AsmToken::Tilde
:
1361 case AsmToken::Integer
:
1362 case AsmToken::String
:
1363 case AsmToken::Identifier
:
1364 if (getParser().parseExpression(Res
))
1365 return MatchOperand_ParseFail
;
1367 case AsmToken::Percent
:
1368 return parseOperandWithModifier(Operands
);
1371 Operands
.push_back(RISCVOperand::createImm(Res
, S
, E
, isRV64()));
1372 return MatchOperand_Success
;
1375 OperandMatchResultTy
1376 RISCVAsmParser::parseOperandWithModifier(OperandVector
&Operands
) {
1378 SMLoc E
= SMLoc::getFromPointer(S
.getPointer() - 1);
1380 if (getLexer().getKind() != AsmToken::Percent
) {
1381 Error(getLoc(), "expected '%' for operand modifier");
1382 return MatchOperand_ParseFail
;
1385 getParser().Lex(); // Eat '%'
1387 if (getLexer().getKind() != AsmToken::Identifier
) {
1388 Error(getLoc(), "expected valid identifier for operand modifier");
1389 return MatchOperand_ParseFail
;
1391 StringRef Identifier
= getParser().getTok().getIdentifier();
1392 RISCVMCExpr::VariantKind VK
= RISCVMCExpr::getVariantKindForName(Identifier
);
1393 if (VK
== RISCVMCExpr::VK_RISCV_Invalid
) {
1394 Error(getLoc(), "unrecognized operand modifier");
1395 return MatchOperand_ParseFail
;
1398 getParser().Lex(); // Eat the identifier
1399 if (getLexer().getKind() != AsmToken::LParen
) {
1400 Error(getLoc(), "expected '('");
1401 return MatchOperand_ParseFail
;
1403 getParser().Lex(); // Eat '('
1405 const MCExpr
*SubExpr
;
1406 if (getParser().parseParenExpression(SubExpr
, E
)) {
1407 return MatchOperand_ParseFail
;
1410 const MCExpr
*ModExpr
= RISCVMCExpr::create(SubExpr
, VK
, getContext());
1411 Operands
.push_back(RISCVOperand::createImm(ModExpr
, S
, E
, isRV64()));
1412 return MatchOperand_Success
;
1415 OperandMatchResultTy
RISCVAsmParser::parseBareSymbol(OperandVector
&Operands
) {
1417 SMLoc E
= SMLoc::getFromPointer(S
.getPointer() - 1);
1420 if (getLexer().getKind() != AsmToken::Identifier
)
1421 return MatchOperand_NoMatch
;
1423 StringRef Identifier
;
1424 AsmToken Tok
= getLexer().getTok();
1426 if (getParser().parseIdentifier(Identifier
))
1427 return MatchOperand_ParseFail
;
1429 if (Identifier
.consume_back("@plt")) {
1430 Error(getLoc(), "'@plt' operand not valid for instruction");
1431 return MatchOperand_ParseFail
;
1434 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Identifier
);
1436 if (Sym
->isVariable()) {
1437 const MCExpr
*V
= Sym
->getVariableValue(/*SetUsed=*/false);
1438 if (!isa
<MCSymbolRefExpr
>(V
)) {
1439 getLexer().UnLex(Tok
); // Put back if it's not a bare symbol.
1440 return MatchOperand_NoMatch
;
1444 Res
= MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
1446 MCBinaryExpr::Opcode Opcode
;
1447 switch (getLexer().getKind()) {
1449 Operands
.push_back(RISCVOperand::createImm(Res
, S
, E
, isRV64()));
1450 return MatchOperand_Success
;
1451 case AsmToken::Plus
:
1452 Opcode
= MCBinaryExpr::Add
;
1454 case AsmToken::Minus
:
1455 Opcode
= MCBinaryExpr::Sub
;
1460 if (getParser().parseExpression(Expr
))
1461 return MatchOperand_ParseFail
;
1462 Res
= MCBinaryExpr::create(Opcode
, Res
, Expr
, getContext());
1463 Operands
.push_back(RISCVOperand::createImm(Res
, S
, E
, isRV64()));
1464 return MatchOperand_Success
;
1467 OperandMatchResultTy
RISCVAsmParser::parseCallSymbol(OperandVector
&Operands
) {
1469 SMLoc E
= SMLoc::getFromPointer(S
.getPointer() - 1);
1472 if (getLexer().getKind() != AsmToken::Identifier
)
1473 return MatchOperand_NoMatch
;
1475 // Avoid parsing the register in `call rd, foo` as a call symbol.
1476 if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement
)
1477 return MatchOperand_NoMatch
;
1479 StringRef Identifier
;
1480 if (getParser().parseIdentifier(Identifier
))
1481 return MatchOperand_ParseFail
;
1483 RISCVMCExpr::VariantKind Kind
= RISCVMCExpr::VK_RISCV_CALL
;
1484 if (Identifier
.consume_back("@plt"))
1485 Kind
= RISCVMCExpr::VK_RISCV_CALL_PLT
;
1487 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Identifier
);
1488 Res
= MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, getContext());
1489 Res
= RISCVMCExpr::create(Res
, Kind
, getContext());
1490 Operands
.push_back(RISCVOperand::createImm(Res
, S
, E
, isRV64()));
1491 return MatchOperand_Success
;
1494 OperandMatchResultTy
1495 RISCVAsmParser::parsePseudoJumpSymbol(OperandVector
&Operands
) {
1497 SMLoc E
= SMLoc::getFromPointer(S
.getPointer() - 1);
1500 if (getParser().parseExpression(Res
))
1501 return MatchOperand_ParseFail
;
1503 if (Res
->getKind() != MCExpr::ExprKind::SymbolRef
||
1504 cast
<MCSymbolRefExpr
>(Res
)->getKind() ==
1505 MCSymbolRefExpr::VariantKind::VK_PLT
) {
1506 Error(S
, "operand must be a valid jump target");
1507 return MatchOperand_ParseFail
;
1510 Res
= RISCVMCExpr::create(Res
, RISCVMCExpr::VK_RISCV_CALL
, getContext());
1511 Operands
.push_back(RISCVOperand::createImm(Res
, S
, E
, isRV64()));
1512 return MatchOperand_Success
;
1515 OperandMatchResultTy
RISCVAsmParser::parseJALOffset(OperandVector
&Operands
) {
1516 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo`
1517 // both being acceptable forms. When parsing `jal ra, foo` this function
1518 // will be called for the `ra` register operand in an attempt to match the
1519 // single-operand alias. parseJALOffset must fail for this case. It would
1520 // seem logical to try parse the operand using parseImmediate and return
1521 // NoMatch if the next token is a comma (meaning we must be parsing a jal in
1522 // the second form rather than the first). We can't do this as there's no
1523 // way of rewinding the lexer state. Instead, return NoMatch if this operand
1524 // is an identifier and is followed by a comma.
1525 if (getLexer().is(AsmToken::Identifier
) &&
1526 getLexer().peekTok().is(AsmToken::Comma
))
1527 return MatchOperand_NoMatch
;
1529 return parseImmediate(Operands
);
1532 OperandMatchResultTy
RISCVAsmParser::parseVTypeI(OperandVector
&Operands
) {
1534 if (getLexer().isNot(AsmToken::Identifier
))
1535 return MatchOperand_NoMatch
;
1537 SmallVector
<AsmToken
, 7> VTypeIElements
;
1538 // Put all the tokens for vtypei operand into VTypeIElements vector.
1539 while (getLexer().isNot(AsmToken::EndOfStatement
)) {
1540 VTypeIElements
.push_back(getLexer().getTok());
1542 if (getLexer().is(AsmToken::EndOfStatement
))
1544 if (getLexer().isNot(AsmToken::Comma
))
1546 AsmToken Comma
= getLexer().getTok();
1547 VTypeIElements
.push_back(Comma
);
1551 if (VTypeIElements
.size() == 7) {
1552 // The VTypeIElements layout is:
1553 // SEW comma LMUL comma TA comma MA
1555 StringRef Name
= VTypeIElements
[0].getIdentifier();
1556 if (!Name
.consume_front("e"))
1559 if (Name
.getAsInteger(10, Sew
))
1561 if (!RISCVVType::isValidSEW(Sew
))
1564 Name
= VTypeIElements
[2].getIdentifier();
1565 if (!Name
.consume_front("m"))
1568 bool Fractional
= Name
.consume_front("f");
1570 if (Name
.getAsInteger(10, Lmul
))
1572 if (!RISCVVType::isValidLMUL(Lmul
, Fractional
))
1576 Name
= VTypeIElements
[4].getIdentifier();
1579 TailAgnostic
= true;
1580 else if (Name
== "tu")
1581 TailAgnostic
= false;
1586 Name
= VTypeIElements
[6].getIdentifier();
1589 MaskAgnostic
= true;
1590 else if (Name
== "mu")
1591 MaskAgnostic
= false;
1595 unsigned LmulLog2
= Log2_32(Lmul
);
1596 RISCVII::VLMUL VLMUL
=
1597 static_cast<RISCVII::VLMUL
>(Fractional
? 8 - LmulLog2
: LmulLog2
);
1600 RISCVVType::encodeVTYPE(VLMUL
, Sew
, TailAgnostic
, MaskAgnostic
);
1601 Operands
.push_back(RISCVOperand::createVType(VTypeI
, S
, isRV64()));
1602 return MatchOperand_Success
;
1605 // If NoMatch, unlex all the tokens that comprise a vtypei operand
1607 while (!VTypeIElements
.empty())
1608 getLexer().UnLex(VTypeIElements
.pop_back_val());
1609 return MatchOperand_NoMatch
;
1612 OperandMatchResultTy
RISCVAsmParser::parseMaskReg(OperandVector
&Operands
) {
1613 switch (getLexer().getKind()) {
1615 return MatchOperand_NoMatch
;
1616 case AsmToken::Identifier
:
1617 StringRef Name
= getLexer().getTok().getIdentifier();
1618 if (!Name
.consume_back(".t")) {
1619 Error(getLoc(), "expected '.t' suffix");
1620 return MatchOperand_ParseFail
;
1623 matchRegisterNameHelper(isRV32E(), RegNo
, Name
);
1625 if (RegNo
== RISCV::NoRegister
)
1626 return MatchOperand_NoMatch
;
1627 if (RegNo
!= RISCV::V0
)
1628 return MatchOperand_NoMatch
;
1630 SMLoc E
= SMLoc::getFromPointer(S
.getPointer() - 1);
1632 Operands
.push_back(RISCVOperand::createReg(RegNo
, S
, E
, isRV64()));
1635 return MatchOperand_Success
;
1638 OperandMatchResultTy
1639 RISCVAsmParser::parseMemOpBaseReg(OperandVector
&Operands
) {
1640 if (getLexer().isNot(AsmToken::LParen
)) {
1641 Error(getLoc(), "expected '('");
1642 return MatchOperand_ParseFail
;
1645 getParser().Lex(); // Eat '('
1646 Operands
.push_back(RISCVOperand::createToken("(", getLoc(), isRV64()));
1648 if (parseRegister(Operands
) != MatchOperand_Success
) {
1649 Error(getLoc(), "expected register");
1650 return MatchOperand_ParseFail
;
1653 if (getLexer().isNot(AsmToken::RParen
)) {
1654 Error(getLoc(), "expected ')'");
1655 return MatchOperand_ParseFail
;
1658 getParser().Lex(); // Eat ')'
1659 Operands
.push_back(RISCVOperand::createToken(")", getLoc(), isRV64()));
1661 return MatchOperand_Success
;
1664 OperandMatchResultTy
RISCVAsmParser::parseAtomicMemOp(OperandVector
&Operands
) {
1665 // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand"
1666 // as one of their register operands, such as `(a0)`. This just denotes that
1667 // the register (in this case `a0`) contains a memory address.
1669 // Normally, we would be able to parse these by putting the parens into the
1670 // instruction string. However, GNU as also accepts a zero-offset memory
1671 // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed
1672 // with parseImmediate followed by parseMemOpBaseReg, but these instructions
1673 // do not accept an immediate operand, and we do not want to add a "dummy"
1674 // operand that is silently dropped.
1676 // Instead, we use this custom parser. This will: allow (and discard) an
1677 // offset if it is zero; require (and discard) parentheses; and add only the
1678 // parsed register operand to `Operands`.
1680 // These operands are printed with RISCVInstPrinter::printAtomicMemOp, which
1681 // will only print the register surrounded by parentheses (which GNU as also
1682 // uses as its canonical representation for these operands).
1683 std::unique_ptr
<RISCVOperand
> OptionalImmOp
;
1685 if (getLexer().isNot(AsmToken::LParen
)) {
1686 // Parse an Integer token. We do not accept arbritrary constant expressions
1687 // in the offset field (because they may include parens, which complicates
1690 SMLoc ImmStart
= getLoc();
1691 if (getParser().parseIntToken(ImmVal
,
1692 "expected '(' or optional integer offset"))
1693 return MatchOperand_ParseFail
;
1695 // Create a RISCVOperand for checking later (so the error messages are
1696 // nicer), but we don't add it to Operands.
1697 SMLoc ImmEnd
= getLoc();
1699 RISCVOperand::createImm(MCConstantExpr::create(ImmVal
, getContext()),
1700 ImmStart
, ImmEnd
, isRV64());
1703 if (getLexer().isNot(AsmToken::LParen
)) {
1704 Error(getLoc(), OptionalImmOp
? "expected '(' after optional integer offset"
1705 : "expected '(' or optional integer offset");
1706 return MatchOperand_ParseFail
;
1708 getParser().Lex(); // Eat '('
1710 if (parseRegister(Operands
) != MatchOperand_Success
) {
1711 Error(getLoc(), "expected register");
1712 return MatchOperand_ParseFail
;
1715 if (getLexer().isNot(AsmToken::RParen
)) {
1716 Error(getLoc(), "expected ')'");
1717 return MatchOperand_ParseFail
;
1719 getParser().Lex(); // Eat ')'
1721 // Deferred Handling of non-zero offsets. This makes the error messages nicer.
1722 if (OptionalImmOp
&& !OptionalImmOp
->isImmZero()) {
1723 Error(OptionalImmOp
->getStartLoc(), "optional integer offset must be 0",
1724 SMRange(OptionalImmOp
->getStartLoc(), OptionalImmOp
->getEndLoc()));
1725 return MatchOperand_ParseFail
;
1728 return MatchOperand_Success
;
1731 /// Looks at a token type and creates the relevant operand from this
1732 /// information, adding to Operands. If operand was parsed, returns false, else
1734 bool RISCVAsmParser::parseOperand(OperandVector
&Operands
, StringRef Mnemonic
) {
1735 // Check if the current operand has a custom associated parser, if so, try to
1736 // custom parse the operand, or fallback to the general approach.
1737 OperandMatchResultTy Result
=
1738 MatchOperandParserImpl(Operands
, Mnemonic
, /*ParseForAllFeatures=*/true);
1739 if (Result
== MatchOperand_Success
)
1741 if (Result
== MatchOperand_ParseFail
)
1744 // Attempt to parse token as a register.
1745 if (parseRegister(Operands
, true) == MatchOperand_Success
)
1748 // Attempt to parse token as an immediate
1749 if (parseImmediate(Operands
) == MatchOperand_Success
) {
1750 // Parse memory base register if present
1751 if (getLexer().is(AsmToken::LParen
))
1752 return parseMemOpBaseReg(Operands
) != MatchOperand_Success
;
1756 // Finally we have exhausted all options and must declare defeat.
1757 Error(getLoc(), "unknown operand");
1761 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo
&Info
,
1762 StringRef Name
, SMLoc NameLoc
,
1763 OperandVector
&Operands
) {
1764 // Ensure that if the instruction occurs when relaxation is enabled,
1765 // relocations are forced for the file. Ideally this would be done when there
1766 // is enough information to reliably determine if the instruction itself may
1767 // cause relaxations. Unfortunately instruction processing stage occurs in the
1768 // same pass as relocation emission, so it's too late to set a 'sticky bit'
1769 // for the entire file.
1770 if (getSTI().getFeatureBits()[RISCV::FeatureRelax
]) {
1771 auto *Assembler
= getTargetStreamer().getStreamer().getAssemblerPtr();
1772 if (Assembler
!= nullptr) {
1773 RISCVAsmBackend
&MAB
=
1774 static_cast<RISCVAsmBackend
&>(Assembler
->getBackend());
1775 MAB
.setForceRelocs();
1779 // First operand is token for instruction
1780 Operands
.push_back(RISCVOperand::createToken(Name
, NameLoc
, isRV64()));
1782 // If there are no more operands, then finish
1783 if (getLexer().is(AsmToken::EndOfStatement
))
1786 // Parse first operand
1787 if (parseOperand(Operands
, Name
))
1790 // Parse until end of statement, consuming commas between operands
1791 unsigned OperandIdx
= 1;
1792 while (getLexer().is(AsmToken::Comma
)) {
1793 // Consume comma token
1796 // Parse next operand
1797 if (parseOperand(Operands
, Name
))
1803 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
1804 SMLoc Loc
= getLexer().getLoc();
1805 getParser().eatToEndOfStatement();
1806 return Error(Loc
, "unexpected token");
1809 getParser().Lex(); // Consume the EndOfStatement.
1813 bool RISCVAsmParser::classifySymbolRef(const MCExpr
*Expr
,
1814 RISCVMCExpr::VariantKind
&Kind
) {
1815 Kind
= RISCVMCExpr::VK_RISCV_None
;
1817 if (const RISCVMCExpr
*RE
= dyn_cast
<RISCVMCExpr
>(Expr
)) {
1818 Kind
= RE
->getKind();
1819 Expr
= RE
->getSubExpr();
1824 if (Expr
->evaluateAsRelocatable(Res
, nullptr, &Fixup
))
1825 return Res
.getRefKind() == RISCVMCExpr::VK_RISCV_None
;
1829 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID
) {
1830 // This returns false if this function recognizes the directive
1831 // regardless of whether it is successfully handles or reports an
1832 // error. Otherwise it returns true to give the generic parser a
1833 // chance at recognizing it.
1834 StringRef IDVal
= DirectiveID
.getString();
1836 if (IDVal
== ".option")
1837 return parseDirectiveOption();
1838 else if (IDVal
== ".attribute")
1839 return parseDirectiveAttribute();
1844 bool RISCVAsmParser::parseDirectiveOption() {
1845 MCAsmParser
&Parser
= getParser();
1846 // Get the option token.
1847 AsmToken Tok
= Parser
.getTok();
1848 // At the moment only identifiers are supported.
1849 if (Tok
.isNot(AsmToken::Identifier
))
1850 return Error(Parser
.getTok().getLoc(),
1851 "unexpected token, expected identifier");
1853 StringRef Option
= Tok
.getIdentifier();
1855 if (Option
== "push") {
1856 getTargetStreamer().emitDirectiveOptionPush();
1859 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
))
1860 return Error(Parser
.getTok().getLoc(),
1861 "unexpected token, expected end of statement");
1867 if (Option
== "pop") {
1868 SMLoc StartLoc
= Parser
.getTok().getLoc();
1869 getTargetStreamer().emitDirectiveOptionPop();
1872 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
))
1873 return Error(Parser
.getTok().getLoc(),
1874 "unexpected token, expected end of statement");
1876 if (popFeatureBits())
1877 return Error(StartLoc
, ".option pop with no .option push");
1882 if (Option
== "rvc") {
1883 getTargetStreamer().emitDirectiveOptionRVC();
1886 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
))
1887 return Error(Parser
.getTok().getLoc(),
1888 "unexpected token, expected end of statement");
1890 setFeatureBits(RISCV::FeatureStdExtC
, "c");
1894 if (Option
== "norvc") {
1895 getTargetStreamer().emitDirectiveOptionNoRVC();
1898 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
))
1899 return Error(Parser
.getTok().getLoc(),
1900 "unexpected token, expected end of statement");
1902 clearFeatureBits(RISCV::FeatureStdExtC
, "c");
1906 if (Option
== "pic") {
1907 getTargetStreamer().emitDirectiveOptionPIC();
1910 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
))
1911 return Error(Parser
.getTok().getLoc(),
1912 "unexpected token, expected end of statement");
1914 ParserOptions
.IsPicEnabled
= true;
1918 if (Option
== "nopic") {
1919 getTargetStreamer().emitDirectiveOptionNoPIC();
1922 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
))
1923 return Error(Parser
.getTok().getLoc(),
1924 "unexpected token, expected end of statement");
1926 ParserOptions
.IsPicEnabled
= false;
1930 if (Option
== "relax") {
1931 getTargetStreamer().emitDirectiveOptionRelax();
1934 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
))
1935 return Error(Parser
.getTok().getLoc(),
1936 "unexpected token, expected end of statement");
1938 setFeatureBits(RISCV::FeatureRelax
, "relax");
1942 if (Option
== "norelax") {
1943 getTargetStreamer().emitDirectiveOptionNoRelax();
1946 if (Parser
.getTok().isNot(AsmToken::EndOfStatement
))
1947 return Error(Parser
.getTok().getLoc(),
1948 "unexpected token, expected end of statement");
1950 clearFeatureBits(RISCV::FeatureRelax
, "relax");
1955 Warning(Parser
.getTok().getLoc(),
1956 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or "
1958 Parser
.eatToEndOfStatement();
1962 /// parseDirectiveAttribute
1963 /// ::= .attribute expression ',' ( expression | "string" )
1964 /// ::= .attribute identifier ',' ( expression | "string" )
1965 bool RISCVAsmParser::parseDirectiveAttribute() {
1966 MCAsmParser
&Parser
= getParser();
1969 TagLoc
= Parser
.getTok().getLoc();
1970 if (Parser
.getTok().is(AsmToken::Identifier
)) {
1971 StringRef Name
= Parser
.getTok().getIdentifier();
1972 Optional
<unsigned> Ret
=
1973 ELFAttrs::attrTypeFromString(Name
, RISCVAttrs::getRISCVAttributeTags());
1974 if (!Ret
.hasValue()) {
1975 Error(TagLoc
, "attribute name not recognised: " + Name
);
1978 Tag
= Ret
.getValue();
1981 const MCExpr
*AttrExpr
;
1983 TagLoc
= Parser
.getTok().getLoc();
1984 if (Parser
.parseExpression(AttrExpr
))
1987 const MCConstantExpr
*CE
= dyn_cast
<MCConstantExpr
>(AttrExpr
);
1988 if (check(!CE
, TagLoc
, "expected numeric constant"))
1991 Tag
= CE
->getValue();
1994 if (Parser
.parseToken(AsmToken::Comma
, "comma expected"))
1997 StringRef StringValue
;
1998 int64_t IntegerValue
= 0;
1999 bool IsIntegerValue
= true;
2001 // RISC-V attributes have a string value if the tag number is odd
2002 // and an integer value if the tag number is even.
2004 IsIntegerValue
= false;
2006 SMLoc ValueExprLoc
= Parser
.getTok().getLoc();
2007 if (IsIntegerValue
) {
2008 const MCExpr
*ValueExpr
;
2009 if (Parser
.parseExpression(ValueExpr
))
2012 const MCConstantExpr
*CE
= dyn_cast
<MCConstantExpr
>(ValueExpr
);
2014 return Error(ValueExprLoc
, "expected numeric constant");
2015 IntegerValue
= CE
->getValue();
2017 if (Parser
.getTok().isNot(AsmToken::String
))
2018 return Error(Parser
.getTok().getLoc(), "expected string constant");
2020 StringValue
= Parser
.getTok().getStringContents();
2024 if (Parser
.parseToken(AsmToken::EndOfStatement
,
2025 "unexpected token in '.attribute' directive"))
2028 if (Tag
== RISCVAttrs::ARCH
) {
2029 StringRef Arch
= StringValue
;
2030 if (Arch
.consume_front("rv32"))
2031 clearFeatureBits(RISCV::Feature64Bit
, "64bit");
2032 else if (Arch
.consume_front("rv64"))
2033 setFeatureBits(RISCV::Feature64Bit
, "64bit");
2035 return Error(ValueExprLoc
, "bad arch string " + Arch
);
2037 // .attribute arch overrides the current architecture, so unset all
2038 // currently enabled extensions
2039 clearFeatureBits(RISCV::FeatureRV32E
, "e");
2040 clearFeatureBits(RISCV::FeatureStdExtM
, "m");
2041 clearFeatureBits(RISCV::FeatureStdExtA
, "a");
2042 clearFeatureBits(RISCV::FeatureStdExtF
, "f");
2043 clearFeatureBits(RISCV::FeatureStdExtD
, "d");
2044 clearFeatureBits(RISCV::FeatureStdExtC
, "c");
2045 clearFeatureBits(RISCV::FeatureStdExtB
, "experimental-b");
2046 clearFeatureBits(RISCV::FeatureStdExtV
, "experimental-v");
2047 clearFeatureBits(RISCV::FeatureExtZfh
, "experimental-zfh");
2048 clearFeatureBits(RISCV::FeatureExtZba
, "experimental-zba");
2049 clearFeatureBits(RISCV::FeatureExtZbb
, "experimental-zbb");
2050 clearFeatureBits(RISCV::FeatureExtZbc
, "experimental-zbc");
2051 clearFeatureBits(RISCV::FeatureExtZbe
, "experimental-zbe");
2052 clearFeatureBits(RISCV::FeatureExtZbf
, "experimental-zbf");
2053 clearFeatureBits(RISCV::FeatureExtZbm
, "experimental-zbm");
2054 clearFeatureBits(RISCV::FeatureExtZbp
, "experimental-zbp");
2055 clearFeatureBits(RISCV::FeatureExtZbproposedc
, "experimental-zbproposedc");
2056 clearFeatureBits(RISCV::FeatureExtZbr
, "experimental-zbr");
2057 clearFeatureBits(RISCV::FeatureExtZbs
, "experimental-zbs");
2058 clearFeatureBits(RISCV::FeatureExtZbt
, "experimental-zbt");
2059 clearFeatureBits(RISCV::FeatureExtZvamo
, "experimental-zvamo");
2060 clearFeatureBits(RISCV::FeatureStdExtZvlsseg
, "experimental-zvlsseg");
2062 while (!Arch
.empty()) {
2063 bool DropFirst
= true;
2065 clearFeatureBits(RISCV::FeatureRV32E
, "e");
2066 else if (Arch
[0] == 'e')
2067 setFeatureBits(RISCV::FeatureRV32E
, "e");
2068 else if (Arch
[0] == 'g') {
2069 clearFeatureBits(RISCV::FeatureRV32E
, "e");
2070 setFeatureBits(RISCV::FeatureStdExtM
, "m");
2071 setFeatureBits(RISCV::FeatureStdExtA
, "a");
2072 setFeatureBits(RISCV::FeatureStdExtF
, "f");
2073 setFeatureBits(RISCV::FeatureStdExtD
, "d");
2074 } else if (Arch
[0] == 'm')
2075 setFeatureBits(RISCV::FeatureStdExtM
, "m");
2076 else if (Arch
[0] == 'a')
2077 setFeatureBits(RISCV::FeatureStdExtA
, "a");
2078 else if (Arch
[0] == 'f')
2079 setFeatureBits(RISCV::FeatureStdExtF
, "f");
2080 else if (Arch
[0] == 'd') {
2081 setFeatureBits(RISCV::FeatureStdExtF
, "f");
2082 setFeatureBits(RISCV::FeatureStdExtD
, "d");
2083 } else if (Arch
[0] == 'c') {
2084 setFeatureBits(RISCV::FeatureStdExtC
, "c");
2085 } else if (Arch
[0] == 'b') {
2086 setFeatureBits(RISCV::FeatureStdExtB
, "experimental-b");
2087 } else if (Arch
[0] == 'v') {
2088 setFeatureBits(RISCV::FeatureStdExtV
, "experimental-v");
2089 } else if (Arch
[0] == 's' || Arch
[0] == 'x' || Arch
[0] == 'z') {
2091 Arch
.take_until([](char c
) { return ::isdigit(c
) || c
== '_'; });
2093 setFeatureBits(RISCV::FeatureExtZba
, "experimental-zba");
2094 else if (Ext
== "zbb")
2095 setFeatureBits(RISCV::FeatureExtZbb
, "experimental-zbb");
2096 else if (Ext
== "zbc")
2097 setFeatureBits(RISCV::FeatureExtZbc
, "experimental-zbc");
2098 else if (Ext
== "zbe")
2099 setFeatureBits(RISCV::FeatureExtZbe
, "experimental-zbe");
2100 else if (Ext
== "zbf")
2101 setFeatureBits(RISCV::FeatureExtZbf
, "experimental-zbf");
2102 else if (Ext
== "zbm")
2103 setFeatureBits(RISCV::FeatureExtZbm
, "experimental-zbm");
2104 else if (Ext
== "zbp")
2105 setFeatureBits(RISCV::FeatureExtZbp
, "experimental-zbp");
2106 else if (Ext
== "zbproposedc")
2107 setFeatureBits(RISCV::FeatureExtZbproposedc
,
2108 "experimental-zbproposedc");
2109 else if (Ext
== "zbr")
2110 setFeatureBits(RISCV::FeatureExtZbr
, "experimental-zbr");
2111 else if (Ext
== "zbs")
2112 setFeatureBits(RISCV::FeatureExtZbs
, "experimental-zbs");
2113 else if (Ext
== "zbt")
2114 setFeatureBits(RISCV::FeatureExtZbt
, "experimental-zbt");
2115 else if (Ext
== "zfh")
2116 setFeatureBits(RISCV::FeatureExtZfh
, "experimental-zfh");
2117 else if (Ext
== "zvamo")
2118 setFeatureBits(RISCV::FeatureExtZvamo
, "experimental-zvamo");
2119 else if (Ext
== "zvlsseg")
2120 setFeatureBits(RISCV::FeatureStdExtZvlsseg
, "experimental-zvlsseg");
2122 return Error(ValueExprLoc
, "bad arch string " + Ext
);
2123 Arch
= Arch
.drop_until([](char c
) { return ::isdigit(c
) || c
== '_'; });
2126 return Error(ValueExprLoc
, "bad arch string " + Arch
);
2129 Arch
= Arch
.drop_front(1);
2132 Arch
.consumeInteger(10, major
);
2133 Arch
.consume_front("p");
2134 Arch
.consumeInteger(10, minor
);
2135 Arch
= Arch
.drop_while([](char c
) { return c
== '_'; });
2140 getTargetStreamer().emitAttribute(Tag
, IntegerValue
);
2142 if (Tag
!= RISCVAttrs::ARCH
) {
2143 getTargetStreamer().emitTextAttribute(Tag
, StringValue
);
2145 std::string formalArchStr
= "rv32";
2146 if (getFeatureBits(RISCV::Feature64Bit
))
2147 formalArchStr
= "rv64";
2148 if (getFeatureBits(RISCV::FeatureRV32E
))
2149 formalArchStr
= (Twine(formalArchStr
) + "e1p9").str();
2151 formalArchStr
= (Twine(formalArchStr
) + "i2p0").str();
2153 if (getFeatureBits(RISCV::FeatureStdExtM
))
2154 formalArchStr
= (Twine(formalArchStr
) + "_m2p0").str();
2155 if (getFeatureBits(RISCV::FeatureStdExtA
))
2156 formalArchStr
= (Twine(formalArchStr
) + "_a2p0").str();
2157 if (getFeatureBits(RISCV::FeatureStdExtF
))
2158 formalArchStr
= (Twine(formalArchStr
) + "_f2p0").str();
2159 if (getFeatureBits(RISCV::FeatureStdExtD
))
2160 formalArchStr
= (Twine(formalArchStr
) + "_d2p0").str();
2161 if (getFeatureBits(RISCV::FeatureStdExtC
))
2162 formalArchStr
= (Twine(formalArchStr
) + "_c2p0").str();
2163 if (getFeatureBits(RISCV::FeatureStdExtB
))
2164 formalArchStr
= (Twine(formalArchStr
) + "_b0p93").str();
2165 if (getFeatureBits(RISCV::FeatureStdExtV
))
2166 formalArchStr
= (Twine(formalArchStr
) + "_v0p10").str();
2167 if (getFeatureBits(RISCV::FeatureExtZfh
))
2168 formalArchStr
= (Twine(formalArchStr
) + "_zfh0p1").str();
2169 if (getFeatureBits(RISCV::FeatureExtZba
))
2170 formalArchStr
= (Twine(formalArchStr
) + "_zba0p93").str();
2171 if (getFeatureBits(RISCV::FeatureExtZbb
))
2172 formalArchStr
= (Twine(formalArchStr
) + "_zbb0p93").str();
2173 if (getFeatureBits(RISCV::FeatureExtZbc
))
2174 formalArchStr
= (Twine(formalArchStr
) + "_zbc0p93").str();
2175 if (getFeatureBits(RISCV::FeatureExtZbe
))
2176 formalArchStr
= (Twine(formalArchStr
) + "_zbe0p93").str();
2177 if (getFeatureBits(RISCV::FeatureExtZbf
))
2178 formalArchStr
= (Twine(formalArchStr
) + "_zbf0p93").str();
2179 if (getFeatureBits(RISCV::FeatureExtZbm
))
2180 formalArchStr
= (Twine(formalArchStr
) + "_zbm0p93").str();
2181 if (getFeatureBits(RISCV::FeatureExtZbp
))
2182 formalArchStr
= (Twine(formalArchStr
) + "_zbp0p93").str();
2183 if (getFeatureBits(RISCV::FeatureExtZbproposedc
))
2184 formalArchStr
= (Twine(formalArchStr
) + "_zbproposedc0p93").str();
2185 if (getFeatureBits(RISCV::FeatureExtZbr
))
2186 formalArchStr
= (Twine(formalArchStr
) + "_zbr0p93").str();
2187 if (getFeatureBits(RISCV::FeatureExtZbs
))
2188 formalArchStr
= (Twine(formalArchStr
) + "_zbs0p93").str();
2189 if (getFeatureBits(RISCV::FeatureExtZbt
))
2190 formalArchStr
= (Twine(formalArchStr
) + "_zbt0p93").str();
2191 if (getFeatureBits(RISCV::FeatureExtZvamo
))
2192 formalArchStr
= (Twine(formalArchStr
) + "_zvamo0p10").str();
2193 if (getFeatureBits(RISCV::FeatureStdExtZvlsseg
))
2194 formalArchStr
= (Twine(formalArchStr
) + "_zvlsseg0p10").str();
2196 getTargetStreamer().emitTextAttribute(Tag
, formalArchStr
);
2203 void RISCVAsmParser::emitToStreamer(MCStreamer
&S
, const MCInst
&Inst
) {
2205 bool Res
= compressInst(CInst
, Inst
, getSTI(), S
.getContext());
2207 ++RISCVNumInstrsCompressed
;
2208 S
.emitInstruction((Res
? CInst
: Inst
), getSTI());
2211 void RISCVAsmParser::emitLoadImm(MCRegister DestReg
, int64_t Value
,
2213 RISCVMatInt::InstSeq Seq
=
2214 RISCVMatInt::generateInstSeq(Value
, getSTI().getFeatureBits());
2216 MCRegister SrcReg
= RISCV::X0
;
2217 for (RISCVMatInt::Inst
&Inst
: Seq
) {
2218 if (Inst
.Opc
== RISCV::LUI
) {
2220 Out
, MCInstBuilder(RISCV::LUI
).addReg(DestReg
).addImm(Inst
.Imm
));
2221 } else if (Inst
.Opc
== RISCV::ADDUW
) {
2222 emitToStreamer(Out
, MCInstBuilder(RISCV::ADDUW
)
2225 .addReg(RISCV::X0
));
2228 Out
, MCInstBuilder(Inst
.Opc
).addReg(DestReg
).addReg(SrcReg
).addImm(
2232 // Only the first instruction has X0 as its source.
2237 void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg
, MCOperand TmpReg
,
2238 const MCExpr
*Symbol
,
2239 RISCVMCExpr::VariantKind VKHi
,
2240 unsigned SecondOpcode
, SMLoc IDLoc
,
2242 // A pair of instructions for PC-relative addressing; expands to
2243 // TmpLabel: AUIPC TmpReg, VKHi(symbol)
2244 // OP DestReg, TmpReg, %pcrel_lo(TmpLabel)
2245 MCContext
&Ctx
= getContext();
2247 MCSymbol
*TmpLabel
= Ctx
.createNamedTempSymbol("pcrel_hi");
2248 Out
.emitLabel(TmpLabel
);
2250 const RISCVMCExpr
*SymbolHi
= RISCVMCExpr::create(Symbol
, VKHi
, Ctx
);
2252 Out
, MCInstBuilder(RISCV::AUIPC
).addOperand(TmpReg
).addExpr(SymbolHi
));
2254 const MCExpr
*RefToLinkTmpLabel
=
2255 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel
, Ctx
),
2256 RISCVMCExpr::VK_RISCV_PCREL_LO
, Ctx
);
2258 emitToStreamer(Out
, MCInstBuilder(SecondOpcode
)
2259 .addOperand(DestReg
)
2261 .addExpr(RefToLinkTmpLabel
));
2264 void RISCVAsmParser::emitLoadLocalAddress(MCInst
&Inst
, SMLoc IDLoc
,
2266 // The load local address pseudo-instruction "lla" is used in PC-relative
2267 // addressing of local symbols:
2268 // lla rdest, symbol
2270 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
2271 // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
2272 MCOperand DestReg
= Inst
.getOperand(0);
2273 const MCExpr
*Symbol
= Inst
.getOperand(1).getExpr();
2274 emitAuipcInstPair(DestReg
, DestReg
, Symbol
, RISCVMCExpr::VK_RISCV_PCREL_HI
,
2275 RISCV::ADDI
, IDLoc
, Out
);
2278 void RISCVAsmParser::emitLoadAddress(MCInst
&Inst
, SMLoc IDLoc
,
2280 // The load address pseudo-instruction "la" is used in PC-relative and
2281 // GOT-indirect addressing of global symbols:
2283 // expands to either (for non-PIC)
2284 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol)
2285 // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
2287 // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol)
2288 // Lx rdest, %pcrel_lo(TmpLabel)(rdest)
2289 MCOperand DestReg
= Inst
.getOperand(0);
2290 const MCExpr
*Symbol
= Inst
.getOperand(1).getExpr();
2291 unsigned SecondOpcode
;
2292 RISCVMCExpr::VariantKind VKHi
;
2293 if (ParserOptions
.IsPicEnabled
) {
2294 SecondOpcode
= isRV64() ? RISCV::LD
: RISCV::LW
;
2295 VKHi
= RISCVMCExpr::VK_RISCV_GOT_HI
;
2297 SecondOpcode
= RISCV::ADDI
;
2298 VKHi
= RISCVMCExpr::VK_RISCV_PCREL_HI
;
2300 emitAuipcInstPair(DestReg
, DestReg
, Symbol
, VKHi
, SecondOpcode
, IDLoc
, Out
);
2303 void RISCVAsmParser::emitLoadTLSIEAddress(MCInst
&Inst
, SMLoc IDLoc
,
2305 // The load TLS IE address pseudo-instruction "la.tls.ie" is used in
2306 // initial-exec TLS model addressing of global symbols:
2307 // la.tls.ie rdest, symbol
2309 // TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol)
2310 // Lx rdest, %pcrel_lo(TmpLabel)(rdest)
2311 MCOperand DestReg
= Inst
.getOperand(0);
2312 const MCExpr
*Symbol
= Inst
.getOperand(1).getExpr();
2313 unsigned SecondOpcode
= isRV64() ? RISCV::LD
: RISCV::LW
;
2314 emitAuipcInstPair(DestReg
, DestReg
, Symbol
, RISCVMCExpr::VK_RISCV_TLS_GOT_HI
,
2315 SecondOpcode
, IDLoc
, Out
);
2318 void RISCVAsmParser::emitLoadTLSGDAddress(MCInst
&Inst
, SMLoc IDLoc
,
2320 // The load TLS GD address pseudo-instruction "la.tls.gd" is used in
2321 // global-dynamic TLS model addressing of global symbols:
2322 // la.tls.gd rdest, symbol
2324 // TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol)
2325 // ADDI rdest, rdest, %pcrel_lo(TmpLabel)
2326 MCOperand DestReg
= Inst
.getOperand(0);
2327 const MCExpr
*Symbol
= Inst
.getOperand(1).getExpr();
2328 emitAuipcInstPair(DestReg
, DestReg
, Symbol
, RISCVMCExpr::VK_RISCV_TLS_GD_HI
,
2329 RISCV::ADDI
, IDLoc
, Out
);
2332 void RISCVAsmParser::emitLoadStoreSymbol(MCInst
&Inst
, unsigned Opcode
,
2333 SMLoc IDLoc
, MCStreamer
&Out
,
2335 // The load/store pseudo-instruction does a pc-relative load with
2338 // The expansion looks like this
2340 // TmpLabel: AUIPC tmp, %pcrel_hi(symbol)
2341 // [S|L]X rd, %pcrel_lo(TmpLabel)(tmp)
2342 unsigned DestRegOpIdx
= HasTmpReg
? 1 : 0;
2343 MCOperand DestReg
= Inst
.getOperand(DestRegOpIdx
);
2344 unsigned SymbolOpIdx
= HasTmpReg
? 2 : 1;
2345 MCOperand TmpReg
= Inst
.getOperand(0);
2346 const MCExpr
*Symbol
= Inst
.getOperand(SymbolOpIdx
).getExpr();
2347 emitAuipcInstPair(DestReg
, TmpReg
, Symbol
, RISCVMCExpr::VK_RISCV_PCREL_HI
,
2348 Opcode
, IDLoc
, Out
);
2351 void RISCVAsmParser::emitPseudoExtend(MCInst
&Inst
, bool SignExtend
,
2352 int64_t Width
, SMLoc IDLoc
,
2354 // The sign/zero extend pseudo-instruction does two shifts, with the shift
2355 // amounts dependent on the XLEN.
2357 // The expansion looks like this
2359 // SLLI rd, rs, XLEN - Width
2360 // SR[A|R]I rd, rd, XLEN - Width
2361 MCOperand DestReg
= Inst
.getOperand(0);
2362 MCOperand SourceReg
= Inst
.getOperand(1);
2364 unsigned SecondOpcode
= SignExtend
? RISCV::SRAI
: RISCV::SRLI
;
2365 int64_t ShAmt
= (isRV64() ? 64 : 32) - Width
;
2367 assert(ShAmt
> 0 && "Shift amount must be non-zero.");
2369 emitToStreamer(Out
, MCInstBuilder(RISCV::SLLI
)
2370 .addOperand(DestReg
)
2371 .addOperand(SourceReg
)
2374 emitToStreamer(Out
, MCInstBuilder(SecondOpcode
)
2375 .addOperand(DestReg
)
2376 .addOperand(DestReg
)
2380 void RISCVAsmParser::emitVMSGE(MCInst
&Inst
, unsigned Opcode
, SMLoc IDLoc
,
2382 if (Inst
.getNumOperands() == 3) {
2385 // pseudoinstruction: vmsge{u}.vx vd, va, x
2386 // expansion: vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd
2387 emitToStreamer(Out
, MCInstBuilder(Opcode
)
2388 .addOperand(Inst
.getOperand(0))
2389 .addOperand(Inst
.getOperand(1))
2390 .addOperand(Inst
.getOperand(2))
2391 .addReg(RISCV::NoRegister
));
2392 emitToStreamer(Out
, MCInstBuilder(RISCV::VMNAND_MM
)
2393 .addOperand(Inst
.getOperand(0))
2394 .addOperand(Inst
.getOperand(0))
2395 .addOperand(Inst
.getOperand(0)));
2396 } else if (Inst
.getNumOperands() == 4) {
2397 // masked va >= x, vd != v0
2399 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t
2400 // expansion: vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0
2401 assert(Inst
.getOperand(0).getReg() != RISCV::V0
&&
2402 "The destination register should not be V0.");
2403 emitToStreamer(Out
, MCInstBuilder(Opcode
)
2404 .addOperand(Inst
.getOperand(0))
2405 .addOperand(Inst
.getOperand(1))
2406 .addOperand(Inst
.getOperand(2))
2407 .addOperand(Inst
.getOperand(3)));
2408 emitToStreamer(Out
, MCInstBuilder(RISCV::VMXOR_MM
)
2409 .addOperand(Inst
.getOperand(0))
2410 .addOperand(Inst
.getOperand(0))
2411 .addReg(RISCV::V0
));
2412 } else if (Inst
.getNumOperands() == 5 &&
2413 Inst
.getOperand(0).getReg() == RISCV::V0
) {
2414 // masked va >= x, vd == v0
2416 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt
2417 // expansion: vmslt{u}.vx vt, va, x; vmandnot.mm vd, vd, vt
2418 assert(Inst
.getOperand(0).getReg() == RISCV::V0
&&
2419 "The destination register should be V0.");
2420 assert(Inst
.getOperand(1).getReg() != RISCV::V0
&&
2421 "The temporary vector register should not be V0.");
2422 emitToStreamer(Out
, MCInstBuilder(Opcode
)
2423 .addOperand(Inst
.getOperand(1))
2424 .addOperand(Inst
.getOperand(2))
2425 .addOperand(Inst
.getOperand(3))
2426 .addOperand(Inst
.getOperand(4)));
2427 emitToStreamer(Out
, MCInstBuilder(RISCV::VMANDNOT_MM
)
2428 .addOperand(Inst
.getOperand(0))
2429 .addOperand(Inst
.getOperand(0))
2430 .addOperand(Inst
.getOperand(1)));
2431 } else if (Inst
.getNumOperands() == 5) {
2432 // masked va >= x, any vd
2434 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt
2435 // expansion: vmslt{u}.vx vt, va, x; vmandnot.mm vt, v0, vt; vmandnot.mm vd,
2436 // vd, v0; vmor.mm vd, vt, vd
2437 assert(Inst
.getOperand(1).getReg() != RISCV::V0
&&
2438 "The temporary vector register should not be V0.");
2439 emitToStreamer(Out
, MCInstBuilder(Opcode
)
2440 .addOperand(Inst
.getOperand(1))
2441 .addOperand(Inst
.getOperand(2))
2442 .addOperand(Inst
.getOperand(3))
2443 .addReg(RISCV::NoRegister
));
2444 emitToStreamer(Out
, MCInstBuilder(RISCV::VMANDNOT_MM
)
2445 .addOperand(Inst
.getOperand(1))
2447 .addOperand(Inst
.getOperand(1)));
2448 emitToStreamer(Out
, MCInstBuilder(RISCV::VMANDNOT_MM
)
2449 .addOperand(Inst
.getOperand(0))
2450 .addOperand(Inst
.getOperand(0))
2451 .addReg(RISCV::V0
));
2452 emitToStreamer(Out
, MCInstBuilder(RISCV::VMOR_MM
)
2453 .addOperand(Inst
.getOperand(0))
2454 .addOperand(Inst
.getOperand(1))
2455 .addOperand(Inst
.getOperand(0)));
2459 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst
&Inst
,
2460 OperandVector
&Operands
) {
2461 assert(Inst
.getOpcode() == RISCV::PseudoAddTPRel
&& "Invalid instruction");
2462 assert(Inst
.getOperand(2).isReg() && "Unexpected second operand kind");
2463 if (Inst
.getOperand(2).getReg() != RISCV::X4
) {
2464 SMLoc ErrorLoc
= ((RISCVOperand
&)*Operands
[3]).getStartLoc();
2465 return Error(ErrorLoc
, "the second input operand must be tp/x4 when using "
2466 "%tprel_add modifier");
2472 std::unique_ptr
<RISCVOperand
> RISCVAsmParser::defaultMaskRegOp() const {
2473 return RISCVOperand::createReg(RISCV::NoRegister
, llvm::SMLoc(),
2474 llvm::SMLoc(), isRV64());
2477 bool RISCVAsmParser::validateInstruction(MCInst
&Inst
,
2478 OperandVector
&Operands
) {
2479 if (Inst
.getOpcode() == RISCV::PseudoVMSGEU_VX_M_T
||
2480 Inst
.getOpcode() == RISCV::PseudoVMSGE_VX_M_T
) {
2481 unsigned DestReg
= Inst
.getOperand(0).getReg();
2482 unsigned TempReg
= Inst
.getOperand(1).getReg();
2483 if (DestReg
== TempReg
) {
2484 SMLoc Loc
= Operands
.back()->getStartLoc();
2485 return Error(Loc
, "The temporary vector register cannot be the same as "
2486 "the destination register.");
2490 const MCInstrDesc
&MCID
= MII
.get(Inst
.getOpcode());
2491 RISCVII::VConstraintType Constraints
=
2492 RISCVII::getConstraint(MCID
.TSFlags
);
2493 if (Constraints
== RISCVII::NoConstraint
)
2496 unsigned DestReg
= Inst
.getOperand(0).getReg();
2497 // Operands[1] will be the first operand, DestReg.
2498 SMLoc Loc
= Operands
[1]->getStartLoc();
2499 if (Constraints
& RISCVII::VS2Constraint
) {
2500 unsigned CheckReg
= Inst
.getOperand(1).getReg();
2501 if (DestReg
== CheckReg
)
2502 return Error(Loc
, "The destination vector register group cannot overlap"
2503 " the source vector register group.");
2505 if ((Constraints
& RISCVII::VS1Constraint
) && (Inst
.getOperand(2).isReg())) {
2506 unsigned CheckReg
= Inst
.getOperand(2).getReg();
2507 if (DestReg
== CheckReg
)
2508 return Error(Loc
, "The destination vector register group cannot overlap"
2509 " the source vector register group.");
2511 if ((Constraints
& RISCVII::VMConstraint
) && (DestReg
== RISCV::V0
)) {
2512 // vadc, vsbc are special cases. These instructions have no mask register.
2513 // The destination register could not be V0.
2514 unsigned Opcode
= Inst
.getOpcode();
2515 if (Opcode
== RISCV::VADC_VVM
|| Opcode
== RISCV::VADC_VXM
||
2516 Opcode
== RISCV::VADC_VIM
|| Opcode
== RISCV::VSBC_VVM
||
2517 Opcode
== RISCV::VSBC_VXM
|| Opcode
== RISCV::VFMERGE_VFM
||
2518 Opcode
== RISCV::VMERGE_VIM
|| Opcode
== RISCV::VMERGE_VVM
||
2519 Opcode
== RISCV::VMERGE_VXM
)
2520 return Error(Loc
, "The destination vector register group cannot be V0.");
2522 // Regardless masked or unmasked version, the number of operands is the
2523 // same. For example, "viota.m v0, v2" is "viota.m v0, v2, NoRegister"
2524 // actually. We need to check the last operand to ensure whether it is
2526 unsigned CheckReg
= Inst
.getOperand(Inst
.getNumOperands() - 1).getReg();
2527 assert((CheckReg
== RISCV::V0
|| CheckReg
== RISCV::NoRegister
) &&
2528 "Unexpected register for mask operand");
2530 if (DestReg
== CheckReg
)
2531 return Error(Loc
, "The destination vector register group cannot overlap"
2532 " the mask register.");
2537 bool RISCVAsmParser::processInstruction(MCInst
&Inst
, SMLoc IDLoc
,
2538 OperandVector
&Operands
,
2542 switch (Inst
.getOpcode()) {
2545 case RISCV::PseudoLI
: {
2546 MCRegister Reg
= Inst
.getOperand(0).getReg();
2547 const MCOperand
&Op1
= Inst
.getOperand(1);
2549 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar.
2550 // Just convert to an addi. This allows compatibility with gas.
2551 emitToStreamer(Out
, MCInstBuilder(RISCV::ADDI
)
2554 .addExpr(Op1
.getExpr()));
2557 int64_t Imm
= Inst
.getOperand(1).getImm();
2558 // On RV32 the immediate here can either be a signed or an unsigned
2559 // 32-bit number. Sign extension has to be performed to ensure that Imm
2560 // represents the expected signed 64-bit number.
2562 Imm
= SignExtend64
<32>(Imm
);
2563 emitLoadImm(Reg
, Imm
, Out
);
2566 case RISCV::PseudoLLA
:
2567 emitLoadLocalAddress(Inst
, IDLoc
, Out
);
2569 case RISCV::PseudoLA
:
2570 emitLoadAddress(Inst
, IDLoc
, Out
);
2572 case RISCV::PseudoLA_TLS_IE
:
2573 emitLoadTLSIEAddress(Inst
, IDLoc
, Out
);
2575 case RISCV::PseudoLA_TLS_GD
:
2576 emitLoadTLSGDAddress(Inst
, IDLoc
, Out
);
2578 case RISCV::PseudoLB
:
2579 emitLoadStoreSymbol(Inst
, RISCV::LB
, IDLoc
, Out
, /*HasTmpReg=*/false);
2581 case RISCV::PseudoLBU
:
2582 emitLoadStoreSymbol(Inst
, RISCV::LBU
, IDLoc
, Out
, /*HasTmpReg=*/false);
2584 case RISCV::PseudoLH
:
2585 emitLoadStoreSymbol(Inst
, RISCV::LH
, IDLoc
, Out
, /*HasTmpReg=*/false);
2587 case RISCV::PseudoLHU
:
2588 emitLoadStoreSymbol(Inst
, RISCV::LHU
, IDLoc
, Out
, /*HasTmpReg=*/false);
2590 case RISCV::PseudoLW
:
2591 emitLoadStoreSymbol(Inst
, RISCV::LW
, IDLoc
, Out
, /*HasTmpReg=*/false);
2593 case RISCV::PseudoLWU
:
2594 emitLoadStoreSymbol(Inst
, RISCV::LWU
, IDLoc
, Out
, /*HasTmpReg=*/false);
2596 case RISCV::PseudoLD
:
2597 emitLoadStoreSymbol(Inst
, RISCV::LD
, IDLoc
, Out
, /*HasTmpReg=*/false);
2599 case RISCV::PseudoFLH
:
2600 emitLoadStoreSymbol(Inst
, RISCV::FLH
, IDLoc
, Out
, /*HasTmpReg=*/true);
2602 case RISCV::PseudoFLW
:
2603 emitLoadStoreSymbol(Inst
, RISCV::FLW
, IDLoc
, Out
, /*HasTmpReg=*/true);
2605 case RISCV::PseudoFLD
:
2606 emitLoadStoreSymbol(Inst
, RISCV::FLD
, IDLoc
, Out
, /*HasTmpReg=*/true);
2608 case RISCV::PseudoSB
:
2609 emitLoadStoreSymbol(Inst
, RISCV::SB
, IDLoc
, Out
, /*HasTmpReg=*/true);
2611 case RISCV::PseudoSH
:
2612 emitLoadStoreSymbol(Inst
, RISCV::SH
, IDLoc
, Out
, /*HasTmpReg=*/true);
2614 case RISCV::PseudoSW
:
2615 emitLoadStoreSymbol(Inst
, RISCV::SW
, IDLoc
, Out
, /*HasTmpReg=*/true);
2617 case RISCV::PseudoSD
:
2618 emitLoadStoreSymbol(Inst
, RISCV::SD
, IDLoc
, Out
, /*HasTmpReg=*/true);
2620 case RISCV::PseudoFSH
:
2621 emitLoadStoreSymbol(Inst
, RISCV::FSH
, IDLoc
, Out
, /*HasTmpReg=*/true);
2623 case RISCV::PseudoFSW
:
2624 emitLoadStoreSymbol(Inst
, RISCV::FSW
, IDLoc
, Out
, /*HasTmpReg=*/true);
2626 case RISCV::PseudoFSD
:
2627 emitLoadStoreSymbol(Inst
, RISCV::FSD
, IDLoc
, Out
, /*HasTmpReg=*/true);
2629 case RISCV::PseudoAddTPRel
:
2630 if (checkPseudoAddTPRel(Inst
, Operands
))
2633 case RISCV::PseudoSEXT_B
:
2634 emitPseudoExtend(Inst
, /*SignExtend=*/true, /*Width=*/8, IDLoc
, Out
);
2636 case RISCV::PseudoSEXT_H
:
2637 emitPseudoExtend(Inst
, /*SignExtend=*/true, /*Width=*/16, IDLoc
, Out
);
2639 case RISCV::PseudoZEXT_H
:
2640 emitPseudoExtend(Inst
, /*SignExtend=*/false, /*Width=*/16, IDLoc
, Out
);
2642 case RISCV::PseudoZEXT_W
:
2643 emitPseudoExtend(Inst
, /*SignExtend=*/false, /*Width=*/32, IDLoc
, Out
);
2645 case RISCV::PseudoVMSGEU_VX
:
2646 case RISCV::PseudoVMSGEU_VX_M
:
2647 case RISCV::PseudoVMSGEU_VX_M_T
:
2648 emitVMSGE(Inst
, RISCV::VMSLTU_VX
, IDLoc
, Out
);
2650 case RISCV::PseudoVMSGE_VX
:
2651 case RISCV::PseudoVMSGE_VX_M
:
2652 case RISCV::PseudoVMSGE_VX_M_T
:
2653 emitVMSGE(Inst
, RISCV::VMSLT_VX
, IDLoc
, Out
);
2655 case RISCV::PseudoVMSGE_VI
:
2656 case RISCV::PseudoVMSLT_VI
: {
2657 // These instructions are signed and so is immediate so we can subtract one
2658 // and change the opcode.
2659 int64_t Imm
= Inst
.getOperand(2).getImm();
2660 unsigned Opc
= Inst
.getOpcode() == RISCV::PseudoVMSGE_VI
? RISCV::VMSGT_VI
2662 emitToStreamer(Out
, MCInstBuilder(Opc
)
2663 .addOperand(Inst
.getOperand(0))
2664 .addOperand(Inst
.getOperand(1))
2666 .addOperand(Inst
.getOperand(3)));
2669 case RISCV::PseudoVMSGEU_VI
:
2670 case RISCV::PseudoVMSLTU_VI
: {
2671 int64_t Imm
= Inst
.getOperand(2).getImm();
2672 // Unsigned comparisons are tricky because the immediate is signed. If the
2673 // immediate is 0 we can't just subtract one. vmsltu.vi v0, v1, 0 is always
2674 // false, but vmsle.vi v0, v1, -1 is always true. Instead we use
2675 // vmsne v0, v1, v1 which is always false.
2677 unsigned Opc
= Inst
.getOpcode() == RISCV::PseudoVMSGEU_VI
2680 emitToStreamer(Out
, MCInstBuilder(Opc
)
2681 .addOperand(Inst
.getOperand(0))
2682 .addOperand(Inst
.getOperand(1))
2683 .addOperand(Inst
.getOperand(1))
2684 .addOperand(Inst
.getOperand(3)));
2686 // Other immediate values can subtract one like signed.
2687 unsigned Opc
= Inst
.getOpcode() == RISCV::PseudoVMSGEU_VI
2690 emitToStreamer(Out
, MCInstBuilder(Opc
)
2691 .addOperand(Inst
.getOperand(0))
2692 .addOperand(Inst
.getOperand(1))
2694 .addOperand(Inst
.getOperand(3)));
2701 emitToStreamer(Out
, Inst
);
2705 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeRISCVAsmParser() {
2706 RegisterMCAsmParser
<RISCVAsmParser
> X(getTheRISCV32Target());
2707 RegisterMCAsmParser
<RISCVAsmParser
> Y(getTheRISCV64Target());