1 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43440
3 --- gcc-4.4.4.orig/gcc/config/arm/aout.h
4 +++ gcc-4.4.4/gcc/config/arm/aout.h
10 - {"d0", 63}, {"q0", 63}, \
12 - {"d2", 67}, {"q1", 67}, \
14 - {"d4", 71}, {"q2", 71}, \
16 - {"d6", 75}, {"q3", 75}, \
18 - {"d8", 79}, {"q4", 79}, \
20 - {"d10", 83}, {"q5", 83}, \
22 - {"d12", 87}, {"q6", 87}, \
24 - {"d14", 91}, {"q7", 91}, \
38 +#ifndef OVERLAPPING_REGISTER_NAMES
39 +#define OVERLAPPING_REGISTER_NAMES \
77 #ifndef NO_DOLLAR_IN_LABEL
78 #define NO_DOLLAR_IN_LABEL 1
80 --- gcc-4.4.4.orig/gcc/output.h
81 +++ gcc-4.4.4/gcc/output.h
83 Prefixes such as % are optional. */
84 extern int decode_reg_name (const char *);
86 +/* Similar to decode_reg_name, but takes an extra parameter that is a
87 + pointer to the number of (internal) registers described by the
89 +extern int decode_reg_name_and_count (const char *, int *);
91 extern void assemble_alias (tree, tree);
93 extern void default_assemble_visibility (tree, int);
94 --- gcc-4.4.4.orig/gcc/reginfo.c
95 +++ gcc-4.4.4/gcc/reginfo.c
97 fix_register (const char *name, int fixed, int call_used)
102 /* Decode the name and update the primary form of
103 the register info. */
105 - if ((i = decode_reg_name (name)) >= 0)
106 + if ((reg = decode_reg_name_and_count (name, &nregs)) >= 0)
108 - if ((i == STACK_POINTER_REGNUM
109 + gcc_assert (nregs >= 1);
110 + for (i = reg; i < reg + nregs; i++)
112 + if ((i == STACK_POINTER_REGNUM
113 #ifdef HARD_FRAME_POINTER_REGNUM
114 - || i == HARD_FRAME_POINTER_REGNUM
115 + || i == HARD_FRAME_POINTER_REGNUM
117 - || i == FRAME_POINTER_REGNUM
118 + || i == FRAME_POINTER_REGNUM
121 - && (fixed == 0 || call_used == 0))
123 - static const char * const what_option[2][2] = {
124 - { "call-saved", "call-used" },
125 - { "no-such-option", "fixed" }};
127 + && (fixed == 0 || call_used == 0))
129 + static const char * const what_option[2][2] = {
130 + { "call-saved", "call-used" },
131 + { "no-such-option", "fixed" }};
133 - error ("can't use '%s' as a %s register", name,
134 - what_option[fixed][call_used]);
138 - fixed_regs[i] = fixed;
139 - call_used_regs[i] = call_used;
140 + error ("can't use '%s' as a %s register", name,
141 + what_option[fixed][call_used]);
145 + fixed_regs[i] = fixed;
146 + call_used_regs[i] = call_used;
147 #ifdef CALL_REALLY_USED_REGISTERS
149 - call_really_used_regs[i] = call_used;
151 + call_really_used_regs[i] = call_used;
162 warning (0, "unknown register name: %s", name);
164 --- gcc-4.4.4.orig/gcc/stmt.c
165 +++ gcc-4.4.4/gcc/stmt.c
166 @@ -681,13 +681,14 @@
167 for (tail = clobbers; tail; tail = TREE_CHAIN (tail))
172 if (TREE_VALUE (tail) == error_mark_node)
174 regname = TREE_STRING_POINTER (TREE_VALUE (tail));
176 - i = decode_reg_name (regname);
177 - if (i >= 0 || i == -4)
178 + i = decode_reg_name_and_count (regname, &nregs);
182 error ("unknown register name %qs in %<asm%>", regname);
183 @@ -695,14 +696,21 @@
184 /* Mark clobbered registers. */
187 - /* Clobbering the PIC register is an error. */
188 - if (i == (int) PIC_OFFSET_TABLE_REGNUM)
190 - error ("PIC register %qs clobbered in %<asm%>", regname);
195 - SET_HARD_REG_BIT (clobbered_regs, i);
196 + for (reg = i; reg < i + nregs; reg++)
200 + /* Clobbering the PIC register is an error. */
201 + if (reg == (int) PIC_OFFSET_TABLE_REGNUM)
203 + error ("PIC register clobbered by %qs in %<asm%>", regname);
207 + SET_HARD_REG_BIT (clobbered_regs, reg);
212 @@ -1012,8 +1020,9 @@
213 for (tail = clobbers; tail; tail = TREE_CHAIN (tail))
215 const char *regname = TREE_STRING_POINTER (TREE_VALUE (tail));
216 - int j = decode_reg_name (regname);
219 + int j = decode_reg_name_and_count (regname, &nregs);
224 @@ -1033,31 +1042,40 @@
225 /* Ignore unknown register, error already signaled. */
229 - /* Use QImode since that's guaranteed to clobber just one reg. */
230 - clobbered_reg = gen_rtx_REG (QImode, j);
232 - /* Do sanity check for overlap between clobbers and respectively
233 - input and outputs that hasn't been handled. Such overlap
234 - should have been detected and reported above. */
235 - if (!clobber_conflict_found)
239 - /* We test the old body (obody) contents to avoid tripping
240 - over the under-construction body. */
241 - for (opno = 0; opno < noutputs; opno++)
242 - if (reg_overlap_mentioned_p (clobbered_reg, output_rtx[opno]))
243 - internal_error ("asm clobber conflict with output operand");
245 - for (opno = 0; opno < ninputs - ninout; opno++)
246 - if (reg_overlap_mentioned_p (clobbered_reg,
247 - ASM_OPERANDS_INPUT (obody, opno)))
248 - internal_error ("asm clobber conflict with input operand");
250 + for (reg = j; reg < j + nregs; reg++)
252 + /* Use QImode since that's guaranteed to clobber just
254 + clobbered_reg = gen_rtx_REG (QImode, reg);
256 + /* Do sanity check for overlap between clobbers and
257 + respectively input and outputs that hasn't been
258 + handled. Such overlap should have been detected and
260 + if (!clobber_conflict_found)
264 + /* We test the old body (obody) contents to avoid
265 + tripping over the under-construction body. */
266 + for (opno = 0; opno < noutputs; opno++)
267 + if (reg_overlap_mentioned_p (clobbered_reg,
270 + ("asm clobber conflict with output operand");
272 + for (opno = 0; opno < ninputs - ninout; opno++)
273 + if (reg_overlap_mentioned_p (clobbered_reg,
274 + ASM_OPERANDS_INPUT (obody,
277 + ("asm clobber conflict with input operand");
280 + XVECEXP (body, 0, i++)
281 + = gen_rtx_CLOBBER (VOIDmode, clobbered_reg);
284 - XVECEXP (body, 0, i++)
285 - = gen_rtx_CLOBBER (VOIDmode, clobbered_reg);
289 --- gcc-4.4.4.orig/gcc/varasm.c
290 +++ gcc-4.4.4/gcc/varasm.c
291 @@ -1031,8 +1031,11 @@
292 Prefixes such as % are optional. */
295 -decode_reg_name (const char *asmspec)
296 +decode_reg_name_and_count (const char *asmspec, int *pnregs)
298 + /* Presume just one register is clobbered. */
304 @@ -1058,6 +1061,25 @@
305 && ! strcmp (asmspec, strip_reg_name (reg_names[i])))
308 +#ifdef OVERLAPPING_REGISTER_NAMES
310 + static const struct
312 + const char *const name;
315 + } table[] = OVERLAPPING_REGISTER_NAMES;
317 + for (i = 0; i < (int) ARRAY_SIZE (table); i++)
318 + if (table[i].name[0]
319 + && ! strcmp (asmspec, table[i].name))
321 + *pnregs = table[i].nregs;
322 + return table[i].number;
325 +#endif /* OVERLAPPING_REGISTER_NAMES */
327 #ifdef ADDITIONAL_REGISTER_NAMES
329 static const struct { const char *const name; const int number; } table[]
330 @@ -1081,6 +1103,15 @@
336 +decode_reg_name (const char *name)
339 + return decode_reg_name_and_count (name, &count);
344 /* Return true if DECL's initializer is suitable for a BSS section. */