1 //===-- RISCVCInstructions.h ----------------------------------------------===//
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 #ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVCINSTRUCTION_H
10 #define LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVCINSTRUCTION_H
15 #include "Plugins/Process/Utility/lldb-riscv-register-enums.h"
16 #include "RISCVInstructions.h"
18 namespace lldb_private
{
20 /// Unified RISC-V C register encoding.
24 operator int() { return rd
; }
25 operator Rd() { return Rd
{rd
+ (shift
? 8 : 0)}; }
26 operator Rs() { return Rs
{rd
+ (shift
? 8 : 0)}; }
29 // decode register for RVC
30 constexpr RxC
DecodeCR_RD(uint32_t inst
) { return RxC
{DecodeRD(inst
), false}; }
31 constexpr RxC
DecodeCI_RD(uint32_t inst
) { return RxC
{DecodeRD(inst
), false}; }
32 constexpr RxC
DecodeCR_RS1(uint32_t inst
) { return RxC
{DecodeRD(inst
), false}; }
33 constexpr RxC
DecodeCI_RS1(uint32_t inst
) { return RxC
{DecodeRD(inst
), false}; }
34 constexpr RxC
DecodeCR_RS2(uint32_t inst
) {
35 return RxC
{(inst
& 0x7C) >> 2, false};
38 constexpr RxC
DecodeCIW_RD(uint32_t inst
) { return RxC
{(inst
& 0x1C) >> 2}; }
39 constexpr RxC
DecodeCL_RD(uint32_t inst
) { return RxC
{DecodeCIW_RD(inst
)}; }
40 constexpr RxC
DecodeCA_RD(uint32_t inst
) { return RxC
{(inst
& 0x380) >> 7}; }
41 constexpr RxC
DecodeCB_RD(uint32_t inst
) { return RxC
{DecodeCA_RD(inst
)}; }
43 constexpr RxC
DecodeCL_RS1(uint32_t inst
) { return RxC
{DecodeCA_RD(inst
)}; }
44 constexpr RxC
DecodeCS_RS1(uint32_t inst
) { return RxC
{DecodeCA_RD(inst
)}; }
45 constexpr RxC
DecodeCA_RS1(uint32_t inst
) { return RxC
{DecodeCA_RD(inst
)}; }
46 constexpr RxC
DecodeCB_RS1(uint32_t inst
) { return RxC
{DecodeCA_RD(inst
)}; }
48 constexpr RxC
DecodeCSS_RS2(uint32_t inst
) { return DecodeCR_RS2(inst
); }
49 constexpr RxC
DecodeCS_RS2(uint32_t inst
) { return RxC
{DecodeCIW_RD(inst
)}; }
50 constexpr RxC
DecodeCA_RS2(uint32_t inst
) { return RxC
{DecodeCIW_RD(inst
)}; }
52 RISCVInst
DecodeC_LWSP(uint32_t inst
) {
53 auto rd
= DecodeCI_RD(inst
);
54 uint16_t offset
= ((inst
<< 4) & 0xc0) // offset[7:6]
55 | ((inst
>> 7) & 0x20) // offset[5]
56 | ((inst
>> 2) & 0x1c); // offset[4:2]
58 return RESERVED
{inst
};
59 return LW
{rd
, Rs
{gpr_sp_riscv
}, uint32_t(offset
)};
62 RISCVInst
DecodeC_LDSP(uint32_t inst
) {
63 auto rd
= DecodeCI_RD(inst
);
64 uint16_t offset
= ((inst
<< 4) & 0x1c0) // offset[8:6]
65 | ((inst
>> 7) & 0x20) // offset[5]
66 | ((inst
>> 2) & 0x18); // offset[4:3]
68 return RESERVED
{inst
};
69 return LD
{rd
, Rs
{gpr_sp_riscv
}, uint32_t(offset
)};
72 RISCVInst
DecodeC_SWSP(uint32_t inst
) {
73 uint16_t offset
= ((inst
>> 1) & 0xc0) // offset[7:6]
74 | ((inst
>> 7) & 0x3c); // offset[5:2]
75 return SW
{Rs
{gpr_sp_riscv
}, DecodeCSS_RS2(inst
), uint32_t(offset
)};
78 RISCVInst
DecodeC_SDSP(uint32_t inst
) {
79 uint16_t offset
= ((inst
>> 1) & 0x1c0) // offset[8:6]
80 | ((inst
>> 7) & 0x38); // offset[5:3]
81 return SD
{Rs
{gpr_sp_riscv
}, DecodeCSS_RS2(inst
), uint32_t(offset
)};
84 RISCVInst
DecodeC_LW(uint32_t inst
) {
85 uint16_t offset
= ((inst
<< 1) & 0x40) // imm[6]
86 | ((inst
>> 7) & 0x38) // imm[5:3]
87 | ((inst
>> 4) & 0x4); // imm[2]
88 return LW
{DecodeCL_RD(inst
), DecodeCL_RS1(inst
), uint32_t(offset
)};
91 RISCVInst
DecodeC_LD(uint32_t inst
) {
92 uint16_t offset
= ((inst
<< 1) & 0xc0) // imm[7:6]
93 | ((inst
>> 7) & 0x38); // imm[5:3]
94 return LD
{DecodeCL_RD(inst
), DecodeCL_RS1(inst
), uint32_t(offset
)};
97 RISCVInst
DecodeC_SW(uint32_t inst
) {
98 uint16_t offset
= ((inst
<< 1) & 0x40) // imm[6]
99 | ((inst
>> 7) & 0x38) // imm[5:3]
100 | ((inst
>> 4) & 0x4); // imm[2]
101 return SW
{DecodeCS_RS1(inst
), DecodeCS_RS2(inst
), uint32_t(offset
)};
104 RISCVInst
DecodeC_SD(uint32_t inst
) {
105 uint16_t offset
= ((inst
<< 1) & 0xc0) // imm[7:6]
106 | ((inst
>> 7) & 0x38); // imm[5:3]
107 return SD
{DecodeCS_RS1(inst
), DecodeCS_RS2(inst
), uint32_t(offset
)};
110 RISCVInst
DecodeC_J(uint32_t inst
) {
111 uint16_t offset
= ((inst
>> 1) & 0x800) // offset[11]
112 | ((inst
<< 2) & 0x400) // offset[10]
113 | ((inst
>> 1) & 0x300) // offset[9:8]
114 | ((inst
<< 1) & 0x80) // offset[7]
115 | ((inst
>> 1) & 0x40) // offset[6]
116 | ((inst
<< 3) & 0x20) // offset[5]
117 | ((inst
>> 7) & 0x10) // offset[4]
118 | ((inst
>> 2) & 0xe); // offset[3:1]
119 if ((offset
& 0x800) == 0)
120 return JAL
{Rd
{0}, uint32_t(offset
)};
121 return JAL
{Rd
{0}, uint32_t(int32_t(int16_t(offset
| 0xf000)))};
124 RISCVInst
DecodeC_JR(uint32_t inst
) {
125 auto rs1
= DecodeCR_RS1(inst
);
127 return RESERVED
{inst
};
128 return JALR
{Rd
{0}, rs1
, 0};
131 RISCVInst
DecodeC_JALR(uint32_t inst
) {
132 auto rs1
= DecodeCR_RS1(inst
);
135 return JALR
{Rd
{1}, rs1
, 0};
138 constexpr uint16_t BOffset(uint32_t inst
) {
139 return ((inst
>> 4) & 0x100) // offset[8]
140 | ((inst
<< 1) & 0xc0) // offset[7:6]
141 | ((inst
<< 3) & 0x20) // offset[5]
142 | ((inst
>> 7) & 0x18) // offset[4:3]
143 | ((inst
>> 2) & 0x6); // offset[2:1]
146 RISCVInst
DecodeC_BNEZ(uint32_t inst
) {
147 auto rs1
= DecodeCB_RS1(inst
);
148 uint16_t offset
= BOffset(inst
);
149 if ((offset
& 0x100) == 0)
150 return B
{rs1
, Rs
{0}, uint32_t(offset
), 0b001};
151 return B
{rs1
, Rs
{0}, uint32_t(int32_t(int16_t(offset
| 0xfe00))), 0b001};
154 RISCVInst
DecodeC_BEQZ(uint32_t inst
) {
155 auto rs1
= DecodeCB_RS1(inst
);
156 uint16_t offset
= BOffset(inst
);
157 if ((offset
& 0x100) == 0)
158 return B
{rs1
, Rs
{0}, uint32_t(offset
), 0b000};
159 return B
{rs1
, Rs
{0}, uint32_t(int32_t(int16_t(offset
| 0xfe00))), 0b000};
162 RISCVInst
DecodeC_LI(uint32_t inst
) {
163 auto rd
= DecodeCI_RD(inst
);
164 uint16_t imm
= ((inst
>> 7) & 0x20) | ((inst
>> 2) & 0x1f);
165 if ((imm
& 0x20) == 0)
166 return ADDI
{rd
, Rs
{0}, uint32_t(imm
)};
167 return ADDI
{rd
, Rs
{0}, uint32_t(int32_t(int8_t(imm
| 0xc0)))};
170 RISCVInst
DecodeC_LUI_ADDI16SP(uint32_t inst
) {
171 auto rd
= DecodeCI_RD(inst
);
175 uint16_t nzimm
= ((inst
>> 3) & 0x200) // nzimm[9]
176 | ((inst
>> 2) & 0x10) // nzimm[4]
177 | ((inst
<< 1) & 0x40) // nzimm[6]
178 | ((inst
<< 4) & 0x180) // nzimm[8:7]
179 | ((inst
<< 3) & 0x20); // nzimm[5]
181 return RESERVED
{inst
};
182 if ((nzimm
& 0x200) == 0)
183 return ADDI
{Rd
{gpr_sp_riscv
}, Rs
{gpr_sp_riscv
}, uint32_t(nzimm
)};
184 return ADDI
{Rd
{gpr_sp_riscv
}, Rs
{gpr_sp_riscv
},
185 uint32_t(int32_t(int16_t(nzimm
| 0xfc00)))};
188 ((uint32_t(inst
) << 5) & 0x20000) | ((uint32_t(inst
) << 10) & 0x1f000);
189 if ((imm
& 0x20000) == 0)
191 return LUI
{rd
, uint32_t(int32_t(imm
| 0xfffc0000))};
194 RISCVInst
DecodeC_ADDI(uint32_t inst
) {
195 auto rd
= DecodeCI_RD(inst
);
198 uint16_t imm
= ((inst
>> 7) & 0x20) | ((inst
>> 2) & 0x1f);
199 if ((imm
& 0x20) == 0)
200 return ADDI
{rd
, rd
, uint32_t(imm
)};
201 return ADDI
{rd
, rd
, uint32_t(int32_t(int8_t(imm
| 0xc0)))};
204 RISCVInst
DecodeC_ADDIW(uint32_t inst
) {
205 auto rd
= DecodeCI_RD(inst
);
207 return RESERVED
{inst
};
208 uint16_t imm
= ((inst
>> 7) & 0x20) | ((inst
>> 2) & 0x1f);
209 if ((imm
& 0x20) == 0)
210 return ADDIW
{rd
, rd
, uint32_t(imm
)};
211 return ADDIW
{rd
, rd
, uint32_t(int32_t(int8_t(imm
| 0xc0)))};
214 RISCVInst
DecodeC_ADDI4SPN(uint32_t inst
) {
215 auto rd
= DecodeCIW_RD(inst
);
216 uint16_t nzuimm
= ((inst
>> 1) & 0x3c0) // nzuimm[9:6]
217 | ((inst
>> 7) & 0x30) // nzuimm[5:4]
218 | ((inst
>> 2) & 0x8) // nzuimm[3]
219 | ((inst
>> 4) & 0x4); // nzuimm[2]
221 if (rd
== 0 && nzuimm
== 0)
222 return INVALID
{inst
};
224 return RESERVED
{inst
};
225 return ADDI
{rd
, Rs
{gpr_sp_riscv
}, uint32_t(nzuimm
)};
228 RISCVInst
DecodeC_SLLI(uint32_t inst
) {
229 auto rd
= DecodeCI_RD(inst
);
230 uint16_t shamt
= ((inst
>> 7) & 0x20) | ((inst
>> 2) & 0x1f);
231 if (rd
== 0 || shamt
== 0)
233 return SLLI
{rd
, rd
, uint8_t(shamt
)};
236 RISCVInst
DecodeC_SRLI(uint32_t inst
) {
237 auto rd
= DecodeCB_RD(inst
);
238 uint16_t shamt
= ((inst
>> 7) & 0x20) | ((inst
>> 2) & 0x1f);
241 return SRLI
{rd
, rd
, uint8_t(shamt
)};
244 RISCVInst
DecodeC_SRAI(uint32_t inst
) {
245 auto rd
= DecodeCB_RD(inst
);
246 uint16_t shamt
= ((inst
>> 7) & 0x20) | ((inst
>> 2) & 0x1f);
249 return SRAI
{rd
, rd
, uint8_t(shamt
)};
252 RISCVInst
DecodeC_ANDI(uint32_t inst
) {
253 auto rd
= DecodeCB_RD(inst
);
254 uint16_t imm
= ((inst
>> 7) & 0x20) | ((inst
>> 2) & 0x1f);
255 if ((imm
& 0x20) == 0)
256 return ANDI
{rd
, rd
, uint32_t(imm
)};
257 return ANDI
{rd
, rd
, uint32_t(int32_t(int8_t(imm
| 0xc0)))};
260 RISCVInst
DecodeC_MV(uint32_t inst
) {
261 auto rd
= DecodeCR_RD(inst
);
262 auto rs2
= DecodeCR_RS2(inst
);
265 return ADD
{rd
, Rs
{0}, rs2
};
268 RISCVInst
DecodeC_ADD(uint32_t inst
) {
269 auto rd
= DecodeCR_RD(inst
);
270 return ADD
{rd
, rd
, DecodeCR_RS2(inst
)};
273 RISCVInst
DecodeC_AND(uint32_t inst
) {
274 auto rd
= DecodeCA_RD(inst
);
275 return AND
{rd
, rd
, DecodeCA_RS2(inst
)};
278 RISCVInst
DecodeC_OR(uint32_t inst
) {
279 auto rd
= DecodeCA_RD(inst
);
280 return OR
{rd
, rd
, DecodeCA_RS2(inst
)};
283 RISCVInst
DecodeC_XOR(uint32_t inst
) {
284 auto rd
= DecodeCA_RD(inst
);
285 return XOR
{rd
, rd
, DecodeCA_RS2(inst
)};
288 RISCVInst
DecodeC_SUB(uint32_t inst
) {
289 auto rd
= DecodeCA_RD(inst
);
290 return SUB
{rd
, rd
, DecodeCA_RS2(inst
)};
293 RISCVInst
DecodeC_SUBW(uint32_t inst
) {
294 auto rd
= DecodeCA_RD(inst
);
295 return SUBW
{rd
, rd
, DecodeCA_RS2(inst
)};
298 RISCVInst
DecodeC_ADDW(uint32_t inst
) {
299 auto rd
= DecodeCA_RD(inst
);
300 return ADDW
{rd
, rd
, DecodeCA_RS2(inst
)};
302 RISCVInst
DecodeC_FLW(uint32_t inst
) {
303 uint16_t offset
= ((inst
<< 1) & 0x40) // imm[6]
304 | ((inst
>> 7) & 0x38) // imm[5:3]
305 | ((inst
>> 4) & 0x4); // imm[2]
306 return FLW
{DecodeCL_RD(inst
), DecodeCL_RS1(inst
), uint32_t(offset
)};
309 RISCVInst
DecodeC_FSW(uint32_t inst
) {
310 uint16_t offset
= ((inst
<< 1) & 0x40) // imm[6]
311 | ((inst
>> 7) & 0x38) // imm[5:3]
312 | ((inst
>> 4) & 0x4); // imm[2]
313 return FSW
{DecodeCS_RS1(inst
), DecodeCS_RS2(inst
), uint32_t(offset
)};
316 RISCVInst
DecodeC_FLWSP(uint32_t inst
) {
317 auto rd
= DecodeCI_RD(inst
);
318 uint16_t offset
= ((inst
<< 4) & 0xc0) // offset[7:6]
319 | ((inst
>> 7) & 0x20) // offset[5]
320 | ((inst
>> 2) & 0x1c); // offset[4:2]
321 return FLW
{rd
, Rs
{gpr_sp_riscv
}, uint32_t(offset
)};
324 RISCVInst
DecodeC_FSWSP(uint32_t inst
) {
325 uint16_t offset
= ((inst
>> 1) & 0xc0) // offset[7:6]
326 | ((inst
>> 7) & 0x3c); // offset[5:2]
327 return FSW
{Rs
{gpr_sp_riscv
}, DecodeCSS_RS2(inst
), uint32_t(offset
)};
330 RISCVInst
DecodeC_FLDSP(uint32_t inst
) {
331 auto rd
= DecodeCI_RD(inst
);
332 uint16_t offset
= ((inst
<< 4) & 0x1c0) // offset[8:6]
333 | ((inst
>> 7) & 0x20) // offset[5]
334 | ((inst
>> 2) & 0x18); // offset[4:3]
335 return FLD
{rd
, Rs
{gpr_sp_riscv
}, uint32_t(offset
)};
338 RISCVInst
DecodeC_FSDSP(uint32_t inst
) {
339 uint16_t offset
= ((inst
>> 1) & 0x1c0) // offset[8:6]
340 | ((inst
>> 7) & 0x38); // offset[5:3]
341 return FSD
{Rs
{gpr_sp_riscv
}, DecodeCSS_RS2(inst
), uint32_t(offset
)};
344 RISCVInst
DecodeC_FLD(uint32_t inst
) {
345 uint16_t offset
= ((inst
<< 1) & 0xc0) // imm[7:6]
346 | ((inst
>> 7) & 0x38); // imm[5:3]
347 return FLD
{DecodeCL_RD(inst
), DecodeCL_RS1(inst
), uint32_t(offset
)};
350 RISCVInst
DecodeC_FSD(uint32_t inst
) {
351 uint16_t offset
= ((inst
<< 1) & 0xc0) // imm[7:6]
352 | ((inst
>> 7) & 0x38); // imm[5:3]
353 return FSD
{DecodeCS_RS1(inst
), DecodeCS_RS2(inst
), uint32_t(offset
)};
356 } // namespace lldb_private
357 #endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVCINSTRUCTION_H