[LoongArch][Clang] Make the parameters and return value of {x,}vorn.v builti ns ...
[llvm-project.git] / lldb / source / Plugins / Instruction / RISCV / RISCVInstructions.h
blob252cef805408cbaafabd3320bbdd845444960d25
1 //===-- RISCVInstructions.h -----------------------------------------------===//
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 //===----------------------------------------------------------------------===//
9 #ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVINSTRUCTION_H
10 #define LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVINSTRUCTION_H
12 #include <cstdint>
13 #include <optional>
14 #include <variant>
16 #include "llvm/ADT/APFloat.h"
18 namespace lldb_private {
20 class EmulateInstructionRISCV;
22 struct Rd {
23 uint32_t rd;
24 bool Write(EmulateInstructionRISCV &emulator, uint64_t value);
25 bool WriteAPFloat(EmulateInstructionRISCV &emulator, llvm::APFloat value);
28 struct Rs {
29 uint32_t rs;
30 std::optional<uint64_t> Read(EmulateInstructionRISCV &emulator);
31 std::optional<int32_t> ReadI32(EmulateInstructionRISCV &emulator);
32 std::optional<int64_t> ReadI64(EmulateInstructionRISCV &emulator);
33 std::optional<uint32_t> ReadU32(EmulateInstructionRISCV &emulator);
34 std::optional<llvm::APFloat> ReadAPFloat(EmulateInstructionRISCV &emulator,
35 bool isDouble);
38 #define DERIVE_EQ(NAME) \
39 bool operator==(const NAME &r) const { \
40 return std::memcmp(this, &r, sizeof(NAME)) == 0; \
43 #define I_TYPE_INST(NAME) \
44 struct NAME { \
45 Rd rd; \
46 Rs rs1; \
47 uint32_t imm; \
48 DERIVE_EQ(NAME); \
50 #define S_TYPE_INST(NAME) \
51 struct NAME { \
52 Rs rs1; \
53 Rs rs2; \
54 uint32_t imm; \
55 DERIVE_EQ(NAME); \
57 #define U_TYPE_INST(NAME) \
58 struct NAME { \
59 Rd rd; \
60 uint32_t imm; \
61 DERIVE_EQ(NAME); \
63 /// The memory layout are the same in our code.
64 #define J_TYPE_INST(NAME) U_TYPE_INST(NAME)
65 #define R_TYPE_INST(NAME) \
66 struct NAME { \
67 Rd rd; \
68 Rs rs1; \
69 Rs rs2; \
70 DERIVE_EQ(NAME); \
72 #define R_SHAMT_TYPE_INST(NAME) \
73 struct NAME { \
74 Rd rd; \
75 Rs rs1; \
76 uint32_t shamt; \
77 DERIVE_EQ(NAME); \
79 #define R_RS1_TYPE_INST(NAME) \
80 struct NAME { \
81 Rd rd; \
82 Rs rs1; \
83 DERIVE_EQ(NAME); \
85 #define R4_TYPE_INST(NAME) \
86 struct NAME { \
87 Rd rd; \
88 Rs rs1; \
89 Rs rs2; \
90 Rs rs3; \
91 int32_t rm; \
92 DERIVE_EQ(NAME); \
94 /// The `inst` fields are used for debugging.
95 #define INVALID_INST(NAME) \
96 struct NAME { \
97 uint32_t inst; \
98 DERIVE_EQ(NAME); \
101 // RV32I instructions (The base integer ISA)
102 struct B {
103 Rs rs1;
104 Rs rs2;
105 uint32_t imm;
106 uint32_t funct3;
107 DERIVE_EQ(B);
109 U_TYPE_INST(LUI);
110 U_TYPE_INST(AUIPC);
111 J_TYPE_INST(JAL);
112 I_TYPE_INST(JALR);
113 I_TYPE_INST(LB);
114 I_TYPE_INST(LH);
115 I_TYPE_INST(LW);
116 I_TYPE_INST(LBU);
117 I_TYPE_INST(LHU);
118 S_TYPE_INST(SB);
119 S_TYPE_INST(SH);
120 S_TYPE_INST(SW);
121 I_TYPE_INST(ADDI);
122 I_TYPE_INST(SLTI);
123 I_TYPE_INST(SLTIU);
124 I_TYPE_INST(XORI);
125 I_TYPE_INST(ORI);
126 I_TYPE_INST(ANDI);
127 R_TYPE_INST(ADD);
128 R_TYPE_INST(SUB);
129 R_TYPE_INST(SLL);
130 R_TYPE_INST(SLT);
131 R_TYPE_INST(SLTU);
132 R_TYPE_INST(XOR);
133 R_TYPE_INST(SRL);
134 R_TYPE_INST(SRA);
135 R_TYPE_INST(OR);
136 R_TYPE_INST(AND);
138 // RV64I inst (The base integer ISA)
139 I_TYPE_INST(LWU);
140 I_TYPE_INST(LD);
141 S_TYPE_INST(SD);
142 R_SHAMT_TYPE_INST(SLLI);
143 R_SHAMT_TYPE_INST(SRLI);
144 R_SHAMT_TYPE_INST(SRAI);
145 I_TYPE_INST(ADDIW);
146 R_SHAMT_TYPE_INST(SLLIW);
147 R_SHAMT_TYPE_INST(SRLIW);
148 R_SHAMT_TYPE_INST(SRAIW);
149 R_TYPE_INST(ADDW);
150 R_TYPE_INST(SUBW);
151 R_TYPE_INST(SLLW);
152 R_TYPE_INST(SRLW);
153 R_TYPE_INST(SRAW);
155 // RV32M inst (The standard integer multiplication and division extension)
156 R_TYPE_INST(MUL);
157 R_TYPE_INST(MULH);
158 R_TYPE_INST(MULHSU);
159 R_TYPE_INST(MULHU);
160 R_TYPE_INST(DIV);
161 R_TYPE_INST(DIVU);
162 R_TYPE_INST(REM);
163 R_TYPE_INST(REMU);
165 // RV64M inst (The standard integer multiplication and division extension)
166 R_TYPE_INST(MULW);
167 R_TYPE_INST(DIVW);
168 R_TYPE_INST(DIVUW);
169 R_TYPE_INST(REMW);
170 R_TYPE_INST(REMUW);
172 // RV32A inst (The standard atomic instruction extension)
173 R_RS1_TYPE_INST(LR_W);
174 R_TYPE_INST(SC_W);
175 R_TYPE_INST(AMOSWAP_W);
176 R_TYPE_INST(AMOADD_W);
177 R_TYPE_INST(AMOXOR_W);
178 R_TYPE_INST(AMOAND_W);
179 R_TYPE_INST(AMOOR_W);
180 R_TYPE_INST(AMOMIN_W);
181 R_TYPE_INST(AMOMAX_W);
182 R_TYPE_INST(AMOMINU_W);
183 R_TYPE_INST(AMOMAXU_W);
185 // RV64A inst (The standard atomic instruction extension)
186 R_RS1_TYPE_INST(LR_D);
187 R_TYPE_INST(SC_D);
188 R_TYPE_INST(AMOSWAP_D);
189 R_TYPE_INST(AMOADD_D);
190 R_TYPE_INST(AMOXOR_D);
191 R_TYPE_INST(AMOAND_D);
192 R_TYPE_INST(AMOOR_D);
193 R_TYPE_INST(AMOMIN_D);
194 R_TYPE_INST(AMOMAX_D);
195 R_TYPE_INST(AMOMINU_D);
196 R_TYPE_INST(AMOMAXU_D);
198 // RV32F inst (The standard single-precision floating-point extension)
199 I_TYPE_INST(FLW);
200 S_TYPE_INST(FSW);
201 R4_TYPE_INST(FMADD_S);
202 R4_TYPE_INST(FMSUB_S);
203 R4_TYPE_INST(FNMADD_S);
204 R4_TYPE_INST(FNMSUB_S);
205 R_TYPE_INST(FADD_S);
206 R_TYPE_INST(FSUB_S);
207 R_TYPE_INST(FMUL_S);
208 R_TYPE_INST(FDIV_S);
209 I_TYPE_INST(FSQRT_S);
210 R_TYPE_INST(FSGNJ_S);
211 R_TYPE_INST(FSGNJN_S);
212 R_TYPE_INST(FSGNJX_S);
213 R_TYPE_INST(FMIN_S);
214 R_TYPE_INST(FMAX_S);
215 I_TYPE_INST(FCVT_W_S);
216 I_TYPE_INST(FCVT_WU_S);
217 I_TYPE_INST(FMV_X_W);
218 R_TYPE_INST(FEQ_S);
219 R_TYPE_INST(FLT_S);
220 R_TYPE_INST(FLE_S);
221 I_TYPE_INST(FCLASS_S);
222 I_TYPE_INST(FCVT_S_W);
223 I_TYPE_INST(FCVT_S_WU);
224 I_TYPE_INST(FMV_W_X);
226 // RV64F inst (The standard single-precision floating-point extension)
227 I_TYPE_INST(FCVT_L_S);
228 I_TYPE_INST(FCVT_LU_S);
229 I_TYPE_INST(FCVT_S_L);
230 I_TYPE_INST(FCVT_S_LU);
232 // RV32D inst (Extension for Double-Precision Floating-Point)
233 I_TYPE_INST(FLD);
234 S_TYPE_INST(FSD);
235 R4_TYPE_INST(FMADD_D);
236 R4_TYPE_INST(FMSUB_D);
237 R4_TYPE_INST(FNMSUB_D);
238 R4_TYPE_INST(FNMADD_D);
239 R_TYPE_INST(FADD_D);
240 R_TYPE_INST(FSUB_D);
241 R_TYPE_INST(FMUL_D);
242 R_TYPE_INST(FDIV_D);
243 I_TYPE_INST(FSQRT_D);
244 R_TYPE_INST(FSGNJ_D);
245 R_TYPE_INST(FSGNJN_D);
246 R_TYPE_INST(FSGNJX_D);
247 R_TYPE_INST(FMIN_D);
248 R_TYPE_INST(FMAX_D);
249 I_TYPE_INST(FCVT_S_D);
250 I_TYPE_INST(FCVT_D_S);
251 R_TYPE_INST(FEQ_D);
252 R_TYPE_INST(FLT_D);
253 R_TYPE_INST(FLE_D);
254 I_TYPE_INST(FCLASS_D);
255 I_TYPE_INST(FCVT_W_D);
256 I_TYPE_INST(FCVT_WU_D);
257 I_TYPE_INST(FCVT_D_W);
258 I_TYPE_INST(FCVT_D_WU);
260 // RV64D inst (Extension for Double-Precision Floating-Point)
261 I_TYPE_INST(FCVT_L_D);
262 I_TYPE_INST(FCVT_LU_D);
263 I_TYPE_INST(FMV_X_D);
264 I_TYPE_INST(FCVT_D_L);
265 I_TYPE_INST(FCVT_D_LU);
266 I_TYPE_INST(FMV_D_X);
268 /// Invalid and reserved instructions, the `inst` fields are used for debugging.
269 INVALID_INST(INVALID);
270 INVALID_INST(RESERVED);
271 INVALID_INST(EBREAK);
272 INVALID_INST(HINT);
273 INVALID_INST(NOP);
275 using RISCVInst = std::variant<
276 LUI, AUIPC, JAL, JALR, B, LB, LH, LW, LBU, LHU, SB, SH, SW, ADDI, SLTI,
277 SLTIU, XORI, ORI, ANDI, ADD, SUB, SLL, SLT, SLTU, XOR, SRL, SRA, OR, AND,
278 LWU, LD, SD, SLLI, SRLI, SRAI, ADDIW, SLLIW, SRLIW, SRAIW, ADDW, SUBW, SLLW,
279 SRLW, SRAW, MUL, MULH, MULHSU, MULHU, DIV, DIVU, REM, REMU, MULW, DIVW,
280 DIVUW, REMW, REMUW, LR_W, SC_W, AMOSWAP_W, AMOADD_W, AMOXOR_W, AMOAND_W,
281 AMOOR_W, AMOMIN_W, AMOMAX_W, AMOMINU_W, AMOMAXU_W, LR_D, SC_D, AMOSWAP_D,
282 AMOADD_D, AMOXOR_D, AMOAND_D, AMOOR_D, AMOMIN_D, AMOMAX_D, AMOMINU_D,
283 AMOMAXU_D, FLW, FSW, FMADD_S, FMSUB_S, FNMADD_S, FNMSUB_S, FADD_S, FSUB_S,
284 FMUL_S, FDIV_S, FSQRT_S, FSGNJ_S, FSGNJN_S, FSGNJX_S, FMIN_S, FMAX_S,
285 FCVT_W_S, FCVT_WU_S, FMV_X_W, FEQ_S, FLT_S, FLE_S, FCLASS_S, FCVT_S_W,
286 FCVT_S_WU, FMV_W_X, FCVT_L_S, FCVT_LU_S, FCVT_S_L, FCVT_S_LU, FLD, FSD,
287 FMADD_D, FMSUB_D, FNMSUB_D, FNMADD_D, FADD_D, FSUB_D, FMUL_D, FDIV_D,
288 FSQRT_D, FSGNJ_D, FSGNJN_D, FSGNJX_D, FMIN_D, FMAX_D, FCVT_S_D, FCVT_D_S,
289 FEQ_D, FLT_D, FLE_D, FCLASS_D, FCVT_W_D, FCVT_WU_D, FCVT_D_W, FCVT_D_WU,
290 FCVT_L_D, FCVT_LU_D, FMV_X_D, FCVT_D_L, FCVT_D_LU, FMV_D_X, INVALID, EBREAK,
291 RESERVED, HINT, NOP>;
293 constexpr uint8_t RV32 = 1;
294 constexpr uint8_t RV64 = 2;
295 constexpr uint8_t RV128 = 4;
297 struct InstrPattern {
298 const char *name;
299 /// Bit mask to check the type of a instruction (B-Type, I-Type, J-Type, etc.)
300 uint32_t type_mask;
301 /// Characteristic value after bitwise-and with type_mask.
302 uint32_t eigen;
303 RISCVInst (*decode)(uint32_t inst);
304 /// If not specified, the inst will be supported by all RV versions.
305 uint8_t inst_type = RV32 | RV64 | RV128;
308 struct DecodeResult {
309 RISCVInst decoded;
310 uint32_t inst;
311 bool is_rvc;
312 InstrPattern pattern;
315 constexpr uint32_t DecodeRD(uint32_t inst) { return (inst & 0xF80) >> 7; }
316 constexpr uint32_t DecodeRS1(uint32_t inst) { return (inst & 0xF8000) >> 15; }
317 constexpr uint32_t DecodeRS2(uint32_t inst) { return (inst & 0x1F00000) >> 20; }
318 constexpr uint32_t DecodeRS3(uint32_t inst) {
319 return (inst & 0xF0000000) >> 27;
321 constexpr uint32_t DecodeFunct3(uint32_t inst) { return (inst & 0x7000) >> 12; }
322 constexpr uint32_t DecodeFunct2(uint32_t inst) {
323 return (inst & 0xE000000) >> 25;
325 constexpr uint32_t DecodeFunct7(uint32_t inst) {
326 return (inst & 0xFE000000) >> 25;
329 constexpr int32_t DecodeRM(uint32_t inst) { return DecodeFunct3(inst); }
331 /// RISC-V spec: The upper bits of a valid NaN-boxed value must be all 1s.
332 constexpr uint64_t NanBoxing(uint64_t val) {
333 return val | 0xFFFF'FFFF'0000'0000;
335 constexpr uint32_t NanUnBoxing(uint64_t val) {
336 return val & (~0xFFFF'FFFF'0000'0000);
339 #undef R_TYPE_INST
340 #undef R_SHAMT_TYPE_INST
341 #undef R_RS1_TYPE_INST
342 #undef R4_TYPE_INST
343 #undef I_TYPE_INST
344 #undef S_TYPE_INST
345 #undef B_TYPE_INST
346 #undef U_TYPE_INST
347 #undef J_TYPE_INST
348 #undef INVALID_INST
349 #undef DERIVE_EQ
351 } // namespace lldb_private
352 #endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVINSTRUCTION_H