variant.h (1944B)
1 /* RISC-V XLEN variant descriptor — an immutable per-XLEN table threaded 2 * through the otherwise stateless decode / asm / disasm / link / dbg / native 3 * paths so a single RISC-V backend serves both rv32 and rv64. It is always 4 * reached through a context (RvNativeTarget.variant, or 5 * riscv_variant_for_kind(c->target.arch) in the stateless paths), never as 6 * ambient global state. 7 * 8 * Three distinct widths are deliberately split out so rv32 cannot be derived 9 * by conflating them (all three are 8 on rv64, which is why the rv64-only code 10 * could get away with a single literal): 11 * - ptr_bytes pointer / native GPR width (4 / 8) 12 * - gp_slot_bytes ABI vararg-save & callee-save slot stride (4 / 8) 13 * - frame_save_size saved ra+s0 pair size = 2 * ptr_bytes (8 / 16) 14 */ 15 #ifndef KIT_ARCH_RISCV_VARIANT_H 16 #define KIT_ARCH_RISCV_VARIANT_H 17 18 #include "core/core.h" /* u8 / u32, KitArchKind */ 19 20 typedef struct RiscvVariant { 21 KitArchKind kind; /* KIT_ARCH_RV32 / KIT_ARCH_RV64 */ 22 const char* name; /* "rv32" / "rv64" */ 23 const char* isa_prefix; /* "rv32" / "rv64" — for -march parsing */ 24 u8 xlen; /* 32 / 64 */ 25 u8 ptr_bytes; /* 4 / 8 — pointer & native register width */ 26 u8 gp_slot_bytes; /* 4 / 8 — vararg-save & callee-save slot stride */ 27 u8 has_w_forms; /* 0 rv32 / 1 rv64 — ADDW/ADDIW/SLLIW/... */ 28 u8 shamt_bits; /* 5 rv32 / 6 rv64 — SLLI/SRLI/SRAI immediate */ 29 u32 frame_save_size; /* 2 * ptr_bytes (8 rv32 / 16 rv64) */ 30 } RiscvVariant; 31 32 extern const RiscvVariant riscv_variant_rv32; 33 extern const RiscvVariant riscv_variant_rv64; 34 35 /* Returns the variant for KIT_ARCH_RV32 / KIT_ARCH_RV64. Any other arch maps 36 * to the rv64 variant (the historical default), so shared code that only ever 37 * sees a RISC-V kind never dereferences NULL. */ 38 const RiscvVariant* riscv_variant_for_kind(KitArchKind kind); 39 40 #endif