diff options
Diffstat (limited to 'recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99354.patch')
| -rw-r--r-- | recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99354.patch | 384 |
1 files changed, 384 insertions, 0 deletions
diff --git a/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99354.patch b/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99354.patch new file mode 100644 index 0000000000..743e2751c7 --- /dev/null +++ b/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99354.patch | |||
| @@ -0,0 +1,384 @@ | |||
| 1 | Richard Earnshaw <rearnsha@arm.com> | ||
| 2 | |||
| 3 | gcc/ | ||
| 4 | * doc/tm.texi (OVERLAPPING_REGISTER_NAMES): Document new macro. | ||
| 5 | * output.h (decode_reg_name_and_count): Declare. | ||
| 6 | * varasm.c (decode_reg_name_and_count): New function. | ||
| 7 | (decode_reg_name): Reimplement using decode_reg_name_and_count. | ||
| 8 | * reginfo.c (fix_register): Use decode_reg_name_and_count and | ||
| 9 | iterate over all regs used. | ||
| 10 | * stmt.c (expand_asm_operands): Likewise. | ||
| 11 | * config/arm/aout.h (OVERLAPPING_REGISTER_NAMES): Define. | ||
| 12 | (ADDITIONAL_REGISTER_NAMES): Remove aliases that overlap | ||
| 13 | multiple machine registers. | ||
| 14 | |||
| 15 | 2010-07-26 Julian Brown <julian@codesourcery.com> | ||
| 16 | |||
| 17 | Merge from Sourcery G++ 4.4: | ||
| 18 | |||
| 19 | 2010-04-08 Bernd Schmidt <bernds@codesourcery.com> | ||
| 20 | |||
| 21 | Issue #6952 | ||
| 22 | |||
| 23 | === modified file 'gcc/config/arm/aout.h' | ||
| 24 | --- old/gcc/config/arm/aout.h 2009-06-21 19:48:15 +0000 | ||
| 25 | +++ new/gcc/config/arm/aout.h 2010-08-13 11:53:46 +0000 | ||
| 26 | @@ -163,31 +163,45 @@ | ||
| 27 | {"mvdx12", 39}, \ | ||
| 28 | {"mvdx13", 40}, \ | ||
| 29 | {"mvdx14", 41}, \ | ||
| 30 | - {"mvdx15", 42}, \ | ||
| 31 | - {"d0", 63}, {"q0", 63}, \ | ||
| 32 | - {"d1", 65}, \ | ||
| 33 | - {"d2", 67}, {"q1", 67}, \ | ||
| 34 | - {"d3", 69}, \ | ||
| 35 | - {"d4", 71}, {"q2", 71}, \ | ||
| 36 | - {"d5", 73}, \ | ||
| 37 | - {"d6", 75}, {"q3", 75}, \ | ||
| 38 | - {"d7", 77}, \ | ||
| 39 | - {"d8", 79}, {"q4", 79}, \ | ||
| 40 | - {"d9", 81}, \ | ||
| 41 | - {"d10", 83}, {"q5", 83}, \ | ||
| 42 | - {"d11", 85}, \ | ||
| 43 | - {"d12", 87}, {"q6", 87}, \ | ||
| 44 | - {"d13", 89}, \ | ||
| 45 | - {"d14", 91}, {"q7", 91}, \ | ||
| 46 | - {"d15", 93}, \ | ||
| 47 | - {"q8", 95}, \ | ||
| 48 | - {"q9", 99}, \ | ||
| 49 | - {"q10", 103}, \ | ||
| 50 | - {"q11", 107}, \ | ||
| 51 | - {"q12", 111}, \ | ||
| 52 | - {"q13", 115}, \ | ||
| 53 | - {"q14", 119}, \ | ||
| 54 | - {"q15", 123} \ | ||
| 55 | + {"mvdx15", 42} \ | ||
| 56 | +} | ||
| 57 | +#endif | ||
| 58 | + | ||
| 59 | +#ifndef OVERLAPPING_REGISTER_NAMES | ||
| 60 | +#define OVERLAPPING_REGISTER_NAMES \ | ||
| 61 | +{ \ | ||
| 62 | + {"d0", 63, 2}, \ | ||
| 63 | + {"d1", 65, 2}, \ | ||
| 64 | + {"d2", 67, 2}, \ | ||
| 65 | + {"d3", 69, 2}, \ | ||
| 66 | + {"d4", 71, 2}, \ | ||
| 67 | + {"d5", 73, 2}, \ | ||
| 68 | + {"d6", 75, 2}, \ | ||
| 69 | + {"d7", 77, 2}, \ | ||
| 70 | + {"d8", 79, 2}, \ | ||
| 71 | + {"d9", 81, 2}, \ | ||
| 72 | + {"d10", 83, 2}, \ | ||
| 73 | + {"d11", 85, 2}, \ | ||
| 74 | + {"d12", 87, 2}, \ | ||
| 75 | + {"d13", 89, 2}, \ | ||
| 76 | + {"d14", 91, 2}, \ | ||
| 77 | + {"d15", 93, 2}, \ | ||
| 78 | + {"q0", 63, 4}, \ | ||
| 79 | + {"q1", 67, 4}, \ | ||
| 80 | + {"q2", 71, 4}, \ | ||
| 81 | + {"q3", 75, 4}, \ | ||
| 82 | + {"q4", 79, 4}, \ | ||
| 83 | + {"q5", 83, 4}, \ | ||
| 84 | + {"q6", 87, 4}, \ | ||
| 85 | + {"q7", 91, 4}, \ | ||
| 86 | + {"q8", 95, 4}, \ | ||
| 87 | + {"q9", 99, 4}, \ | ||
| 88 | + {"q10", 103, 4}, \ | ||
| 89 | + {"q11", 107, 4}, \ | ||
| 90 | + {"q12", 111, 4}, \ | ||
| 91 | + {"q13", 115, 4}, \ | ||
| 92 | + {"q14", 119, 4}, \ | ||
| 93 | + {"q15", 123, 4} \ | ||
| 94 | } | ||
| 95 | #endif | ||
| 96 | |||
| 97 | |||
| 98 | === modified file 'gcc/doc/tm.texi' | ||
| 99 | --- old/gcc/doc/tm.texi 2010-06-24 20:06:37 +0000 | ||
| 100 | +++ new/gcc/doc/tm.texi 2010-08-13 11:53:46 +0000 | ||
| 101 | @@ -8339,6 +8339,22 @@ | ||
| 102 | to registers using alternate names. | ||
| 103 | @end defmac | ||
| 104 | |||
| 105 | +@defmac OVERLAPPING_REGISTER_NAMES | ||
| 106 | +If defined, a C initializer for an array of structures containing a | ||
| 107 | +name, a register number and a count of the number of consecutive | ||
| 108 | +machine registers the name overlaps. This macro defines additional | ||
| 109 | +names for hard registers, thus allowing the @code{asm} option in | ||
| 110 | +declarations to refer to registers using alternate names. Unlike | ||
| 111 | +@code{ADDITIONAL_REGISTER_NAMES}, this macro should be used when the | ||
| 112 | +register name implies multiple underlying registers. | ||
| 113 | + | ||
| 114 | +This macro should be used when it is important that a clobber in an | ||
| 115 | +@code{asm} statement clobbers all the underlying values implied by the | ||
| 116 | +register name. For example, on ARM, clobbering the double-precision | ||
| 117 | +VFP register ``d0'' implies clobbering both single-precision registers | ||
| 118 | +``s0'' and ``s1''. | ||
| 119 | +@end defmac | ||
| 120 | + | ||
| 121 | @defmac ASM_OUTPUT_OPCODE (@var{stream}, @var{ptr}) | ||
| 122 | Define this macro if you are using an unusual assembler that | ||
| 123 | requires different names for the machine instructions. | ||
| 124 | |||
| 125 | === modified file 'gcc/output.h' | ||
| 126 | --- old/gcc/output.h 2009-10-26 21:57:10 +0000 | ||
| 127 | +++ new/gcc/output.h 2010-08-13 11:53:46 +0000 | ||
| 128 | @@ -173,6 +173,11 @@ | ||
| 129 | Prefixes such as % are optional. */ | ||
| 130 | extern int decode_reg_name (const char *); | ||
| 131 | |||
| 132 | +/* Similar to decode_reg_name, but takes an extra parameter that is a | ||
| 133 | + pointer to the number of (internal) registers described by the | ||
| 134 | + external name. */ | ||
| 135 | +extern int decode_reg_name_and_count (const char *, int *); | ||
| 136 | + | ||
| 137 | extern void assemble_alias (tree, tree); | ||
| 138 | |||
| 139 | extern void default_assemble_visibility (tree, int); | ||
| 140 | |||
| 141 | === modified file 'gcc/reginfo.c' | ||
| 142 | --- old/gcc/reginfo.c 2010-04-19 09:04:43 +0000 | ||
| 143 | +++ new/gcc/reginfo.c 2010-08-13 11:53:46 +0000 | ||
| 144 | @@ -799,36 +799,41 @@ | ||
| 145 | fix_register (const char *name, int fixed, int call_used) | ||
| 146 | { | ||
| 147 | int i; | ||
| 148 | + int reg, nregs; | ||
| 149 | |||
| 150 | /* Decode the name and update the primary form of | ||
| 151 | the register info. */ | ||
| 152 | |||
| 153 | - if ((i = decode_reg_name (name)) >= 0) | ||
| 154 | + if ((reg = decode_reg_name_and_count (name, &nregs)) >= 0) | ||
| 155 | { | ||
| 156 | - if ((i == STACK_POINTER_REGNUM | ||
| 157 | + gcc_assert (nregs >= 1); | ||
| 158 | + for (i = reg; i < reg + nregs; i++) | ||
| 159 | + { | ||
| 160 | + if ((i == STACK_POINTER_REGNUM | ||
| 161 | #ifdef HARD_FRAME_POINTER_REGNUM | ||
| 162 | - || i == HARD_FRAME_POINTER_REGNUM | ||
| 163 | + || i == HARD_FRAME_POINTER_REGNUM | ||
| 164 | #else | ||
| 165 | - || i == FRAME_POINTER_REGNUM | ||
| 166 | + || i == FRAME_POINTER_REGNUM | ||
| 167 | #endif | ||
| 168 | - ) | ||
| 169 | - && (fixed == 0 || call_used == 0)) | ||
| 170 | - { | ||
| 171 | - static const char * const what_option[2][2] = { | ||
| 172 | - { "call-saved", "call-used" }, | ||
| 173 | - { "no-such-option", "fixed" }}; | ||
| 174 | + ) | ||
| 175 | + && (fixed == 0 || call_used == 0)) | ||
| 176 | + { | ||
| 177 | + static const char * const what_option[2][2] = { | ||
| 178 | + { "call-saved", "call-used" }, | ||
| 179 | + { "no-such-option", "fixed" }}; | ||
| 180 | |||
| 181 | - error ("can't use '%s' as a %s register", name, | ||
| 182 | - what_option[fixed][call_used]); | ||
| 183 | - } | ||
| 184 | - else | ||
| 185 | - { | ||
| 186 | - fixed_regs[i] = fixed; | ||
| 187 | - call_used_regs[i] = call_used; | ||
| 188 | + error ("can't use '%s' as a %s register", name, | ||
| 189 | + what_option[fixed][call_used]); | ||
| 190 | + } | ||
| 191 | + else | ||
| 192 | + { | ||
| 193 | + fixed_regs[i] = fixed; | ||
| 194 | + call_used_regs[i] = call_used; | ||
| 195 | #ifdef CALL_REALLY_USED_REGISTERS | ||
| 196 | - if (fixed == 0) | ||
| 197 | - call_really_used_regs[i] = call_used; | ||
| 198 | + if (fixed == 0) | ||
| 199 | + call_really_used_regs[i] = call_used; | ||
| 200 | #endif | ||
| 201 | + } | ||
| 202 | } | ||
| 203 | } | ||
| 204 | else | ||
| 205 | |||
| 206 | === modified file 'gcc/stmt.c' | ||
| 207 | --- old/gcc/stmt.c 2010-02-19 09:53:51 +0000 | ||
| 208 | +++ new/gcc/stmt.c 2010-08-13 11:53:46 +0000 | ||
| 209 | @@ -684,13 +684,14 @@ | ||
| 210 | for (tail = clobbers; tail; tail = TREE_CHAIN (tail)) | ||
| 211 | { | ||
| 212 | const char *regname; | ||
| 213 | + int nregs; | ||
| 214 | |||
| 215 | if (TREE_VALUE (tail) == error_mark_node) | ||
| 216 | return; | ||
| 217 | regname = TREE_STRING_POINTER (TREE_VALUE (tail)); | ||
| 218 | |||
| 219 | - i = decode_reg_name (regname); | ||
| 220 | - if (i >= 0 || i == -4) | ||
| 221 | + i = decode_reg_name_and_count (regname, &nregs); | ||
| 222 | + if (i == -4) | ||
| 223 | ++nclobbers; | ||
| 224 | else if (i == -2) | ||
| 225 | error ("unknown register name %qs in %<asm%>", regname); | ||
| 226 | @@ -698,14 +699,21 @@ | ||
| 227 | /* Mark clobbered registers. */ | ||
| 228 | if (i >= 0) | ||
| 229 | { | ||
| 230 | - /* Clobbering the PIC register is an error. */ | ||
| 231 | - if (i == (int) PIC_OFFSET_TABLE_REGNUM) | ||
| 232 | + int reg; | ||
| 233 | + | ||
| 234 | + for (reg = i; reg < i + nregs; reg++) | ||
| 235 | { | ||
| 236 | - error ("PIC register %qs clobbered in %<asm%>", regname); | ||
| 237 | - return; | ||
| 238 | + ++nclobbers; | ||
| 239 | + | ||
| 240 | + /* Clobbering the PIC register is an error. */ | ||
| 241 | + if (reg == (int) PIC_OFFSET_TABLE_REGNUM) | ||
| 242 | + { | ||
| 243 | + error ("PIC register clobbered by %qs in %<asm%>", regname); | ||
| 244 | + return; | ||
| 245 | + } | ||
| 246 | + | ||
| 247 | + SET_HARD_REG_BIT (clobbered_regs, reg); | ||
| 248 | } | ||
| 249 | - | ||
| 250 | - SET_HARD_REG_BIT (clobbered_regs, i); | ||
| 251 | } | ||
| 252 | } | ||
| 253 | |||
| 254 | @@ -1026,7 +1034,8 @@ | ||
| 255 | for (tail = clobbers; tail; tail = TREE_CHAIN (tail)) | ||
| 256 | { | ||
| 257 | const char *regname = TREE_STRING_POINTER (TREE_VALUE (tail)); | ||
| 258 | - int j = decode_reg_name (regname); | ||
| 259 | + int reg, nregs; | ||
| 260 | + int j = decode_reg_name_and_count (regname, &nregs); | ||
| 261 | rtx clobbered_reg; | ||
| 262 | |||
| 263 | if (j < 0) | ||
| 264 | @@ -1048,30 +1057,39 @@ | ||
| 265 | continue; | ||
| 266 | } | ||
| 267 | |||
| 268 | - /* Use QImode since that's guaranteed to clobber just one reg. */ | ||
| 269 | - clobbered_reg = gen_rtx_REG (QImode, j); | ||
| 270 | - | ||
| 271 | - /* Do sanity check for overlap between clobbers and respectively | ||
| 272 | - input and outputs that hasn't been handled. Such overlap | ||
| 273 | - should have been detected and reported above. */ | ||
| 274 | - if (!clobber_conflict_found) | ||
| 275 | + for (reg = j; reg < j + nregs; reg++) | ||
| 276 | { | ||
| 277 | - int opno; | ||
| 278 | - | ||
| 279 | - /* We test the old body (obody) contents to avoid tripping | ||
| 280 | - over the under-construction body. */ | ||
| 281 | - for (opno = 0; opno < noutputs; opno++) | ||
| 282 | - if (reg_overlap_mentioned_p (clobbered_reg, output_rtx[opno])) | ||
| 283 | - internal_error ("asm clobber conflict with output operand"); | ||
| 284 | - | ||
| 285 | - for (opno = 0; opno < ninputs - ninout; opno++) | ||
| 286 | - if (reg_overlap_mentioned_p (clobbered_reg, | ||
| 287 | - ASM_OPERANDS_INPUT (obody, opno))) | ||
| 288 | - internal_error ("asm clobber conflict with input operand"); | ||
| 289 | + /* Use QImode since that's guaranteed to clobber just | ||
| 290 | + * one reg. */ | ||
| 291 | + clobbered_reg = gen_rtx_REG (QImode, reg); | ||
| 292 | + | ||
| 293 | + /* Do sanity check for overlap between clobbers and | ||
| 294 | + respectively input and outputs that hasn't been | ||
| 295 | + handled. Such overlap should have been detected and | ||
| 296 | + reported above. */ | ||
| 297 | + if (!clobber_conflict_found) | ||
| 298 | + { | ||
| 299 | + int opno; | ||
| 300 | + | ||
| 301 | + /* We test the old body (obody) contents to avoid | ||
| 302 | + tripping over the under-construction body. */ | ||
| 303 | + for (opno = 0; opno < noutputs; opno++) | ||
| 304 | + if (reg_overlap_mentioned_p (clobbered_reg, | ||
| 305 | + output_rtx[opno])) | ||
| 306 | + internal_error | ||
| 307 | + ("asm clobber conflict with output operand"); | ||
| 308 | + | ||
| 309 | + for (opno = 0; opno < ninputs - ninout; opno++) | ||
| 310 | + if (reg_overlap_mentioned_p (clobbered_reg, | ||
| 311 | + ASM_OPERANDS_INPUT (obody, | ||
| 312 | + opno))) | ||
| 313 | + internal_error | ||
| 314 | + ("asm clobber conflict with input operand"); | ||
| 315 | + } | ||
| 316 | + | ||
| 317 | + XVECEXP (body, 0, i++) | ||
| 318 | + = gen_rtx_CLOBBER (VOIDmode, clobbered_reg); | ||
| 319 | } | ||
| 320 | - | ||
| 321 | - XVECEXP (body, 0, i++) | ||
| 322 | - = gen_rtx_CLOBBER (VOIDmode, clobbered_reg); | ||
| 323 | } | ||
| 324 | |||
| 325 | if (nlabels > 0) | ||
| 326 | |||
| 327 | === modified file 'gcc/varasm.c' | ||
| 328 | --- old/gcc/varasm.c 2010-03-27 11:56:30 +0000 | ||
| 329 | +++ new/gcc/varasm.c 2010-08-13 11:53:46 +0000 | ||
| 330 | @@ -1043,8 +1043,11 @@ | ||
| 331 | Prefixes such as % are optional. */ | ||
| 332 | |||
| 333 | int | ||
| 334 | -decode_reg_name (const char *asmspec) | ||
| 335 | +decode_reg_name_and_count (const char *asmspec, int *pnregs) | ||
| 336 | { | ||
| 337 | + /* Presume just one register is clobbered. */ | ||
| 338 | + *pnregs = 1; | ||
| 339 | + | ||
| 340 | if (asmspec != 0) | ||
| 341 | { | ||
| 342 | int i; | ||
| 343 | @@ -1070,6 +1073,25 @@ | ||
| 344 | && ! strcmp (asmspec, strip_reg_name (reg_names[i]))) | ||
| 345 | return i; | ||
| 346 | |||
| 347 | +#ifdef OVERLAPPING_REGISTER_NAMES | ||
| 348 | + { | ||
| 349 | + static const struct | ||
| 350 | + { | ||
| 351 | + const char *const name; | ||
| 352 | + const int number; | ||
| 353 | + const int nregs; | ||
| 354 | + } table[] = OVERLAPPING_REGISTER_NAMES; | ||
| 355 | + | ||
| 356 | + for (i = 0; i < (int) ARRAY_SIZE (table); i++) | ||
| 357 | + if (table[i].name[0] | ||
| 358 | + && ! strcmp (asmspec, table[i].name)) | ||
| 359 | + { | ||
| 360 | + *pnregs = table[i].nregs; | ||
| 361 | + return table[i].number; | ||
| 362 | + } | ||
| 363 | + } | ||
| 364 | +#endif /* OVERLAPPING_REGISTER_NAMES */ | ||
| 365 | + | ||
| 366 | #ifdef ADDITIONAL_REGISTER_NAMES | ||
| 367 | { | ||
| 368 | static const struct { const char *const name; const int number; } table[] | ||
| 369 | @@ -1093,6 +1115,14 @@ | ||
| 370 | |||
| 371 | return -1; | ||
| 372 | } | ||
| 373 | + | ||
| 374 | +int | ||
| 375 | +decode_reg_name (const char *name) | ||
| 376 | +{ | ||
| 377 | + int count; | ||
| 378 | + return decode_reg_name_and_count (name, &count); | ||
| 379 | +} | ||
| 380 | + | ||
| 381 | |||
| 382 | /* Return true if DECL's initializer is suitable for a BSS section. */ | ||
| 383 | |||
| 384 | |||
