summaryrefslogtreecommitdiffstats
path: root/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99424.patch
diff options
context:
space:
mode:
authorKoen Kooi <koen@dominion.thruhere.net>2010-12-23 14:02:13 +0100
committerKoen Kooi <koen@dominion.thruhere.net>2010-12-23 14:02:13 +0100
commit7eb7dce48ba082c30f1fceced04c275420158b9a (patch)
treed2f5b6bed38d7ffc0aad7f5c313701da4d8a8e19 /recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99424.patch
parent8bb6722b1356cc3b8494e33553240363addd2d80 (diff)
downloadmeta-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.patch687
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