muldi3.c revision 222656
1219019Sgabor/* ===-- muldi3.c - Implement __muldi3 -------------------------------------===
2219019Sgabor *
3219019Sgabor *                     The LLVM Compiler Infrastructure
4219019Sgabor *
5219019Sgabor * This file is dual licensed under the MIT and the University of Illinois Open
6219019Sgabor * Source Licenses. See LICENSE.TXT for details.
7219019Sgabor *
8219019Sgabor * ===----------------------------------------------------------------------===
9222354Sgabor *
10222354Sgabor * This file implements __muldi3 for the compiler_rt library.
11222354Sgabor *
12222354Sgabor * ===----------------------------------------------------------------------===
13222354Sgabor */
14222354Sgabor#include "abi.h"
15222354Sgabor
16222354Sgabor#include "int_lib.h"
17222354Sgabor
18222354Sgabor/* Returns: a * b */
19222354Sgabor
20252458Speterstatic
21254273Speterdi_int
22252458Speter__muldsi3(su_int a, su_int b)
23252458Speter{
24252458Speter    dwords r;
25252458Speter    const int bits_in_word_2 = (int)(sizeof(si_int) * CHAR_BIT) / 2;
26252458Speter    const su_int lower_mask = (su_int)~0 >> bits_in_word_2;
27252458Speter    r.s.low = (a & lower_mask) * (b & lower_mask);
28252458Speter    su_int t = r.s.low >> bits_in_word_2;
29252458Speter    r.s.low &= lower_mask;
30252458Speter    t += (a >> bits_in_word_2) * (b & lower_mask);
31222354Sgabor    r.s.low += (t & lower_mask) << bits_in_word_2;
32219019Sgabor    r.s.high = t >> bits_in_word_2;
33219019Sgabor    t = r.s.low >> bits_in_word_2;
34219019Sgabor    r.s.low &= lower_mask;
35219019Sgabor    t += (b >> bits_in_word_2) * (a & lower_mask);
36219019Sgabor    r.s.low += (t & lower_mask) << bits_in_word_2;
37219019Sgabor    r.s.high += t >> bits_in_word_2;
38219019Sgabor    r.s.high += (a >> bits_in_word_2) * (b >> bits_in_word_2);
39219019Sgabor    return r.all;
40219019Sgabor}
41219019Sgabor
42219019Sgabor/* Returns: a * b */
43219019Sgabor
44219019SgaborARM_EABI_FNALIAS(lmul, muldi3);
45219019Sgabor
46219019SgaborCOMPILER_RT_ABI di_int
47219019Sgabor__muldi3(di_int a, di_int b)
48219019Sgabor{
49219019Sgabor    dwords x;
50219019Sgabor    x.all = a;
51219019Sgabor    dwords y;
52219019Sgabor    y.all = b;
53254285Speter    dwords r;
54219019Sgabor    r.all = __muldsi3(x.s.low, y.s.low);
55219019Sgabor    r.s.high += x.s.high * y.s.low + x.s.low * y.s.high;
56219019Sgabor    return r.all;
57219019Sgabor}
58219019Sgabor