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