Home | History | Annotate | Download | only in lib
      1 /* ===-- multi3.c - Implement __multi3 -------------------------------------===
      2  *
      3  *                     The LLVM Compiler Infrastructure
      4  *
      5  * This file is dual licensed under the MIT and the University of Illinois Open
      6  * Source Licenses. See LICENSE.TXT for details.
      7  *
      8  * ===----------------------------------------------------------------------===
      9 
     10  * This file implements __multi3 for the compiler_rt library.
     11  *
     12  * ===----------------------------------------------------------------------===
     13  */
     14 
     15 #include "int_lib.h"
     16 
     17 #if __x86_64
     18 
     19 /* Returns: a * b */
     20 
     21 static
     22 ti_int
     23 __mulddi3(du_int a, du_int b)
     24 {
     25     twords r;
     26     const int bits_in_dword_2 = (int)(sizeof(di_int) * CHAR_BIT) / 2;
     27     const du_int lower_mask = (du_int)~0 >> bits_in_dword_2;
     28     r.s.low = (a & lower_mask) * (b & lower_mask);
     29     du_int t = r.s.low >> bits_in_dword_2;
     30     r.s.low &= lower_mask;
     31     t += (a >> bits_in_dword_2) * (b & lower_mask);
     32     r.s.low += (t & lower_mask) << bits_in_dword_2;
     33     r.s.high = t >> bits_in_dword_2;
     34     t = r.s.low >> bits_in_dword_2;
     35     r.s.low &= lower_mask;
     36     t += (b >> bits_in_dword_2) * (a & lower_mask);
     37     r.s.low += (t & lower_mask) << bits_in_dword_2;
     38     r.s.high += t >> bits_in_dword_2;
     39     r.s.high += (a >> bits_in_dword_2) * (b >> bits_in_dword_2);
     40     return r.all;
     41 }
     42 
     43 /* Returns: a * b */
     44 
     45 ti_int
     46 __multi3(ti_int a, ti_int b)
     47 {
     48     twords x;
     49     x.all = a;
     50     twords y;
     51     y.all = b;
     52     twords r;
     53     r.all = __mulddi3(x.s.low, y.s.low);
     54     r.s.high += x.s.high * y.s.low + x.s.low * y.s.high;
     55     return r.all;
     56 }
     57 
     58 #endif /* __x86_64 */
     59