# `fcmpu` — Floating Compare Unordered > **Category:** [Floating-Point](../categories/fpu.md) · **Form:** [X](../forms/X.md) · **Opcode:** `0xfc000000` ## Assembler Mnemonics | Mnemonic | XML entry | Flags | Description | | --- | --- | --- | --- | | `fcmpu` | `fcmpu` | — | Floating Compare Unordered | ## Syntax ```asm fcmpu [CRFD], [FA], [FB] ``` ## Encoding ### `fcmpu` — form `X` - **Opcode word:** `0xfc000000` - **Primary opcode (bits 0–5):** `63` - **Extended opcode:** `0` - **Synchronising:** no | Bits | Field | Meaning | | --- | --- | --- | | 0–5 | `OPCD` | primary opcode | | 6–10 | `RT/FRT/VRT` | destination | | 11–15 | `RA/FRA/VRA` | source A | | 16–20 | `RB/FRB/VRB` | source B | | 21–30 | `XO` | extended opcode (10 bits) | | 31 | `Rc` | record-form flag | ## Operands | Field | Role | Description | | --- | --- | --- | | `FA` | fcmpu: read | Source A floating-point register (`fr0`–`fr31`). | | `FB` | fcmpu: read | Source B floating-point register. | | `CRFD` | fcmpu: write | CR destination field (`crf`, 0–7). | | `FPSCR` | fcmpu: write | Floating-Point Status and Control Register. | ## Register Effects ### `fcmpu` - **Reads (always):** `FA`, `FB` - **Reads (conditional):** _none_ - **Writes (always):** `CRFD`, `FPSCR` - **Writes (conditional):** _none_ ## Status-Register Effects - `fcmpu`: **FPSCR** updated per IEEE-754 flags (FX, FEX, FPRF, FR, FI, exceptions). ## 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 **`fcmpu`** - xenia-canary XML: [`tools/ppc-instructions.xml` — search for `mnem="fcmpu"`](../../xenia-canary/tools/ppc-instructions.xml) - xenia-canary emit: [`src/xenia/cpu/ppc/ppc_emit_fpu.cc:365`](../../xenia-canary/src/xenia/cpu/ppc/ppc_emit_fpu.cc#L365) - xenia-rs opcode: [`crates/xenia-cpu/src/opcode.rs:27`](../../xenia-rs/crates/xenia-cpu/src/opcode.rs#L27) - xenia-rs decoder: [`crates/xenia-cpu/src/decoder.rs:897`](../../xenia-rs/crates/xenia-cpu/src/decoder.rs#L897) - xenia-rs interpreter: [`crates/xenia-cpu/src/interpreter.rs:2972-3001`](../../xenia-rs/crates/xenia-cpu/src/interpreter.rs#L2972-L3001)
xenia-rs interpreter body (frozen snapshot) ```rust PpcOpcode::fcmpu => { let fra = ctx.fpr[instr.ra()]; let frb = ctx.fpr[instr.rb()]; let crfd = instr.crfd(); if fra.is_nan() || frb.is_nan() { ctx.cr[crfd] = crate::context::CrField { lt: false, gt: false, eq: false, so: true }; // fcmpu: VXSNAN on SNaN input; no VXVC even on QNaN. if fpscr::is_snan(fra) || fpscr::is_snan(frb) { fpscr::set_exception(ctx, fpscr::VXSNAN); } } else if fra < frb { ctx.cr[crfd] = crate::context::CrField { lt: true, gt: false, eq: false, so: false }; } else if fra > frb { ctx.cr[crfd] = crate::context::CrField { lt: false, gt: true, eq: false, so: false }; } else { ctx.cr[crfd] = crate::context::CrField { lt: false, gt: false, eq: true, so: false }; } // Also mirror the comparison result into FPSCR[FPRF (FL/FG/FE/FU)]. let fprf = if fra.is_nan() || frb.is_nan() { 0b0_0001 } else if fra < frb { 0b0_1000 } else if fra > frb { 0b0_0100 } else { 0b0_0010 }; fpscr::set_fprf(ctx, fprf); ctx.pc += 4; } ```
## Special Cases & Edge Conditions - **Unordered compare.** "Unordered" means NaN inputs do **not** signal an invalid-operation exception — they merely set the unordered (`SO`) bit in the destination CR field. Use [`fcmpox`](fcmpo.md) when NaN should raise `VXSNAN`/`VXVC`. - **CR field bits.** Writes the 4-bit CR field selected by `BF` (`crfd`): - `LT` (bit 0) — `FRA < FRB` - `GT` (bit 1) — `FRA > FRB` - `EQ` (bit 2) — `FRA == FRB` - `SO` (bit 3) — **unordered** (one or both operands is NaN) - **NaN handling.** Either operand NaN → set `SO=1`, clear `LT/GT/EQ`. xenia-rs matches. - **Signalling NaN.** Per PowerISA, `fcmpu` sets `FPSCR[VXSNAN]` if either operand is a signalling NaN, but does **not** set `FPSCR[VXVC]` (the difference vs `fcmpo`). xenia-rs does **not** model this — **xenia quirk**: `fcmpu` and `fcmpo` are observationally identical in xenia. - **`+0` and `-0` compare equal.** Standard IEEE rule; xenia's host `<` / `>` on `f64` matches. - **No `Rc` bit.** The CR field destination is encoded in the instruction (`BF`); there's no record-form variant. - **FPSCR side effects.** Hardware updates `FPSCR[FPCC]` (the four-bit floating-point condition code) and `FPSCR[FX]`. xenia-rs does not maintain `FPCC`. - **Precision-agnostic.** Compares the full binary64 values; works equally for single-precision values stored in FPRs (they are bit-identical to their double-precision representation). - **Encoding.** X-form, primary 63, XO 0. Bits 9–10 of `BF` are unused (reserved 0). ## Related Instructions - [`fcmpox`](fcmpo.md) — ordered compare; raises `VXSNAN`/`VXVC` on NaN/SNaN. - `mcrf`, `mcrfs`, `mfcr` — copy CR fields, useful after `fcmpu` to fan out the result. - `bc`, `bclr`, `bcctr` — conditional branches consume the CR fields written by `fcmpu`. - [`fselx`](fselx.md) — branch-free alternative when only the sign of `FRA - FRB` is needed. - [`mcrfs`](mcrfs.md), [`mffsx`](mffsx.md) — move FPSCR data into the CR. ## IBM Reference - [AIX 7.3 — `fcmpu` (Floating Compare Unordered)](https://www.ibm.com/docs/en/aix/7.3.0?topic=set-fcmpu-floating-compare-unordered-instruction) - [PowerISA v2.07B, Book I, Chapter 4 — Floating-Point Processor](https://openpowerfoundation.org/specifications/isa/) (compare semantics, `FPCC` updates, NaN/SNaN exception rules).