SWI 0x07 — DivArm¶
- Entry:
0x000003A8(ARM) - Status: verified (hardware-checked 2026-07-08: cycle counts and return values measured on real GBA via the worker ROM)
Summary¶
Identical to SWI 0x06 Div, but with the operand registers swapped. DivArm exists purely so callers that hold the denominator in r0 and numerator in r1 (the opposite of Div's convention) can divide without shuffling registers first.
Parameters¶
| Reg | In | Meaning |
|---|---|---|
| r0 | s32 | Denominator (divisor) |
| r1 | s32 | Numerator (dividend) |
Returns¶
| Reg | Out | Meaning |
|---|---|---|
| r0 | s32 | Quotient r1 / r0, rounded toward zero |
| r1 | s32 | Remainder; sign follows the numerator (r1 in) |
| r3 | s32 | Absolute value of the quotient |
Clobbered registers¶
r2, r12 (ip). Same as Div.
Hardware audit (2026-07-08, canary r4–r12 + CPSR snapshot): caller-visible clobbers: identical to Div: r0 = quotient, r1 = remainder, r3 = |quotient|; r2 preserved. r2, r4–r12, r13, and CPSR (flags and mode) came back bit-identical on every tested path. r11/r12 are explained by the SWI dispatcher (it pushes {r11, r12, lr} — see 10_irq_boot_and_iwram.md) and CPSR by the SPSR restore on return; r2 and r4–r10 must be preserved or restored by the routine itself — where a static note above claims r2 is destroyed, the hardware disagrees at the caller level. Raw data: results/clobber_audit_pass2.csv.
Algorithm¶
Three instructions: r3 = r0, r0 = r1, r1 = r3, i.e. exchange r0 and r1,
then fall through into the Div body at 0x000003B4. All arithmetic, edge cases,
and sign rules are exactly those of SWI 0x06 Div — see swi_06_div.md.
Edge cases & known bugs¶
Same as Div: divide-by-zero hangs for |numerator| >= 2; INT_MIN / -1 returns
0x80000000 without crashing. Because the operands are swapped, divide-by-zero
here means r1 (numerator) / r0 (denominator) == 0.
Cycle count¶
Hardware-measured net CPU cycles (worker-ROM harness, TM0/TM1 cascade at F/1,
13-cycle baseline subtracted; identical across 3 runs — see
02_hardware_verification_checklist.md § Measurement setup).
Exactly Div + 3 cycles for the same operands: 100/7 = 111, 0x7FFFFFFF/1 =
462 — confirming the 3-instruction register-swap shim.
Open questions (need hardware verification)¶
Same as Div.
GBATEK cross-reference¶
GBATEK documents SWI 07h as "same as Div, but incoming parameters are exchanged". Confirmed.