This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Width of volatile bitfields (PR23623)


The patch below attempts to fix PR23623.

The problem is that there are two conflicting definitions of the semantics of 
volatile bitfields:

a) The container type should determine the type of the memory access. This 
allows the user explicit control over the access, which is typically useful 
for memory mapped peripherals.
b) The narrowest single access should be used. This is the historic behavior. 
I guess this is to avoid superfluous memory accesses for unaligned or wider 
than memory bus accesses.

Given the definitions above I guess that STRICT_ALIGNMENT is as good a way as 
any to differentiate between the two behaviors. I'm open to other suggestions 
on how to control this behavior (eg. add a target hook). My only real 
criteria is that the ARM EABI requires behavior (a).

Tested with cross to arm-none-eabi, and spot check on i686-inux.
Ok?

Paul

2006-03-28  Paul Brook  <paul@codesourcery.com>

	PR middle-end/23623
	* stor-layout.c (get_best_mode): Use STRICT_ALIGNMENT when determining
	width of volatile accesses.

Index: gcc/stor-layout.c
===================================================================
--- gcc/stor-layout.c	(revision 112423)
+++ gcc/stor-layout.c	(working copy)
@@ -2126,13 +2126,22 @@ fixup_unsigned_type (tree type)
    If LARGEST_MODE is not VOIDmode, it means that we should not use a mode
    larger than LARGEST_MODE (usually SImode).
 
-   If no mode meets all these conditions, we return VOIDmode.  Otherwise, if
-   VOLATILEP is true or SLOW_BYTE_ACCESS is false, we return the smallest
-   mode meeting these conditions.
-
-   Otherwise (VOLATILEP is false and SLOW_BYTE_ACCESS is true), we return
-   the largest mode (but a mode no wider than UNITS_PER_WORD) that meets
-   all the conditions.  */
+   If no mode meets all these conditions, we return VOIDmode.
+   
+   If VOLATILEP is false and SLOW_BYTE_ACCESS is false, we return the
+   smallest mode meeting these conditions.
+
+   If VOLATILEP is false and SLOW_BYTE_ACCESS is true, we return the
+   largest mode (but a mode no wider than UNITS_PER_WORD) that meets
+   all the conditions.
+   
+   If VOLATILEP is true and STRICT_ALIGNMENT is true we return the wider
+   type.  This is generally the prefered behavior for memory mapped
+   peripherals on RISC architectures.
+
+   If VOLATILEP is true and STRICT_ALIGNMENT is false we return the narrower
+   type.  This is typically used to avoid spurious page faults and extra
+   memory accesses due to unaligned accesses on CISC architectures.  */
 
 enum machine_mode
 get_best_mode (int bitsize, int bitpos, unsigned int align,
@@ -2162,7 +2171,8 @@ get_best_mode (int bitsize, int bitpos, 
       || (largest_mode != VOIDmode && unit > GET_MODE_BITSIZE 
(largest_mode)))
     return VOIDmode;
 
-  if (SLOW_BYTE_ACCESS && ! volatilep)
+  if ((SLOW_BYTE_ACCESS && ! volatilep)
+      || (volatilep && STRICT_ALIGNMENT))
     {
       enum machine_mode wide_mode = VOIDmode, tmode;
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]