The hand-written parts of the manual still described how the retired xenia-rs interpreter behaved: its snapshots, Rust casts and helpers. Each of those 490 statements is now either restated as what Canary's emitters and x64 backend actually do (at the pinned canary_experimental commit), or dropped where it only made sense for xenia-rs. Checking them turned up claims that were wrong, not just outdated: - VSCR[SAT] is never modelled in Canary (DID_SATURATE is a stub and mfvscr cannot see it); the pages said saturating ops set it stickily. - Canary does not implement lswi/lswx/stswi/stswx, dcbi, mtfsb0/mtfsb1, vmsum*, vmhaddshs, vupkhpx/vupklpx, and most SPRs; pages described them as working. - Traps evaluate TO in Canary; stvebx/stvehx/stvewx store one element, not 16 bytes; mtmsrd writes only EE; fres/frsqrte/vrsqrtefp precision claims and the stfs "rounds under RN / sets FPSCR" claim contradicted the spec. - Reservations are a 64 KiB block bitmap plus a value compare, not per-address tracking. Claims that neither Canary's source nor a public spec settles are marked unverified (NI at boot, vmaddcfp128 operand order, estimate bit-exactness). Generated regions are untouched; re-running the generator changes nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
5.9 KiB
mftb — Move from Time Base
Category: Control / CR / SPR · Form: XFX · Opcode:
0x7c0002e6
Assembler Mnemonics
| Mnemonic | XML entry | Flags | Description |
|---|---|---|---|
mftb |
mftb |
— | Move from Time Base |
Syntax
mftb [RD], [TBR]
Encoding
mftb — form XFX
- Opcode word:
0x7c0002e6 - Primary opcode (bits 0–5):
31 - Extended opcode:
371 - Synchronising: no
| Bits | Field | Meaning |
|---|---|---|
| 0–5 | OPCD |
primary opcode (31) |
| 6–10 | RT |
destination / source GPR |
| 11–20 | spr/tbr/FXM |
SPR/TBR number (byte-swapped halves) or CR field mask |
| 21–30 | XO |
extended opcode |
| 31 | — |
reserved |
Operands
| Field | Role | Description |
|---|---|---|
TBR |
mftb: read | Time-Base Register selector for mftb. |
RD |
mftb: write | Destination GPR. |
Register Effects
mftb
- Reads (always):
TBR - Reads (conditional): none
- Writes (always):
RD - 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
/* 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
mftb
- Canary XML:
tools/ppc-instructions.xml— search formnem="mftb" - Canary emitter:
src/xenia/cpu/ppc/ppc_emit_control.cc:721 - Sylpheed opcode:
crates/sylpheed-ppc/src/opcode.rs:175 - Sylpheed decoder:
crates/sylpheed-ppc/src/decoder.rs:918
Canary emitter (frozen snapshot @ f21ebd49e9)
int InstrEmit_mftb(PPCHIRBuilder& f, const InstrData& i) {
Value* time = f.LoadClock();
const uint32_t n = ((i.XFX.spr & 0x1F) << 5) | ((i.XFX.spr >> 5) & 0x1F);
if (n == 268) {
// TB - full bits.
} else {
// TBU - upper bits only.
time = f.Shr(time, 32);
}
f.StoreGPR(i.XFX.RT, time);
return 0;
}
Special Cases & Edge Conditions
-
Time-base register selectors. The 10-bit
tbrfield encodes the same way asmfspr'ssprfield (two halves swapped). The two values defined for the Xenon:Decoded Name Meaning 268 TBL Time Base, lower 32 bits 269 TBU Time Base, upper 32 bits Canary returns the full 64-bit guest clock for 268 and the clock's upper 32 bits for any other selector.
-
Atomic 64-bit read pattern. Because
mftbreads only 32 bits at a time, software performs the canonical retry loop to avoid TBL→TBU rollover skew:retry: mftbu rH ; read upper mftb rL ; read lower (TBR=268) mftbu rH2 ; read upper again cmpw rH, rH2 bne retry -
Xenon clock rate. Real hardware ticks the time base at ~3.2 GHz (one tick per CPU clock divided by the architectural ratio). The PVR signature the kernel exposes (
0x00710800) and the kernel-reported tick rate jointly let titles convert TB ticks to seconds. -
Canary behaviour. Canary's
mftbreads its guest clock (LoadClock), which follows host time — TB for SPR 268, otherwise just the upper 32 bits. Guest time therefore tracks real time, and TB readings are not reproducible from run to run. -
mftb RT(no operand) is the simplified mnemonic formftb RT, 268— read the lower half.mftbu RT≡mftb RT, 269. -
Deprecated alternative.
mfspr RT, 268/269works on the Xenon (Canary accepts both) but post-PowerISA v2.06 deprecated reading TB throughmfspr. Prefermftb.
Related Instructions
mfspr— generic SPR read; can also read TBL/TBU on Xenon (deprecated).mtspr— TBL/TBU writes are privileged; not user-accessible.isync— context-synchronising fence sometimes paired withmftbfor tight measurement loops.
Simplified Mnemonics
| Simplified | Expansion | Notes |
|---|---|---|
mftb RT |
mftb RT, 268 |
read TBL |
mftbu RT |
mftb RT, 269 |
read TBU |
IBM Reference
- AIX 7.3 —
mftb(Move from Time Base) - PowerISA v2.07B, Book II §6.1 — Time Base description and the canonical 64-bit read sequence.