Re: Bitfields problem

2009-12-11 Thread Jean Christophe Beyler
Interestingly enough, if I do this instead:

typedef struct sTest {
int a:12;
int b:20;
int c:7;
int d:15;
}STest;


int64_t bar2 (STest *a)
{
int64_t res = a-b;
return res;
}

I get at the expand pass :

(insn 6 5 7 3 struct3.c:27 (set (reg:SI 75)
(mem/s:SI (reg/v/f:DI 73 [ a ]) [0 S4 A32])) -1 (nil)) -
Actually get the data

(insn 7 6 8 3 struct3.c:27 (set (reg:DI 77)
(zero_extract:DI (subreg:DI (reg:SI 75) 0)
(const_int 20 [0x14])
(const_int 12 [0xc]))) -1 (nil))   - Extract the
bits we want but this is zero_extracted

(insn 8 7 9 3 struct3.c:27 (set (reg:DI 78)
(ashift:DI (reg:DI 77)
(const_int 43 [0x2b]))) -1 (nil))

(insn 9 8 10 3 struct3.c:27 (set (subreg:DI (reg:SI 76) 0)
(ashiftrt:DI (reg:DI 78)
(const_int 43 [0x2b]))) -1 (nil))   - These two
instructions actually sign extend it

(insn 10 9 11 3 struct3.c:27 (set (reg:DI 79)
(ashift:DI (reg:SI 76)
(const_int 32 [0x20]))) -1 (nil))

(insn 11 10 12 3 struct3.c:27 (set (reg:DI 74)
(ashiftrt:DI (reg:DI 79)
(const_int 32 [0x20]))) -1 (expr_list:REG_EQUAL
(sign_extend:DI (reg:SI 76))
(nil)))   - Because it's seen as a SI, these last two sign
extend it again...


And I get later on in the passes (the instructions are removed by the
combine pass):

(insn 6 3 7 2 struct3.c:27 (set (reg:SI 75)
(mem/s:SI (reg:DI 8 r8 [ a ]) [0 S4 A32])) 74
{movsi_internal2} (expr_list:REG_DEAD (reg:DI 8 r8 [ a ])
(nil)))

(note 7 6 8 2 NOTE_INSN_DELETED)

(note 8 7 9 2 NOTE_INSN_DELETED)

(note 9 8 10 2 NOTE_INSN_DELETED)

(note 10 9 11 2 NOTE_INSN_DELETED)

(note 11 10 16 2 NOTE_INSN_DELETED)

(insn 16 11 22 2 struct3.c:30 (set (reg/i:DI 6 r6)
(zero_extract:DI (subreg:DI (reg:SI 75) 0)
(const_int 20 [0x14])
(const_int 12 [0xc]))) 63 {extzvdi} (expr_list:REG_DEAD (reg:SI 75)
(nil)))

So now I have two issues that I can't seem to figure out :

- Why can combine remove these 4 instructions ?

- Why do I have such a difference between a local variable that is not
a pointer, a pointer and a global variable ?

I remember having a different behavior if the variable was a global
variable or if it was a parameter. It seems that this is the case also
for here. However, this is worse, since it transforms my signed
extract into a simple zero_extract.

Thanks for your help,
Jc

PS: here is the combine pass debug information:

;; Function bar2 (bar2)

starting the processing of deferred insns
ending the processing of deferred insns
df_analyze called
insn_cost 2: 4
insn_cost 6: 4
insn_cost 7: 36
insn_cost 8: 4
insn_cost 9: 4
insn_cost 10: 4
insn_cost 11: 4
insn_cost 16: 4
insn_cost 22: 0
deferring deletion of insn with uid = 2.
modifying insn i3 6 r75:SI=[r8:DI]
  REG_DEAD: r8:DI
deferring rescan insn with uid = 6.
deferring deletion of insn with uid = 8.
modifying insn i3 9 r76:SI#0=r77:DI
  REG_DEAD: r77:DI
deferring rescan insn with uid = 9.
deferring deletion of insn with uid = 7.
modifying insn i3 9 r76:SI#0=zero_extract(r75:SI#0,0x14,0xc)
  REG_DEAD: r75:SI
