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)
38 beq LOCAL_LABEL(divzero)
45 // We use a simple digit by digit algorithm; before we get into the actual
46 // divide loop, we must calculate the left-shift amount necessary to align
47 // the MSB of the divisor with that of the dividend (If this shift is
48 // negative, then the result is zero, and we early out). We also conjure a
49 // bit mask of 1 to use in constructing the quotient, and initialize the
53 tst b, b // detect divide-by-zero
56 beq LOCAL_LABEL(return) // return 0 if b is zero.
59 blt LOCAL_LABEL(return) // return 0 if MSB(a) < MSB(b)
61 LOCAL_LABEL(mainLoop):
62 // This loop basically implements the following:
72 // Note that this does not perform the final iteration (i == 0); by doing it
73 // this way, we can merge the two branches which is a substantial win for
74 // such a tight loop on current ARM architectures.
79 bhi LOCAL_LABEL(mainLoop)
81 // Do the final test subtraction and update of quotient (i == 0), as it is
82 // not performed in the main loop.
87 // Move the quotient to r0 and return.
89 CLEAR_FRAME_AND_RETURN