summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/gcc/gcc-csl-arm/gcc_optab_arm.patch
diff options
context:
space:
mode:
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.patch95
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 @@
1ARM is the only architecture that has a helper function that returns
2an unbiased result. This fix is trivial enough that we can show it
3doesn't effect any of the other arches. Can we consider this a
4regression fix since it used to work until the helper was added :}
5
6Tested with no regressions on x86_64-pc-linux-gnu and arm-none-eabi.
7
8Cheers,
9Carlos.
10--
11Carlos O'Donell
12CodeSourcery
13carlos@codesourcery.com
14(650) 331-3385 x716
15
16gcc/
17
182006-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
23gcc/testsuite/
24
252006-01-27 Carlos O'Donell <carlos@codesourcery.com>
26
27 * gcc.dg/unsigned-long-compare.c: New test.
28
29Index: 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 }
67Index: 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+}