mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-19 16:42:33 +00:00
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.
90 lines
3.5 KiB
Odin
90 lines
3.5 KiB
Odin
// rexcode · Brendan Punsky (dotbmp@github), original author
|
|
|
|
package rexcode_ppc_vle
|
|
|
|
// =============================================================================
|
|
// PowerPC VLE Relocations
|
|
// =============================================================================
|
|
//
|
|
// VLE-specific branch and immediate relocation forms.
|
|
//
|
|
// Branch displacements (from binutils):
|
|
// BD8 (16-bit): 8-bit signed << 1, PC-rel, ±256 bytes (se_b, se_bl)
|
|
// BD8IO (16-bit): same width, with BO/BI baked
|
|
// BD15 (32-bit): 15-bit signed << 1, PC-rel, ±32KB (e_bc, e_bcl)
|
|
// EBD15/EBD15BI (32-bit): same width, with BO/BI baked
|
|
// BD24 (32-bit): 24-bit signed << 1, PC-rel, ±16MB (e_b, e_bl)
|
|
//
|
|
// ELF relocation types (binutils elf/ppc.h R_PPC_VLE_*):
|
|
// REL8/REL15/REL24 PC-relative branches (matches BD8/BD15/BD24)
|
|
// LO16A/HI16A/HA16A 16-bit immediate halves, A-form (I16A imm position)
|
|
// LO16D/HI16D/HA16D 16-bit immediate halves, D-form (32-bit D-form)
|
|
// SDA21 21-bit small data area (e_add16i_sda variant)
|
|
// SDAREL_*16{A,D} SDA-relative variants of LO/HI/HA
|
|
// ADDR20 20-bit absolute address (LI20 form)
|
|
|
|
Relocation_Type :: enum u8 {
|
|
NONE = 0,
|
|
|
|
// Internal (encoder-resolved) branch relocations
|
|
BRANCH_BD8, // 8-bit signed << 1 at bits 7..0 of halfword
|
|
BRANCH_BD15, // 15-bit signed << 1 at bits 1..15 of low halfword
|
|
BRANCH_BD24, // 24-bit signed << 1 at bits 1..24 of word
|
|
|
|
// ELF-spec relocations (linker-bound — encoder emits them but doesn't
|
|
// resolve them locally)
|
|
R_PPC_VLE_REL8, // 216 — like BRANCH_BD8 but ELF-emitted
|
|
R_PPC_VLE_REL15, // 217
|
|
R_PPC_VLE_REL24, // 218
|
|
R_PPC_VLE_LO16A, // 219 — low 16 bits, A-form imm (I16A bit positions)
|
|
R_PPC_VLE_LO16D, // 220 — low 16 bits, D-form imm
|
|
R_PPC_VLE_HI16A, // 221 — high 16 bits, A-form
|
|
R_PPC_VLE_HI16D, // 222 — high 16 bits, D-form
|
|
R_PPC_VLE_HA16A, // 223 — high-adjusted 16 bits, A-form
|
|
R_PPC_VLE_HA16D, // 224 — high-adjusted 16 bits, D-form
|
|
R_PPC_VLE_SDA21, // 225 — 21-bit small-data-area
|
|
R_PPC_VLE_SDA21_LO, // 226 — like SDA21 but no overflow check
|
|
R_PPC_VLE_SDAREL_LO16A, // 227
|
|
R_PPC_VLE_SDAREL_LO16D, // 228
|
|
R_PPC_VLE_SDAREL_HI16A, // 229
|
|
R_PPC_VLE_SDAREL_HI16D, // 230
|
|
R_PPC_VLE_SDAREL_HA16A, // 231
|
|
R_PPC_VLE_SDAREL_HA16D, // 232
|
|
R_PPC_VLE_ADDR20, // 233 — 20-bit absolute (LI20)
|
|
}
|
|
|
|
// Mapping table — each VLE reloc's official ELF number.
|
|
elf_reloc_number :: proc(t: Relocation_Type) -> u32 {
|
|
#partial switch t {
|
|
case .R_PPC_VLE_REL8: return 216
|
|
case .R_PPC_VLE_REL15: return 217
|
|
case .R_PPC_VLE_REL24: return 218
|
|
case .R_PPC_VLE_LO16A: return 219
|
|
case .R_PPC_VLE_LO16D: return 220
|
|
case .R_PPC_VLE_HI16A: return 221
|
|
case .R_PPC_VLE_HI16D: return 222
|
|
case .R_PPC_VLE_HA16A: return 223
|
|
case .R_PPC_VLE_HA16D: return 224
|
|
case .R_PPC_VLE_SDA21: return 225
|
|
case .R_PPC_VLE_SDA21_LO: return 226
|
|
case .R_PPC_VLE_SDAREL_LO16A: return 227
|
|
case .R_PPC_VLE_SDAREL_LO16D: return 228
|
|
case .R_PPC_VLE_SDAREL_HI16A: return 229
|
|
case .R_PPC_VLE_SDAREL_HI16D: return 230
|
|
case .R_PPC_VLE_SDAREL_HA16A: return 231
|
|
case .R_PPC_VLE_SDAREL_HA16D: return 232
|
|
case .R_PPC_VLE_ADDR20: return 233
|
|
}
|
|
return 0
|
|
}
|
|
|
|
Relocation :: struct #packed {
|
|
offset: u32,
|
|
label_id: u32,
|
|
addend: i32,
|
|
type: Relocation_Type,
|
|
size: u8,
|
|
inst_idx: u16,
|
|
}
|
|
#assert(size_of(Relocation) == 16)
|