Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Instruction/RISCV/RISCVCInstructions.h
39648 views
//===-- RISCVCInstructions.h ----------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVCINSTRUCTION_H9#define LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVCINSTRUCTION_H1011#include <cstdint>12#include <variant>1314#include "Plugins/Process/Utility/lldb-riscv-register-enums.h"15#include "RISCVInstructions.h"1617namespace lldb_private {1819/// Unified RISC-V C register encoding.20struct RxC {21uint32_t rd;22bool shift = true;23operator int() { return rd; }24operator Rd() { return Rd{rd + (shift ? 8 : 0)}; }25operator Rs() { return Rs{rd + (shift ? 8 : 0)}; }26};2728// decode register for RVC29constexpr RxC DecodeCR_RD(uint32_t inst) { return RxC{DecodeRD(inst), false}; }30constexpr RxC DecodeCI_RD(uint32_t inst) { return RxC{DecodeRD(inst), false}; }31constexpr RxC DecodeCR_RS1(uint32_t inst) { return RxC{DecodeRD(inst), false}; }32constexpr RxC DecodeCI_RS1(uint32_t inst) { return RxC{DecodeRD(inst), false}; }33constexpr RxC DecodeCR_RS2(uint32_t inst) {34return RxC{(inst & 0x7C) >> 2, false};35}3637constexpr RxC DecodeCIW_RD(uint32_t inst) { return RxC{(inst & 0x1C) >> 2}; }38constexpr RxC DecodeCL_RD(uint32_t inst) { return RxC{DecodeCIW_RD(inst)}; }39constexpr RxC DecodeCA_RD(uint32_t inst) { return RxC{(inst & 0x380) >> 7}; }40constexpr RxC DecodeCB_RD(uint32_t inst) { return RxC{DecodeCA_RD(inst)}; }4142constexpr RxC DecodeCL_RS1(uint32_t inst) { return RxC{DecodeCA_RD(inst)}; }43constexpr RxC DecodeCS_RS1(uint32_t inst) { return RxC{DecodeCA_RD(inst)}; }44constexpr RxC DecodeCA_RS1(uint32_t inst) { return RxC{DecodeCA_RD(inst)}; }45constexpr RxC DecodeCB_RS1(uint32_t inst) { return RxC{DecodeCA_RD(inst)}; }4647constexpr RxC DecodeCSS_RS2(uint32_t inst) { return DecodeCR_RS2(inst); }48constexpr RxC DecodeCS_RS2(uint32_t inst) { return RxC{DecodeCIW_RD(inst)}; }49constexpr RxC DecodeCA_RS2(uint32_t inst) { return RxC{DecodeCIW_RD(inst)}; }5051RISCVInst DecodeC_LWSP(uint32_t inst) {52auto rd = DecodeCI_RD(inst);53uint16_t offset = ((inst << 4) & 0xc0) // offset[7:6]54| ((inst >> 7) & 0x20) // offset[5]55| ((inst >> 2) & 0x1c); // offset[4:2]56if (rd == 0)57return RESERVED{inst};58return LW{rd, Rs{gpr_sp_riscv}, uint32_t(offset)};59}6061RISCVInst DecodeC_LDSP(uint32_t inst) {62auto rd = DecodeCI_RD(inst);63uint16_t offset = ((inst << 4) & 0x1c0) // offset[8:6]64| ((inst >> 7) & 0x20) // offset[5]65| ((inst >> 2) & 0x18); // offset[4:3]66if (rd == 0)67return RESERVED{inst};68return LD{rd, Rs{gpr_sp_riscv}, uint32_t(offset)};69}7071RISCVInst DecodeC_SWSP(uint32_t inst) {72uint16_t offset = ((inst >> 1) & 0xc0) // offset[7:6]73| ((inst >> 7) & 0x3c); // offset[5:2]74return SW{Rs{gpr_sp_riscv}, DecodeCSS_RS2(inst), uint32_t(offset)};75}7677RISCVInst DecodeC_SDSP(uint32_t inst) {78uint16_t offset = ((inst >> 1) & 0x1c0) // offset[8:6]79| ((inst >> 7) & 0x38); // offset[5:3]80return SD{Rs{gpr_sp_riscv}, DecodeCSS_RS2(inst), uint32_t(offset)};81}8283RISCVInst DecodeC_LW(uint32_t inst) {84uint16_t offset = ((inst << 1) & 0x40) // imm[6]85| ((inst >> 7) & 0x38) // imm[5:3]86| ((inst >> 4) & 0x4); // imm[2]87return LW{DecodeCL_RD(inst), DecodeCL_RS1(inst), uint32_t(offset)};88}8990RISCVInst DecodeC_LD(uint32_t inst) {91uint16_t offset = ((inst << 1) & 0xc0) // imm[7:6]92| ((inst >> 7) & 0x38); // imm[5:3]93return LD{DecodeCL_RD(inst), DecodeCL_RS1(inst), uint32_t(offset)};94}9596RISCVInst DecodeC_SW(uint32_t inst) {97uint16_t offset = ((inst << 1) & 0x40) // imm[6]98| ((inst >> 7) & 0x38) // imm[5:3]99| ((inst >> 4) & 0x4); // imm[2]100return SW{DecodeCS_RS1(inst), DecodeCS_RS2(inst), uint32_t(offset)};101}102103RISCVInst DecodeC_SD(uint32_t inst) {104uint16_t offset = ((inst << 1) & 0xc0) // imm[7:6]105| ((inst >> 7) & 0x38); // imm[5:3]106return SD{DecodeCS_RS1(inst), DecodeCS_RS2(inst), uint32_t(offset)};107}108109RISCVInst DecodeC_J(uint32_t inst) {110uint16_t offset = ((inst >> 1) & 0x800) // offset[11]111| ((inst << 2) & 0x400) // offset[10]112| ((inst >> 1) & 0x300) // offset[9:8]113| ((inst << 1) & 0x80) // offset[7]114| ((inst >> 1) & 0x40) // offset[6]115| ((inst << 3) & 0x20) // offset[5]116| ((inst >> 7) & 0x10) // offset[4]117| ((inst >> 2) & 0xe); // offset[3:1]118if ((offset & 0x800) == 0)119return JAL{Rd{0}, uint32_t(offset)};120return JAL{Rd{0}, uint32_t(int32_t(int16_t(offset | 0xf000)))};121}122123RISCVInst DecodeC_JR(uint32_t inst) {124auto rs1 = DecodeCR_RS1(inst);125if (rs1 == 0)126return RESERVED{inst};127return JALR{Rd{0}, rs1, 0};128}129130RISCVInst DecodeC_JALR(uint32_t inst) {131auto rs1 = DecodeCR_RS1(inst);132if (rs1 == 0)133return EBREAK{inst};134return JALR{Rd{1}, rs1, 0};135}136137constexpr uint16_t BOffset(uint32_t inst) {138return ((inst >> 4) & 0x100) // offset[8]139| ((inst << 1) & 0xc0) // offset[7:6]140| ((inst << 3) & 0x20) // offset[5]141| ((inst >> 7) & 0x18) // offset[4:3]142| ((inst >> 2) & 0x6); // offset[2:1]143}144145RISCVInst DecodeC_BNEZ(uint32_t inst) {146auto rs1 = DecodeCB_RS1(inst);147uint16_t offset = BOffset(inst);148if ((offset & 0x100) == 0)149return B{rs1, Rs{0}, uint32_t(offset), 0b001};150return B{rs1, Rs{0}, uint32_t(int32_t(int16_t(offset | 0xfe00))), 0b001};151}152153RISCVInst DecodeC_BEQZ(uint32_t inst) {154auto rs1 = DecodeCB_RS1(inst);155uint16_t offset = BOffset(inst);156if ((offset & 0x100) == 0)157return B{rs1, Rs{0}, uint32_t(offset), 0b000};158return B{rs1, Rs{0}, uint32_t(int32_t(int16_t(offset | 0xfe00))), 0b000};159}160161RISCVInst DecodeC_LI(uint32_t inst) {162auto rd = DecodeCI_RD(inst);163uint16_t imm = ((inst >> 7) & 0x20) | ((inst >> 2) & 0x1f);164if ((imm & 0x20) == 0)165return ADDI{rd, Rs{0}, uint32_t(imm)};166return ADDI{rd, Rs{0}, uint32_t(int32_t(int8_t(imm | 0xc0)))};167}168169RISCVInst DecodeC_LUI_ADDI16SP(uint32_t inst) {170auto rd = DecodeCI_RD(inst);171if (rd == 0)172return HINT{inst};173if (rd == 2) {174uint16_t nzimm = ((inst >> 3) & 0x200) // nzimm[9]175| ((inst >> 2) & 0x10) // nzimm[4]176| ((inst << 1) & 0x40) // nzimm[6]177| ((inst << 4) & 0x180) // nzimm[8:7]178| ((inst << 3) & 0x20); // nzimm[5]179if (nzimm == 0)180return RESERVED{inst};181if ((nzimm & 0x200) == 0)182return ADDI{Rd{gpr_sp_riscv}, Rs{gpr_sp_riscv}, uint32_t(nzimm)};183return ADDI{Rd{gpr_sp_riscv}, Rs{gpr_sp_riscv},184uint32_t(int32_t(int16_t(nzimm | 0xfc00)))};185}186uint32_t imm =187((uint32_t(inst) << 5) & 0x20000) | ((uint32_t(inst) << 10) & 0x1f000);188if ((imm & 0x20000) == 0)189return LUI{rd, imm};190return LUI{rd, uint32_t(int32_t(imm | 0xfffc0000))};191}192193RISCVInst DecodeC_ADDI(uint32_t inst) {194auto rd = DecodeCI_RD(inst);195if (rd == 0)196return NOP{inst};197uint16_t imm = ((inst >> 7) & 0x20) | ((inst >> 2) & 0x1f);198if ((imm & 0x20) == 0)199return ADDI{rd, rd, uint32_t(imm)};200return ADDI{rd, rd, uint32_t(int32_t(int8_t(imm | 0xc0)))};201}202203RISCVInst DecodeC_ADDIW(uint32_t inst) {204auto rd = DecodeCI_RD(inst);205if (rd == 0)206return RESERVED{inst};207uint16_t imm = ((inst >> 7) & 0x20) | ((inst >> 2) & 0x1f);208if ((imm & 0x20) == 0)209return ADDIW{rd, rd, uint32_t(imm)};210return ADDIW{rd, rd, uint32_t(int32_t(int8_t(imm | 0xc0)))};211}212213RISCVInst DecodeC_ADDI4SPN(uint32_t inst) {214auto rd = DecodeCIW_RD(inst);215uint16_t nzuimm = ((inst >> 1) & 0x3c0) // nzuimm[9:6]216| ((inst >> 7) & 0x30) // nzuimm[5:4]217| ((inst >> 2) & 0x8) // nzuimm[3]218| ((inst >> 4) & 0x4); // nzuimm[2]219220if (rd == 0 && nzuimm == 0)221return INVALID{inst};222if (nzuimm == 0)223return RESERVED{inst};224return ADDI{rd, Rs{gpr_sp_riscv}, uint32_t(nzuimm)};225}226227RISCVInst DecodeC_SLLI(uint32_t inst) {228auto rd = DecodeCI_RD(inst);229uint16_t shamt = ((inst >> 7) & 0x20) | ((inst >> 2) & 0x1f);230if (rd == 0 || shamt == 0)231return HINT{inst};232return SLLI{rd, rd, uint8_t(shamt)};233}234235RISCVInst DecodeC_SRLI(uint32_t inst) {236auto rd = DecodeCB_RD(inst);237uint16_t shamt = ((inst >> 7) & 0x20) | ((inst >> 2) & 0x1f);238if (shamt == 0)239return HINT{inst};240return SRLI{rd, rd, uint8_t(shamt)};241}242243RISCVInst DecodeC_SRAI(uint32_t inst) {244auto rd = DecodeCB_RD(inst);245uint16_t shamt = ((inst >> 7) & 0x20) | ((inst >> 2) & 0x1f);246if (shamt == 0)247return HINT{inst};248return SRAI{rd, rd, uint8_t(shamt)};249}250251RISCVInst DecodeC_ANDI(uint32_t inst) {252auto rd = DecodeCB_RD(inst);253uint16_t imm = ((inst >> 7) & 0x20) | ((inst >> 2) & 0x1f);254if ((imm & 0x20) == 0)255return ANDI{rd, rd, uint32_t(imm)};256return ANDI{rd, rd, uint32_t(int32_t(int8_t(imm | 0xc0)))};257}258259RISCVInst DecodeC_MV(uint32_t inst) {260auto rd = DecodeCR_RD(inst);261auto rs2 = DecodeCR_RS2(inst);262if (rd == 0)263return HINT{inst};264return ADD{rd, Rs{0}, rs2};265}266267RISCVInst DecodeC_ADD(uint32_t inst) {268auto rd = DecodeCR_RD(inst);269return ADD{rd, rd, DecodeCR_RS2(inst)};270}271272RISCVInst DecodeC_AND(uint32_t inst) {273auto rd = DecodeCA_RD(inst);274return AND{rd, rd, DecodeCA_RS2(inst)};275}276277RISCVInst DecodeC_OR(uint32_t inst) {278auto rd = DecodeCA_RD(inst);279return OR{rd, rd, DecodeCA_RS2(inst)};280}281282RISCVInst DecodeC_XOR(uint32_t inst) {283auto rd = DecodeCA_RD(inst);284return XOR{rd, rd, DecodeCA_RS2(inst)};285}286287RISCVInst DecodeC_SUB(uint32_t inst) {288auto rd = DecodeCA_RD(inst);289return SUB{rd, rd, DecodeCA_RS2(inst)};290}291292RISCVInst DecodeC_SUBW(uint32_t inst) {293auto rd = DecodeCA_RD(inst);294return SUBW{rd, rd, DecodeCA_RS2(inst)};295}296297RISCVInst DecodeC_ADDW(uint32_t inst) {298auto rd = DecodeCA_RD(inst);299return ADDW{rd, rd, DecodeCA_RS2(inst)};300}301RISCVInst DecodeC_FLW(uint32_t inst) {302uint16_t offset = ((inst << 1) & 0x40) // imm[6]303| ((inst >> 7) & 0x38) // imm[5:3]304| ((inst >> 4) & 0x4); // imm[2]305return FLW{DecodeCL_RD(inst), DecodeCL_RS1(inst), uint32_t(offset)};306}307308RISCVInst DecodeC_FSW(uint32_t inst) {309uint16_t offset = ((inst << 1) & 0x40) // imm[6]310| ((inst >> 7) & 0x38) // imm[5:3]311| ((inst >> 4) & 0x4); // imm[2]312return FSW{DecodeCS_RS1(inst), DecodeCS_RS2(inst), uint32_t(offset)};313}314315RISCVInst DecodeC_FLWSP(uint32_t inst) {316auto rd = DecodeCI_RD(inst);317uint16_t offset = ((inst << 4) & 0xc0) // offset[7:6]318| ((inst >> 7) & 0x20) // offset[5]319| ((inst >> 2) & 0x1c); // offset[4:2]320return FLW{rd, Rs{gpr_sp_riscv}, uint32_t(offset)};321}322323RISCVInst DecodeC_FSWSP(uint32_t inst) {324uint16_t offset = ((inst >> 1) & 0xc0) // offset[7:6]325| ((inst >> 7) & 0x3c); // offset[5:2]326return FSW{Rs{gpr_sp_riscv}, DecodeCSS_RS2(inst), uint32_t(offset)};327}328329RISCVInst DecodeC_FLDSP(uint32_t inst) {330auto rd = DecodeCI_RD(inst);331uint16_t offset = ((inst << 4) & 0x1c0) // offset[8:6]332| ((inst >> 7) & 0x20) // offset[5]333| ((inst >> 2) & 0x18); // offset[4:3]334return FLD{rd, Rs{gpr_sp_riscv}, uint32_t(offset)};335}336337RISCVInst DecodeC_FSDSP(uint32_t inst) {338uint16_t offset = ((inst >> 1) & 0x1c0) // offset[8:6]339| ((inst >> 7) & 0x38); // offset[5:3]340return FSD{Rs{gpr_sp_riscv}, DecodeCSS_RS2(inst), uint32_t(offset)};341}342343RISCVInst DecodeC_FLD(uint32_t inst) {344uint16_t offset = ((inst << 1) & 0xc0) // imm[7:6]345| ((inst >> 7) & 0x38); // imm[5:3]346return FLD{DecodeCL_RD(inst), DecodeCL_RS1(inst), uint32_t(offset)};347}348349RISCVInst DecodeC_FSD(uint32_t inst) {350uint16_t offset = ((inst << 1) & 0xc0) // imm[7:6]351| ((inst >> 7) & 0x38); // imm[5:3]352return FSD{DecodeCS_RS1(inst), DecodeCS_RS2(inst), uint32_t(offset)};353}354355} // namespace lldb_private356#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVCINSTRUCTION_H357358359