Files
xenia-rs/migration/project-root/ppc-manual/control/mtfsfix.md
MechaCat02 e6d43a23ac chore: add migration/ bundle for cross-machine setup
Bundles state that lives OUTSIDE the xenia-rs repo so a fresh clone on
another machine can be brought up to identical configuration via
migration/setup.sh:

  - claude-memory/             ~/.claude/projects/-home-fabi-RE-Project-Sylpheed/memory/
                               (103 files, 1.1 MB - MEMORY.md + every
                                project_xenia_rs_*.md from audits
                                addis_signext through audit-058)
  - project-root/dot-claude/   <project-root>/.claude/settings.json
                               (Stop hook + permissions)
  - project-root/ppc-manual/   <project-root>/ppc-manual/
                               (PowerPC reference docs, 397 files, 3.7 MB)
  - project-root/run-canary.sh <project-root>/run-canary.sh
  - README.md                  Human-readable setup checklist
  - setup.sh                   Idempotent installer (also reclones
                               xenia-canary at pinned HEAD 6de80dffe)
  - MANIFEST.md                Per-file mapping + per-file-not-bundled
                               restoration recipe

Excluded from bundle (not shippable via git):
  - Sylpheed ISO (7.8 GB; copyright; manual copy required)
  - sylpheed.db (395 MB; regenerable from XEX via analysis tooling)
  - target/ build artifacts (rebuild on target)
  - audit-runs probe firehoses (.log/.stdout/.stderr ~11 GB; rerun if needed)
  - audit-runs memory dumps (.bin ~4.5 GB; rerun audit-026/027/029 if needed)
  - xenia-canary checkout (setup.sh reclones from
    git.mc02.dev/fabi/Xenia-Canary.git at HEAD 6de80dffe)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 21:38:38 +02:00

