# `tdi` — Trap Doubleword Immediate > **Category:** [Branch & System](../categories/branch.md) · **Form:** [D](../forms/D.md) · **Opcode:** `0x08000000` ## Assembler Mnemonics | Mnemonic | XML entry | Flags | Description | | --- | --- | --- | --- | | `tdi` | `tdi` | — | Trap Doubleword Immediate | ## Syntax ```asm tdi [TO], [RA], [SIMM] ``` ## Encoding ### `tdi` — form `D` - **Opcode word:** `0x08000000` - **Primary opcode (bits 0–5):** `2` - **Extended opcode:** — - **Synchronising:** no | Bits | Field | Meaning | | --- | --- | --- | | 0–5 | `OPCD` | primary opcode | | 6–10 | `RT` | destination GPR (or RS when storing) | | 11–15 | `RA` | source GPR (0 ⇒ literal 0 for RA0 forms) | | 16–31 | `D/SI/UI` | 16-bit signed or unsigned immediate | ## Operands | Field | Role | Description | | --- | --- | --- | | `TO` | tdi: read | Trap-on condition mask (5 bits) — LT, GT, EQ, LGT, LLT bits. | | `RA` | tdi: read | Source GPR (`r0`–`r31`). | | `SIMM` | tdi: read | 16-bit signed immediate. Sign-extended to 64 bits before use. | ## Register Effects ### `tdi` - **Reads (always):** `TO`, `RA`, `SIMM` - **Reads (conditional):** _none_ - **Writes (always):** _none_ - **Writes (conditional):** _none_ ## Status-Register Effects _No condition-register or status-register effects._ ## Operation (pseudocode) ``` ; No hand-written pseudocode for this instruction yet. ; The authoritative semantics are the Canary emitter snapshot under ; Implementation References; about half of Canary's emitters open ; with the PPC-style definition as a comment (`RD <- (RA) + (RB)`). ; Every side effect is also enumerated in the Register Effects and ; Status-Register Effects tables above. ``` ## C Translation Example ```c /* No hand-written C yet. Translate the Canary emitter snapshot */ /* under Implementation References; its HIR maps directly: */ /* f.LoadGPR(n) / f.StoreGPR(n, v) -> r[n] / r[n] = v */ /* f.LoadFPR / StoreFPR, f.LoadVR / StoreVR -> f[n], v[n] */ /* f.Load(ea, T), f.Store(ea, v) -> raw read / write; emitters */ /* wrap them in f.ByteSwap for the big-endian guest value */ /* f.UpdateCR(n, v) -> CR field n from v's LOW 32 BITS vs 0 */ /* f.LoadCA / f.StoreCA -> xer.CA; f.StoreSAT -> vscr.SAT */ /* i.XO.RA, i.D.DS, ... -> the bit-fields listed under Operands */ /* The Register Effects and Status-Register Effects tables above */ /* enumerate every side effect a faithful translation must emit. */ ``` ## Implementation References **`tdi`** - Canary XML: [`tools/ppc-instructions.xml` — search for `mnem="tdi"`](https://github.com/xenia-canary/xenia-canary/blob/f21ebd49e979e44f081f474df78c3fbfee9cb3f2/tools/ppc-instructions.xml) - Canary emitter: [`src/xenia/cpu/ppc/ppc_emit_control.cc:570`](https://github.com/xenia-canary/xenia-canary/blob/f21ebd49e979e44f081f474df78c3fbfee9cb3f2/src/xenia/cpu/ppc/ppc_emit_control.cc#L570) - Sylpheed opcode: [`crates/sylpheed-ppc/src/opcode.rs:291`](../../../crates/sylpheed-ppc/src/opcode.rs#L291) - Sylpheed decoder: [`crates/sylpheed-ppc/src/decoder.rs:442`](../../../crates/sylpheed-ppc/src/decoder.rs#L442)
Canary emitter (frozen snapshot @ f21ebd49e9) ```cpp int InstrEmit_tdi(PPCHIRBuilder& f, const InstrData& i) { if (cvars::ignore_trap_instructions) { return 0; } // a <- (RA) // if (a < EXTS(SI)) & TO[0] then TRAP // if (a > EXTS(SI)) & TO[1] then TRAP // if (a = EXTS(SI)) & TO[2] then TRAP // if (a u EXTS(SI)) & TO[4] then TRAP Value* ra = f.LoadGPR(i.D.RA); Value* rb = f.LoadConstantInt64(XEEXTS16(i.D.DS)); return InstrEmit_trap(f, i, ra, rb, i.D.RT); } ```
## Special Cases & Edge Conditions - **Immediate is sign-extended.** `SIMM` is treated as a 16-bit signed value, then sign-extended to 64 bits before comparison. To trap against a small unsigned constant, the same encoding works because both signed and unsigned interpretations agree for `SIMM ∈ [0, 0x7FFF]`. - **`TO` mask.** Identical bit layout to [`td`](td.md): bit 0 = signed LT, 1 = signed GT, 2 = EQ, 3 = unsigned LT (LGT), 4 = unsigned GT (LLT). Trap fires if any selected bit's condition is true. - **`TO = 31` is unconditional.** `tdi 31, 0, 0` is a debugger / assert trap. Compilers sometimes use it as a "should not reach" marker. - **64-bit comparison only.** Unlike [`twi`](twi.md), `tdi` always compares the full 64-bit GPR — it has no PPC32 analogue. The Xenon's PPC64 mode makes this meaningful. - **No register effects.** Pure side effect on success: Program interrupt → vector `0x700` with `SRR1[TRAP]=1`. - **Canary evaluates the condition.** Canary evaluates `TO` properly: it compares the operands for each set bit and emits a conditional trap (`TrapTrue`), and `TO = 0` emits nothing. So `tdi 0, r0, 0` falls through, as on hardware. - **Reserved bits.** Bits 6–10 carry the `TO` field; there is no `Rc` / `OE` on D-form trap immediates. ## Related Instructions - [`td`](td.md) — register-register doubleword trap (X-form). - [`twi`](twi.md) / [`tw`](tw.md) — 32-bit-comparison siblings. - [`sc`](sc.md) — kernel-entry counterpart via system call exception. - [`mtmsrd`](../control/mtmsrd.md) (control category) — kernel `rfid`-style return path after handling. ### Simplified Mnemonics | Simplified | Expansion | Triggered when | | --- | --- | --- | | `tdi RA, value` | `tdi 31, RA, value` | unconditional trap | | `tdeqi RA, value` | `tdi 4, RA, value` | `RA == EXTS(value)` | | `tdnei RA, value` | `tdi 24, RA, value` | `RA != EXTS(value)` | | `tdlti RA, value` | `tdi 16, RA, value` | signed less than | | `tdlei RA, value` | `tdi 20, RA, value` | signed less or equal | | `tdgti RA, value` | `tdi 8, RA, value` | signed greater than | | `tdgei RA, value` | `tdi 12, RA, value` | signed greater or equal | | `tdllti RA, value` | `tdi 2, RA, value` | unsigned less than | | `tdlgei RA, value` | `tdi 5, RA, value` | unsigned greater or equal | | `tdlgti RA, value` | `tdi 1, RA, value` | unsigned greater than | | `tdllei RA, value` | `tdi 6, RA, value` | unsigned less or equal | ## IBM Reference - [AIX 7.3 — `tdi` (Trap Doubleword Immediate)](https://www.ibm.com/docs/en/aix/7.3.0?topic=set-tdi-trap-doubleword-immediate-instruction) - [AIX 7.3 — Trap simplified mnemonics](https://www.ibm.com/docs/en/aix/7.3.0?topic=mnemonics-trap-simplified) - PowerISA v2.07B, Book I §3.3.11 — fixed-point trap instructions.