Tor 0.4.9.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
23di_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
30COMPILER_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.