Tor  0.4.7.0-alpha-dev
mulodi4.c
1 /*===-- mulodi4.c - Implement __mulodi4 -----------------------------------===
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 __mulodi4 for the compiler_rt library.
11  *
12  * ===----------------------------------------------------------------------===
13  */
14 
15 #if 0
16 #include "int_lib.h"
17 #else
18 #define COMPILER_RT_ABI
19 #define di_int int64_t
20 #define di_uint uint64_t
21 #include "lib/cc/torint.h"
22 
23 di_int __mulodi4(di_int a, di_int b, int* overflow);
24 #endif
25 
26 /* Returns: a * b */
27 
28 /* Effects: sets *overflow to 1 if a * b overflows */
29 
30 COMPILER_RT_ABI di_int
31 __mulodi4(di_int a, di_int b, int* overflow)
32 {
33  const int N = (int)(sizeof(di_int) * CHAR_BIT);
34  const di_int MIN = (di_int) ((di_uint)1 << (N-1));
35  const di_int MAX = ~MIN;
36  *overflow = 0;
37  di_int result = a * b;
38  if (a == MIN)
39  {
40  if (b != 0 && b != 1)
41  *overflow = 1;
42  return result;
43  }
44  if (b == MIN)
45  {
46  if (a != 0 && a != 1)
47  *overflow = 1;
48  return result;
49  }
50  di_int sa = a >> (N - 1);
51  di_int abs_a = (a ^ sa) - sa;
52  di_int sb = b >> (N - 1);
53  di_int abs_b = (b ^ sb) - sb;
54  if (abs_a < 2 || abs_b < 2)
55  return result;
56  if (sa == sb)
57  {
58  if (abs_a > MAX / abs_b)
59  *overflow = 1;
60  }
61  else
62  {
63  if (abs_a > MIN / -abs_b)
64  *overflow = 1;
65  }
66  return result;
67 }
#define MAX(a, b)
Definition: cmp.h:22
Integer definitions used throughout Tor.