deferring rescan insn with uid = 9.
deferring deletion of insn with uid = 10.
modifying insn i311 r74:DI=r76:SI#00xf
  REG_DEAD: r76:SI
deferring rescan insn with uid = 11.
deferring deletion of insn with uid = 9.
modifying insn i311 r74:DI=zero_extract(r75:SI#0,0x14,0xc)
  REG_DEAD: r75:SI
deferring rescan insn with uid = 11.
deferring deletion of insn with uid = 11.
modifying insn i316 r6:DI=zero_extract(r75:SI#0,0x14,0xc)
  REG_DEAD: r75:SI
deferring rescan insn with uid = 16.
(note 1 0 4 NOTE_INSN_DELETED)

(note 4 1 2 2 [bb 2] NOTE_INSN_BASIC_BLOCK)

(note 2 4 3 2 NOTE_INSN_DELETED)

(note 3 2 6 2 NOTE_INSN_FUNCTION_BEG)

(insn 6 3 7 2 struct3.c:27 (set (reg:SI 75)
(mem/s:SI (reg:DI 8 r8 [ a ]) [0 S4 A32])) 74
{movsi_internal2} (expr_list:REG_DEAD (reg:DI 8 r8 [ a ])
(nil)))

(note 7 6 8 2 NOTE_INSN_DELETED)

(note 8 7 9 2 NOTE_INSN_DELETED)

(note 9 8 10 2 NOTE_INSN_DELETED)

(note 10 9 11 2 NOTE_INSN_DELETED)

(note 11 10 16 2 NOTE_INSN_DELETED)

(insn 16 11 22 2 struct3.c:30 (set (reg/i:DI 6 r6)
(zero_extract:DI (subreg:DI (reg:SI 75) 0)
(const_int 20 [0x14])
(const_int 12 [0xc]))) 63 {extzvdi} (expr_list:REG_DEAD (reg:SI 75)
(nil)))

(insn 22 16 0 2 struct3.c:30 (use (reg/i:DI 6 r6)) -1 (nil))
starting the processing of deferred insns
deleting insn with uid = 2.
deleting insn with uid = 7.
deleting insn with uid = 8.
deleting insn with uid = 9.
deleting insn with uid = 10.
deleting insn with uid = 11.
rescanning insn with uid = 6.
deleting insn with uid = 6.
rescanning insn with uid = 16.
deleting insn with uid = 16.
ending the processing of deferred insns

;; Combiner totals: 16 attempts, 16 substitutions (2 requiring new space),
;; 6 successes.


On Fri, Dec 11, 2009 at 11:57 AM, Jean Christophe 

Re: Bitfields

2009-09-20 Thread Paolo Bonzini



reg.field1 = val1, reg.field2 = val2;

would then turn into fetch, mask with a combined mask of field1 and
field2, or val1, or val2, store.


You can also do the RMW yourself: declare the register volatile, but not 
the fields of it, and copy in/out of the register manually.


volatile struct reg x;

...
{
  struct reg mine = x;
  mine.field1 = true;
  mine.field2 = 0;
  mine.field3++;
  x = mine;
}


Is it a completely brain-dead idea?


If I understood it correctly, it would not be standard compliant.

Paolo



Re: Bitfields

2009-09-20 Thread Robert Dewar

Paolo Bonzini wrote:


Is it a completely brain-dead idea?


If I understood it correctly, it would not be standard compliant.


But it's an extension, so I don't see that is an issue of itself.


Paolo





Re: Bitfields

2009-09-20 Thread Joseph S. Myers
On Sun, 20 Sep 2009, Zolt??n K??csi wrote:

 I wonder if there would be at least a theoretical support by the
 developers to a proposal for volatile bitfields:

It has been proposed (and not rejected, but not yet implemented) that 
volatile bit-fields should follow the ARM EABI specification (on all 
targets); that certainly seems better than inventing something new unless 
you have a very good reason to prefer the something new on some targets.

-- 
Joseph S. Myers
jos...@codesourcery.com

Re: Bitfields

2009-09-20 Thread zoltan
On Sun, 20 Sep 2009, Joseph S. Myers wrote:

 On Sun, 20 Sep 2009, Zolt??n K??csi wrote:

  I wonder if there would be at least a theoretical support by the
  developers to a proposal for volatile bitfields:

 It has been proposed (and not rejected, but not yet implemented) that
 volatile bit-fields should follow the ARM EABI specification (on all
 targets); that certainly seems better than inventing something new unless
 you have a very good reason to prefer the something new on some targets.

Yes, that discussion was that made me thinking and suggesting this
*before* the ARM EABI gets implemented. I don't suggest to implement
something instead of the ARM EABI, I suggest to implement something on top
of it. The suggested behaviour is also architecture-neutral.

It is nothing more than if the user expressly asks the compiler to break
the standard in a particular way, then the compiler does so. The breaking
of the standard is at one single point. The ARM EABI spec clearly states
that bitfield operations are never to be combined, not even in the case
where consecutive bitfield assignments refer to bitfields located in the
same machine word. My suggestion was that if a new command line switch is
present, then in the special case of consecutive bitfield assignments
being made to fields within the same word and the assignments being
separated by the comma operator, then the compiler combines those
assignments. The rationale of such behaviour is writing low-level code
dealing with HW registers. To have a practical example, let's have a SoC
chip with multi-function pins. Let's assume that we have a register that
has 2 bits for each actual pin and the value of the 2 bits selects the
actual function for the pin; a 32 bit register can thus control 16 pins.
Now if you want to, say, assign 4 pins to the SPI interface, without
bitfields you would (and indeed do) write something along these lines:

temp = *pin_control_reg;
temp = ~(PIN_03_MASK | PIN_04_MASK | PIN_05_MASK | PIN_06_MASK);
temp |= PIN_O3_MISO | PIN_04_MOSI | PIN_05_SCLK | PIN_06_SSEL;
*pin_ctrl_reg = temp;

You can't really use bitfields to achieve the above, because if you write

pin_control_reg-pin_03 = MISO;
pin_control_reg-pin_04 = MOSI;

and so on, pin_xx being 2-bit wide bitfields, then according to the ARM
EABI spec each statement would be translated to a temp = *pin_contorl_reg;
temp =...; temp |=...;  *pin_control_reg=temp; sequence. What I suggest
is that if you write

pin_control_reg-pin_03 = MISO, // Note the comma
pin_control_reg-pin_04 = MOSI,
pin_control_reg-pin_05 = SCLK,
pin_control_reg-pin_06 = SSEL;

and compile it with a -fcomma-combines-bitfields switch, then you get the
equivalent of the first code fragment where you manually combined the
masks and the settings and only a single load and a single store was used.

If the switch is not given or the consecutive assignments are not
separated by commas or the bitfields do not belong to the same word, then
the behaviour falls back to the default ARM EABI spec.

The advantage of the suggested behaviour is that it would allow the use of
the more elegant and expressive bitfields in place of the many hundreds of
#define REGNAME_FIELDNAME_MASK and #define REGNAME_FIELDNAME_SHIFT macros
that you can currently find in code that deals with HW. The suggestion
does not introduce any new functionality or performance advantage, it just
provides a way of writing (in my opinion) more readable and more
maintainable code than what we have now with all the #defines. The fact
that structure members live in their own namespace as opposed to the
global #define namespace is an added benefit, of course.

The suggested extension does not break backward compatibility, because the
#define stuff would not be affected and the ARM EABI is not yet
implemented anyway; it would not break the expected behaviour because it
becomes active only when an explicite command line switch is given and has
no side-effects outside the single expression where the subexpressions are
separated by commas.

The change, I believe, would benefit gcc users who deal with HW a lot,
i.e. low level embedded system and device driver designers. Outside of
that circle the suggested behavior would have only a little performance
benefit.

Zoltan



Re: bitfields: types vs modes?

2009-07-16 Thread DJ Delorie

 At the risk of being naive: implement it.  I'm not quite sure what
 you're looking for here?

Ok, time to ask for a hint.  I started at get_best_mode(), adding a
TREE argument for the type, and worked my way out, adding arguments to
functions as needed to propogate the type information.  It's getting
out of hand.  Is there some easier way to track the type that an rtx
came from?  Perhaps we could call get_best_mode() earlier in the whole
process, and put that mode in the rtx instead of BLKmode ?


Re: bitfields: types vs modes?

2009-07-14 Thread DJ Delorie

  I think the ARM specification is pretty sensible, and would make a
   good cross-platform approach.
  
  Could you distill it for us? 
 
 The relevant bits are from AAPCS \S 7.1.7.5, and quoted below.

I finally got the last of the feedback I needed from our customers,
and they agree that the AAPCS functionality is suitable for their
ports as well.

What's the next step?


Re: bitfields: types vs modes?

2009-07-14 Thread Mark Mitchell
DJ Delorie wrote:
 I think the ARM specification is pretty sensible, and would make a
  good cross-platform approach.

 I finally got the last of the feedback I needed from our customers,
 and they agree that the AAPCS functionality is suitable for their
 ports as well.

Great!

 What's the next step?

At the risk of being naive: implement it.  I'm not quite sure what
you're looking for here?

I'd assume that we should try to do some of this at the tree-rtl
conversion point, in a platform-independent manner, but I'm not an
expert on those bits.

Thanks,

-- 
Mark Mitchell
CodeSourcery
m...@codesourcery.com
(650) 331-3385 x713


Re: bitfields: types vs modes?

2009-07-14 Thread DJ Delorie

 At the risk of being naive: implement it.  I'm not quite sure what
 you're looking for here?

I'd rather have some confidence that the way I choose to implement it
would be acceptable to those who would be reviewing it ;-)

I'll give it a shot at the same point in the code where we call the
target now.


Re: bitfields: types vs modes?

2009-05-21 Thread Mark Mitchell
DJ Delorie wrote:
 I think the ARM specification is pretty sensible, and would make a
  good cross-platform approach.
 
 Could you distill it for us? 

The relevant bits are from AAPCS \S 7.1.7.5, and quoted below.

The term container here means the declared type of the bit-field.
(There's a corner-case for C++ bit-fields that are bigger than their
declared type, but don't worry about that.)  So int i:6 has a 32-bit
container, whereas char c:6 has an 8-bit container.

(In the ARM ABI, a bit-field never crosses a container boundary; struct
{ char c1:6; char c2:3} puts c2 completely into the second byte, not
straddling the first two bytes.  But, if those were int bit-fields, then
the second bit-field would straddle the two bytes.  Packed structures
are outside the scope of the ABI.)

 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.

 Multiple accesses to the same volatile bit-field, or to additional
 volatile bit-fields within the same container may not be merged. For
 example, an increment of a volatile bit-field must always be
 implemented as two reads and a write.

 Note the volatile access rules apply even when the width and
 alignment of the bit-field imply that the access could be achieved
 more efficiently using a narrower type. For a write operation the
 read must always occur even if the entire contents of the container
 will be replaced.

 If the containers of two volatile bit-fields overlap then access to
 one bit-field will cause an access to the other. For example, in
 struct S {volatile int a:8; volatile char b:2}; an access to a will
 also cause an access to b, but not vice-versa.

 If the container of a non-volatile bit-field overlaps a volatile
 bit-field then it is undefined whether access to the non-volatile
 field will cause the volatile field to be accessed.

-- 
Mark Mitchell
CodeSourcery
m...@codesourcery.com
(650) 331-3385 x713


Re: bitfields: types vs modes?

2009-05-20 Thread DJ Delorie

We seem to have dropped this discussion.  I now have *two* customers
asking for this functionality.  Can we pick it up again?  We need to
decide:

1. If the functionality will be allowed in gcc at all

2. What info the target needs to be provided to make the choices it wants

3. What, if any, common code can be shared between the CPUs


Re: bitfields: types vs modes?

2009-05-20 Thread Mark Mitchell
Ian Lance Taylor wrote:

 1. If the functionality will be allowed in gcc at all

 2. What info the target needs to be provided to make the choices it wants

 3. What, if any, common code can be shared between the CPUs
 
 Since the ARM ABI apparently specifies something about volatile
 bitfields, I think we ought to implement that.

Yes, we should.  I am aware of real user demand for this feature as
well.  It's a competitive disadvantage for GCC not to have this feature.

 I continue to think that a sane programmer would use a different
 mechanism.  C/C++ provides mechanisms for working with memory mapped
 hardware.  Bitfields are not one of those mechanisms.

I think the ARM specification is pretty sensible, and would make a good
cross-platform approach.  Using bit-fields may not be portable at
present, but it would sure be nice if it was; it maps directly onto how
people think about memory-mapped peripherals.

-- 
Mark Mitchell
CodeSourcery
m...@codesourcery.com
(650) 331-3385 x713


Re: bitfields: types vs modes?

2009-05-20 Thread DJ Delorie

 I think the ARM specification is pretty sensible, and would make a
 good cross-platform approach.

Could you distill it for us?  If it's acceptable to my two customers,
it would be a good starting point to define an API for the targets.


Re: bitfields: types vs modes?

2009-04-06 Thread Mark Mitchell
Ian Lance Taylor wrote:

 So... can I/we move forward on this?  Or will such a change be
 rejected?

 It's hard for me to get excited about something like this.  It's
 straightforward a programmer to write code that is clearly correct in
 this sort of situation: just don't use a bitfield. 

In part, because of the ARM ABI issue, I think we ought to accept
patches that fix this problem.  It's true that GCC doesn't in general
document these semantics, but users of some ABIs have expectations about
how volatile bitfields will work.

DJ, I'd suggest you look at:

http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042c/IHI0042C_aapcs.pdf

and, in particular, \S 7.1.7.5, entitled Volatile bit-fields.

A first question is if these are the semantics that you're looking for
in your project.  If so, then we could collaborate with you on
implementing them.  If not, there may be still be some common parts.

-- 
Mark Mitchell
CodeSourcery
m...@codesourcery.com
(650) 331-3385 x713


Re: bitfields: types vs modes?

2009-04-06 Thread DJ Delorie

 http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042c/IHI0042C_aapcs.pdf
 
 and, in particular, \S 7.1.7.5, entitled Volatile bit-fields.
 
 A first question is if these are the semantics that you're looking for
 in your project.  If so, then we could collaborate with you on
 implementing them.  If not, there may be still be some common parts.

Yes, that's pretty much what they asked for.  However, it is still
somewhat ambiguous - for example, if you have an 8-bit int field,
which 4 bytes are read to get that field?  Should we take into
consideration adjacent field types, or the type's natural alignment?
What if the field spans natural alignment boundaries?  What if the
larger-than-field access exceeds the memory region and causes a fault?

For example, in this case, when we access x.b does it also read a, or
c?  Will reading x.d cause a segment fault?

volatile struct {
char a:8;
int b:24;
char c:8;
int d:8;
} x;

We need to figure out how much information we should pass to the
target to let it make these decisions, if it needs to.  A common
function to do by-type access could be called from your target and
mine.


Re: bitfields: types vs modes?

2009-04-06 Thread Mark Mitchell
DJ Delorie wrote:

 Yes, that's pretty much what they asked for.  However, it is still
 somewhat ambiguous - for example, if you have an 8-bit int field,
 which 4 bytes are read to get that field? 

I haven't gone back just now to try to find the right words in the ABI,
so I don't know for sure that they're there, but the intent is the
types' natural alignment.  All int bit-fields in that ABI are located
within a 32-bit aligned range of memory; the intent is that you
read/write that entire 4-byte range.  In other words, take the byte
address of the start of the bit-field, mask off the two low-order bits,
that's the 4-byte address to read.

On an ARM, you can never cross a protection boundary in that way; you're
never going to get a SEGV from the bytes you read in that way if you
wouldn't have gotten one from the byte containing the start of the
bit-field.  Protection is done at the page (or cache-line, I forget)
boundary; in either case, the granularity of protection is greater than
the granularity of any basic type.  And, if it's not, that's your
problem; the ABI semantics of a volatile bit-field of type T are that
you get sizeof(T) bytes, and if it blows up (which I don't think it
can), it's not the compiler's fault.

If you have an ABI where an int bit-field can cross a sizeof(int)-byte
boundary, that's a harder case.  That can happen on ARM with GCC's
packed-structure extension, but that's outside the ARM ABI, and
therefore the behavior is not specified.

 We need to figure out how much information we should pass to the
 target to let it make these decisions, if it needs to.  A common
 function to do by-type access could be called from your target and
 mine.

I'd like to know how many of the assumptions above are valid on your
target.  I would imagine that many of them are.  In which case, the
existing hook is good enough; we just need to implement middle-end
behavior depending on the hook.

-- 
Mark Mitchell
CodeSourcery
m...@codesourcery.com
(650) 331-3385 x713


Re: bitfields: types vs modes?

2009-03-31 Thread DJ Delorie

So... can I/we move forward on this?  Or will such a change be
rejected?

BTW, Since sending this I discovered that gcc treats these
differently wrt TARGET_NARROW_VOLATILE_BITFIELD:

volatile struct
{
  unsigned int a:8;
  unsigned int b:24;
} t1;

volatile struct
{
  unsigned int a:7;
  unsigned int b:25;
} t2;

t1.a will be accessed as a byte regardless of the target's
preferences, whereas t2.c follows the target preferences.

 One of our customers has a chip with memory-mapped peripheral
 registers that need to be accessed in a specific mode.  The registers
 represent bitfields within the hardware, so a volatile struct is an
 obvious choice to represent them in C.
 
 However, gcc has a very simplistic heuristic for deciding what mode to
 use to access bitfields in structures - it uses either the biggest or
 smallest mode practical.  This offers the programmer no way to tell
 gcc what mode the accesses need to be in, aside from manually
 reading/writing memory with integer types and casting.
 
 Options?  My thought, after some internal discussion, is that (if the
 target chooses) we allow gcc to honor the type of a volatile bitfield
 as the mode as long as it can do so without otherwise violating the
 structure's layout.  Some new hook will be needed for the backend, and
 perhaps a -W option for when the type cannot be honored.
 
 I.e. if the programmer is careful enough to properly lay out the
 struct, the programmer should get what the programmer asks for.
 
 Comments?  Alternatives?


Re: bitfields: types vs modes?

2009-03-31 Thread Ian Lance Taylor
DJ Delorie d...@redhat.com writes:

 So... can I/we move forward on this?  Or will such a change be
 rejected?

 BTW, Since sending this I discovered that gcc treats these
 differently wrt TARGET_NARROW_VOLATILE_BITFIELD:

 volatile struct
 {
   unsigned int a:8;
   unsigned int b:24;
 } t1;

 volatile struct
 {
   unsigned int a:7;
   unsigned int b:25;
 } t2;

 t1.a will be accessed as a byte regardless of the target's
 preferences, whereas t2.c follows the target preferences.

 One of our customers has a chip with memory-mapped peripheral
 registers that need to be accessed in a specific mode.  The registers
 represent bitfields within the hardware, so a volatile struct is an
 obvious choice to represent them in C.
 
 However, gcc has a very simplistic heuristic for deciding what mode to
 use to access bitfields in structures - it uses either the biggest or
 smallest mode practical.  This offers the programmer no way to tell
 gcc what mode the accesses need to be in, aside from manually
 reading/writing memory with integer types and casting.
 
 Options?  My thought, after some internal discussion, is that (if the
 target chooses) we allow gcc to honor the type of a volatile bitfield
 as the mode as long as it can do so without otherwise violating the
 structure's layout.  Some new hook will be needed for the backend, and
 perhaps a -W option for when the type cannot be honored.
 
 I.e. if the programmer is careful enough to properly lay out the
 struct, the programmer should get what the programmer asks for.
 
 Comments?  Alternatives?


It's hard for me to get excited about something like this.  It's
straightforward a programmer to write code that is clearly correct in
this sort of situation: just don't use a bitfield.  gcc doesn't even
document the order of bits in a bitfield, so it's generally difficult to
reliably use bitfields to access memory mapped registers.  If this were
my customer, I would tell them to write inline functions which access
the data as integers of the appropriate size and do the required
shifting and masking.  That code only has to be written once, it will be
just as efficient as the code generated by using a volatile bitfield
struct, and it will be clearly correct with any reasonable compiler.

A volatile bitfield is a dubious construct all by itself.  The volatile
qualifier is supposed to direct the compiler to act exactly like the
virtual machine.  But what does the virtual machine do on an assignment
to a volatile bitfield?  Many real machines must read the value, change
some bits, and then write the value back.  Is that following the virtual
machine or not?  Is the volatile qualifier misleading in such a case?

In any case, while I recommend against it, I won't stop you if you
really want to follow your proposal.  The most important thing for this
approach would be the documentation, so write that first.  Your brief
description above is insufficient; I'm not sure what you mean by
without otherwise violating the structure's layout, and I don't know
why you might need a -W option.  Then, of course, you will need a fairly
complete set of test cases.


I want to say that I think that this comment:

 I.e. if the programmer is careful enough to properly lay out the
 struct, the programmer should get what the programmer asks for.

is misleading.  When I give a type to a bitfield, I don't think I am
asking for the bitfield to be accessed in that type.  It's not a case of
the programmer getting what he or she asks for; it's a case of the
programmer wants to define a specific set of semantics to bitfields, a
language construct which can provide a range of different semantics.

Ian


Re: bitfields: types vs modes?

2009-03-11 Thread Paul Brook
On Tuesday 10 March 2009, DJ Delorie wrote:
 One of our customers has a chip with memory-mapped peripheral
 registers that need to be accessed in a specific mode.  The registers
 represent bitfields within the hardware, so a volatile struct is an
 obvious choice to represent them in C.

 Comments?  Alternatives?

PR23623 (I suspect the status on that bug is incorrect, it's nt actually 
fixed). The ARM EABI defines semantics for volatile bitfields, and gcc gets 
this wrong.

Paul


Re: bitfields: types vs modes?

2009-03-11 Thread Laurent GUERBY
On Wed, 2009-03-11 at 01:05 -0400, DJ Delorie wrote:
  Can you provide example code?  I'm confused enough to believe
  that you *should* get this effect with PCC_BITFIELD_TYPE_MATTERS
  (modulo current bugs).
 
 Imagine a device with four 8-bit registers followed by a 32-bit
 register with an 8-bit field:
 
 byte  status (read-only, clears after reading)
 byte  control (read/write)
 byte  tx buf (write only)
 byte  rx buf (read only)
 long  uart configuration
   divisor:8
   bits:3
   stop:1
   start:1
   reserved:3
   clock source:8
   pin_selection:8
 
 so, you'd do this:
 
 typedef struct {
   char status:8;
   char control:8;
   char tx:8;
   char rx:8;
   long divisor:8;
   long bits:3;
   long stop:1;
   long start:1;
   long reserved:3;
   long clock_source:8;
   long pin_selection:8;
 } UartDev;
 
 extern volatile UartDev uart1;
 
 If you use SImode to access any of the first four registers, you may
 end up clearing a status bit you haven't read yet.  If you use QImode
 to write the divisor, you may end up clearing the other bits if gcc
 doesn't drive the right values onto the bus.
 
 With our current code, the mode for access for the above would either
 always be QI or always be SI; there's no way to have QI for the first
 four and SI for the rest.
 
 The culprit is get_best_mode(), which doesn't know the C type of the
 field.  PCC_BITFIELD_TYPE_MATTERS seems to only control layout, not
 access.  Even if it did solve the type-v-mode problem, turning it on
 would break ABI compatibility.

I don't know how the Ada front-end achieve this and wether it's portable
but the following seem to work:

procedure Aa is

   type U8 is mod 2**8;
   for U8'Size use 8;
   pragma Atomic (U8);

   type U8B is mod 2**8;
   type U3B is mod 2**3;
   type U1B is mod 2;

   type R1 is record
  B1 : U8B;
  B2 : U3B;
  B3 : U1B;
  B4 : U1B;
  B5 : U3B;
  B6, B7 : U8B;
   end record;
   pragma Pack (R1);
   pragma Atomic (R1);

   type R is record
  B1, B2, B3, B4 : U8;
  B5 : R1;
   end record;
   pragma Pack (R);
   pragma Volatile (R);

   X : R;
   X1 : R1;
begin
   X.B1 := 0;
   X.B2 := 0;
   X.B3 := 0;
   X.B4 := 0;
   X1 := X.B5;
end AA;


gcc -S -O2 aa.adb
_ada_aa:
.LFB1:
movb$0, -12(%rsp)
movb$0, -11(%rsp)
movb$0, -10(%rsp)
movb$0, -9(%rsp)
movl$0, -24(%rsp)
ret





Re: bitfields: types vs modes?

2009-03-11 Thread Hans-Peter Nilsson
On Wed, 11 Mar 2009, Paul Brook wrote:
 PR23623 (I suspect the status on that bug is incorrect, it's nt actually
 fixed). The ARM EABI defines semantics for volatile bitfields, and gcc gets
 this wrong.

If the ARM EABI really documents the semantics for that,
implement-c.texi:Qualifiers does need to defer to the ABI just
as the other items there, rather than using weasel words to the
effect of flying demons up your nose, ha ha.  After fixing the
mentioned bug that is; *with* the bug the current wording fits. ;)
(Yeah yeah, I know: patches welcome.)

brgds, H-P


Re: bitfields: types vs modes?

2009-03-10 Thread Hans-Peter Nilsson
On Tue, 10 Mar 2009, DJ Delorie wrote:
 One of our customers has a chip with memory-mapped peripheral
 registers that need to be accessed in a specific mode.  The registers
 represent bitfields within the hardware, so a volatile struct is an
 obvious choice to represent them in C.

Thank you for those words.  ;)