136 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# `mtfsfix` — Move to FPSCR Field Immediate
> **Category:** [Control / CR / SPR](../categories/control.md) · **Form:** [X](../forms/X.md) · **Opcode:** `0xfc00010c`
<!-- GENERATED: BEGIN -->
## Assembler Mnemonics
| Mnemonic | XML entry | Flags | Description |
| --- | --- | --- | --- |
| `mtfsfi` | `mtfsfix` | — | Move to FPSCR Field Immediate |
| `mtfsfi.` | `mtfsfix` | Rc=1 | Move to FPSCR Field Immediate |
## Syntax
```asm
mtfsfi[Rc] [CRFD], [IMM]
```
## Encoding
### `mtfsfix` — form `X`
- **Opcode word:** `0xfc00010c`
- **Primary opcode (bits 05):** `63`
- **Extended opcode:** `134`
- **Synchronising:** no
| Bits | Field | Meaning |
| --- | --- | --- |
| 05 | `OPCD` | primary opcode |
| 610 | `RT/FRT/VRT` | destination |
| 1115 | `RA/FRA/VRA` | source A |
| 1620 | `RB/FRB/VRB` | source B |
| 2130 | `XO` | extended opcode (10 bits) |
| 31 | `Rc` | record-form flag |
## Operands
| Field | Role | Description |
| --- | --- | --- |
| `IMM` | mtfsfix: read | Generic immediate field. |
| `CRFD` | mtfsfix: write | CR destination field (`crf`, 07). |
| `CR` | mtfsfix: write (conditional) | Condition-register update. When `Rc=1`, CR field 0 (or CR6 for vector compares, CR1 for FPU) is updated from the result. |
## Register Effects
### `mtfsfix`
- **Reads (always):** `IMM`
- **Reads (conditional):** _none_
- **Writes (always):** `CRFD`
- **Writes (conditional):** `CR`
## Status-Register Effects
- `mtfsfix`: **CR0** ← signed-compare(result, 0) with `SO ← XER[SO]`, when `Rc=1`.
## Operation (pseudocode)
```
; Pseudocode derives directly from the xenia-rs interpreter
; arm (see Implementation References). Operation semantics:
; - Read source operands from the fields listed under Operands.
; - Apply the arithmetic / logical / memory action described
; in the Description field above.
; - Write results to the destination register(s); update any
; status bits enumerated under Status-Register Effects.
; Consult the IBM AIX reference link under IBM Reference for
; canonical PPC-style pseudocode where xenia's expression is
; terse.
```
## C Translation Example
```c
/* C translation: the xenia-rs interpreter arm below in */
/* Implementation References is the authoritative semantic */
/* snapshot. Translate it line-by-line: */
/* - ctx.gpr[N] -> r[N] (or f[]/v[] for FPRs/VRs) */
/* - mem.read_u*/write_u* -> mem_read_u*_be / mem_write_u*_be */
/* - ctx.update_cr_signed(fld, v) -> update_cr_signed(fld, v) */
/* - ctx.xer_ca / xer_ov / xer_so -> xer.CA / xer.OV / xer.SO */
/* The Register Effects and Status-Register Effects tables above */
/* enumerate every side effect a faithful translation must emit. */
```
## Implementation References
**`mtfsfix`**
- xenia-canary XML: [`tools/ppc-instructions.xml` — search for `mnem="mtfsfix"`](../../xenia-canary/tools/ppc-instructions.xml)
- xenia-canary emit: [`src/xenia/cpu/ppc/ppc_emit_fpu.cc:452`](../../xenia-canary/src/xenia/cpu/ppc/ppc_emit_fpu.cc#L452)
- xenia-rs opcode: [`crates/xenia-cpu/src/opcode.rs:55`](../../xenia-rs/crates/xenia-cpu/src/opcode.rs#L55)
- xenia-rs decoder: [`crates/xenia-cpu/src/decoder.rs:907`](../../xenia-rs/crates/xenia-cpu/src/decoder.rs#L907)
- xenia-rs interpreter: [`crates/xenia-cpu/src/interpreter.rs:3069-3077`](../../xenia-rs/crates/xenia-cpu/src/interpreter.rs#L3069-L3077)
<details><summary>xenia-rs interpreter body (frozen snapshot)</summary>
```rust
PpcOpcode::mtfsfix => {
// Move to FPSCR field immediate: crfD = IMM (4 bits)
let crfd = instr.crfd();
let imm = (instr.raw >> 12) & 0xF;
let shift = 28 - crfd as u32 * 4;
ctx.fpscr = (ctx.fpscr & !(0xF << shift)) | (imm << shift);
if instr.rc_bit() { update_cr1_from_fpscr(ctx); }
ctx.pc += 4;
}
```
</details>
<!-- GENERATED: END -->
## Special Cases & Edge Conditions
- **Operation.** Loads a **4-bit immediate** (`IMM`, encoded in instruction bits 16..19) into a single FPSCR field selected by `CRFD` (3-bit, 0..7). All other FPSCR fields are preserved.
- **Most common use: rounding-mode set.** `mtfsfi 7, 0` selects round-to-nearest, `mtfsfi 7, 1` round-toward-zero, `mtfsfi 7, 2` round-toward-+∞, `mtfsfi 7, 3` round-toward-−∞. The four immediate values map to RN per IEEE-754. Compilers emit this when transitioning into and out of strict-IEEE regions.
- **No FPR source.** Unlike [`mtfsfx`](mtfsfx.md), `mtfsfi` doesn't need an FPR — it carries its 4-bit value in the instruction word, making it cheaper for constant updates.
- **`Rc=1`.** `mtfsfi.` copies FPSCR's top 4 bits (FX, FEX, VX, OX) into CR1 after the write.
- **Restrictions in newer PowerISA.** v2.05+ disallows writing FEX/VX (summary bits) via `mtfsfi`. xenia-rs does **not** enforce this — the immediate goes straight into the chosen field.
- **xenia simplification.** xenia stores FPSCR as a `u32` and applies the field-shift correctly. Same caveat as `mtfsf`: most xenia FP paths don't honour FPSCR, so the rounding-mode change is architecturally visible (via [`mffsx`](mffsx.md)) but typically does not change subsequent FP results.
- **Not synchronising.** PowerISA recommends `isync` after rounding-mode changes if subsequent FP correctness depends on the new mode.
## Related Instructions
- [`mtfsfx`](mtfsfx.md) — write FPSCR fields from an FPR (uses 8-bit field-mask).
- [`mtfsb0x`](mtfsb0x.md), [`mtfsb1x`](mtfsb1x.md) — clear / set a single FPSCR bit.
- [`mffsx`](mffsx.md) — read FPSCR.
- [`mcrfs`](mcrfs.md) — FPSCR field → CR field (also clears sticky bits).
`mtfsfi` is the simplified form (`Rc=0`); `mtfsfi.` is the recording variant.
## IBM Reference
- [AIX 7.3 — `mtfsfi` (Move to FPSCR Field Immediate)](https://www.ibm.com/docs/en/aix/7.3.0?topic=set-mtfsfi-move-fpscr-field-immediate-instruction)
- PowerISA v2.07B, Book I §4.6.6 — FPSCR-field write semantics and the FEX/VX restriction.