Skip to content
This repository was archived by the owner on May 21, 2019. It is now read-only.

Commit 1ace405

Browse files
committed
Implement mulo<mode>4 for use in signed overflow checking.
Fixes rdar://9219742 and rdar://9218244 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@133284 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 90467a6 commit 1ace405

File tree

9 files changed

+823
-9
lines changed

9 files changed

+823
-9
lines changed

README.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,15 @@ si_int __mulvsi3(si_int a, si_int b); // a * b
106106
di_int __mulvdi3(di_int a, di_int b); // a * b
107107
ti_int __mulvti3(ti_int a, ti_int b); // a * b
108108

109+
110+
// Integral arithmetic which returns if overflow
111+
112+
si_int __mulosi4(si_int a, si_int b, int* overflow); // a * b, overflow set to one if result not in signed range
113+
di_int __mulodi4(di_int a, di_int b, int* overflow); // a * b, overflow set to one if result not in signed range
114+
ti_int __muloti4(ti_int a, ti_int b, int* overflow); // a * b, overflow set to
115+
one if result not in signed range
116+
117+
109118
// Integral comparison: a < b -> 0
110119
// a == b -> 1
111120
// a > b -> 2

lib/mulodi4.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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+
#include "int_lib.h"
16+
#include <stdlib.h>
17+
18+
/* Returns: a * b */
19+
20+
/* Effects: sets *overflow to 1 if a * b overflows */
21+
22+
di_int
23+
__mulodi4(di_int a, di_int b, int* overflow)
24+
{
25+
const int N = (int)(sizeof(di_int) * CHAR_BIT);
26+
const di_int MIN = (di_int)1 << (N-1);
27+
const di_int MAX = ~MIN;
28+
*overflow = 0;
29+
di_int result = a * b;
30+
if (a == MIN)
31+
{
32+
if (b != 0 && b != 1)
33+
*overflow = 1;
34+
return result;
35+
}
36+
if (b == MIN)
37+
{
38+
if (a != 0 && a != 1)
39+
*overflow = 1;
40+
return result;
41+
}
42+
di_int sa = a >> (N - 1);
43+
di_int abs_a = (a ^ sa) - sa;
44+
di_int sb = b >> (N - 1);
45+
di_int abs_b = (b ^ sb) - sb;
46+
if (abs_a < 2 || abs_b < 2)
47+
return result;
48+
if (sa == sb)
49+
{
50+
if (abs_a > MAX / abs_b)
51+
*overflow = 1;
52+
}
53+
else
54+
{
55+
if (abs_a > MIN / -abs_b)
56+
*overflow = 1;
57+
}
58+
return result;
59+
}

lib/mulosi4.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*===-- mulosi4.c - Implement __mulosi4 -----------------------------------===
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 __mulosi4 for the compiler_rt library.
11+
*
12+
* ===----------------------------------------------------------------------===
13+
*/
14+
15+
#include "int_lib.h"
16+
#include <stdlib.h>
17+
18+
/* Returns: a * b */
19+
20+
/* Effects: sets *overflow to 1 if a * b overflows */
21+
22+
si_int
23+
__mulosi4(si_int a, si_int b, int* overflow)
24+
{
25+
const int N = (int)(sizeof(si_int) * CHAR_BIT);
26+
const si_int MIN = (si_int)1 << (N-1);
27+
const si_int MAX = ~MIN;
28+
*overflow = 0;
29+
si_int result = a * b;
30+
if (a == MIN)
31+
{
32+
if (b != 0 && b != 1)
33+
*overflow = 1;
34+
return result;
35+
}
36+
if (b == MIN)
37+
{
38+
if (a != 0 && a != 1)
39+
*overflow = 1;
40+
return result;
41+
}
42+
si_int sa = a >> (N - 1);
43+
si_int abs_a = (a ^ sa) - sa;
44+
si_int sb = b >> (N - 1);
45+
si_int abs_b = (b ^ sb) - sb;
46+
if (abs_a < 2 || abs_b < 2)
47+
return result;
48+
if (sa == sb)
49+
{
50+
if (abs_a > MAX / abs_b)
51+
*overflow = 1;
52+
}
53+
else
54+
{
55+
if (abs_a > MIN / -abs_b)
56+
*overflow = 1;
57+
}
58+
return result;
59+
}

