mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-20 00:52:33 +00:00
rexcode: buffer-sizing helpers across all ISAs + naming-contract doc
Roll the encode/decode buffer-sizing helpers (added for x86 in 49787b7de) out
to every other ISA, and document them in the cross-arch naming contract.
Per arch (arm32, arm64, mips, riscv, ppc, ppc_vle, rsp, mos6502, mos65816):
- encode_max_code_size / encode_max_relocation_count now key off the
[]Instruction slice (were int counts); bodies unchanged (* MAX_INST_SIZE).
- encode_reserve(code, relocs, instructions): grows the caller's code []u8 by
length and reserves relocs by capacity; allocates no new buffers.
- decode_max_instruction_count / decode_estimate_instruction_count: exact
ceiling and typical estimate, keyed off the min/avg instruction size per
arch (fixed-4: arm64/mips/ppc/rsp; min-2: arm32/riscv/ppc_vle; min-1: mos).
- decode_reserve(instructions, inst_info, label_defs, data, exact=false).
docs/cross_arch_design.md: helpers added to the naming contract.
No behavior change to the existing size helpers (signature only). All 10 ISAs
check + test green (x86 2282, arm32 600, arm64 461, mips 281, riscv 154, ppc 31,
ppc_vle 281, rsp 70, mos6502 148, mos65816 53).
This commit is contained in:
@@ -178,6 +178,32 @@ print/println/aprint/tprint/bprint/fprint/wprint(+ln)(
|
||||
label_defs: []Label_Definition, tokens=nil, options=nil, label_names=nil)
|
||||
```
|
||||
|
||||
**Buffer-sizing helpers (identical names across arches).** `encode`/`decode`
|
||||
allocate nothing — the caller owns every buffer. These let the caller pre-size
|
||||
them so the hot path never reallocates, either as a plain size (caller manages
|
||||
its own memory) or by growing the caller's own dynamic arrays directly. They
|
||||
never allocate a fresh buffer; they only grow the caller's arrays, and Odin's
|
||||
`reserve` no-ops when capacity already suffices.
|
||||
|
||||
```odin
|
||||
// size-only (caller does the resize/reserve)
|
||||
encode_max_code_size(instructions: []Instruction) -> int // exact code bytes
|
||||
encode_max_relocation_count(instructions: []Instruction) -> int // exact reloc ceiling
|
||||
decode_max_instruction_count(data: []u8) -> int // exact instr ceiling
|
||||
decode_estimate_instruction_count(data: []u8) -> int // typical estimate
|
||||
|
||||
// pre-size the caller's dynamic arrays (nil to skip any; reserves on top of existing)
|
||||
encode_reserve(code: ^[dynamic]u8, relocs: ^[dynamic]Relocation, instructions: []Instruction)
|
||||
decode_reserve(instructions: ^[dynamic]Instruction, inst_info: ^[dynamic]Instruction_Info,
|
||||
label_defs: ^[dynamic]Label_Definition, data: []u8, exact := false)
|
||||
```
|
||||
|
||||
> `encode_reserve` grows `code` by *length* (so `code[:]` is a valid emit
|
||||
> target) and reserves `relocs` by *capacity*. The decode `*_count` pair differs
|
||||
> per arch by the min/typical instruction size; `decode_reserve(exact=true)`
|
||||
> uses the guaranteed ceiling, otherwise the lighter estimate. Error arrays grow
|
||||
> only on the failure path and are intentionally not covered.
|
||||
|
||||
**Register/label/print helpers:** `reg_hw reg_class reg_size register_name
|
||||
mnemonic_to_string label label_forward label_named label_reserve
|
||||
label_set`.
|
||||
|
||||
Reference in New Issue
Block a user