The MIPS decode tables are universal — every variant (MIPS I..64/R6, the PS1
GTE, PS2 MMI/VU, PSP VFPU) shares one table. Some primary opcodes collide
across variants: most visibly 0x37 is `LD` on 64-bit MIPS but `vfim.s` on the
PSP Allegrex VFPU. The decoder took the first table match, so `LD $ra, 0($sp)`
(0xdfbf0000) mis-decoded as `vfim.s $31, 0`.
Each Decode_Entry already carries a `feature`; the decoder just ignored it.
`decode` now takes a `features: Feature_Set` (a bit_set over `Feature`),
defaulting to `FEATURES_ALL` so existing callers are unchanged, and skips an
entry whose feature isn't enabled — the first ENABLED match wins, preserving
the most-specific-mask-first order. Added `FEATURES_MIPS_III` (MIPS I/II/III +
COP0 + FPU — the VR4300 / classic 64-bit baseline) for N64/MIPS-III consumers.
decode_smoke: opcode 0x37 decodes as LD under FEATURES_MIPS_III and (still)
as the PSP VFPU entry under FEATURES_ALL. 65 decoder checks pass.
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).
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.