public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/23623] New: volatile keyword changes bitfield access size from 32bit to 8bit
@ 2005-08-29 14:11 m dot reszat at kostal dot com
  2005-08-29 15:39 ` [Bug middle-end/23623] " pinskia at gcc dot gnu dot org
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: m dot reszat at kostal dot com @ 2005-08-29 14:11 UTC (permalink / raw)
  To: gcc-bugs

struct
{
   unsigned int b : 1;
} bf1;

volatile struct
{
   unsigned int b : 1;
} bf2;

void test(void)
{
   bf1.b = 1;
   bf2.b = 1;
}

Access to bf1.b is correctly done as 32-bits (lwz/stw opcodes), bf2.b is
accessed as 8-bits (lbz/stb opcodes). GCC3.4.3 shows the same behaviour, can't
go back any further. The same happens when the bitfield itself is made volatile,
not the whole struct.

-- 
           Summary: volatile keyword changes bitfield access size from 32bit
                    to 8bit
           Product: gcc
           Version: 4.0.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: m dot reszat at kostal dot com
                CC: gcc-bugs at gcc dot gnu dot org
  GCC host triplet: i686-pc-cygwin
GCC target triplet: powerpc-elf-eabispe


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23623


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/23623] volatile keyword changes bitfield access size from 32bit to 8bit
  2005-08-29 14:11 [Bug c/23623] New: volatile keyword changes bitfield access size from 32bit to 8bit m dot reszat at kostal dot com
@ 2005-08-29 15:39 ` pinskia at gcc dot gnu dot org
  2005-08-29 16:21 ` pinskia at gcc dot gnu dot org
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-08-29 15:39 UTC (permalink / raw)
  To: gcc-bugs



-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|c                           |middle-end


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23623


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/23623] volatile keyword changes bitfield access size from 32bit to 8bit
  2005-08-29 14:11 [Bug c/23623] New: volatile keyword changes bitfield access size from 32bit to 8bit m dot reszat at kostal dot com
  2005-08-29 15:39 ` [Bug middle-end/23623] " pinskia at gcc dot gnu dot org
@ 2005-08-29 16:21 ` pinskia at gcc dot gnu dot org
  2005-08-29 21:27 ` falk at debian dot org
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2005-08-29 16:21 UTC (permalink / raw)
  To: gcc-bugs



-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
      Known to fail|                            |3.1 3.3 4.1.0 4.0.0


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23623


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/23623] volatile keyword changes bitfield access size from 32bit to 8bit
  2005-08-29 14:11 [Bug c/23623] New: volatile keyword changes bitfield access size from 32bit to 8bit m dot reszat at kostal dot com
  2005-08-29 15:39 ` [Bug middle-end/23623] " pinskia at gcc dot gnu dot org
  2005-08-29 16:21 ` pinskia at gcc dot gnu dot org
@ 2005-08-29 21:27 ` falk at debian dot org
  2005-08-30  7:59 ` m dot reszat at kostal dot com
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: falk at debian dot org @ 2005-08-29 21:27 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From falk at debian dot org  2005-08-29 21:10 -------
(In reply to comment #0)

> Access to bf1.b is correctly done as 32-bits (lwz/stw opcodes), bf2.b is
> accessed as 8-bits (lbz/stb opcodes). GCC3.4.3 shows the same behaviour, can't
> go back any further. The same happens when the bitfield itself is made volatile,
> not the whole struct.

This is intentional. The idea is not to touch any more of that volatile stuff
than absolutely needed. Why do you think it is a bug?

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23623


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/23623] volatile keyword changes bitfield access size from 32bit to 8bit
  2005-08-29 14:11 [Bug c/23623] New: volatile keyword changes bitfield access size from 32bit to 8bit m dot reszat at kostal dot com
                   ` (2 preceding siblings ...)
  2005-08-29 21:27 ` falk at debian dot org
