PATCH, ARM: fix PR23623 and PR27628

Frikkie Thirion frikkie@zitera.co.za
Mon Mar 23 09:09:00 GMT 2009


Good day,

PR27628 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27628) described a case where the fix in PR23623 (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23623) still didn't work correctly. The attached patch addresses this situation. Patches for GCC4.4.0 and GCC4.3.2 are attached, along with the disassembly of the test programs, showing that the patch resolves this problem.

Regards,
Frikkie Thirion

GCC 4.4.0:

===============================================================
--- gcc-4.4.0/gcc/expr.c.Orig   2009-01-12 17:50:41.000000000 +0200
+++ gcc-4.4.0/gcc/expr.c        2009-01-13 11:41:47.000000000 +0200
@@ -6081,6 +6081,13 @@
     *pmode = BLKmode;
   else
     *pmode = mode;
+
+  /* Check to see if the container type of volatile bitfields must be honoured: */
+  /*   Variable is volatile and target hook: TARGET_NARROW_VOLATILE_BITFIELD is false */
+  if ( (*pvolatilep==1) && (!targetm.narrow_volatile_bitfield ()) )
+  {
+        *pmode=VOIDmode;
+  }

   return exp;
 }
===============================================================
--- gcc-4.4.0/gcc/expmed.c.Orig 2009-01-12 17:51:46.000000000 +0200
+++ gcc-4.4.0/gcc/expmed.c      2009-01-13 11:41:39.000000000 +0200
@@ -1368,6 +1368,13 @@
                  || (offset * BITS_PER_UNIT % bitsize == 0
                      && MEM_ALIGN (op0) % bitsize == 0)))))
     {
+      /* Check to see if the container type of volatile bitfields must be honoured: */
+      /*   Variable is volatile and target hook: TARGET_NARROW_VOLATILE_BITFIELD is false */
+      if ( (MEM_VOLATILE_P(str_rtx)==1) && (!targetm.narrow_volatile_bitfield()) )
+      {
+         goto no_subreg_mode_swap;
+      }
+
       if (MEM_P (op0))
        op0 = adjust_address (op0, mode1, offset);
       else if (mode1 != GET_MODE (op0))
--- gcc-4.4.0/gcc/expmed.c.Orig 2009-01-12 17:51:46.000000000 +0200
+++ gcc-4.4.0/gcc/expmed.c      2009-01-13 11:41:39.000000000 +0200
@@ -1368,6 +1368,13 @@
                  || (offset * BITS_PER_UNIT % bitsize == 0
                      && MEM_ALIGN (op0) % bitsize == 0)))))
     {
+      /* Check to see if the container type of volatile bitfields must be honoured: */
+      /*   Variable is volatile and target hook: TARGET_NARROW_VOLATILE_BITFIELD is false */
+      if ( (MEM_VOLATILE_P(str_rtx)==1) && (!targetm.narrow_volatile_bitfield()) )
+      {
+         goto no_subreg_mode_swap;
+      }
+
       if (MEM_P (op0))
        op0 = adjust_address (op0, mode1, offset);
       else if (mode1 != GET_MODE (op0))
===============================================================



GCC 4.3.2
===============================================================
--- gcc-4.3.2/gcc/expr.c.Orig   2009-01-12 17:26:08.000000000 +0200
+++ gcc-4.3.2/gcc/expr.c        2009-01-13 17:27:03.000000000 +0200
@@ -6006,6 +6006,13 @@
       exp = TREE_OPERAND (exp, 0);
     }
  done:
+  /* Check to see if the container type of volatile bitfields must be honoured: */
+  /*   Variable is volatile and target hook: TARGET_NARROW_VOLATILE_BITFIELD is false */
+  if ( (*pvolatilep==1) && (!targetm.narrow_volatile_bitfield ()) )
+  {
+     *pmode=VOIDmode;
+  }
+

   /* If OFFSET is constant, see if we can return the whole thing as a
      constant bit position.  Make sure to handle overflow during
===============================================================
--- gcc-4.3.2/gcc/expmed.c.Orig 2009-01-12 17:29:47.000000000 +0200
+++ gcc-4.3.2/gcc/expmed.c      2009-01-13 17:27:09.000000000 +0200
@@ -1339,6 +1339,13 @@
                  || (offset * BITS_PER_UNIT % bitsize == 0
                      && MEM_ALIGN (op0) % bitsize == 0)))))
     {
+      /* Check to see if the container type of volatile bitfields must be honoured: */
+      /*   Variable is volatile and target hook: TARGET_NARROW_VOLATILE_BITFIELD is false */
+      if ( (MEM_VOLATILE_P(str_rtx)==1) && (!targetm.narrow_volatile_bitfield()) )
+      {
+         goto no_subreg_mode_swap;
+      }
+
       if (MEM_P (op0))
        op0 = adjust_address (op0, mode1, offset);
       else if (mode1 != GET_MODE (op0))
