From 8a3a2c0ee59d4c3181f9706ec7c622ce4f4d1c0d Mon Sep 17 00:00:00 2001 From: Xavier Leroy Date: Mon, 23 Sep 2024 13:18:36 +0200 Subject: [PATCH] ARM i64_udivmod: reduce number of instructions and number of iterations --- runtime/arm/i64_udivmod.S | 46 ++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/runtime/arm/i64_udivmod.S b/runtime/arm/i64_udivmod.S index c9b116929c..d35d61c0df 100644 --- a/runtime/arm/i64_udivmod.S +++ b/runtime/arm/i64_udivmod.S @@ -40,40 +40,36 @@ @ On entry: N = (r0, r1) numerator D = (r2, r3) divisor @ On exit: Q = (r4, r5) quotient R = (r0, r1) remainder -@ Locals: M = (r6, r7) mask TMP = r8 temporary +@ Locals: COUNT = r6 round counter +@ TMP = r7, r8 temporary FUNCTION(__compcert_i64_udivmod) - orrs r8, Reg1LO, Reg1HI @ is D == 0? + orrs r7, Reg1LO, Reg1HI @ is D == 0? it eq bxeq lr @ if so, return with unspecified results MOV Reg2LO, #0 @ Q = 0 MOV Reg2HI, #0 - MOV Reg3LO, #1 @ M = 1 - MOV Reg3HI, #0 -1: cmp Reg1HI, #0 @ while ((signed) D >= 0) ... - blt 2f - subs r8, Reg0LO, Reg1LO @ ... and N >= D ... - sbcs r8, Reg0HI, Reg1HI - blo 2f + MOV r6, #1 @ round = 1 +1: cmp Reg1HI, #0 @ while ((signed) D >= 0) + blt 3f adds Reg1LO, Reg1LO, Reg1LO @ D = D << 1 adc Reg1HI, Reg1HI, Reg1HI - adds Reg3LO, Reg3LO, Reg3LO @ M = M << 1 - adc Reg3HI, Reg3HI, Reg3HI + subs r7, Reg0LO, Reg1LO @ if N < D + sbcs r8, Reg0HI, Reg1HI + blo 2f @ break and restore D to previous value + ADD r6, r6, #1 @ increment count b 1b -2: subs Reg0LO, Reg0LO, Reg1LO @ N = N - D - sbcs Reg0HI, Reg0HI, Reg1HI - orr Reg2LO, Reg2LO, Reg3LO @ Q = Q | M - orr Reg2HI, Reg2HI, Reg3HI - bhs 3f @ if N was >= D, continue - adds Reg0LO, Reg0LO, Reg1LO @ otherwise, undo what we just did - adc Reg0HI, Reg0HI, Reg1HI @ N = N + D - bic Reg2LO, Reg2LO, Reg3LO @ Q = Q & ~M - bic Reg2HI, Reg2HI, Reg3HI -3: lsrs Reg3HI, Reg3HI, #1 @ M = M >> 1 - rrx Reg3LO, Reg3LO - lsrs Reg1HI, Reg1HI, #1 @ D = D >> 1 +2: lsrs Reg1HI, Reg1HI, #1 @ D = D >> 1 rrx Reg1LO, Reg1LO - orrs r8, Reg3LO, Reg3HI @ repeat while (M != 0) ... - bne 2b +3: adds Reg2LO, Reg2LO, Reg2LO @ Q = Q << 1 + adc Reg2HI, Reg2HI, Reg2HI + subs r7, Reg0LO, Reg1LO @ TMP = N - D + sbcs r8, Reg0HI, Reg1HI + blo 4f @ if N < D, leave N and Q unchanged + MOV Reg0LO, r7 @ N = N - D + MOV Reg0HI, r8 + orr Reg2LO, Reg2LO, #1 @ Q = Q | 1 +4: subs r6, r6, #1 @ decrement count + bne 2b @ repeat until count = 0 bx lr ENDFUNCTION(__compcert_i64_udivmod)