lib/muloti4.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*===-- muloti4.c - Implement __muloti4 -----------------------------------===
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 __muloti4 for the compiler_rt library.
11+
*
12+
* ===----------------------------------------------------------------------===
13+
*/
14+
15+
#if __x86_64
16+
17+
#include "int_lib.h"
18+
#include <stdlib.h>
19+
20+
/* Returns: a * b */
21+
22+
/* Effects: sets *overflow to 1 if a * b overflows */
23+
24+
ti_int
25+
__muloti4(ti_int a, ti_int b, int* overflow)
26+
{
27+
const int N = (int)(sizeof(ti_int) * CHAR_BIT);
28+
const ti_int MIN = (ti_int)1 << (N-1);
29+
const ti_int MAX = ~MIN;
30+
*overflow = 0;
31+
ti_int result = a * b;
32+
if (a == MIN)
33+
{
34+
if (b != 0 && b != 1)
35+
*overflow = 1;
36+
return result;
37+
}
38+
if (b == MIN)
39+
{
40+
if (a != 0 && a != 1)
41+
*overflow = 1;
42+
return result;
43+
}
44+
ti_int sa = a >> (N - 1);
45+
ti_int abs_a = (a ^ sa) - sa;
46+
ti_int sb = b >> (N - 1);
47+
ti_int abs_b = (b ^ sb) - sb;
48+
if (abs_a < 2 || abs_b < 2)
49+
return result;
50+
if (sa == sb)
51+
{
52+
if (abs_a > MAX / abs_b)
53+
*overflow = 1;
54+
}
55+
else
56+
{
57+
if (abs_a > MIN / -abs_b)
58+
*overflow = 1;
59+
}
60+
return result;
61+
}
62+
63+
#endif

make/platform/clang_darwin.mk

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ UniversalArchs.10.4 := $(call CheckArches,i386 x86_64)
4242
Configs += ios
4343
UniversalArchs.ios := $(call CheckArches,i386 x86_64 armv6 armv7)
4444

45+
# Configuration for targetting OSX. These functions may not be in libSystem
46+
# so we should provide our own.
47+
Configs += osx
48+
UniversalArchs.osx := $(call CheckArches,i386 x86_64)
49+
4550
# Configuration for use with kernel/kexts.
4651
Configs += cc_kext
4752
UniversalArchs.cc_kext := $(call CheckArches,armv6 armv7 i386 x86_64)
@@ -74,6 +79,10 @@ CFLAGS.ios.i386 := $(CFLAGS) $(X86_DEPLOYMENT_ARGS)
7479
CFLAGS.ios.x86_64 := $(CFLAGS) $(X86_DEPLOYMENT_ARGS)
7580
CFLAGS.ios.armv6 := $(CFLAGS) $(ARM_DEPLOYMENT_ARGS)
7681
CFLAGS.ios.armv7 := $(CFLAGS) $(ARM_DEPLOYMENT_ARGS)
82+
CFLAGS.osx.i386 := $(CFLAGS) $(X86_DEPLOYMENT_ARGS)
83+
CFLAGS.osx.x86_64 := $(CFLAGS) $(X86_DEPLOYMENT_ARGS)
84+
CFLAGS.osx.armv6 := $(CFLAGS) $(ARM_DEPLOYMENT_ARGS)
85+
CFLAGS.osx.armv7 := $(CFLAGS) $(ARM_DEPLOYMENT_ARGS)
7786
CFLAGS.cc_kext.i386 := $(CFLAGS) $(X86_DEPLOYMENT_ARGS)
7887
CFLAGS.cc_kext.x86_64 := $(CFLAGS) $(X86_DEPLOYMENT_ARGS)
7988
CFLAGS.cc_kext.armv6 := $(CFLAGS) $(ARM_DEPLOYMENT_ARGS) -mthumb
@@ -82,7 +91,7 @@ CFLAGS.cc_kext.armv7 := $(CFLAGS) $(ARM_DEPLOYMENT_ARGS) -mthumb
8291
FUNCTIONS.eprintf := eprintf
8392
FUNCTIONS.10.4 := eprintf floatundidf floatundisf floatundixf
8493

85-
FUNCTIONS.ios := divmodsi4 udivmodsi4
94+
FUNCTIONS.ios := divmodsi4 udivmodsi4 mulosi4 mulodi4 muloti4
8695
# On x86, the divmod functions reference divsi.
8796
FUNCTIONS.ios.i386 := $(FUNCTIONS.ios) \
8897
divsi3 udivsi3
@@ -93,6 +102,8 @@ FUNCTIONS.ios.armv6 := $(FUNCTIONS.ios) \
93102
switch16 switch32 switch8 switchu8 \
94103
save_vfp_d8_d15_regs restore_vfp_d8_d15_regs
95104

