On 2008-02-14, Peter Jansen <[email protected]> wrote:

>> I'm afraid you've lost me completely.  I thought the OP was
>> complaining about mps430-gcc not generating correct code for
>> accessing misaligned fields in packed structs.
>
> Where is the test case?

Excellent question.  I tried to wade through the OP's code, but
didn't make it all the way through.  I'm still not 100% sure
what he thought was wrong.  That's why I asked a few posts back
if he was complaining that msp43-gcc didn't generate correct
code when accessing a misaligned field in a packed struct.  At
least that's what I meant to ask, because it _does_ work
correctly on other targets (e.g. ARM, SPARC).

> there are many ways to generate misaligned access, an example
> (with Makefile or command line arguments) that replicates the
> problem would make it easier to find. I have seen one case and
> not been able to replicate it all the time, I think it was 
> something to do with passing pointers to structures to
> functions.

De-referencing a pointer to a field in a packed struct is an
excellent way to shoot yourself in the foot -- I've done that a
couple of times.  However, that's not supposed to work.  Is
_that_ what the OP was complaining abuot?  It would be cool if
there was some sort of "pointer to packed <foo>" type that
would generate alignment-neutral code, but that's not a feature
that gcc has.

>> I wasn't aware we were discussing type casting...
>
> Ok I thought that you were trying to use your packed structure
> to get an array of bytes to send/receive over a communications
> channel. This is a type conversion between a structure and an
> array of bytes.

Right.  Using a packed struct to get things aligned in memory
the way you want works fine. Accessing the structure as an
array of bytes works fine.  On _other_targets_, accessing
fields within the packed stuct works fine.  With msp430-gcc it
doesn't work.

Here's an example:

struct foo
{
  char c;
  unsigned u;
} __attribute__((packed));

struct foo s;

unsigned bar(void)
{
  return s.u;
}

On the MSP430, you get code like this:

GAS LISTING /tmp/ccfoE3n2.s                     page 1

   9:testit.c      **** unsigned bar(void)
  10:testit.c      **** {
  51                    .LM1:
  52                    /* prologue: frame size = 0 */
  53                    .L__FrameSize_bar=0x0
  54                    .L__FrameOffset_bar=0x0
  55                    /* prologue end (size=0) */
  11:testit.c      ****   return s.u;
  12:testit.c      **** }
  57                    .LM2:
  58 0000 1F42 0000             mov     &s+1, r15 
  59 0004 3041                  ret

That's wrong.  The "mov" instruction at line 58 is a word
access to an odd address.  Apparently this is a known bug, but
it isn't clearly documented.

If you compile the same code for ARM, you get this:

unsigned bar(void)
{
  return s.u;
   0:   e59f2020        ldr     r2, [pc, #32]   ; 28 <bar+0x28>
   4:   e5d23002        ldrb    r3, [r2, #2]
   8:   e5d21001        ldrb    r1, [r2, #1]
   c:   e5d2c003        ldrb    ip, [r2, #3]
  10:   e1a03803        mov     r3, r3, lsl #16
  14:   e1833c01        orr     r3, r3, r1, lsl #24
  18:   e5d20004        ldrb    r0, [r2, #4]
  1c:   e183340c        orr     r3, r3, ip, lsl #8
  20:   e1800003        orr     r0, r0, r3
}
  24:   e1a0f00e        mov     pc, lr


As you can see, the ARM backend generates byte-accesses and
assembles the return value from the individually accessed bytes
as it should.

-- 
Grant Edwards                   grante             Yow! Am I elected yet?
                                  at               
                               visi.com            


Reply via email to