358 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVCINSTRUCTION_H10#define LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVCINSTRUCTION_H11 12#include <cstdint>13#include <variant>14 15#include "Plugins/Process/Utility/lldb-riscv-register-enums.h"16#include "RISCVInstructions.h"17 18namespace lldb_private {19 20/// Unified RISC-V C register encoding.21struct 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 RVC30constexpr RxC DecodeCR_RD(uint32_t inst) { return RxC{DecodeRD(inst), false}; }31constexpr RxC DecodeCI_RD(uint32_t inst) { return RxC{DecodeRD(inst), false}; }32constexpr RxC DecodeCR_RS1(uint32_t inst) { return RxC{DecodeRD(inst), false}; }33constexpr RxC DecodeCI_RS1(uint32_t inst) { return RxC{DecodeRD(inst), false}; }34constexpr RxC DecodeCR_RS2(uint32_t inst) {35 return RxC{(inst & 0x7C) >> 2, false};36}37 38constexpr RxC DecodeCIW_RD(uint32_t inst) { return RxC{(inst & 0x1C) >> 2}; }39constexpr RxC DecodeCL_RD(uint32_t inst) { return RxC{DecodeCIW_RD(inst)}; }40constexpr RxC DecodeCA_RD(uint32_t inst) { return RxC{(inst & 0x380) >> 7}; }41constexpr RxC DecodeCB_RD(uint32_t inst) { return RxC{DecodeCA_RD(inst)}; }42 43constexpr RxC DecodeCL_RS1(uint32_t inst) { return RxC{DecodeCA_RD(inst)}; }44constexpr RxC DecodeCS_RS1(uint32_t inst) { return RxC{DecodeCA_RD(inst)}; }45constexpr RxC DecodeCA_RS1(uint32_t inst) { return RxC{DecodeCA_RD(inst)}; }46constexpr RxC DecodeCB_RS1(uint32_t inst) { return RxC{DecodeCA_RD(inst)}; }47 48constexpr RxC DecodeCSS_RS2(uint32_t inst) { return DecodeCR_RS2(inst); }49constexpr RxC DecodeCS_RS2(uint32_t inst) { return RxC{DecodeCIW_RD(inst)}; }50constexpr RxC DecodeCA_RS2(uint32_t inst) { return RxC{DecodeCIW_RD(inst)}; }51 52RISCVInst 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 62RISCVInst 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 72RISCVInst 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 78RISCVInst 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 84RISCVInst 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 91RISCVInst 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 97RISCVInst 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 104RISCVInst 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 110RISCVInst 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 124RISCVInst 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 131RISCVInst 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 138constexpr 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 146RISCVInst 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 154RISCVInst 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 162RISCVInst 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 170RISCVInst 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 194RISCVInst 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 204RISCVInst 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 214RISCVInst 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 228RISCVInst 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 236RISCVInst 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 244RISCVInst 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 252RISCVInst 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 260RISCVInst 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 268RISCVInst DecodeC_ADD(uint32_t inst) {269 auto rd = DecodeCR_RD(inst);270 return ADD{rd, rd, DecodeCR_RS2(inst)};271}272 273RISCVInst DecodeC_AND(uint32_t inst) {274 auto rd = DecodeCA_RD(inst);275 return AND{rd, rd, DecodeCA_RS2(inst)};276}277 278RISCVInst DecodeC_OR(uint32_t inst) {279 auto rd = DecodeCA_RD(inst);280 return OR{rd, rd, DecodeCA_RS2(inst)};281}282 283RISCVInst DecodeC_XOR(uint32_t inst) {284 auto rd = DecodeCA_RD(inst);285 return XOR{rd, rd, DecodeCA_RS2(inst)};286}287 288RISCVInst DecodeC_SUB(uint32_t inst) {289 auto rd = DecodeCA_RD(inst);290 return SUB{rd, rd, DecodeCA_RS2(inst)};291}292 293RISCVInst DecodeC_SUBW(uint32_t inst) {294 auto rd = DecodeCA_RD(inst);295 return SUBW{rd, rd, DecodeCA_RS2(inst)};296}297 298RISCVInst DecodeC_ADDW(uint32_t inst) {299 auto rd = DecodeCA_RD(inst);300 return ADDW{rd, rd, DecodeCA_RS2(inst)};301}302RISCVInst 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 309RISCVInst 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 316RISCVInst 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 324RISCVInst 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 330RISCVInst 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 338RISCVInst 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 344RISCVInst 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 350RISCVInst 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_private357#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVCINSTRUCTION_H358