(There was a minor argument on IRC some time ago on a related
subject.)

 However, gcc has a very simplistic heuristic for deciding what mode to
 use to access bitfields in structures - it uses either the biggest or
 smallest mode practical.  This offers the programmer no way to tell
 gcc what mode the accesses need to be in, aside from manually
 reading/writing memory with integer types and casting.

And not even *then* are you guaranteed the intended semantics as
per the documentation (though at least each target should be
able to promise that, IMNSHO).  IMHO GCC should have the means
to do what you suggest for *all* targets; memory-mapped I/O that
needs to be accessed in a specific mode is a general-enough
situation.

 Options?  My thought, after some internal discussion, is that (if the
 target chooses) we allow gcc to honor the type of a volatile bitfield
 as the mode as long as it can do so without otherwise violating the
 structure's layout.  Some new hook will be needed for the backend, and
 perhaps a -W option for when the type cannot be honored.

 I.e. if the programmer is careful enough to properly lay out the
 struct, the programmer should get what the programmer asks for.

Can you provide example code?  I'm confused enough to believe
that you *should* get this effect with PCC_BITFIELD_TYPE_MATTERS
(modulo current bugs).

 Comments?

The concept is certainly agreeable.  I'd recommend -fno-tree-sra
when you inspect current behavior; there be bugs there.  Sorry,
no PR yet.

