divsi3.c revision 222656
143902Sbrian/* ===-- divsi3.c - Implement __divsi3 -------------------------------------===
243902Sbrian *
343948Sbrian *                     The LLVM Compiler Infrastructure
443902Sbrian *
543948Sbrian * This file is dual licensed under the MIT and the University of Illinois Open
643902Sbrian * Source Licenses. See LICENSE.TXT for details.
750476Speter *
843902Sbrian * ===----------------------------------------------------------------------===
943902Sbrian *
1043902Sbrian * This file implements __divsi3 for the compiler_rt library.
1143902Sbrian *
1243902Sbrian * ===----------------------------------------------------------------------===
1343902Sbrian */
1443902Sbrian#include "abi.h"
1543902Sbrian
1643902Sbrian#include "int_lib.h"
1743902Sbrian
1843902Sbriansu_int COMPILER_RT_ABI __udivsi3(su_int n, su_int d);
1943902Sbrian
2043902Sbrian/* Returns: a / b */
2143948Sbrian
2243902SbrianARM_EABI_FNALIAS(idiv, divsi3);
2343902Sbrian
2443948SbrianCOMPILER_RT_ABI si_int
2543948Sbrian__divsi3(si_int a, si_int b)
2643902Sbrian{
2743902Sbrian    const int bits_in_word_m1 = (int)(sizeof(si_int) * CHAR_BIT) - 1;
2843902Sbrian    si_int s_a = a >> bits_in_word_m1;           /* s_a = a < 0 ? -1 : 0 */
2943902Sbrian    si_int s_b = b >> bits_in_word_m1;           /* s_b = b < 0 ? -1 : 0 */
3043902Sbrian    a = (a ^ s_a) - s_a;                         /* negate if s_a == -1 */
3143948Sbrian    b = (b ^ s_b) - s_b;                         /* negate if s_b == -1 */
3243948Sbrian    s_a ^= s_b;                                  /* sign of quotient */
3343902Sbrian    return (__udivsi3(a, b) ^ s_a) - s_a;        /* negate if s_a == -1 */
3443902Sbrian}
3543902Sbrian