# MC64 — Summary A 64-bit generalization of the Turbo Modula-2 MCode virtual machine (see `mc64-spec.md`). ## Core model - **Word = 64 bits**; flat, byte-addressable, little-endian address space. - Stack machine, single stack shared by values and frames; **grows down** (`Push` = `SP -= 8`). - State: `IP`, `SP`, `FP` (frame), `GP` (current module data window), `OFP` (static link), `MTBL` (256 module pointers). ## Data types | Type | Width | Stack slots | |---|---|---| | BYTE/CHAR/BOOLEAN | 8 bits (in a slot) | 1 | | CARDINAL | 32 bits (zero-extended) | 1 | | INTEGER | 32 bits (sign-extended) | 1 | | SET | 64 bits | 1 | | LONGINT / LONGCARD | 64 bits | 1 | | REAL | 64-bit binary64 | 1 | | LONGREAL | 128-bit | 2 (quad) | | pointer | 64 bits | 1 | Slots are always 64 bits; 32-bit values live in the low 32 bits, so 32↔64-bit widening is a value no-op. ## Frames & calls - Locals at `FP[-1], FP[-2], …`; param *k* at `FP[k+2]`; args pushed in reverse order. - `ENTER k` reserves `(255−k)×8` bytes of locals (k=0FFH → none). - `PROC_LEAVE n`: drops `n & 0x7F` words; bit 7 re-enters the outer module (reloads `GP` from `OFP`). ## Addressing Local (FP) / Global (GP) / Extern (`MTBL[mod]`) / Indirect (popped ptr) / Indexed (ptr + index). Word offsets = bytes × 8. ## Opcode map All **256 opcodes preserved 1:1**, positions from MCode/16: - `00–1F` params, legacy dword (slot) loads/stores, indexed byte/slot/quad - `20–3F` dup/swap, local/global/extern load+store, memcpy/string copy - `40` extended sub-dispatch (ALLOCATE/MARK/MOVE/FILL/BIOS…, LONGCARD `uc_*` arithmetic, `long_negate`), `41/51` slot0 aliases, global 2–15 - `60–7F` indirect load/store offsets 0–15 - `80–9F` addresses, leaves, strings, immediates (byte / 8-byte / 16-byte) - `A0–BF` comparisons & arithmetic on the **32-bit** CARDINAL/INTEGER types, LONGINT↔CARDINAL/INTEGER/REAL conversions, shifts - `12H` sub-opcode: the only **128-bit LONGREAL** (quad) load/store/compare/arith family - `C0–DF` checked 32-bit arithmetic, SYSTEM host calls, **64-bit LONGINT** (`long_*`) compare/arith, switch, reserve, range checks, short-circuit `and_jp`/`or_jp` - `E0–FF` jumps, bitset ops (64-bit SET), procedure calls (`call 1..15`, extern, nested) The old MCode/16 "dword/long" (32-bit LONGINT/REAL) groups become the 64-bit LONGINT family; 64-bit unsigned (LONGCARD) `uc_*` primitives move to the `40H` extended dispatch. ## Complex instructions - **Switch (0CDH)**: low/high u64 bounds + i64 jump table; offset relative to its cell end; negative offset = call-switch (pushes return = end of table). - **String compare (0C4H)**: pushes `(s1>s2)` then `(s1