Files
Odin/core/rexcode/isa/x86/tables.odin
Brendan Punsky 95df04fbe1 rexcode: re-house ISA packages under core:rexcode/isa/<arch>
Move all ten ISA packages (x86, arm32, arm64, mips, riscv, ppc, ppc_vle,
rsp, mos6502, mos65816) from core/rexcode/<arch> to core/rexcode/isa/<arch>,
so the import pattern is now `import "core:rexcode/isa/x86"`. The shared
core stays at core:rexcode/isa.

Mechanical: relative `import "../isa"` / "../../isa" -> absolute
"core:rexcode/isa" (the only path that survives the move; the "../" and
"../.." self/generated imports move with their packages). build.lua now
builds paths as <root>/isa/<name>; stale `cd <arch>` hints in the verify
tools and the doc.odin paths updated.

WASM stays at core/rexcode/wasm for now -- it is an IR, not an ISA, and
will move under the forthcoming core:rexcode/ir once that layer lands.

All 10 arches gen/builders/check/test green; import core:rexcode/isa/x86
verified working; wasm still compiles.
2026-06-18 19:03:27 -04:00

114 lines
4.5 KiB
Odin

// rexcode · Brendan Punsky (dotbmp@github), original author
package rexcode_x86
// =============================================================================
// GENERATED FILE - DO NOT EDIT
// =============================================================================
//
// Loads the flat binary encode/decode tables into @(rodata) and exposes the
// accessors the encoder/decoder drive. Produced by tablegen:
//
// odin run tablegen # Stage A: ENCODING_TABLE -> generated/ + this file
// odin run tablegen/generated # Stage B: typed Odin literals -> tables/*.bin
//
// The .bin blobs are raw, host-endian, packed struct images.
// -----------------------------------------------------------------------------
// Subsidiary table types (generated scaffolding)
// -----------------------------------------------------------------------------
// Companion run index: ENCODE_RUNS[mnemonic] -> contiguous run in ENCODE_FORMS.
Encode_Run :: struct {
start: u32, // start index in ENCODE_FORMS
count: u32, // number of forms for this mnemonic
}
// Precomputed extraction of mod, reg, rm fields from a ModR/M byte.
ModRM_Info :: struct #packed {
mod: u8,
reg: u8,
rm: u8,
has_sib: bool,
disp_size: u8,
}
// Precomputed extraction of scale, index, base fields from a SIB byte.
SIB_Info :: struct #packed {
scale: u8,
index: u8,
base: u8,
}
// Information needed to decode an instruction given its opcode bytes.
Decode_Entry :: struct {
esc: Escape,
prefix: u8,
opcode: u8,
ext: u8,
mnemonic: Mnemonic,
ops: [4]Operand_Type,
enc: [4]Operand_Encoding,
flags: Encoding_Flags,
}
VEX_Decode_Entry :: struct {
esc: Escape,
prefix: u8,
opcode: u8,
ext: u8,
vex_w: VEX_W,
vex_l: VEX_L,
mnemonic: Mnemonic,
ops: [4]Operand_Type,
enc: [4]Operand_Encoding,
flags: Encoding_Flags,
}
// (start, count) into a *_DECODE_ENTRIES array. Index tables are stored flat:
// a logical [4][256] is loaded as [1024]; address with `didx`.
Decode_Index :: struct {
start: u16,
count: u8,
}
// -----------------------------------------------------------------------------
// Loaded tables (rodata, embedded from tables/*.bin at compile time)
// -----------------------------------------------------------------------------
@(rodata) ENCODE_FORMS := #load("tables/x86.encode_forms.bin", []Encoding)
@(rodata) ENCODE_RUNS := #load("tables/x86.encode_runs.bin", []Encode_Run)
@(rodata) MODRM_TABLE := #load("tables/x86.modrm.bin", []ModRM_Info)
@(rodata) SIB_TABLE := #load("tables/x86.sib.bin", []SIB_Info)
@(rodata) LEGACY_DECODE_ENTRIES := #load("tables/x86.legacy.bin", []Decode_Entry)
@(rodata) VEX_DECODE_ENTRIES := #load("tables/x86.vex.bin", []VEX_Decode_Entry)
@(rodata) EVEX_DECODE_ENTRIES := #load("tables/x86.evex.bin", []VEX_Decode_Entry)
@(rodata) DECODE_INDEX_LEGACY := #load("tables/x86.idx_legacy.bin", []Decode_Index)
@(rodata) DECODE_INDEX_ESC_0F := #load("tables/x86.idx_0f.bin", []Decode_Index)
@(rodata) DECODE_INDEX_ESC_0F38 := #load("tables/x86.idx_0f38.bin", []Decode_Index)
@(rodata) DECODE_INDEX_ESC_0F3A := #load("tables/x86.idx_0f3a.bin", []Decode_Index)
@(rodata) VEX_INDEX_0F := #load("tables/x86.vex_idx_0f.bin", []Decode_Index)
@(rodata) VEX_INDEX_0F38 := #load("tables/x86.vex_idx_0f38.bin", []Decode_Index)
@(rodata) VEX_INDEX_0F3A := #load("tables/x86.vex_idx_0f3a.bin", []Decode_Index)
@(rodata) EVEX_INDEX_0F := #load("tables/x86.evex_idx_0f.bin", []Decode_Index)
@(rodata) EVEX_INDEX_0F38 := #load("tables/x86.evex_idx_0f38.bin", []Decode_Index)
@(rodata) EVEX_INDEX_0F3A := #load("tables/x86.evex_idx_0f3a.bin", []Decode_Index)
// -----------------------------------------------------------------------------
// Accessors
// -----------------------------------------------------------------------------
// Per-mnemonic encode forms: the run of ENCODE_FORMS belonging to `m`.
// Replaces the old ENCODING_TABLE[m] slice; the returned view is into rodata.
@(private, require_results)
encoding_forms :: #force_inline proc "contextless" (m: Mnemonic) -> []Encoding {
r := ENCODE_RUNS[u16(m)]
return ENCODE_FORMS[r.start:][:r.count]
}
// Flat [prefix][opcode] lookup into a logical [4][256] index table.
@(private, require_results)
didx :: #force_inline proc "contextless" (t: []Decode_Index, prefix, opcode: u8) -> Decode_Index {
return t[(int(prefix) << 8) | int(opcode)]
}