1 /*===-- udivmodsi4.S - 32-bit unsigned integer divide and modulus ---------===//
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 __udivmodsi4 (32-bit unsigned integer divide and
11 * modulus) function for the ARM architecture. A naive digit-by-digit
12 * computation is employed for simplicity.
14 *===----------------------------------------------------------------------===*/
16 #include "../assembly.h"
18 #define ESTABLISH_FRAME \
21 #define CLEAR_FRAME_AND_RETURN \
33 DEFINE_COMPILERRT_FUNCTION(__udivmodsi4)
34 // We use a simple digit by digit algorithm; before we get into the actual
35 // divide loop, we must calculate the left-shift amount necessary to align
36 // the MSB of the divisor with that of the dividend (If this shift is
37 // negative, then the result is zero, and we early out). We also conjure a
38 // bit mask of 1 to use in constructing the quotient, and initialize the
42 tst b, b // detect divide-by-zero
45 beq LOCAL_LABEL(return) // return 0 if b is zero.
48 blt LOCAL_LABEL(return) // return 0 if MSB(a) < MSB(b)
50 LOCAL_LABEL(mainLoop):
51 // This loop basically implements the following:
61 // Note that this does not perform the final iteration (i == 0); by doing it
62 // this way, we can merge the two branches which is a substantial win for
63 // such a tight loop on current ARM architectures.
68 bhi LOCAL_LABEL(mainLoop)
70 // Do the final test subtraction and update of quotient (i == 0), as it is
71 // not performed in the main loop.
77 // Store the remainder, and move the quotient to r0, then return.
80 CLEAR_FRAME_AND_RETURN