Files
Odin/core/rexcode/riscv/tables.odin
Flāvius a4f08f8307 Load rexcode encode/decode tables from committed binary blobs
Each ISA's hand-written ENCODING_TABLE (the single source of truth) now lives
in a per-arch tablegen/ metaprogram that flattens it and serializes committed
binary blobs; the library #loads those into @(rodata) at compile time rather
than compiling a table body. No arch keeps encoding_table.odin or
decoding_tables.odin -- only a generated tables.odin loader and tables/*.bin.

* Two-stage, type-checked pipeline: tablegen Stage A emits human-readable
  generated Odin, which compiles and serializes the blobs in Stage B.
* encode() goes through encoding_forms(m); decoders are unchanged apart from
  x86's flattened 2-D index. Decode tables are byte-identical to the old ones.
* build.lua: a LuaJIT driver for the metaprograms, validations, and tests,
  with cross-platform gating and a clear report.
* Docs refreshed; the obsolete forward-looking plan in cross_arch_design.md
  trimmed to what was actually built.
* Attribution headers added to all rexcode source files; the generators emit
  them so generated files keep them.
2026-06-15 07:43:29 -04:00

65 lines
2.6 KiB
Odin

// rexcode · Brendan Punsky (dotbmp@github), original author
package rexcode_riscv
// =============================================================================
// GENERATED FILE - DO NOT EDIT
// =============================================================================
//
// Loads the flat binary encode/decode tables into @(rodata). 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,
count: u32,
}
Decode_Entry :: struct #packed {
mnemonic: Mnemonic, // 2
ops: [4]Operand_Type, // 4
enc: [4]Operand_Encoding, // 4
bits: u32, // 4
mask: u32, // 4
feature: Feature, // 1
flags: Encoding_Flags, // 1
}
#assert(size_of(Decode_Entry) == 20)
Decode_Index :: struct #packed {
start: u16,
count: u16,
}
#assert(size_of(Decode_Index) == 4)
// -----------------------------------------------------------------------------
// Loaded tables (rodata, embedded from tables/*.bin at compile time)
// -----------------------------------------------------------------------------
@(rodata) ENCODE_FORMS := #load("tables/riscv.encode_forms.bin", []Encoding)
@(rodata) ENCODE_RUNS := #load("tables/riscv.encode_runs.bin", []Encode_Run)
@(rodata) DECODE_ENTRIES := #load("tables/riscv.entries.bin", []Decode_Entry)
@(rodata) DECODE_INDEX_OPCODE := #load("tables/riscv.idx_opcode.bin", []Decode_Index)
@(rodata) DECODE_INDEX_OP_FP := #load("tables/riscv.idx_op_fp.bin", []Decode_Index)
@(rodata) DECODE_INDEX_RVC := #load("tables/riscv.idx_rvc.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]
}