1 /*===-- udivsi3.S - 32-bit unsigned integer divide ------------------------===//
3 * The LLVM Compiler Infrastructure
5 * This file is dual licensed under the MIT and the University of Illinois Open
6 * Source Licenses. See LICENSE.TXT for details.
8 *===----------------------------------------------------------------------===//
10 * This file implements the __udivsi3 (32-bit unsigned integer divide)
11 * function for the ARM architecture. A naive digit-by-digit computation is
12 * employed for simplicity.
14 *===----------------------------------------------------------------------===*/
16 #include "../assembly.h"
18 #define ESTABLISH_FRAME \
21 #define CLEAR_FRAME_AND_RETURN \
33 // Ok, APCS and AAPCS agree on 32 bit args, so it's safe to use the same routine.
34 DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_uidiv, __udivsi3)
35 DEFINE_COMPILERRT_FUNCTION(__udivsi3)
36 // We use a simple digit by digit algorithm; before we get into the actual
37 // divide loop, we must calculate the left-shift amount necessary to align
38 // the MSB of the divisor with that of the dividend (If this shift is
39 // negative, then the result is zero, and we early out). We also conjure a
40 // bit mask of 1 to use in constructing the quotient, and initialize the
44 tst b, b // detect divide-by-zero
47 beq LOCAL_LABEL(return) // return 0 if b is zero.
50 blt LOCAL_LABEL(return) // return 0 if MSB(a) < MSB(b)
52 LOCAL_LABEL(mainLoop):
53 // This loop basically implements the following:
63 // Note that this does not perform the final iteration (i == 0); by doing it
64 // this way, we can merge the two branches which is a substantial win for
65 // such a tight loop on current ARM architectures.
70 bhi LOCAL_LABEL(mainLoop)
72 // Do the final test subtraction and update of quotient (i == 0), as it is
73 // not performed in the main loop.
78 // Move the quotient to r0 and return.
80 CLEAR_FRAME_AND_RETURN