diff options
author | Koen Kooi <koen@dominion.thruhere.net> | 2010-12-23 14:02:13 +0100 |
---|---|---|
committer | Koen Kooi <koen@dominion.thruhere.net> | 2010-12-23 14:02:13 +0100 |
commit | 7eb7dce48ba082c30f1fceced04c275420158b9a (patch) | |
tree | d2f5b6bed38d7ffc0aad7f5c313701da4d8a8e19 /recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99424.patch | |
parent | 8bb6722b1356cc3b8494e33553240363addd2d80 (diff) | |
download | meta-openembedded-7eb7dce48ba082c30f1fceced04c275420158b9a.tar.gz |
gcc 4.5: sync with both OE and yocto
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
Diffstat (limited to 'recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99424.patch')
-rw-r--r-- | recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99424.patch | 687 |
1 files changed, 687 insertions, 0 deletions
diff --git a/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99424.patch b/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99424.patch new file mode 100644 index 0000000000..b6c6532661 --- /dev/null +++ b/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99424.patch | |||
@@ -0,0 +1,687 @@ | |||
1 | Issue #1259 | ||
2 | |||
3 | Backport from mainline: | ||
4 | |||
5 | gcc/ | ||
6 | 2010-10-22 Jie Zhang <jie@codesourcery.com> | ||
7 | |||
8 | * expr.c (emit_group_load_1): Update calls to extract_bit_field. | ||
9 | (copy_blkmode_from_reg): Likewise. | ||
10 | (read_complex_part): Likewise. | ||
11 | (expand_expr_real_1): Calculate packedp and pass it to | ||
12 | extract_bit_field. | ||
13 | * expr.h (extract_bit_field): Update declaration. | ||
14 | * calls.c (store_unaligned_arguments_into_pseudos): Update call | ||
15 | to extract_bit_field. | ||
16 | * expmed.c (extract_fixed_bit_field): Update calls to | ||
17 | extract_fixed_bit_field. | ||
18 | (store_split_bit_field): Likewise. | ||
19 | (extract_bit_field_1): Add new argument packedp. | ||
20 | (extract_bit_field): Add new argument packedp. | ||
21 | (extract_fixed_bit_field): Add new argument packedp and let | ||
22 | packed attribute override volatile. | ||
23 | * stmt.c (expand_return): Update call to extract_bit_field. | ||
24 | |||
25 | 2010-10-15 Jie Zhang <jie@codesourcery.com> | ||
26 | |||
27 | * doc/invoke.texi: Add -fstrict-volatile-bitfields to | ||
28 | Option Summary and Index. | ||
29 | |||
30 | 2010-07-13 DJ Delorie <dj@redhat.com> | ||
31 | |||
32 | * config/h8300/h8300.c (h8300_init_once): Default to | ||
33 | -fstrict_volatile_bitfields. | ||
34 | |||
35 | * config/sh/sh.c (sh_override_options): Default to | ||
36 | -fstrict_volatile_bitfields. | ||
37 | |||
38 | * config/rx/rx.c (rx_option_override): New. | ||
39 | |||
40 | * config/m32c/m32c.c (m32c_override_options): Default to | ||
41 | -fstrict_volatile_bitfields. | ||
42 | |||
43 | 2010-06-16 DJ Delorie <dj@redhat.com> | ||
44 | |||
45 | * common.opt (-fstrict-volatile-bitfields): new. | ||
46 | * doc/invoke.texi: Document it. | ||
47 | * fold-const.c (optimize_bit_field_compare): For volatile | ||
48 | bitfields, use the field's type to determine the mode, not the | ||
49 | field's size. | ||
50 | * expr.c (expand_assignment): Likewise. | ||
51 | (get_inner_reference): Likewise. | ||
52 | (expand_expr_real_1): Likewise. | ||
53 | * expmed.c (store_fixed_bit_field): Likewise. | ||
54 | (extract_bit_field_1): Likewise. | ||
55 | (extract_fixed_bit_field): Likewise. | ||
56 | |||
57 | gcc/testsuite/ | ||
58 | 2010-08-19 Uros Bizjak <ubizjak@gmail.com> | ||
59 | |||
60 | PR testsuite/45324 | ||
61 | * gcc.target/i386/volatile-bitfields-1.c: Also scan movb. | ||
62 | |||
63 | 2010-06-16 DJ Delorie <dj@redhat.com> | ||
64 | |||
65 | * gcc.target/i386/volatile-bitfields-1.c: New. | ||
66 | * gcc.target/i386/volatile-bitfields-2.c: New. | ||
67 | |||
68 | === modified file 'gcc/calls.c' | ||
69 | --- old/gcc/calls.c 2010-10-04 00:50:43 +0000 | ||
70 | +++ new/gcc/calls.c 2010-11-04 12:43:52 +0000 | ||
71 | @@ -878,7 +878,7 @@ | ||
72 | int bitsize = MIN (bytes * BITS_PER_UNIT, BITS_PER_WORD); | ||
73 | |||
74 | args[i].aligned_regs[j] = reg; | ||
75 | - word = extract_bit_field (word, bitsize, 0, 1, NULL_RTX, | ||
76 | + word = extract_bit_field (word, bitsize, 0, 1, false, NULL_RTX, | ||
77 | word_mode, word_mode); | ||
78 | |||
79 | /* There is no need to restrict this code to loading items | ||
80 | |||
81 | === modified file 'gcc/common.opt' | ||
82 | --- old/gcc/common.opt 2010-07-29 14:59:35 +0000 | ||
83 | +++ new/gcc/common.opt 2010-11-04 12:43:52 +0000 | ||
84 | @@ -613,6 +613,10 @@ | ||
85 | Common Report Var(flag_loop_block) Optimization | ||
86 | Enable Loop Blocking transformation | ||
87 | |||
88 | +fstrict-volatile-bitfields | ||
89 | +Common Report Var(flag_strict_volatile_bitfields) Init(-1) | ||
90 | +Force bitfield accesses to match their type width | ||
91 | + | ||
92 | fguess-branch-probability | ||
93 | Common Report Var(flag_guess_branch_prob) Optimization | ||
94 | Enable guessing of branch probabilities | ||
95 | |||
96 | === modified file 'gcc/config/h8300/h8300.c' | ||
97 | --- old/gcc/config/h8300/h8300.c 2010-04-02 18:54:46 +0000 | ||
98 | +++ new/gcc/config/h8300/h8300.c 2010-11-04 12:43:52 +0000 | ||
99 | @@ -403,6 +403,10 @@ | ||
100 | restore er6 though, so bump up the cost. */ | ||
101 | h8300_move_ratio = 6; | ||
102 | } | ||
103 | + | ||
104 | + /* This target defaults to strict volatile bitfields. */ | ||
105 | + if (flag_strict_volatile_bitfields < 0) | ||
106 | + flag_strict_volatile_bitfields = 1; | ||
107 | } | ||
108 | |||
109 | /* Implement REG_CLASS_FROM_LETTER. | ||
110 | |||
111 | === modified file 'gcc/config/m32c/m32c.c' | ||
112 | --- old/gcc/config/m32c/m32c.c 2009-10-22 18:46:26 +0000 | ||
113 | +++ new/gcc/config/m32c/m32c.c 2010-11-04 12:43:52 +0000 | ||
114 | @@ -428,6 +428,10 @@ | ||
115 | |||
116 | if (TARGET_A24) | ||
117 | flag_ivopts = 0; | ||
118 | + | ||
119 | + /* This target defaults to strict volatile bitfields. */ | ||
120 | + if (flag_strict_volatile_bitfields < 0) | ||
121 | + flag_strict_volatile_bitfields = 1; | ||
122 | } | ||
123 | |||
124 | /* Defining data structures for per-function information */ | ||
125 | |||
126 | === modified file 'gcc/config/rx/rx.c' | ||
127 | --- old/gcc/config/rx/rx.c 2010-07-27 14:39:53 +0000 | ||
128 | +++ new/gcc/config/rx/rx.c 2010-11-04 12:43:52 +0000 | ||
129 | @@ -2187,6 +2187,14 @@ | ||
130 | } | ||
131 | } | ||
132 | |||
133 | +static void | ||
134 | +rx_option_override (void) | ||
135 | +{ | ||
136 | + /* This target defaults to strict volatile bitfields. */ | ||
137 | + if (flag_strict_volatile_bitfields < 0) | ||
138 | + flag_strict_volatile_bitfields = 1; | ||
139 | +} | ||
140 | + | ||
141 | |||
142 | static bool | ||
143 | rx_allocate_stack_slots_for_args (void) | ||
144 | @@ -2759,6 +2767,9 @@ | ||
145 | #undef TARGET_CC_MODES_COMPATIBLE | ||
146 | #define TARGET_CC_MODES_COMPATIBLE rx_cc_modes_compatible | ||
147 | |||
148 | +#undef TARGET_OPTION_OVERRIDE | ||
149 | +#define TARGET_OPTION_OVERRIDE rx_option_override | ||
150 | + | ||
151 | struct gcc_target targetm = TARGET_INITIALIZER; | ||
152 | |||
153 | /* #include "gt-rx.h" */ | ||
154 | |||
155 | === modified file 'gcc/config/sh/sh.c' | ||
156 | --- old/gcc/config/sh/sh.c 2010-05-05 21:12:17 +0000 | ||
157 | +++ new/gcc/config/sh/sh.c 2010-11-04 12:43:52 +0000 | ||
158 | @@ -950,6 +950,10 @@ | ||
159 | |||
160 | if (sh_fixed_range_str) | ||
161 | sh_fix_range (sh_fixed_range_str); | ||
162 | + | ||
163 | + /* This target defaults to strict volatile bitfields. */ | ||
164 | + if (flag_strict_volatile_bitfields < 0) | ||
165 | + flag_strict_volatile_bitfields = 1; | ||
166 | } | ||
167 | |||
168 | /* Print the operand address in x to the stream. */ | ||
169 | |||
170 | === modified file 'gcc/doc/invoke.texi' | ||
171 | --- old/gcc/doc/invoke.texi 2010-10-04 00:50:43 +0000 | ||
172 | +++ new/gcc/doc/invoke.texi 2010-11-04 12:43:52 +0000 | ||
173 | @@ -922,7 +922,7 @@ | ||
174 | -fargument-noalias-global -fargument-noalias-anything @gol | ||
175 | -fleading-underscore -ftls-model=@var{model} @gol | ||
176 | -ftrapv -fwrapv -fbounds-check @gol | ||
177 | --fvisibility} | ||
178 | +-fvisibility -fstrict-volatile-bitfields} | ||
179 | @end table | ||
180 | |||
181 | @menu | ||
182 | @@ -17629,6 +17629,33 @@ | ||
183 | An overview of these techniques, their benefits and how to use them | ||
184 | is at @w{@uref{http://gcc.gnu.org/wiki/Visibility}}. | ||
185 | |||
186 | +@item -fstrict-volatile-bitfields | ||
187 | +@opindex fstrict-volatile-bitfields | ||
188 | +This option should be used if accesses to volatile bitfields (or other | ||
189 | +structure fields, although the compiler usually honors those types | ||
190 | +anyway) should use a single access in a mode of the same size as the | ||
191 | +container's type, aligned to a natural alignment if possible. For | ||
192 | +example, targets with memory-mapped peripheral registers might require | ||
193 | +all such accesses to be 16 bits wide; with this flag the user could | ||
194 | +declare all peripheral bitfields as ``unsigned short'' (assuming short | ||
195 | +is 16 bits on these targets) to force GCC to use 16 bit accesses | ||
196 | +instead of, perhaps, a more efficient 32 bit access. | ||
197 | + | ||
198 | +If this option is disabled, the compiler will use the most efficient | ||
199 | +instruction. In the previous example, that might be a 32-bit load | ||
200 | +instruction, even though that will access bytes that do not contain | ||
201 | +any portion of the bitfield, or memory-mapped registers unrelated to | ||
202 | +the one being updated. | ||
203 | + | ||
204 | +If the target requires strict alignment, and honoring the container | ||
205 | +type would require violating this alignment, a warning is issued. | ||
206 | +However, the access happens as the user requested, under the | ||
207 | +assumption that the user knows something about the target hardware | ||
208 | +that GCC is unaware of. | ||
209 | + | ||
210 | +The default value of this option is determined by the application binary | ||
211 | +interface for the target processor. | ||
212 | + | ||
213 | @end table | ||
214 | |||
215 | @c man end | ||
216 | |||
217 | === modified file 'gcc/expmed.c' | ||
218 | --- old/gcc/expmed.c 2010-10-04 00:50:43 +0000 | ||
219 | +++ new/gcc/expmed.c 2010-11-04 12:43:52 +0000 | ||
220 | @@ -47,7 +47,7 @@ | ||
221 | static rtx extract_fixed_bit_field (enum machine_mode, rtx, | ||
222 | unsigned HOST_WIDE_INT, | ||
223 | unsigned HOST_WIDE_INT, | ||
224 | - unsigned HOST_WIDE_INT, rtx, int); | ||
225 | + unsigned HOST_WIDE_INT, rtx, int, bool); | ||
226 | static rtx mask_rtx (enum machine_mode, int, int, int); | ||
227 | static rtx lshift_value (enum machine_mode, rtx, int, int); | ||
228 | static rtx extract_split_bit_field (rtx, unsigned HOST_WIDE_INT, | ||
229 | @@ -904,8 +904,14 @@ | ||
230 | if (GET_MODE_BITSIZE (mode) == 0 | ||
231 | || GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (word_mode)) | ||
232 | mode = word_mode; | ||
233 | - mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT, | ||
234 | - MEM_ALIGN (op0), mode, MEM_VOLATILE_P (op0)); | ||
235 | + | ||
236 | + if (MEM_VOLATILE_P (op0) | ||
237 | + && GET_MODE_BITSIZE (GET_MODE (op0)) > 0 | ||
238 | + && flag_strict_volatile_bitfields > 0) | ||
239 | + mode = GET_MODE (op0); | ||
240 | + else | ||
241 | + mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT, | ||
242 | + MEM_ALIGN (op0), mode, MEM_VOLATILE_P (op0)); | ||
243 | |||
244 | if (mode == VOIDmode) | ||
245 | { | ||
246 | @@ -1099,7 +1105,7 @@ | ||
247 | endianness compensation) to fetch the piece we want. */ | ||
248 | part = extract_fixed_bit_field (word_mode, value, 0, thissize, | ||
249 | total_bits - bitsize + bitsdone, | ||
250 | - NULL_RTX, 1); | ||
251 | + NULL_RTX, 1, false); | ||
252 | } | ||
253 | else | ||
254 | { | ||
255 | @@ -1110,7 +1116,7 @@ | ||
256 | & (((HOST_WIDE_INT) 1 << thissize) - 1)); | ||
257 | else | ||
258 | part = extract_fixed_bit_field (word_mode, value, 0, thissize, | ||
259 | - bitsdone, NULL_RTX, 1); | ||
260 | + bitsdone, NULL_RTX, 1, false); | ||
261 | } | ||
262 | |||
263 | /* If OP0 is a register, then handle OFFSET here. | ||
264 | @@ -1176,7 +1182,8 @@ | ||
265 | |||
266 | static rtx | ||
267 | extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, | ||
268 | - unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target, | ||
269 | + unsigned HOST_WIDE_INT bitnum, | ||
270 | + int unsignedp, bool packedp, rtx target, | ||
271 | enum machine_mode mode, enum machine_mode tmode, | ||
272 | bool fallback_p) | ||
273 | { | ||
274 | @@ -1378,6 +1385,14 @@ | ||
275 | ? mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0) | ||
276 | : mode); | ||
277 | |||
278 | + /* If the bitfield is volatile, we need to make sure the access | ||
279 | + remains on a type-aligned boundary. */ | ||
280 | + if (GET_CODE (op0) == MEM | ||
281 | + && MEM_VOLATILE_P (op0) | ||
282 | + && GET_MODE_BITSIZE (GET_MODE (op0)) > 0 | ||
283 | + && flag_strict_volatile_bitfields > 0) | ||
284 | + goto no_subreg_mode_swap; | ||
285 | + | ||
286 | if (((bitsize >= BITS_PER_WORD && bitsize == GET_MODE_BITSIZE (mode) | ||
287 | && bitpos % BITS_PER_WORD == 0) | ||
288 | || (mode1 != BLKmode | ||
289 | @@ -1450,7 +1465,7 @@ | ||
290 | rtx result_part | ||
291 | = extract_bit_field (op0, MIN (BITS_PER_WORD, | ||
292 | bitsize - i * BITS_PER_WORD), | ||
293 | - bitnum + bit_offset, 1, target_part, mode, | ||
294 | + bitnum + bit_offset, 1, false, target_part, mode, | ||
295 | word_mode); | ||
296 | |||
297 | gcc_assert (target_part); | ||
298 | @@ -1649,7 +1664,7 @@ | ||
299 | xop0 = adjust_address (op0, bestmode, xoffset); | ||
300 | xop0 = force_reg (bestmode, xop0); | ||
301 | result = extract_bit_field_1 (xop0, bitsize, xbitpos, | ||
302 | - unsignedp, target, | ||
303 | + unsignedp, packedp, target, | ||
304 | mode, tmode, false); | ||
305 | if (result) | ||
306 | return result; | ||
307 | @@ -1663,7 +1678,7 @@ | ||
308 | return NULL; | ||
309 | |||
310 | target = extract_fixed_bit_field (int_mode, op0, offset, bitsize, | ||
311 | - bitpos, target, unsignedp); | ||
312 | + bitpos, target, unsignedp, packedp); | ||
313 | return convert_extracted_bit_field (target, mode, tmode, unsignedp); | ||
314 | } | ||
315 | |||
316 | @@ -1674,6 +1689,7 @@ | ||
317 | |||
318 | STR_RTX is the structure containing the byte (a REG or MEM). | ||
319 | UNSIGNEDP is nonzero if this is an unsigned bit field. | ||
320 | + PACKEDP is nonzero if the field has the packed attribute. | ||
321 | MODE is the natural mode of the field value once extracted. | ||
322 | TMODE is the mode the caller would like the value to have; | ||
323 | but the value may be returned with type MODE instead. | ||
324 | @@ -1685,10 +1701,10 @@ | ||
325 | |||
326 | rtx | ||
327 | extract_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize, | ||
328 | - unsigned HOST_WIDE_INT bitnum, int unsignedp, rtx target, | ||
329 | - enum machine_mode mode, enum machine_mode tmode) | ||
330 | + unsigned HOST_WIDE_INT bitnum, int unsignedp, bool packedp, | ||
331 | + rtx target, enum machine_mode mode, enum machine_mode tmode) | ||
332 | { | ||
333 | - return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp, | ||
334 | + return extract_bit_field_1 (str_rtx, bitsize, bitnum, unsignedp, packedp, | ||
335 | target, mode, tmode, true); | ||
336 | } | ||
337 | |||
338 | @@ -1704,6 +1720,8 @@ | ||
339 | which is significant on bigendian machines.) | ||
340 | |||
341 | UNSIGNEDP is nonzero for an unsigned bit field (don't sign-extend value). | ||
342 | + PACKEDP is true if the field has the packed attribute. | ||
343 | + | ||
344 | If TARGET is nonzero, attempts to store the value there | ||
345 | and return TARGET, but this is not guaranteed. | ||
346 | If TARGET is not used, create a pseudo-reg of mode TMODE for the value. */ | ||
347 | @@ -1713,7 +1731,7 @@ | ||
348 | unsigned HOST_WIDE_INT offset, | ||
349 | unsigned HOST_WIDE_INT bitsize, | ||
350 | unsigned HOST_WIDE_INT bitpos, rtx target, | ||
351 | - int unsignedp) | ||
352 | + int unsignedp, bool packedp) | ||
353 | { | ||
354 | unsigned int total_bits = BITS_PER_WORD; | ||
355 | enum machine_mode mode; | ||
356 | @@ -1730,8 +1748,19 @@ | ||
357 | includes the entire field. If such a mode would be larger than | ||
358 | a word, we won't be doing the extraction the normal way. */ | ||
359 | |||
360 | - mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT, | ||
361 | - MEM_ALIGN (op0), word_mode, MEM_VOLATILE_P (op0)); | ||
362 | + if (MEM_VOLATILE_P (op0) | ||
363 | + && flag_strict_volatile_bitfields > 0) | ||
364 | + { | ||
365 | + if (GET_MODE_BITSIZE (GET_MODE (op0)) > 0) | ||
366 | + mode = GET_MODE (op0); | ||
367 | + else if (target && GET_MODE_BITSIZE (GET_MODE (target)) > 0) | ||
368 | + mode = GET_MODE (target); | ||
369 | + else | ||
370 | + mode = tmode; | ||
371 | + } | ||
372 | + else | ||
373 | + mode = get_best_mode (bitsize, bitpos + offset * BITS_PER_UNIT, | ||
374 | + MEM_ALIGN (op0), word_mode, MEM_VOLATILE_P (op0)); | ||
375 | |||
376 | if (mode == VOIDmode) | ||
377 | /* The only way this should occur is if the field spans word | ||
378 | @@ -1752,12 +1781,67 @@ | ||
379 | * BITS_PER_UNIT); | ||
380 | } | ||
381 | |||
382 | - /* Get ref to an aligned byte, halfword, or word containing the field. | ||
383 | - Adjust BITPOS to be position within a word, | ||
384 | - and OFFSET to be the offset of that word. | ||
385 | - Then alter OP0 to refer to that word. */ | ||
386 | - bitpos += (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT; | ||
387 | - offset -= (offset % (total_bits / BITS_PER_UNIT)); | ||
388 | + /* If we're accessing a volatile MEM, we can't do the next | ||
389 | + alignment step if it results in a multi-word access where we | ||
390 | + otherwise wouldn't have one. So, check for that case | ||
391 | + here. */ | ||
392 | + if (MEM_P (op0) | ||
393 | + && MEM_VOLATILE_P (op0) | ||
394 | + && flag_strict_volatile_bitfields > 0 | ||
395 | + && bitpos + bitsize <= total_bits | ||
396 | + && bitpos + bitsize + (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT > total_bits) | ||
397 | + { | ||
398 | + if (STRICT_ALIGNMENT) | ||
399 | + { | ||
400 | + static bool informed_about_misalignment = false; | ||
401 | + bool warned; | ||
402 | + | ||
403 | + if (packedp) | ||
404 | + { | ||
405 | + if (bitsize == total_bits) | ||
406 | + warned = warning_at (input_location, OPT_fstrict_volatile_bitfields, | ||
407 | + "multiple accesses to volatile structure member" | ||
408 | + " because of packed attribute"); | ||
409 | + else | ||
410 | + warned = warning_at (input_location, OPT_fstrict_volatile_bitfields, | ||
411 | + "multiple accesses to volatile structure bitfield" | ||
412 | + " because of packed attribute"); | ||
413 | + | ||
414 | + return extract_split_bit_field (op0, bitsize, | ||
415 | + bitpos + offset * BITS_PER_UNIT, | ||
416 | + unsignedp); | ||
417 | + } | ||
418 | + | ||
419 | + if (bitsize == total_bits) | ||
420 | + warned = warning_at (input_location, OPT_fstrict_volatile_bitfields, | ||
421 | + "mis-aligned access used for structure member"); | ||
422 | + else | ||
423 | + warned = warning_at (input_location, OPT_fstrict_volatile_bitfields, | ||
424 | + "mis-aligned access used for structure bitfield"); | ||
425 | + | ||
426 | + if (! informed_about_misalignment && warned) | ||
427 | + { | ||
428 | + informed_about_misalignment = true; | ||
429 | + inform (input_location, | ||
430 | + "When a volatile object spans multiple type-sized locations," | ||
431 | + " the compiler must choose between using a single mis-aligned access to" | ||
432 | + " preserve the volatility, or using multiple aligned accesses to avoid" | ||
433 | + " runtime faults. This code may fail at runtime if the hardware does" | ||
434 | + " not allow this access."); | ||
435 | + } | ||
436 | + } | ||
437 | + } | ||
438 | + else | ||
439 | + { | ||
440 | + | ||
441 | + /* Get ref to an aligned byte, halfword, or word containing the field. | ||
442 | + Adjust BITPOS to be position within a word, | ||
443 | + and OFFSET to be the offset of that word. | ||
444 | + Then alter OP0 to refer to that word. */ | ||
445 | + bitpos += (offset % (total_bits / BITS_PER_UNIT)) * BITS_PER_UNIT; | ||
446 | + offset -= (offset % (total_bits / BITS_PER_UNIT)); | ||
447 | + } | ||
448 | + | ||
449 | op0 = adjust_address (op0, mode, offset); | ||
450 | } | ||
451 | |||
452 | @@ -1966,7 +2050,7 @@ | ||
453 | extract_fixed_bit_field wants offset in bytes. */ | ||
454 | part = extract_fixed_bit_field (word_mode, word, | ||
455 | offset * unit / BITS_PER_UNIT, | ||
456 | - thissize, thispos, 0, 1); | ||
457 | + thissize, thispos, 0, 1, false); | ||
458 | bitsdone += thissize; | ||
459 | |||
460 | /* Shift this part into place for the result. */ | ||
461 | |||
462 | === modified file 'gcc/expr.c' | ||
463 | --- old/gcc/expr.c 2010-10-04 00:50:43 +0000 | ||
464 | +++ new/gcc/expr.c 2010-11-04 12:43:52 +0000 | ||
465 | @@ -1749,7 +1749,7 @@ | ||
466 | && (!REG_P (tmps[i]) || GET_MODE (tmps[i]) != mode)) | ||
467 | tmps[i] = extract_bit_field (tmps[i], bytelen * BITS_PER_UNIT, | ||
468 | (bytepos % slen0) * BITS_PER_UNIT, | ||
469 | - 1, NULL_RTX, mode, mode); | ||
470 | + 1, false, NULL_RTX, mode, mode); | ||
471 | } | ||
472 | else | ||
473 | { | ||
474 | @@ -1759,7 +1759,7 @@ | ||
475 | mem = assign_stack_temp (GET_MODE (src), slen, 0); | ||
476 | emit_move_insn (mem, src); | ||
477 | tmps[i] = extract_bit_field (mem, bytelen * BITS_PER_UNIT, | ||
478 | - 0, 1, NULL_RTX, mode, mode); | ||
479 | + 0, 1, false, NULL_RTX, mode, mode); | ||
480 | } | ||
481 | } | ||
482 | /* FIXME: A SIMD parallel will eventually lead to a subreg of a | ||
483 | @@ -1800,7 +1800,7 @@ | ||
484 | tmps[i] = src; | ||
485 | else | ||
486 | tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT, | ||
487 | - bytepos * BITS_PER_UNIT, 1, NULL_RTX, | ||
488 | + bytepos * BITS_PER_UNIT, 1, false, NULL_RTX, | ||
489 | mode, mode); | ||
490 | |||
491 | if (shift) | ||
492 | @@ -2213,7 +2213,7 @@ | ||
493 | bitpos for the destination store (left justified). */ | ||
494 | store_bit_field (dst, bitsize, bitpos % BITS_PER_WORD, copy_mode, | ||
495 | extract_bit_field (src, bitsize, | ||
496 | - xbitpos % BITS_PER_WORD, 1, | ||
497 | + xbitpos % BITS_PER_WORD, 1, false, | ||
498 | NULL_RTX, copy_mode, copy_mode)); | ||
499 | } | ||
500 | |||
501 | @@ -2970,7 +2970,7 @@ | ||
502 | } | ||
503 | |||
504 | return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0, | ||
505 | - true, NULL_RTX, imode, imode); | ||
506 | + true, false, NULL_RTX, imode, imode); | ||
507 | } | ||
508 | |||
509 | /* A subroutine of emit_move_insn_1. Yet another lowpart generator. | ||
510 | @@ -4233,6 +4233,13 @@ | ||
511 | |||
512 | to_rtx = expand_normal (tem); | ||
513 | |||
514 | + /* If the bitfield is volatile, we want to access it in the | ||
515 | + field's mode, not the computed mode. */ | ||
516 | + if (volatilep | ||
517 | + && GET_CODE (to_rtx) == MEM | ||
518 | + && flag_strict_volatile_bitfields > 0) | ||
519 | + to_rtx = adjust_address (to_rtx, mode1, 0); | ||
520 | + | ||
521 | if (offset != 0) | ||
522 | { | ||
523 | enum machine_mode address_mode; | ||
524 | @@ -5993,6 +6000,12 @@ | ||
525 | mode = DECL_MODE (field); | ||
526 | else if (DECL_MODE (field) == BLKmode) | ||
527 | blkmode_bitfield = true; | ||
528 | + else if (TREE_THIS_VOLATILE (exp) | ||
529 | + && flag_strict_volatile_bitfields > 0) | ||
530 | + /* Volatile bitfields should be accessed in the mode of the | ||
531 | + field's type, not the mode computed based on the bit | ||
532 | + size. */ | ||
533 | + mode = TYPE_MODE (DECL_BIT_FIELD_TYPE (field)); | ||
534 | |||
535 | *punsignedp = DECL_UNSIGNED (field); | ||
536 | } | ||
537 | @@ -8848,6 +8861,7 @@ | ||
538 | HOST_WIDE_INT bitsize, bitpos; | ||
539 | tree offset; | ||
540 | int volatilep = 0, must_force_mem; | ||
541 | + bool packedp = false; | ||
542 | tree tem = get_inner_reference (exp, &bitsize, &bitpos, &offset, | ||
543 | &mode1, &unsignedp, &volatilep, true); | ||
544 | rtx orig_op0, memloc; | ||
545 | @@ -8857,6 +8871,11 @@ | ||
546 | infinitely recurse. */ | ||
547 | gcc_assert (tem != exp); | ||
548 | |||
549 | + if (TYPE_PACKED (TREE_TYPE (TREE_OPERAND (exp, 0))) | ||
550 | + || (TREE_CODE (TREE_OPERAND (exp, 1)) == FIELD_DECL | ||
551 | + && DECL_PACKED (TREE_OPERAND (exp, 1)))) | ||
552 | + packedp = true; | ||
553 | + | ||
554 | /* If TEM's type is a union of variable size, pass TARGET to the inner | ||
555 | computation, since it will need a temporary and TARGET is known | ||
556 | to have to do. This occurs in unchecked conversion in Ada. */ | ||
557 | @@ -8873,6 +8892,14 @@ | ||
558 | || modifier == EXPAND_STACK_PARM) | ||
559 | ? modifier : EXPAND_NORMAL); | ||
560 | |||
561 | + | ||
562 | + /* If the bitfield is volatile, we want to access it in the | ||
563 | + field's mode, not the computed mode. */ | ||
564 | + if (volatilep | ||
565 | + && GET_CODE (op0) == MEM | ||
566 | + && flag_strict_volatile_bitfields > 0) | ||
567 | + op0 = adjust_address (op0, mode1, 0); | ||
568 | + | ||
569 | mode2 | ||
570 | = CONSTANT_P (op0) ? TYPE_MODE (TREE_TYPE (tem)) : GET_MODE (op0); | ||
571 | |||
572 | @@ -8998,6 +9025,9 @@ | ||
573 | && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT | ||
574 | && modifier != EXPAND_CONST_ADDRESS | ||
575 | && modifier != EXPAND_INITIALIZER) | ||
576 | + /* If the field is volatile, we always want an aligned | ||
577 | + access. */ | ||
578 | + || (volatilep && flag_strict_volatile_bitfields > 0) | ||
579 | /* If the field isn't aligned enough to fetch as a memref, | ||
580 | fetch it as a bit field. */ | ||
581 | || (mode1 != BLKmode | ||
582 | @@ -9058,7 +9088,7 @@ | ||
583 | if (MEM_P (op0) && REG_P (XEXP (op0, 0))) | ||
584 | mark_reg_pointer (XEXP (op0, 0), MEM_ALIGN (op0)); | ||
585 | |||
586 | - op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp, | ||
587 | + op0 = extract_bit_field (op0, bitsize, bitpos, unsignedp, packedp, | ||
588 | (modifier == EXPAND_STACK_PARM | ||
589 | ? NULL_RTX : target), | ||
590 | ext_mode, ext_mode); | ||
591 | |||
592 | === modified file 'gcc/expr.h' | ||
593 | --- old/gcc/expr.h 2010-02-19 09:53:51 +0000 | ||
594 | +++ new/gcc/expr.h 2010-11-04 12:43:52 +0000 | ||
595 | @@ -802,7 +802,7 @@ | ||
596 | extern void store_bit_field (rtx, unsigned HOST_WIDE_INT, | ||
597 | unsigned HOST_WIDE_INT, enum machine_mode, rtx); | ||
598 | extern rtx extract_bit_field (rtx, unsigned HOST_WIDE_INT, | ||
599 | - unsigned HOST_WIDE_INT, int, rtx, | ||
600 | + unsigned HOST_WIDE_INT, int, bool, rtx, | ||
601 | enum machine_mode, enum machine_mode); | ||
602 | extern rtx extract_low_bits (enum machine_mode, enum machine_mode, rtx); | ||
603 | extern rtx expand_mult (enum machine_mode, rtx, rtx, rtx, int); | ||
604 | |||
605 | === modified file 'gcc/fold-const.c' | ||
606 | --- old/gcc/fold-const.c 2010-10-04 00:50:43 +0000 | ||
607 | +++ new/gcc/fold-const.c 2010-11-04 12:43:52 +0000 | ||
608 | @@ -4208,11 +4208,16 @@ | ||
609 | |||
610 | /* See if we can find a mode to refer to this field. We should be able to, | ||
611 | but fail if we can't. */ | ||
612 | - nmode = get_best_mode (lbitsize, lbitpos, | ||
613 | - const_p ? TYPE_ALIGN (TREE_TYPE (linner)) | ||
614 | - : MIN (TYPE_ALIGN (TREE_TYPE (linner)), | ||
615 | - TYPE_ALIGN (TREE_TYPE (rinner))), | ||
616 | - word_mode, lvolatilep || rvolatilep); | ||
617 | + if (lvolatilep | ||
618 | + && GET_MODE_BITSIZE (lmode) > 0 | ||
619 | + && flag_strict_volatile_bitfields > 0) | ||
620 | + nmode = lmode; | ||
621 | + else | ||
622 | + nmode = get_best_mode (lbitsize, lbitpos, | ||
623 | + const_p ? TYPE_ALIGN (TREE_TYPE (linner)) | ||
624 | + : MIN (TYPE_ALIGN (TREE_TYPE (linner)), | ||
625 | + TYPE_ALIGN (TREE_TYPE (rinner))), | ||
626 | + word_mode, lvolatilep || rvolatilep); | ||
627 | if (nmode == VOIDmode) | ||
628 | return 0; | ||
629 | |||
630 | |||
631 | === modified file 'gcc/stmt.c' | ||
632 | --- old/gcc/stmt.c 2010-08-13 11:53:46 +0000 | ||
633 | +++ new/gcc/stmt.c 2010-11-04 12:43:52 +0000 | ||
634 | @@ -1751,7 +1751,7 @@ | ||
635 | xbitpos for the destination store (right justified). */ | ||
636 | store_bit_field (dst, bitsize, xbitpos % BITS_PER_WORD, word_mode, | ||
637 | extract_bit_field (src, bitsize, | ||
638 | - bitpos % BITS_PER_WORD, 1, | ||
639 | + bitpos % BITS_PER_WORD, 1, false, | ||
640 | NULL_RTX, word_mode, word_mode)); | ||
641 | } | ||
642 | |||
643 | |||
644 | === added file 'gcc/testsuite/gcc.target/i386/volatile-bitfields-1.c' | ||
645 | --- old/gcc/testsuite/gcc.target/i386/volatile-bitfields-1.c 1970-01-01 00:00:00 +0000 | ||
646 | +++ new/gcc/testsuite/gcc.target/i386/volatile-bitfields-1.c 2010-11-04 12:43:52 +0000 | ||
647 | @@ -0,0 +1,17 @@ | ||
648 | +/* { dg-do compile } */ | ||
649 | +/* { dg-options "-O2 -fstrict-volatile-bitfields" } */ | ||
650 | + | ||
651 | +typedef struct { | ||
652 | + char a:1; | ||
653 | + char b:7; | ||
654 | + int c; | ||
655 | +} BitStruct; | ||
656 | + | ||
657 | +volatile BitStruct bits; | ||
658 | + | ||
659 | +int foo () | ||
660 | +{ | ||
661 | + return bits.b; | ||
662 | +} | ||
663 | + | ||
664 | +/* { dg-final { scan-assembler "mov(b|zbl).*bits" } } */ | ||
665 | |||
666 | === added file 'gcc/testsuite/gcc.target/i386/volatile-bitfields-2.c' | ||
667 | --- old/gcc/testsuite/gcc.target/i386/volatile-bitfields-2.c 1970-01-01 00:00:00 +0000 | ||
668 | +++ new/gcc/testsuite/gcc.target/i386/volatile-bitfields-2.c 2010-11-04 12:43:52 +0000 | ||
669 | @@ -0,0 +1,17 @@ | ||
670 | +/* { dg-do compile } */ | ||
671 | +/* { dg-options "-O2 -fno-strict-volatile-bitfields" } */ | ||
672 | + | ||
673 | +typedef struct { | ||
674 | + char a:1; | ||
675 | + char b:7; | ||
676 | + int c; | ||
677 | +} BitStruct; | ||
678 | + | ||
679 | +volatile BitStruct bits; | ||
680 | + | ||
681 | +int foo () | ||
682 | +{ | ||
683 | + return bits.b; | ||
684 | +} | ||
685 | + | ||
686 | +/* { dg-final { scan-assembler "movl.*bits" } } */ | ||
687 | |||