/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/Instruction/RISCV/RISCVInstructions.h
Line | Count | Source (jump to first uncovered line) |
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 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVINSTRUCTION_H |
10 | | #define LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVINSTRUCTION_H |
11 | | |
12 | | #include <cstdint> |
13 | | #include <optional> |
14 | | #include <variant> |
15 | | |
16 | | #include "llvm/ADT/APFloat.h" |
17 | | |
18 | | namespace lldb_private { |
19 | | |
20 | | class EmulateInstructionRISCV; |
21 | | |
22 | | struct Rd { |
23 | | uint32_t rd; |
24 | | bool Write(EmulateInstructionRISCV &emulator, uint64_t value); |
25 | | bool WriteAPFloat(EmulateInstructionRISCV &emulator, llvm::APFloat value); |
26 | | }; |
27 | | |
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); |
36 | | }; |
37 | | |
38 | | #define DERIVE_EQ(NAME) \ |
39 | 0 | bool operator==(const NAME &r) const { \ |
40 | 0 | return std::memcmp(this, &r, sizeof(NAME)) == 0; \ |
41 | 0 | } Unexecuted instantiation: lldb_private::AUIPC::operator==(lldb_private::AUIPC const&) const Unexecuted instantiation: lldb_private::LB::operator==(lldb_private::LB const&) const Unexecuted instantiation: lldb_private::LH::operator==(lldb_private::LH const&) const Unexecuted instantiation: lldb_private::LBU::operator==(lldb_private::LBU const&) const Unexecuted instantiation: lldb_private::LHU::operator==(lldb_private::LHU const&) const Unexecuted instantiation: lldb_private::SB::operator==(lldb_private::SB const&) const Unexecuted instantiation: lldb_private::SH::operator==(lldb_private::SH const&) const Unexecuted instantiation: lldb_private::SLTI::operator==(lldb_private::SLTI const&) const Unexecuted instantiation: lldb_private::SLTIU::operator==(lldb_private::SLTIU const&) const Unexecuted instantiation: lldb_private::XORI::operator==(lldb_private::XORI const&) const Unexecuted instantiation: lldb_private::ORI::operator==(lldb_private::ORI const&) const Unexecuted instantiation: lldb_private::SLL::operator==(lldb_private::SLL const&) const Unexecuted instantiation: lldb_private::SLT::operator==(lldb_private::SLT const&) const Unexecuted instantiation: lldb_private::SLTU::operator==(lldb_private::SLTU const&) const Unexecuted instantiation: lldb_private::SRL::operator==(lldb_private::SRL const&) const Unexecuted instantiation: lldb_private::SRA::operator==(lldb_private::SRA const&) const Unexecuted instantiation: lldb_private::LWU::operator==(lldb_private::LWU const&) const Unexecuted instantiation: lldb_private::SLLIW::operator==(lldb_private::SLLIW const&) const Unexecuted instantiation: lldb_private::SRLIW::operator==(lldb_private::SRLIW const&) const Unexecuted instantiation: lldb_private::SRAIW::operator==(lldb_private::SRAIW const&) const Unexecuted instantiation: lldb_private::SLLW::operator==(lldb_private::SLLW const&) const Unexecuted instantiation: lldb_private::SRLW::operator==(lldb_private::SRLW const&) const Unexecuted instantiation: lldb_private::SRAW::operator==(lldb_private::SRAW const&) const Unexecuted instantiation: lldb_private::MUL::operator==(lldb_private::MUL const&) const Unexecuted instantiation: lldb_private::MULH::operator==(lldb_private::MULH const&) const Unexecuted instantiation: lldb_private::MULHSU::operator==(lldb_private::MULHSU const&) const Unexecuted instantiation: lldb_private::MULHU::operator==(lldb_private::MULHU const&) const Unexecuted instantiation: lldb_private::DIV::operator==(lldb_private::DIV const&) const Unexecuted instantiation: lldb_private::DIVU::operator==(lldb_private::DIVU const&) const Unexecuted instantiation: lldb_private::REM::operator==(lldb_private::REM const&) const Unexecuted instantiation: lldb_private::REMU::operator==(lldb_private::REMU const&) const Unexecuted instantiation: lldb_private::MULW::operator==(lldb_private::MULW const&) const Unexecuted instantiation: lldb_private::DIVW::operator==(lldb_private::DIVW const&) const Unexecuted instantiation: lldb_private::DIVUW::operator==(lldb_private::DIVUW const&) const Unexecuted instantiation: lldb_private::REMW::operator==(lldb_private::REMW const&) const Unexecuted instantiation: lldb_private::REMUW::operator==(lldb_private::REMUW const&) const Unexecuted instantiation: lldb_private::LR_W::operator==(lldb_private::LR_W const&) const Unexecuted instantiation: lldb_private::SC_W::operator==(lldb_private::SC_W const&) const Unexecuted instantiation: lldb_private::AMOSWAP_W::operator==(lldb_private::AMOSWAP_W const&) const Unexecuted instantiation: lldb_private::AMOADD_W::operator==(lldb_private::AMOADD_W const&) const Unexecuted instantiation: lldb_private::AMOXOR_W::operator==(lldb_private::AMOXOR_W const&) const Unexecuted instantiation: lldb_private::AMOAND_W::operator==(lldb_private::AMOAND_W const&) const Unexecuted instantiation: lldb_private::AMOOR_W::operator==(lldb_private::AMOOR_W const&) const Unexecuted instantiation: lldb_private::AMOMIN_W::operator==(lldb_private::AMOMIN_W const&) const Unexecuted instantiation: lldb_private::AMOMAX_W::operator==(lldb_private::AMOMAX_W const&) const Unexecuted instantiation: lldb_private::AMOMINU_W::operator==(lldb_private::AMOMINU_W const&) const Unexecuted instantiation: lldb_private::AMOMAXU_W::operator==(lldb_private::AMOMAXU_W const&) const Unexecuted instantiation: lldb_private::LR_D::operator==(lldb_private::LR_D const&) const Unexecuted instantiation: lldb_private::SC_D::operator==(lldb_private::SC_D const&) const Unexecuted instantiation: lldb_private::AMOSWAP_D::operator==(lldb_private::AMOSWAP_D const&) const Unexecuted instantiation: lldb_private::AMOADD_D::operator==(lldb_private::AMOADD_D const&) const Unexecuted instantiation: lldb_private::AMOXOR_D::operator==(lldb_private::AMOXOR_D const&) const Unexecuted instantiation: lldb_private::AMOAND_D::operator==(lldb_private::AMOAND_D const&) const Unexecuted instantiation: lldb_private::AMOOR_D::operator==(lldb_private::AMOOR_D const&) const Unexecuted instantiation: lldb_private::AMOMIN_D::operator==(lldb_private::AMOMIN_D const&) const Unexecuted instantiation: lldb_private::AMOMAX_D::operator==(lldb_private::AMOMAX_D const&) const Unexecuted instantiation: lldb_private::AMOMINU_D::operator==(lldb_private::AMOMINU_D const&) const Unexecuted instantiation: lldb_private::AMOMAXU_D::operator==(lldb_private::AMOMAXU_D const&) const Unexecuted instantiation: lldb_private::FMADD_S::operator==(lldb_private::FMADD_S const&) const Unexecuted instantiation: lldb_private::FMSUB_S::operator==(lldb_private::FMSUB_S const&) const Unexecuted instantiation: lldb_private::FNMADD_S::operator==(lldb_private::FNMADD_S const&) const Unexecuted instantiation: lldb_private::FNMSUB_S::operator==(lldb_private::FNMSUB_S const&) const Unexecuted instantiation: lldb_private::FADD_S::operator==(lldb_private::FADD_S const&) const Unexecuted instantiation: lldb_private::FSUB_S::operator==(lldb_private::FSUB_S const&) const Unexecuted instantiation: lldb_private::FMUL_S::operator==(lldb_private::FMUL_S const&) const Unexecuted instantiation: lldb_private::FDIV_S::operator==(lldb_private::FDIV_S const&) const Unexecuted instantiation: lldb_private::FSQRT_S::operator==(lldb_private::FSQRT_S const&) const Unexecuted instantiation: lldb_private::FSGNJ_S::operator==(lldb_private::FSGNJ_S const&) const Unexecuted instantiation: lldb_private::FSGNJN_S::operator==(lldb_private::FSGNJN_S const&) const Unexecuted instantiation: lldb_private::FSGNJX_S::operator==(lldb_private::FSGNJX_S const&) const Unexecuted instantiation: lldb_private::FMIN_S::operator==(lldb_private::FMIN_S const&) const Unexecuted instantiation: lldb_private::FMAX_S::operator==(lldb_private::FMAX_S const&) const Unexecuted instantiation: lldb_private::FCVT_W_S::operator==(lldb_private::FCVT_W_S const&) const Unexecuted instantiation: lldb_private::FCVT_WU_S::operator==(lldb_private::FCVT_WU_S const&) const Unexecuted instantiation: lldb_private::FMV_X_W::operator==(lldb_private::FMV_X_W const&) const Unexecuted instantiation: lldb_private::FEQ_S::operator==(lldb_private::FEQ_S const&) const Unexecuted instantiation: lldb_private::FLT_S::operator==(lldb_private::FLT_S const&) const Unexecuted instantiation: lldb_private::FLE_S::operator==(lldb_private::FLE_S const&) const Unexecuted instantiation: lldb_private::FCLASS_S::operator==(lldb_private::FCLASS_S const&) const Unexecuted instantiation: lldb_private::FCVT_S_W::operator==(lldb_private::FCVT_S_W const&) const Unexecuted instantiation: lldb_private::FCVT_S_WU::operator==(lldb_private::FCVT_S_WU const&) const Unexecuted instantiation: lldb_private::FMV_W_X::operator==(lldb_private::FMV_W_X const&) const Unexecuted instantiation: lldb_private::FCVT_L_S::operator==(lldb_private::FCVT_L_S const&) const Unexecuted instantiation: lldb_private::FCVT_LU_S::operator==(lldb_private::FCVT_LU_S const&) const Unexecuted instantiation: lldb_private::FCVT_S_L::operator==(lldb_private::FCVT_S_L const&) const Unexecuted instantiation: lldb_private::FCVT_S_LU::operator==(lldb_private::FCVT_S_LU const&) const Unexecuted instantiation: lldb_private::FMADD_D::operator==(lldb_private::FMADD_D const&) const Unexecuted instantiation: lldb_private::FMSUB_D::operator==(lldb_private::FMSUB_D const&) const Unexecuted instantiation: lldb_private::FNMSUB_D::operator==(lldb_private::FNMSUB_D const&) const Unexecuted instantiation: lldb_private::FNMADD_D::operator==(lldb_private::FNMADD_D const&) const Unexecuted instantiation: lldb_private::FADD_D::operator==(lldb_private::FADD_D const&) const Unexecuted instantiation: lldb_private::FSUB_D::operator==(lldb_private::FSUB_D const&) const Unexecuted instantiation: lldb_private::FMUL_D::operator==(lldb_private::FMUL_D const&) const Unexecuted instantiation: lldb_private::FDIV_D::operator==(lldb_private::FDIV_D const&) const Unexecuted instantiation: lldb_private::FSQRT_D::operator==(lldb_private::FSQRT_D const&) const Unexecuted instantiation: lldb_private::FSGNJ_D::operator==(lldb_private::FSGNJ_D const&) const Unexecuted instantiation: lldb_private::FSGNJN_D::operator==(lldb_private::FSGNJN_D const&) const Unexecuted instantiation: lldb_private::FSGNJX_D::operator==(lldb_private::FSGNJX_D const&) const Unexecuted instantiation: lldb_private::FMIN_D::operator==(lldb_private::FMIN_D const&) const Unexecuted instantiation: lldb_private::FMAX_D::operator==(lldb_private::FMAX_D const&) const Unexecuted instantiation: lldb_private::FCVT_S_D::operator==(lldb_private::FCVT_S_D const&) const Unexecuted instantiation: lldb_private::FCVT_D_S::operator==(lldb_private::FCVT_D_S const&) const Unexecuted instantiation: lldb_private::FEQ_D::operator==(lldb_private::FEQ_D const&) const Unexecuted instantiation: lldb_private::FLT_D::operator==(lldb_private::FLT_D const&) const Unexecuted instantiation: lldb_private::FLE_D::operator==(lldb_private::FLE_D const&) const Unexecuted instantiation: lldb_private::FCLASS_D::operator==(lldb_private::FCLASS_D const&) const Unexecuted instantiation: lldb_private::FCVT_W_D::operator==(lldb_private::FCVT_W_D const&) const Unexecuted instantiation: lldb_private::FCVT_WU_D::operator==(lldb_private::FCVT_WU_D const&) const Unexecuted instantiation: lldb_private::FCVT_D_W::operator==(lldb_private::FCVT_D_W const&) const Unexecuted instantiation: lldb_private::FCVT_D_WU::operator==(lldb_private::FCVT_D_WU const&) const Unexecuted instantiation: lldb_private::FCVT_L_D::operator==(lldb_private::FCVT_L_D const&) const Unexecuted instantiation: lldb_private::FCVT_LU_D::operator==(lldb_private::FCVT_LU_D const&) const Unexecuted instantiation: lldb_private::FMV_X_D::operator==(lldb_private::FMV_X_D const&) const Unexecuted instantiation: lldb_private::FCVT_D_L::operator==(lldb_private::FCVT_D_L const&) const Unexecuted instantiation: lldb_private::FCVT_D_LU::operator==(lldb_private::FCVT_D_LU const&) const Unexecuted instantiation: lldb_private::FMV_D_X::operator==(lldb_private::FMV_D_X const&) const |
42 | | |
43 | | #define I_TYPE_INST(NAME) \ |
44 | | struct NAME { \ |
45 | | Rd rd; \ |
46 | | Rs rs1; \ |
47 | | uint32_t imm; \ |
48 | | DERIVE_EQ(NAME); \ |
49 | | } |
50 | | #define S_TYPE_INST(NAME) \ |
51 | | struct NAME { \ |
52 | | Rs rs1; \ |
53 | | Rs rs2; \ |
54 | | uint32_t imm; \ |
55 | | DERIVE_EQ(NAME); \ |
56 | | } |
57 | | #define U_TYPE_INST(NAME) \ |
58 | | struct NAME { \ |
59 | | Rd rd; \ |
60 | | uint32_t imm; \ |
61 | | DERIVE_EQ(NAME); \ |
62 | | } |
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); \ |
71 | | } |
72 | | #define R_SHAMT_TYPE_INST(NAME) \ |
73 | | struct NAME { \ |
74 | | Rd rd; \ |
75 | | Rs rs1; \ |
76 | | uint32_t shamt; \ |
77 | | DERIVE_EQ(NAME); \ |
78 | | } |
79 | | #define R_RS1_TYPE_INST(NAME) \ |
80 | | struct NAME { \ |
81 | | Rd rd; \ |
82 | | Rs rs1; \ |
83 | | DERIVE_EQ(NAME); \ |
84 | | } |
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); \ |
93 | | } |
94 | | /// The `inst` fields are used for debugging. |
95 | | #define INVALID_INST(NAME) \ |
96 | | struct NAME { \ |
97 | | uint32_t inst; \ |
98 | | DERIVE_EQ(NAME); \ |
99 | | } |
100 | | |
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); |
108 | | }; |
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); |
137 | | |
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); |
154 | | |
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); |
164 | | |
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); |
171 | | |
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); |
184 | | |
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); |
197 | | |
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); |
225 | | |
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); |
231 | | |
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); |
259 | | |
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); |
267 | | |
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); |
274 | | |
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>; |
292 | | |
293 | | constexpr uint8_t RV32 = 1; |
294 | | constexpr uint8_t RV64 = 2; |
295 | | constexpr uint8_t RV128 = 4; |
296 | | |
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; |
306 | | }; |
307 | | |
308 | | struct DecodeResult { |
309 | | RISCVInst decoded; |
310 | | uint32_t inst; |
311 | | bool is_rvc; |
312 | | InstrPattern pattern; |
313 | | }; |
314 | | |
315 | 244 | constexpr uint32_t DecodeRD(uint32_t inst) { return (inst & 0xF80) >> 7; } |
316 | 253 | constexpr uint32_t DecodeRS1(uint32_t inst) { return (inst & 0xF8000) >> 15; } |
317 | 193 | constexpr uint32_t DecodeRS2(uint32_t inst) { return (inst & 0x1F00000) >> 20; } |
318 | 16 | constexpr uint32_t DecodeRS3(uint32_t inst) { |
319 | 16 | return (inst & 0xF0000000) >> 27; |
320 | 16 | } |
321 | 22 | constexpr uint32_t DecodeFunct3(uint32_t inst) { return (inst & 0x7000) >> 12; } |
322 | 0 | constexpr uint32_t DecodeFunct2(uint32_t inst) { |
323 | 0 | return (inst & 0xE000000) >> 25; |
324 | 0 | } |
325 | 0 | constexpr uint32_t DecodeFunct7(uint32_t inst) { |
326 | 0 | return (inst & 0xFE000000) >> 25; |
327 | 0 | } |
328 | | |
329 | 8 | constexpr int32_t DecodeRM(uint32_t inst) { return DecodeFunct3(inst); } |
330 | | |
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; |
334 | | } |
335 | 2 | constexpr uint32_t NanUnBoxing(uint64_t val) { |
336 | 2 | return val & (~0xFFFF'FFFF'0000'0000); |
337 | 2 | } |
338 | | |
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 |
350 | | |
351 | | } // namespace lldb_private |
352 | | #endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVINSTRUCTION_H |