diff options
Diffstat (limited to 'meta/recipes-devtools/gcc/gcc-csl-arm/gcc_optab_arm.patch')
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-csl-arm/gcc_optab_arm.patch | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-csl-arm/gcc_optab_arm.patch b/meta/recipes-devtools/gcc/gcc-csl-arm/gcc_optab_arm.patch new file mode 100644 index 0000000000..fa21b26554 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-csl-arm/gcc_optab_arm.patch | |||
@@ -0,0 +1,95 @@ | |||
1 | ARM is the only architecture that has a helper function that returns | ||
2 | an unbiased result. This fix is trivial enough that we can show it | ||
3 | doesn't effect any of the other arches. Can we consider this a | ||
4 | regression fix since it used to work until the helper was added :} | ||
5 | |||
6 | Tested with no regressions on x86_64-pc-linux-gnu and arm-none-eabi. | ||
7 | |||
8 | Cheers, | ||
9 | Carlos. | ||
10 | -- | ||
11 | Carlos O'Donell | ||
12 | CodeSourcery | ||
13 | carlos@codesourcery.com | ||
14 | (650) 331-3385 x716 | ||
15 | |||
16 | gcc/ | ||
17 | |||
18 | 2006-01-27 Carlos O'Donell <carlos@codesourcery.com> | ||
19 | |||
20 | * optabs.c (prepare_cmp_insn): If unbaised and unsigned then bias | ||
21 | the comparison routine return. | ||
22 | |||
23 | gcc/testsuite/ | ||
24 | |||
25 | 2006-01-27 Carlos O'Donell <carlos@codesourcery.com> | ||
26 | |||
27 | * gcc.dg/unsigned-long-compare.c: New test. | ||
28 | |||
29 | Index: gcc/optabs.c | ||
30 | =================================================================== | ||
31 | --- 1/gcc/optabs.c (revision 110300) | ||
32 | +++ 2/gcc/optabs.c (working copy) | ||
33 | @@ -3711,18 +3711,24 @@ | ||
34 | result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK, | ||
35 | word_mode, 2, x, mode, y, mode); | ||
36 | |||
37 | + /* There are two kinds of comparison routines. Biased routines | ||
38 | + return 0/1/2, and unbiased routines return -1/0/1. Other parts | ||
39 | + of gcc expect that the comparison operation is equivalent | ||
40 | + to the modified comparison. For signed comparisons compare the | ||
41 | + result against 1 in the unbiased case, and zero in the biased | ||
42 | + case. For unsigned comparisons always compare against 1 after | ||
43 | + biasing the unbased result by adding 1. This gives us a way to | ||
44 | + represent LTU. */ | ||
45 | *px = result; | ||
46 | *pmode = word_mode; | ||
47 | - if (TARGET_LIB_INT_CMP_BIASED) | ||
48 | - /* Integer comparison returns a result that must be compared | ||
49 | - against 1, so that even if we do an unsigned compare | ||
50 | - afterward, there is still a value that can represent the | ||
51 | - result "less than". */ | ||
52 | - *py = const1_rtx; | ||
53 | - else | ||
54 | + *py = const1_rtx; | ||
55 | + | ||
56 | + if (!TARGET_LIB_INT_CMP_BIASED) | ||
57 | { | ||
58 | - *py = const0_rtx; | ||
59 | - *punsignedp = 1; | ||
60 | + if (*punsignedp) | ||
61 | + *px = plus_constant (result, 1); | ||
62 | + else | ||
63 | + *py = const0_rtx; | ||
64 | } | ||
65 | return; | ||
66 | } | ||
67 | Index: gcc/testsuite/gcc.dg/unsigned-long-compare.c | ||
68 | =================================================================== | ||
69 | --- 1/gcc/testsuite/gcc.dg/unsigned-long-compare.c (revision 0) | ||
70 | +++ 2/gcc/testsuite/gcc.dg/unsigned-long-compare.c (revision 0) | ||
71 | @@ -0,0 +1,24 @@ | ||
72 | +/* Copyright (C) 2006 Free Software Foundation, Inc. */ | ||
73 | +/* Contributed by Carlos O'Donell on 2006-01-27 */ | ||
74 | + | ||
75 | +/* Test a division corner case where the expression simplifies | ||
76 | + to a comparison, and the optab expansion is wrong. The optab | ||
77 | + expansion emits a function whose return is unbiased and needs | ||
78 | + adjustment. */ | ||
79 | +/* Origin: Carlos O'Donell <carlos@codesourcery.com> */ | ||
80 | +/* { dg-do run { target arm-*-*eabi* } } */ | ||
81 | +/* { dg-options "" } */ | ||
82 | +#include <stdlib.h> | ||
83 | + | ||
84 | +#define BIG_CONSTANT 0xFFFFFFFF80000000ULL | ||
85 | + | ||
86 | +int main (void) | ||
87 | +{ | ||
88 | + unsigned long long OneULL = 1ULL; | ||
89 | + unsigned long long result; | ||
90 | + | ||
91 | + result = OneULL / BIG_CONSTANT; | ||
92 | + if (result) | ||
93 | + abort (); | ||
94 | + exit (0); | ||
95 | +} | ||