yann@1
|
1 |
See http://gcc.gnu.org/PR16201
|
yann@1
|
2 |
|
yann@1
|
3 |
Should fix "bad immediate value for offset" errors for several flavors of arm, e.g.
|
yann@1
|
4 |
|
yann@1
|
5 |
/tmp/ccmdoQyg.s: Assembler messages:
|
yann@1
|
6 |
/tmp/ccmdoQyg.s:6235: Error: bad immediate value for offset (4096)
|
yann@1
|
7 |
make[2]: *** [crosstool-0.32/build/arm-xscale-linux-gnu/gcc-3.4.3-glibc-2.3.3/build-glibc/locale/ld-collate.o] Error 1
|
yann@1
|
8 |
|
yann@1
|
9 |
/tmp/cc0c7qop.s: Assembler messages:
|
yann@1
|
10 |
/tmp/cc0c7qop.s:6234: Error: bad immediate value for offset (4104)
|
yann@1
|
11 |
make[2]: *** [crosstool-0.32/build/armv5b-softfloat-linux/gcc-3.4.3-glibc-2.3.3/build-glibc/locale/ld-collate.o] Error 1
|
yann@1
|
12 |
|
yann@1
|
13 |
|
yann@1
|
14 |
CVSROOT: /cvs/gcc
|
yann@1
|
15 |
Module name: gcc
|
yann@1
|
16 |
Branch: gcc-3_4-branch
|
yann@1
|
17 |
Changes by: rearnsha@gcc.gnu.org 2005-02-01 15:07:05
|
yann@1
|
18 |
|
yann@1
|
19 |
Modified files:
|
yann@1
|
20 |
gcc : ChangeLog
|
yann@1
|
21 |
gcc/config/arm : arm-protos.h arm.c
|
yann@1
|
22 |
|
yann@1
|
23 |
Log message:
|
yann@1
|
24 |
PR target/16201
|
yann@1
|
25 |
* arm.c (arm_eliminable_register): New function.
|
yann@1
|
26 |
(adjacent_mem_locations): Don't allow eliminable registers. Use
|
yann@1
|
27 |
HOST_WIDE_INT for address offsets.
|
yann@1
|
28 |
* arm-protos.h (arm_eliminable_register): Add prototype.
|
yann@1
|
29 |
|
yann@1
|
30 |
Patches:
|
yann@1
|
31 |
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=2.2326.2.790&r2=2.2326.2.791
|
yann@1
|
32 |
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/arm/arm-protos.h.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.61&r2=1.61.4.1
|
yann@1
|
33 |
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/config/arm/arm.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.317.4.8&r2=1.317.4.9
|
yann@1
|
34 |
|
yann@1
|
35 |
===================================================================
|
yann@1
|
36 |
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm-protos.h,v
|
yann@1
|
37 |
retrieving revision 1.61
|
yann@1
|
38 |
retrieving revision 1.61.4.1
|
yann@1
|
39 |
diff -u -r1.61 -r1.61.4.1
|
yann@1
|
40 |
--- gcc/gcc/config/arm/arm-protos.h 2003/11/20 11:44:18 1.61
|
yann@1
|
41 |
+++ gcc/gcc/config/arm/arm-protos.h 2005/02/01 15:07:02 1.61.4.1
|
yann@1
|
42 |
@@ -1,5 +1,6 @@
|
yann@1
|
43 |
/* Prototypes for exported functions defined in arm.c and pe.c
|
yann@1
|
44 |
- Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
yann@1
|
45 |
+ Copyright (C) 1999, 2000, 2001, 2002, 2003, 2005
|
yann@1
|
46 |
+ Free Software Foundation, Inc.
|
yann@1
|
47 |
Contributed by Richard Earnshaw (rearnsha@arm.com)
|
yann@1
|
48 |
Minor hacks by Nick Clifton (nickc@cygnus.com)
|
yann@1
|
49 |
|
yann@1
|
50 |
@@ -138,6 +139,7 @@
|
yann@1
|
51 |
extern int arm_is_longcall_p (rtx, int, int);
|
yann@1
|
52 |
extern int arm_emit_vector_const (FILE *, rtx);
|
yann@1
|
53 |
extern const char * arm_output_load_gr (rtx *);
|
yann@1
|
54 |
+extern int arm_eliminable_register (rtx);
|
yann@1
|
55 |
|
yann@1
|
56 |
#if defined TREE_CODE
|
yann@1
|
57 |
extern rtx arm_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree, int);
|
yann@1
|
58 |
===================================================================
|
yann@1
|
59 |
RCS file: /cvs/gcc/gcc/gcc/config/arm/arm.c,v
|
yann@1
|
60 |
retrieving revision 1.317.4.8
|
yann@1
|
61 |
retrieving revision 1.317.4.9
|
yann@1
|
62 |
diff -u -r1.317.4.8 -r1.317.4.9
|
yann@1
|
63 |
--- gcc/gcc/config/arm/arm.c 2004/04/29 19:52:41 1.317.4.8
|
yann@1
|
64 |
+++ gcc/gcc/config/arm/arm.c 2005/02/01 15:07:02 1.317.4.9
|
yann@1
|
65 |
@@ -1,6 +1,6 @@
|
yann@1
|
66 |
/* Output routines for GCC for ARM.
|
yann@1
|
67 |
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
yann@1
|
68 |
- 2002, 2003, 2004 Free Software Foundation, Inc.
|
yann@1
|
69 |
+ 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
yann@1
|
70 |
Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
|
yann@1
|
71 |
and Martin Simmons (@harleqn.co.uk).
|
yann@1
|
72 |
More major hacks by Richard Earnshaw (rearnsha@arm.com).
|
yann@1
|
73 |
@@ -4056,6 +4056,16 @@
|
yann@1
|
74 |
&& INTVAL (op) < 64);
|
yann@1
|
75 |
}
|
yann@1
|
76 |
|
yann@1
|
77 |
+/* Return true if X is a register that will be eliminated later on. */
|
yann@1
|
78 |
+int
|
yann@1
|
79 |
+arm_eliminable_register (rtx x)
|
yann@1
|
80 |
+{
|
yann@1
|
81 |
+ return REG_P (x) && (REGNO (x) == FRAME_POINTER_REGNUM
|
yann@1
|
82 |
+ || REGNO (x) == ARG_POINTER_REGNUM
|
yann@1
|
83 |
+ || (REGNO (x) >= FIRST_VIRTUAL_REGISTER
|
yann@1
|
84 |
+ && REGNO (x) <= LAST_VIRTUAL_REGISTER));
|
yann@1
|
85 |
+}
|
yann@1
|
86 |
+
|
yann@1
|
87 |
/* Returns TRUE if INSN is an "LDR REG, ADDR" instruction.
|
yann@1
|
88 |
Use by the Cirrus Maverick code which has to workaround
|
yann@1
|
89 |
a hardware bug triggered by such instructions. */
|
yann@1
|
90 |
@@ -4569,33 +4579,42 @@
|
yann@1
|
91 |
|| (GET_CODE (XEXP (b, 0)) == PLUS
|
yann@1
|
92 |
&& GET_CODE (XEXP (XEXP (b, 0), 1)) == CONST_INT)))
|
yann@1
|
93 |
{
|
yann@1
|
94 |
- int val0 = 0, val1 = 0;
|
yann@1
|
95 |
- int reg0, reg1;
|
yann@1
|
96 |
-
|
yann@1
|
97 |
+ HOST_WIDE_INT val0 = 0, val1 = 0;
|
yann@1
|
98 |
+ rtx reg0, reg1;
|
yann@1
|
99 |
+ int val_diff;
|
yann@1
|
100 |
+
|
yann@1
|
101 |
if (GET_CODE (XEXP (a, 0)) == PLUS)
|
yann@1
|
102 |
{
|
yann@1
|
103 |
- reg0 = REGNO (XEXP (XEXP (a, 0), 0));
|
yann@1
|
104 |
+ reg0 = XEXP (XEXP (a, 0), 0);
|
yann@1
|
105 |
val0 = INTVAL (XEXP (XEXP (a, 0), 1));
|
yann@1
|
106 |
}
|
yann@1
|
107 |
else
|
yann@1
|
108 |
- reg0 = REGNO (XEXP (a, 0));
|
yann@1
|
109 |
+ reg0 = XEXP (a, 0);
|
yann@1
|
110 |
|
yann@1
|
111 |
if (GET_CODE (XEXP (b, 0)) == PLUS)
|
yann@1
|
112 |
{
|
yann@1
|
113 |
- reg1 = REGNO (XEXP (XEXP (b, 0), 0));
|
yann@1
|
114 |
+ reg1 = XEXP (XEXP (b, 0), 0);
|
yann@1
|
115 |
val1 = INTVAL (XEXP (XEXP (b, 0), 1));
|
yann@1
|
116 |
}
|
yann@1
|
117 |
else
|
yann@1
|
118 |
- reg1 = REGNO (XEXP (b, 0));
|
yann@1
|
119 |
+ reg1 = XEXP (b, 0);
|
yann@1
|
120 |
|
yann@1
|
121 |
/* Don't accept any offset that will require multiple
|
yann@1
|
122 |
instructions to handle, since this would cause the
|
yann@1
|
123 |
arith_adjacentmem pattern to output an overlong sequence. */
|
yann@1
|
124 |
if (!const_ok_for_op (PLUS, val0) || !const_ok_for_op (PLUS, val1))
|
yann@1
|
125 |
return 0;
|
yann@1
|
126 |
-
|
yann@1
|
127 |
- return (reg0 == reg1) && ((val1 - val0) == 4 || (val0 - val1) == 4);
|
yann@1
|
128 |
+
|
yann@1
|
129 |
+ /* Don't allow an eliminable register: register elimination can make
|
yann@1
|
130 |
+ the offset too large. */
|
yann@1
|
131 |
+ if (arm_eliminable_register (reg0))
|
yann@1
|
132 |
+ return 0;
|
yann@1
|
133 |
+
|
yann@1
|
134 |
+ val_diff = val1 - val0;
|
yann@1
|
135 |
+ return ((REGNO (reg0) == REGNO (reg1))
|
yann@1
|
136 |
+ && (val_diff == 4 || val_diff == -4));
|
yann@1
|
137 |
}
|
yann@1
|
138 |
+
|
yann@1
|
139 |
return 0;
|
yann@1
|
140 |
}
|
yann@1
|
141 |
|
yann@1
|
142 |
@@ -7301,7 +7320,6 @@
|
yann@1
|
143 |
return "";
|
yann@1
|
144 |
}
|
yann@1
|
145 |
|
yann@1
|
146 |
-
|
yann@1
|
147 |
/* Output a move from arm registers to an fpa registers.
|
yann@1
|
148 |
OPERANDS[0] is an fpa register.
|
yann@1
|
149 |
OPERANDS[1] is the first registers of an arm register pair. */
|