===============================================================




//=============================================================================
// Disassemlby of  a simple program compiled in GCC 4.3.2
//=============================================================================
main()
{
  typedef struct
  {
    __REG32 PLL_MDIV:8;   // [7:0]   PLL Pre-divider
    __REG32 PLL_NDIV:8;   // [15:8]  PLL Feedback divider

    __REG32 PLL_PDIV:3;   // [18:16] PLL Post-divider
    __REG32 PLL_EN:1;     // [19]    PLL Enable (0=off, 1=on)

    __REG32 uwPAD:12;     // [31:20] -PADDING-
  }__Bitfield;

//  __Bitfield REG_bit;                // Use this declaration to let gcc optimise accessed
//  volatile __Bitfield REG_bit;    // Use this declaration to let gcc honour the bitfield container type
  unsigned int uwI;

  REG_bit.PLL_MDIV=0x80;
  uwI = REG_bit.PLL_MDIV;
}
//=============================================================================
// Disassembly for original gcc code, for volatile bitfield declaration
// Note: Incorrect use of 'strb/ldrb' byte accesses: struct definition
//          specified 32-bit container types
  REG_bit.PLL_MDIV=0x80;
    148:    e3e0307f     mvn    r3, #127    ; 0x7f
    14c:    e54b3014     strb    r3, [fp, #-20]

  uwI = REG_bit.PLL_MDIV;
    194:    e55b3014     ldrb    r3, [fp, #-20]
    198:    e20330ff     and    r3, r3, #255    ; 0xff
    19c:    e50b3010     str    r3, [fp, #-16]

// Disassembly for patched gcc code, for volatile bitfield declaration
// Note: Expected code generated: 32-bit register accesses
  REG_bit.PLL_MDIV=0x80;
    148:    e51b2014     ldr    r2, [fp, #-20]
    14c:    e50b2018     str    r2, [fp, #-24]
    150:    e51b2018     ldr    r2, [fp, #-24]
    154:    e3c2307f     bic    r3, r2, #127    ; 0x7f
    158:    e3833080     orr    r3, r3, #128    ; 0x80
    15c:    e50b3018     str    r3, [fp, #-24]
    160:    e51b3018     ldr    r3, [fp, #-24]
    164:    e50b3014     str    r3, [fp, #-20]

  uwI = REG_bit.PLL_MDIV;
    1c4:    e51b3014     ldr    r3, [fp, #-20]
    1c8:    e20330ff     and    r3, r3, #255    ; 0xff
    1cc:    e50b3010     str    r3, [fp, #-16]
//=============================================================================
// Disassembly for original gcc code, for non-volatile bitfield declaration
  REG_bit.PLL_MDIV=0x80;
    148:    e3e0307f     mvn    r3, #127    ; 0x7f
    14c:    e54b3014     strb    r3, [fp, #-20]

  uwI = REG_bit.PLL_MDIV;
    194:    e55b3014     ldrb    r3, [fp, #-20]
    198:    e50b3010     str    r3, [fp, #-16]

// Disassembly for patched gcc code, for non-volatile bitfield declaration
// Note: The disassembly has stayed exactly the same when the bitfield
//       wasn't declared "volatile". The original behaviour was
//       preserved.
  REG_bit.PLL_MDIV=0x80;
    148:    e3e0307f     mvn    r3, #127    ; 0x7f
    14c:    e54b3014     strb    r3, [fp, #-20]

  REG_bit.PLL_MDIV=0x80;
    148:    e3e0307f     mvn    r3, #127    ; 0x7f
    14c:    e54b3014     strb    r3, [fp, #-20]
//=============================================================================




More information about the Gcc-patches mailing list