brgds, H-P


Re: bitfields: types vs modes?

2009-03-10 Thread DJ Delorie

 Can you provide example code?  I'm confused enough to believe
 that you *should* get this effect with PCC_BITFIELD_TYPE_MATTERS
 (modulo current bugs).

Imagine a device with four 8-bit registers followed by a 32-bit
register with an 8-bit field:

bytestatus (read-only, clears after reading)
bytecontrol (read/write)
bytetx buf (write only)
byterx buf (read only)
longuart configuration
divisor:8
bits:3
stop:1
start:1
reserved:3
clock source:8
pin_selection:8

so, you'd do this:

typedef struct {
  char status:8;
  char control:8;
  char tx:8;
  char rx:8;
  long divisor:8;
  long bits:3;
  long stop:1;
  long start:1;
  long reserved:3;
  long clock_source:8;
  long pin_selection:8;
} UartDev;

extern volatile UartDev uart1;

If you use SImode to access any of the first four registers, you may
end up clearing a status bit you haven't read yet.  If you use QImode
to write the divisor, you may end up clearing the other bits if gcc
doesn't drive the right values onto the bus.

With our current code, the mode for access for the above would either
always be QI or always be SI; there's no way to have QI for the first
four and SI for the rest.

The culprit is get_best_mode(), which doesn't know the C type of the
field.  PCC_BITFIELD_TYPE_MATTERS seems to only control layout, not
access.  Even if it did solve the type-v-mode problem, turning it on
would break ABI compatibility.