Skip to content

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.