105+
FUNCTIONS.osx := mulosi4 mulodi4 muloti4
106+
96107
CCKEXT_COMMON_FUNCTIONS := \
97108
absvdi2 \
98109
absvsi2 \

make/platform/darwin_bni.mk

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Description := Target for Darwin using an Apple-style build.
33

4-
Configs := Debug Release Profile Static
4+
Configs := Debug Release Profile Static
55

66
# We override this with RC_ARCHS because B&I may want to build on an ARCH we
77
# haven't explicitly defined support for. If all goes well, this will just work
@@ -18,7 +18,7 @@ endif
1818

1919

2020
CFLAGS := -Wall -Os -fomit-frame-pointer -g
21-
CFLAGS.Static := $(CFLAGS) -static
21+
CFLAGS.Static := $(CFLAGS) -static
2222

2323
VISIBILITY_HIDDEN := 0
2424
VISIBILITY_HIDDEN.Static := 1
@@ -29,8 +29,8 @@ FUNCTIONS := absvdi2 absvsi2 addvdi3 addvsi3 ashldi3 ashrdi3 \
2929
divdc3 divdi3 divsc3 ffsdi2 \
3030
fixdfdi fixsfdi fixunsdfdi fixunsdfsi fixunssfdi \
3131
fixunssfsi floatdidf floatdisf floatundidf floatundisf \
32-
gcc_personality_v0 lshrdi3 moddi3 muldc3 muldi3 \
33-
mulsc3 mulvdi3 mulvsi3 negdi2 negvdi2 negvsi2 \
32+
gcc_personality_v0 lshrdi3 moddi3 muldc3 muldi3 mulosi3 \
33+
mulodi3 muloti3 mulsc3 mulvdi3 mulvsi3 negdi2 negvdi2 negvsi2 \
3434
paritydi2 paritysi2 popcountdi2 popcountsi2 powidf2 \
3535
powisf2 subvdi3 subvsi3 ucmpdi2 udivdi3 \
3636
udivmoddi4 umoddi3 apple_versioning eprintf
@@ -51,7 +51,7 @@ FUNCTIONS.x86_64 := $(FUNCTIONS) \
5151
fixunsxfti fixxfdi fixxfti floatdixf floattidf \
5252
floattisf floattixf floatundixf floatuntidf \
5353
floatuntisf floatuntixf lshrti3 modti3 multi3 \
54-
mulvti3 mulxc3 negti2 negvti2 parityti2 \
54+
muloti3 mulvti3 mulxc3 negti2 negvti2 parityti2 \
5555
popcountti2 powixf2 subvti3 ucmpti2 udivmodti4 \
5656
udivti3 umodti3 clear_cache enable_execute_stack
5757
FUNCTIONS.armv5 := $(FUNCTIONS) \
@@ -65,7 +65,7 @@ FUNCTIONS.armv5 := $(FUNCTIONS) \
6565
truncdfsf2 \
6666
modsi3 umodsi3 udivsi3 divsi3 udivmodsi4 divmodsi4 \
6767
switch8 switchu8 switch16 switch32 \
68-
sync_synchronize
68+
sync_synchronize
6969

7070
FUNCTIONS.armv6 := $(FUNCTIONS) \
7171
comparedf2 comparesf2 \
@@ -81,7 +81,7 @@ FUNCTIONS.armv6 := $(FUNCTIONS) \
8181
modsi3 umodsi3 udivsi3 divsi3 udivmodsi4 divmodsi4 \
8282
switch8 switchu8 switch16 switch32 \
8383
restore_vfp_d8_d15_regs save_vfp_d8_d15_regs \
84-
sync_synchronize
84+
sync_synchronize
8585

8686
FUNCTIONS.armv7 := $(FUNCTIONS) \
8787
comparedf2 comparesf2 \
@@ -95,4 +95,3 @@ FUNCTIONS.armv7 := $(FUNCTIONS) \
9595
nedf2vfp nesf2vfp \
9696
subdf3vfp subsf3vfp truncdfsf2vfp unorddf2vfp unordsf2vfp \
9797
modsi3 umodsi3 udivsi3 divsi3 udivmodsi4 divmodsi4
98-

0 commit comments

Comments
 (0)