rsemu 0.0.4

A multiplatform emulator in pure Rust, built bottom-up on a generic framework.
Documentation
# x86 / x86-64

Consumed by: `cpu/x86`. The largest and most treacherous ISA rsemu
targets — variable-length decode, segmentation, four operating modes,
self-modifying code, and decades of accumulated corner cases.

## Primary

| Source | Covers | Access |
| --- | --- | --- |
| Intel® 64 and IA-32 Architectures Software Developer's Manual (SDM) | Volumes 1–4: instruction set, system programming (paging, protection, mode switches), model-specific registers | intel.com → "Intel SDM" **[browser]** (blocks `curl`) |
| AMD64 Architecture Programmer's Manual | The AMD view of long mode; frequently clearer than Intel on the same subject, and the two occasionally disagree — where they do, note it | amd.com developer docs **[browser]** |
| [bitsavers.org]https://bitsavers.org/ | Original 8086/80186/80286/80386 manuals for the legacy modes | free |

Read both Intel and AMD for anything involving long mode. Disagreements between
them are usually where real CPUs differ too.

## Working references

| Source | Covers |
| --- | --- |
| [felixcloutier.com/x86]https://www.felixcloutier.com/x86/ | The SDM's instruction reference, rendered as browsable HTML. Same content, vastly faster to navigate |
| [sandpile.org]https://sandpile.org/ | Encoding tables, opcode maps, CPUID bit assignments, model-specific behaviour. Excellent for the encoder/decoder |
| [OSDev wiki]https://wiki.osdev.org/Expanded_Main_Page: [GDT]https://wiki.osdev.org/Global_Descriptor_Table, [Paging]https://wiki.osdev.org/Paging, [Interrupts]https://wiki.osdev.org/Interrupts | System-programming orientation with worked examples |
| ~~Bochs `PORTS.LST`~~ | **Withdrawn.** It is documentation inside a copyleft tree, which §1 covers; and a curated table is exactly where selection-and-arrangement copyright attaches, even though an individual port number is a free fact. Use the IBM AT Technical Reference and the chipset datasheets — they answer the same questions |

## Implementation notes

- **Decode is the hard part**, not execution: prefixes (including the REX/VEX/EVEX
  families), ModRM/SIB, and instruction-length limits. Build the decoder from
  the SDM opcode maps and sandpile's tables, and generate it from a declarative
  description rather than hand-writing it twice.
- **Self-modifying code is mandatory**, not optional — real DOS and Windows
  software relies on it. This is why the JIT needs page-level dirty tracking
  (`ROADMAP.md` §9).
- **x86 is TSO.** On a weakly-ordered host (AArch64, wasm), the frontend lifter
  must insert barriers; see [`../techniques/memory-models.md`]../techniques/memory-models.md.
- Segmentation is not vestigial in the modes we must support. Real mode,
  protected mode with a full descriptor cache, `v8086`, compatibility mode and
  long mode all have to coexist.

## What `cpu/x86` implements today

One interpreter, five parts, chosen by a `Variant` construction property:
8086, 8088, 80386, 80486 and a generic x86-64. Real mode on all five;
protected mode, paging, privilege levels, gates, task switching and the
exception model on the 32-bit ones; `CPUID` and the other 486 additions on the
486; long mode, `REX`, the sixteen 64-bit registers and four-level paging on
the last. Gated against `SingleStepTests/8088` twice — as the 8088 it was
captured from, and as a 386, where every disagreement is traced to a
documented difference between the parts.

**A second processor can be started by the first.** `INIT` — a pin, or a
message from this core's own local interrupt controller through
`core::wire::LocalController` — is a *lesser* restart than `RESET`: it leaves
the processor in the wait-for-SIPI state rather than fetching from the reset
vector, and nothing but a Start-Up moves it from there, not an `INTR` and not an
`NMI`. A Start-Up names a page and the processor begins at
`CS:IP = page << 8 : 0`. That is the MultiProcessor Specification's universal
startup algorithm (§B.4), and `tests/pc_apic_smp.rs` drives it with a *guest*
executing the three interrupt-command-register writes.

**The model-specific registers** are a short list, and an address that is not on
it raises `#GP(0)` rather than reading as zero: `IA32_EFER`, the four `SYSCALL`
registers, the three segment-base registers, the time-stamp counter that
`RDTSC` also reads, and `IA32_APIC_BASE` — the one whose state is not in the
processor at all, and which reaches the local controller through the same peer
link the INIT does. Its base-address *field* is reported and not obeyed:
relocating the register window is an address-space retopology, and a machine
file's `map` places the page.

**Floating point is software throughout.** The x87 unit (the eight-register
rotating stack, the tag word, precision and rounding control, the condition
codes, the six exception masks and the deferred `#MF`) and SSE/SSE2 (sixteen
`XMM` registers, `MXCSR`, the scalar and packed arithmetic, `FXSAVE`) both go
through [`src/float`](../../src/float), which has no host `f32` or `f64` in it
at all. That is what `ROADMAP.md` §9.1 asks for and the reason two hosts agree
bit for bit. Which of them an instance *has* is `Features`, not `Variant`: a
486SX is a 486 with `fpu` clear, and `CPUID` follows the features.

Known gaps, each deliberate and none silent: no MMX (its registers alias the
x87 stack); no x87 transcendentals — `F2XM1`, `FYL2X`, `FYL2XP1`, `FPTAN`,
`FPATAN`, `FSIN`, `FCOS`, `FSINCOS` are unassigned and raise `#UD`, because an
approximation would be a silently wrong answer where a missing instruction is
a loud one; no `FBLD`/`FBSTP` and no `FISTTP`; no SSE3 or later, no AVX, no
`XSAVE`; no `FERR#` pin, so an unmasked x87 exception is delivered as `#MF`
only with `CR0.NE` set; no virtual-8086 mode; no debug breakpoints (the
registers round-trip and nothing fires); no alignment check; `LOCK` decoded and
ignored; the accessed bit set on `MOV Sreg` and far transfers but not on the
segment loads a gate or a task switch performs; no 286-format task state
segment (`#TS` rather than a truncated switch); and no A20 gate — that one is
chipset, not CPU.

## ⚠ Do not consult

Bochs (LGPL), DOSBox (GPL), and QEMU (GPLv2) are the three sources people reach
for when x86 gets difficult. All three are forbidden. The SDM answers the
question — it is just longer.