1 //===-- RISCVCInstructions.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_RISCVCINSTRUCTION_H 10 #define LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVCINSTRUCTION_H 11 12 #include <cstdint> 13 #include <variant> 14 15 #include "Plugins/Process/Utility/lldb-riscv-register-enums.h" 16 #include "RISCVInstructions.h" 17 18 namespace lldb_private { 19 20 /// Unified RISC-V C register encoding. 21 struct RxC { 22 uint32_t rd; 23 bool shift = true; 24 operator int() { return rd; } 25 operator Rd() { return Rd{rd + (shift ? 8 : 0)}; } 26 operator Rs() { return Rs{rd + (shift ? 8 : 0)}; } 27 }; 28 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}; 36 } 37 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)}; } 42 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)}; } 47 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)}; } 51 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] 57 if (rd == 0) 58 return RESERVED{inst}; 59 return LW{rd, Rs{gpr_sp_riscv}, uint32_t(offset)}; 60 } 61 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] 67 if (rd == 0) 68 return RESERVED{inst}; 69 return LD{rd, Rs{gpr_sp_riscv}, uint32_t(offset)}; 70 } 71 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)}; 76 } 77 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)}; 82 } 83 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)}; 89 } 90 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)}; 95 } 96 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)}; 102 } 103 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)}; 108 } 109 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)))}; 122 } 123 124 RISCVInst DecodeC_JR(uint32_t inst) { 125 auto rs1 = DecodeCR_RS1(inst); 126 if (rs1 == 0) 127 return RESERVED{inst}; 128 return JALR{Rd{0}, rs1, 0}; 129 } 130 131 RISCVInst DecodeC_JALR(uint32_t inst) { 132 auto rs1 = DecodeCR_RS1(inst); 133 if (rs1 == 0) 134 return EBREAK{inst}; 135 return JALR{Rd{1}, rs1, 0}; 136 } 137 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] 144 } 145 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}; 152 } 153 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}; 160 } 161 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)))}; 168 } 169 170 RISCVInst DecodeC_LUI_ADDI16SP(uint32_t inst) { 171 auto rd = DecodeCI_RD(inst); 172 if (rd == 0) 173 return HINT{inst}; 174 if (rd == 2) { 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] 180 if (nzimm == 0) 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)))}; 186 } 187 uint32_t imm = 188 ((uint32_t(inst) << 5) & 0x20000) | ((uint32_t(inst) << 10) & 0x1f000); 189 if ((imm & 0x20000) == 0) 190 return LUI{rd, imm}; 191 return LUI{rd, uint32_t(int32_t(imm | 0xfffc0000))}; 192 } 193 194 RISCVInst DecodeC_ADDI(uint32_t inst) { 195 auto rd = DecodeCI_RD(inst); 196 if (rd == 0) 197 return NOP{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)))}; 202 } 203 204 RISCVInst DecodeC_ADDIW(uint32_t inst) { 205 auto rd = DecodeCI_RD(inst); 206 if (rd == 0) 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)))}; 212 } 213 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] 220 221 if (rd == 0 && nzuimm == 0) 222 return INVALID{inst}; 223 if (nzuimm == 0) 224 return RESERVED{inst}; 225 return ADDI{rd, Rs{gpr_sp_riscv}, uint32_t(nzuimm)}; 226 } 227 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) 232 return HINT{inst}; 233 return SLLI{rd, rd, uint8_t(shamt)}; 234 } 235 236 RISCVInst DecodeC_SRLI(uint32_t inst) { 237 auto rd = DecodeCB_RD(inst); 238 uint16_t shamt = ((inst >> 7) & 0x20) | ((inst >> 2) & 0x1f); 239 if (shamt == 0) 240 return HINT{inst}; 241 return SRLI{rd, rd, uint8_t(shamt)}; 242 } 243 244 RISCVInst DecodeC_SRAI(uint32_t inst) { 245 auto rd = DecodeCB_RD(inst); 246 uint16_t shamt = ((inst >> 7) & 0x20) | ((inst >> 2) & 0x1f); 247 if (shamt == 0) 248 return HINT{inst}; 249 return SRAI{rd, rd, uint8_t(shamt)}; 250 } 251 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)))}; 258 } 259 260 RISCVInst DecodeC_MV(uint32_t inst) { 261 auto rd = DecodeCR_RD(inst); 262 auto rs2 = DecodeCR_RS2(inst); 263 if (rd == 0) 264 return HINT{inst}; 265 return ADD{rd, Rs{0}, rs2}; 266 } 267 268 RISCVInst DecodeC_ADD(uint32_t inst) { 269 auto rd = DecodeCR_RD(inst); 270 return ADD{rd, rd, DecodeCR_RS2(inst)}; 271 } 272 273 RISCVInst DecodeC_AND(uint32_t inst) { 274 auto rd = DecodeCA_RD(inst); 275 return AND{rd, rd, DecodeCA_RS2(inst)}; 276 } 277 278 RISCVInst DecodeC_OR(uint32_t inst) { 279 auto rd = DecodeCA_RD(inst); 280 return OR{rd, rd, DecodeCA_RS2(inst)}; 281 } 282 283 RISCVInst DecodeC_XOR(uint32_t inst) { 284 auto rd = DecodeCA_RD(inst); 285 return XOR{rd, rd, DecodeCA_RS2(inst)}; 286 } 287 288 RISCVInst DecodeC_SUB(uint32_t inst) { 289 auto rd = DecodeCA_RD(inst); 290 return SUB{rd, rd, DecodeCA_RS2(inst)}; 291 } 292 293 RISCVInst DecodeC_SUBW(uint32_t inst) { 294 auto rd = DecodeCA_RD(inst); 295 return SUBW{rd, rd, DecodeCA_RS2(inst)}; 296 } 297 298 RISCVInst DecodeC_ADDW(uint32_t inst) { 299 auto rd = DecodeCA_RD(inst); 300 return ADDW{rd, rd, DecodeCA_RS2(inst)}; 301 } 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)}; 307 } 308 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)}; 314 } 315 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)}; 322 } 323 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)}; 328 } 329 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)}; 336 } 337 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)}; 342 } 343 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)}; 348 } 349 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)}; 354 } 355 356 } // namespace lldb_private 357 #endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVCINSTRUCTION_H 358