brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.0 KiB · 252cef8 Raw
353 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVINSTRUCTION_H10#define LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVINSTRUCTION_H11 12#include <cstdint>13#include <optional>14#include <variant>15 16#include "llvm/ADT/APFloat.h"17 18namespace lldb_private {19 20class EmulateInstructionRISCV;21 22struct Rd {23  uint32_t rd;24  bool Write(EmulateInstructionRISCV &emulator, uint64_t value);25  bool WriteAPFloat(EmulateInstructionRISCV &emulator, llvm::APFloat value);26};27 28struct 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  bool operator==(const NAME &r) const {                                       \40    return std::memcmp(this, &r, sizeof(NAME)) == 0;                           \41  }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)102struct B {103  Rs rs1;104  Rs rs2;105  uint32_t imm;106  uint32_t funct3;107  DERIVE_EQ(B);108};109U_TYPE_INST(LUI);110U_TYPE_INST(AUIPC);111J_TYPE_INST(JAL);112I_TYPE_INST(JALR);113I_TYPE_INST(LB);114I_TYPE_INST(LH);115I_TYPE_INST(LW);116I_TYPE_INST(LBU);117I_TYPE_INST(LHU);118S_TYPE_INST(SB);119S_TYPE_INST(SH);120S_TYPE_INST(SW);121I_TYPE_INST(ADDI);122I_TYPE_INST(SLTI);123I_TYPE_INST(SLTIU);124I_TYPE_INST(XORI);125I_TYPE_INST(ORI);126I_TYPE_INST(ANDI);127R_TYPE_INST(ADD);128R_TYPE_INST(SUB);129R_TYPE_INST(SLL);130R_TYPE_INST(SLT);131R_TYPE_INST(SLTU);132R_TYPE_INST(XOR);133R_TYPE_INST(SRL);134R_TYPE_INST(SRA);135R_TYPE_INST(OR);136R_TYPE_INST(AND);137 138// RV64I inst (The base integer ISA)139I_TYPE_INST(LWU);140I_TYPE_INST(LD);141S_TYPE_INST(SD);142R_SHAMT_TYPE_INST(SLLI);143R_SHAMT_TYPE_INST(SRLI);144R_SHAMT_TYPE_INST(SRAI);145I_TYPE_INST(ADDIW);146R_SHAMT_TYPE_INST(SLLIW);147R_SHAMT_TYPE_INST(SRLIW);148R_SHAMT_TYPE_INST(SRAIW);149R_TYPE_INST(ADDW);150R_TYPE_INST(SUBW);151R_TYPE_INST(SLLW);152R_TYPE_INST(SRLW);153R_TYPE_INST(SRAW);154 155// RV32M inst (The standard integer multiplication and division extension)156R_TYPE_INST(MUL);157R_TYPE_INST(MULH);158R_TYPE_INST(MULHSU);159R_TYPE_INST(MULHU);160R_TYPE_INST(DIV);161R_TYPE_INST(DIVU);162R_TYPE_INST(REM);163R_TYPE_INST(REMU);164 165// RV64M inst (The standard integer multiplication and division extension)166R_TYPE_INST(MULW);167R_TYPE_INST(DIVW);168R_TYPE_INST(DIVUW);169R_TYPE_INST(REMW);170R_TYPE_INST(REMUW);171 172// RV32A inst (The standard atomic instruction extension)173R_RS1_TYPE_INST(LR_W);174R_TYPE_INST(SC_W);175R_TYPE_INST(AMOSWAP_W);176R_TYPE_INST(AMOADD_W);177R_TYPE_INST(AMOXOR_W);178R_TYPE_INST(AMOAND_W);179R_TYPE_INST(AMOOR_W);180R_TYPE_INST(AMOMIN_W);181R_TYPE_INST(AMOMAX_W);182R_TYPE_INST(AMOMINU_W);183R_TYPE_INST(AMOMAXU_W);184 185// RV64A inst (The standard atomic instruction extension)186R_RS1_TYPE_INST(LR_D);187R_TYPE_INST(SC_D);188R_TYPE_INST(AMOSWAP_D);189R_TYPE_INST(AMOADD_D);190R_TYPE_INST(AMOXOR_D);191R_TYPE_INST(AMOAND_D);192R_TYPE_INST(AMOOR_D);193R_TYPE_INST(AMOMIN_D);194R_TYPE_INST(AMOMAX_D);195R_TYPE_INST(AMOMINU_D);196R_TYPE_INST(AMOMAXU_D);197 198// RV32F inst (The standard single-precision floating-point extension)199I_TYPE_INST(FLW);200S_TYPE_INST(FSW);201R4_TYPE_INST(FMADD_S);202R4_TYPE_INST(FMSUB_S);203R4_TYPE_INST(FNMADD_S);204R4_TYPE_INST(FNMSUB_S);205R_TYPE_INST(FADD_S);206R_TYPE_INST(FSUB_S);207R_TYPE_INST(FMUL_S);208R_TYPE_INST(FDIV_S);209I_TYPE_INST(FSQRT_S);210R_TYPE_INST(FSGNJ_S);211R_TYPE_INST(FSGNJN_S);212R_TYPE_INST(FSGNJX_S);213R_TYPE_INST(FMIN_S);214R_TYPE_INST(FMAX_S);215I_TYPE_INST(FCVT_W_S);216I_TYPE_INST(FCVT_WU_S);217I_TYPE_INST(FMV_X_W);218R_TYPE_INST(FEQ_S);219R_TYPE_INST(FLT_S);220R_TYPE_INST(FLE_S);221I_TYPE_INST(FCLASS_S);222I_TYPE_INST(FCVT_S_W);223I_TYPE_INST(FCVT_S_WU);224I_TYPE_INST(FMV_W_X);225 226// RV64F inst (The standard single-precision floating-point extension)227I_TYPE_INST(FCVT_L_S);228I_TYPE_INST(FCVT_LU_S);229I_TYPE_INST(FCVT_S_L);230I_TYPE_INST(FCVT_S_LU);231 232// RV32D inst (Extension for Double-Precision Floating-Point)233I_TYPE_INST(FLD);234S_TYPE_INST(FSD);235R4_TYPE_INST(FMADD_D);236R4_TYPE_INST(FMSUB_D);237R4_TYPE_INST(FNMSUB_D);238R4_TYPE_INST(FNMADD_D);239R_TYPE_INST(FADD_D);240R_TYPE_INST(FSUB_D);241R_TYPE_INST(FMUL_D);242R_TYPE_INST(FDIV_D);243I_TYPE_INST(FSQRT_D);244R_TYPE_INST(FSGNJ_D);245R_TYPE_INST(FSGNJN_D);246R_TYPE_INST(FSGNJX_D);247R_TYPE_INST(FMIN_D);248R_TYPE_INST(FMAX_D);249I_TYPE_INST(FCVT_S_D);250I_TYPE_INST(FCVT_D_S);251R_TYPE_INST(FEQ_D);252R_TYPE_INST(FLT_D);253R_TYPE_INST(FLE_D);254I_TYPE_INST(FCLASS_D);255I_TYPE_INST(FCVT_W_D);256I_TYPE_INST(FCVT_WU_D);257I_TYPE_INST(FCVT_D_W);258I_TYPE_INST(FCVT_D_WU);259 260// RV64D inst (Extension for Double-Precision Floating-Point)261I_TYPE_INST(FCVT_L_D);262I_TYPE_INST(FCVT_LU_D);263I_TYPE_INST(FMV_X_D);264I_TYPE_INST(FCVT_D_L);265I_TYPE_INST(FCVT_D_LU);266I_TYPE_INST(FMV_D_X);267 268/// Invalid and reserved instructions, the `inst` fields are used for debugging.269INVALID_INST(INVALID);270INVALID_INST(RESERVED);271INVALID_INST(EBREAK);272INVALID_INST(HINT);273INVALID_INST(NOP);274 275using 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 293constexpr uint8_t RV32 = 1;294constexpr uint8_t RV64 = 2;295constexpr uint8_t RV128 = 4;296 297struct 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 308struct DecodeResult {309  RISCVInst decoded;310  uint32_t inst;311  bool is_rvc;312  InstrPattern pattern;313};314 315constexpr uint32_t DecodeRD(uint32_t inst) { return (inst & 0xF80) >> 7; }316constexpr uint32_t DecodeRS1(uint32_t inst) { return (inst & 0xF8000) >> 15; }317constexpr uint32_t DecodeRS2(uint32_t inst) { return (inst & 0x1F00000) >> 20; }318constexpr uint32_t DecodeRS3(uint32_t inst) {319  return (inst & 0xF0000000) >> 27;320}321constexpr uint32_t DecodeFunct3(uint32_t inst) { return (inst & 0x7000) >> 12; }322constexpr uint32_t DecodeFunct2(uint32_t inst) {323  return (inst & 0xE000000) >> 25;324}325constexpr uint32_t DecodeFunct7(uint32_t inst) {326  return (inst & 0xFE000000) >> 25;327}328 329constexpr 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.332constexpr uint64_t NanBoxing(uint64_t val) {333  return val | 0xFFFF'FFFF'0000'0000;334}335constexpr uint32_t NanUnBoxing(uint64_t val) {336  return val & (~0xFFFF'FFFF'0000'0000);337}338 339#undef R_TYPE_INST340#undef R_SHAMT_TYPE_INST341#undef R_RS1_TYPE_INST342#undef R4_TYPE_INST343#undef I_TYPE_INST344#undef S_TYPE_INST345#undef B_TYPE_INST346#undef U_TYPE_INST347#undef J_TYPE_INST348#undef INVALID_INST349#undef DERIVE_EQ350 351} // namespace lldb_private352#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_RISCVINSTRUCTION_H353