@ 2005-08-30  7:59 ` m dot reszat at kostal dot com
  2005-08-30 12:44 ` falk at debian dot org
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: m dot reszat at kostal dot com @ 2005-08-30  7:59 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From m dot reszat at kostal dot com  2005-08-30 07:43 -------
(In reply to comment #1)
> (In reply to comment #0)
> 
> > Access to bf1.b is correctly done as 32-bits (lwz/stw opcodes), bf2.b is
> > accessed as 8-bits (lbz/stb opcodes). GCC3.4.3 shows the same behaviour, can't
> > go back any further. The same happens when the bitfield itself is made volatile,
> > not the whole struct.
> 
> This is intentional. The idea is not to touch any more of that volatile stuff
> than absolutely needed. Why do you think it is a bug?

When dealing with peripherals in embedded systems, the use of bitfields makes
the code much more readable. 

Ex.: 3 bits of a peripheral register define a timer prescaler
It can be s.th. like 
#define PS_VAL_05 0x00140000
#define PS_MASK   0x001c0000
...
per_reg = (per_reg & ~PS_MASK) | PS_VAL_05;

But could be as simple as 
per_reg.ps = 5;, or even per_reg.ps = func(...); 
Try to set up the latter w/o bitfields and you end up
per_reg = (per_reg & ~PS_MASK) | (func(...) << PS_SHIFT);

Most (admittedly not all) modern peripherals allow the bitfield approach, but
correct access size is a must (misalignment traps, access triggered buffering
etc.). 
IMHO the compiler/code generator should always use the basic type when a
variable is declared as volatile, i.e. volatile unsigned int ps:3; should
enforce 32-bit-access, probably even for non-bitfields. All compilers for
embedded systems I know of act this way, so I assumed this was a bug.
In other cases, e.g. communicating between threads through memory, access size
is not an issue and even if so, could be enforced by appropriate declaration or,
god help me, typecasting as a last resort.
Unfortunately, C does not provide a qualifier for access size enforcement,
"volatile" seems to be the closest friend. The current implementation puts me
between a rock and a hard place, as the "core volatile functionality" is needed
as well.
What do you think?

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23623


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/23623] volatile keyword changes bitfield access size from 32bit to 8bit
  2005-08-29 14:11 [Bug c/23623] New: volatile keyword changes bitfield access size from 32bit to 8bit m dot reszat at kostal dot com
                   ` (3 preceding siblings ...)
  2005-08-30  7:59 ` m dot reszat at kostal dot com
@ 2005-08-30 12:44 ` falk at debian dot org
  2005-08-30 12:51 ` rearnsha at gcc dot gnu dot org
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: falk at debian dot org @ 2005-08-30 12:44 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From falk at debian dot org  2005-08-30 12:26 -------
(In reply to comment #2)
> (In reply to comment #1)
> > (In reply to comment #0)

> When dealing with peripherals in embedded systems, the use of bitfields makes
> the code much more readable. 

I can see that.

> Most (admittedly not all) modern peripherals allow the bitfield approach, but
> correct access size is a must (misalignment traps, access triggered buffering
> etc.). 

I can see that too, but I don't see what it has to do with this PR.

> IMHO the compiler/code generator should always use the basic type when a
> variable is declared as volatile, i.e. volatile unsigned int ps:3; should
> enforce 32-bit-access, probably even for non-bitfields.

OK, but why? You still haven't explained. What exactly is the problem with
your code the way gcc does things currently?

> All compilers for
> embedded systems I know of act this way, so I assumed this was a bug.

The only other compiler I have around (DEC C) behaves the same way as gcc
(which is, to take the narrowest possible access that can be still done 
in one instruction).

In any case, even if the current behavior isn't perfect, we would need an
extremely and utterly good reason to change it, lest we screw over lots
of users relying on the current behavior.

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23623


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/23623] volatile keyword changes bitfield access size from 32bit to 8bit
  2005-08-29 14:11 [Bug c/23623] New: volatile keyword changes bitfield access size from 32bit to 8bit m dot reszat at kostal dot com
                   ` (4 preceding siblings ...)
  2005-08-30 12:44 ` falk at debian dot org
@ 2005-08-30 12:51 ` rearnsha at gcc dot gnu dot org
  2005-08-30 13:42 ` m dot reszat at kostal dot com
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 10+ messages in thread
From: rearnsha at gcc dot gnu dot org @ 2005-08-30 12:51 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From rearnsha at gcc dot gnu dot org  2005-08-30 12:43 -------
Note this also happens on ARM where (in the EABI) it is definitely a bug becuase
the procedure call standard says it is.

Quoting from the AAPCS:

7.1.7.5 Volatile bit-fields&#63719;preserving number and width of container accesses

When a volatile bit-field is read, its container must be read exactly once using
the access width appropriate to the type of the container.

When a volatile bit-field is written, its container must be read exactly once
and written exactly once using the access width appropriate to the type of the
container. The two accesses are not atomic.

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rearnsha at gcc dot gnu dot
                   |                            |org
             Status|UNCONFIRMED                 |NEW
     Ever Confirmed|                            |1
   Last reconfirmed|0000-00-00 00:00:00         |2005-08-30 12:43:25
               date|                            |


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23623


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/23623] volatile keyword changes bitfield access size from 32bit to 8bit
  2005-08-29 14:11 [Bug c/23623] New: volatile keyword changes bitfield access size from 32bit to 8bit m dot reszat at kostal dot com
                   ` (5 preceding siblings ...)
  2005-08-30 12:51 ` rearnsha at gcc dot gnu dot org
@ 2005-08-30 13:42 ` m dot reszat at kostal dot com
  2005-08-30 14:06 ` rearnsha at gcc dot gnu dot org
  2005-09-08 15:12 ` m dot reszat at kostal dot com
  8 siblings, 0 replies; 10+ messages in thread
From: m dot reszat at kostal dot com @ 2005-08-30 13:42 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From m dot reszat at kostal dot com  2005-08-30 13:40 -------
(In reply to comment #4)
> Note this also happens on ARM where (in the EABI) it is definitely a bug

I will try and dig up the EABI for PowerPC, but it's not just about sticking to
a paper. It simply does not work for me (and probably others) the way it is. My
system traps out on me or, worce, writes garbage to the 'untouched' register
parts for some peripherals. NEC V850 and, I think, MIPS do the same.
I can't quite see what can be gained by minimizing access size, but not knowing
the complete rationale (why are non-bitfields NOT minimized, e.g. volatile int x
|= 1), how about a command line switch to let the user select?

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23623


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/23623] volatile keyword changes bitfield access size from 32bit to 8bit
  2005-08-29 14:11 [Bug c/23623] New: volatile keyword changes bitfield access size from 32bit to 8bit m dot reszat at kostal dot com
                   ` (6 preceding siblings ...)
  2005-08-30 13:42 ` m dot reszat at kostal dot com
@ 2005-08-30 14:06 ` rearnsha at gcc dot gnu dot org
  2005-09-08 15:12 ` m dot reszat at kostal dot com
  8 siblings, 0 replies; 10+ messages in thread
From: rearnsha at gcc dot gnu dot org @ 2005-08-30 14:06 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From rearnsha at gcc dot gnu dot org  2005-08-30 14:00 -------
(In reply to comment #5)
> I will try and dig up the EABI for PowerPC, but it's not just about sticking to
> a paper. It simply does not work for me (and probably others) the way it is. 

Saying that because it doesn't work for you is not really addressing the issue.
 The point of specifications like this are so that they create a level playing
field for all to start from (and thus avoid 'arguments' as to which one is
correct).  Ultimately, if your code doesn't work with the prescribed model, then
you have to find another way of expressing the problem.

Note, I'm not trying to judge here whether your expectations of the PPC ABI are
right or wrong, I'm trying to set the rational for having ABI specifications and
then trying to stick to them.

> I can't quite see what can be gained by minimizing access size, but not knowing
> the complete rationale (why are non-bitfields NOT minimized, e.g. volatile int x
> |= 1), how about a command line switch to let the user select?

I suspect it's historical.  On a machine that can do arbitrary alignment (eg,
traditional CISC processors) then a common layout rule for a bit-field is to
place it as close as possible to the previous field such that it all fits in one
'access' (but probably multiple memory fetches -- afterall, the memory bus is
still aligned).  If that access happens to be volatile, then you still don't
want the memory system to be accessed twice (even transparently) and you can
normally guarantee that by 'narrowing' the object.  

For RISC processors the alignment tends to be more critical in the normal case,
so bit-fields are generally laid out with more padding.  In this situation it
then makes more sense to say that the bit-field's type governs the nature of the
memory access.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23623


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/23623] volatile keyword changes bitfield access size from 32bit to 8bit
  2005-08-29 14:11 [Bug c/23623] New: volatile keyword changes bitfield access size from 32bit to 8bit m dot reszat at kostal dot com
                   ` (7 preceding siblings ...)
  2005-08-30 14:06 ` rearnsha at gcc dot gnu dot org
@ 2005-09-08 15:12 ` m dot reszat at kostal dot com
  8 siblings, 0 replies; 10+ messages in thread
From: m dot reszat at kostal dot com @ 2005-09-08 15:12 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From m dot reszat at kostal dot com  2005-09-08 15:12 -------
(In reply to comment #6)
> (In reply to comment #5)
> > I will try and dig up the EABI for PowerPC
> > > Note this also happens on ARM where (in the EABI) it is definitely a bug

None of the documents I found makes a statement as clear as the ARM EABI does.
Can someone point me to the source file where the "narrowing" is done, to maybe
simply "comment it out"?; I don't feel capable of providing a real fix, see
below, but I also don't want to rewrite large portions of my code when migrating
to GCC.

Having given more thought to the problem, isn't the "narrowing" an optimization
which should not be a fixed property of the compiler, given that even for the
same type of machine ("target") there can exist various different memory
interfaces? Hence, shouldn't it be an optimization option, "on" by default to be
backwards compatible?

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23623


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2005-09-08 15:12 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-08-29 14:11 [Bug c/23623] New: volatile keyword changes bitfield access size from 32bit to 8bit m dot reszat at kostal dot com
2005-08-29 15:39 ` [Bug middle-end/23623] " pinskia at gcc dot gnu dot org
2005-08-29 16:21 ` pinskia at gcc dot gnu dot org
2005-08-29 21:27 ` falk at debian dot org
2005-08-30  7:59 ` m dot reszat at kostal dot com
2005-08-30 12:44 ` falk at debian dot org
2005-08-30 12:51 ` rearnsha at gcc dot gnu dot org
2005-08-30 13:42 ` m dot reszat at kostal dot com
2005-08-30 14:06 ` rearnsha at gcc dot gnu dot org
2005-09-08 15:12 ` m dot reszat at kostal dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).