Reply by Arne Koewing May 28, 20042004-05-28
Ken Barlow wrote:
>>>Is there a way of forcing all alignment onto four byte boundaries? I've >>>looked through the GCC and LD docs and can find switches for other >>>targets, but not the ARM. >> >>Compiler does this automatically. If you, say, have the structure >> >>struct { >> uint8_t one; >> uint32_t two; >>} foo; >> >>then foo.two will always be word aligned. >> >>What are your trying to do? If you would post a snippet of your data >>structure it might be easier to help. >> > > > Hi again, > > The structure is like this: > > struct { > uint8 aByte; > uint8 aByteArray[ 64 ]; > } foo; > > Hence my problem - the aByteArray is used as a generic buffer that can hold > anything. I was putting 32bit words into it, and as a byte array there is > no way of the compiler knowing that I wanted it 32bit aligned - a bit silly > now I come to look at it but sometimes it takes somebody else to point out > you are doing something daft ;-) >
I think you can force gcc to align the buffer using: struct { uint8 aByte; uint8 aByteArray[ 64 ] __attribute__ ((aligned (4))); } foo; (untested) -- Arne
Reply by Ben Bradley May 28, 20042004-05-28
On Fri, 28 May 2004 18:03:02 +0100, "Ken Barlow"
<ken_barlow@hotmail.com.NOSPAM> wrote:

>Hi again, > >The structure is like this: > >struct { > uint8 aByte; > uint8 aByteArray[ 64 ]; >} foo; > >Hence my problem - the aByteArray is used as a generic buffer that can hold >anything. I was putting 32bit words into it, and as a byte array there is >no way of the compiler knowing that I wanted it 32bit aligned - a bit silly >now I come to look at it but sometimes it takes somebody else to point out >you are doing something daft ;-)
There seems to be something a bit kludgy about what I'm about to suggest (I'm not sure why, except there's this Bogus_Variable defined but never used), but could you use a union of a 4-byte 'bogus' unused varuable with the aByteArray, to make the compiler align it? Like this: struct { uint8 aByte; union { uint32 Bogus_Variable; uint8 aByteArray[ 64 ]; } } foo; There seems like there ought to be another way to do it, perhaps with a compiler-specific #pragma, but this should work with any compiler.
>In answer to the other question: I'm not using -fpack-struct. > >Thanks again.
----- http://mindspring.com/~benbradley
Reply by Vadim Borshchev May 28, 20042004-05-28
On Fri, 28 May 2004 18:03:02 +0100, Ken Barlow 
<ken_barlow@hotmail.com.NOSPAM> wrote:

> The structure is like this: > > struct { > uint8 aByte; > uint8 aByteArray[ 64 ]; > } foo;
Fine, this explains why the value you read is rotated right by one byte. You might probably need to do something like struct { uint8 aByte; union { uint32 aWordArray[16]; uint8 aByteArray[64]; } u; } foo; In this case foo.u.aWordArray[x] is guaranteed to be word aligned, as the whole union will be. HTH, Vadim
Reply by Grant Edwards May 28, 20042004-05-28
In article <cjKtc.4668$Dm2.2182@front-1.news.blueyonder.co.uk>, Ken Barlow wrote:

> struct { > uint8 aByte; > uint8 aByteArray[ 64 ]; > } foo; > > Hence my problem - the aByteArray is used as a generic buffer that can hold > anything. I was putting 32bit words into it, and as a byte array there is > no way of the compiler knowing that I wanted it 32bit aligned - a bit silly > now I come to look at it but sometimes it takes somebody else to point out > you are doing something daft ;-)
You probably need to use memcpy() to copy data to/from your buffer. You could force alignment of the beginning of the array, but things will still fall apart if you use type-punned pointers to put multiple things of differing sizes into the buffer.
> In answer to the other question: I'm not using -fpack-struct.
-- Grant Edwards grante Yow! Nice decor! at visi.com
Reply by Ken Barlow May 28, 20042004-05-28
> > Is there a way of forcing all alignment onto four byte boundaries? I've > > looked through the GCC and LD docs and can find switches for other > > targets, but not the ARM. > > Compiler does this automatically. If you, say, have the structure > > struct { > uint8_t one; > uint32_t two; > } foo; > > then foo.two will always be word aligned. > > What are your trying to do? If you would post a snippet of your data > structure it might be easier to help. >
Hi again, The structure is like this: struct { uint8 aByte; uint8 aByteArray[ 64 ]; } foo; Hence my problem - the aByteArray is used as a generic buffer that can hold anything. I was putting 32bit words into it, and as a byte array there is no way of the compiler knowing that I wanted it 32bit aligned - a bit silly now I come to look at it but sometimes it takes somebody else to point out you are doing something daft ;-) In answer to the other question: I'm not using -fpack-struct. Thanks again.
Reply by Grant Edwards May 28, 20042004-05-28
On 2004-05-28, Ken Barlow <ken_barlow@hotmail.com.NOSPAM> wrote:

>>> The code generated to load R0 is: LDR R0, [R2,#0004] where R2 >>> in this case has the same value as R4 in the previous case - >>> but the value loaded into R0 is 0x25400006 - which is all the >>> correct digits but in the wrong order! >> >> Check that R2 is word aligned. If it is not, the loaded value will be >> rotated. >> >> Your address seems to have bit 0 set. If this is the case -- the compiler >> is doing something really nasty. > > Thanks for the advice - the variable being assigned is > actually part of a structure (I simplified the example). > Ensuring the variable started on a 4byte boundary fixed the > problem. Pointer alignment troubles! > > Is there a way of forcing all alignment onto four byte > boundaries? I've looked through the GCC and LD docs and can > find switches for other targets, but not the ARM.
The compiler will properly align all variables and structure fields unless you tell it to do otherwise. IOW, you had to write code that does something bad to get such an alignment problem (most likely typecasting a pointer or using a packed struct). You're probably better off not doing "bad" things rather than forcing the alignment of everything to a word boundary. If you explain what it is you're actually trying to do, somebody can show you how to do it the "good" way. -- Grant Edwards grante Yow! ... I'm IMAGINING a at sensuous GIRAFFE, CAVORTING visi.com in the BACK ROOMof a KOSHER DELI --
Reply by Andy Sinclair May 28, 20042004-05-28
Ken Barlow wrote:
>Thanks for the advice - the variable being assigned is actually part of a >structure (I simplified the example). Ensuring the variable started on a >4byte boundary fixed the problem. Pointer alignment troubles! > >Is there a way of forcing all alignment onto four byte boundaries? I've >looked through the GCC and LD docs and can find switches for other targets, >but not the ARM.
Are you using the compiler switch '-fpack-struct' ? If so you must manually ensure the correct padding is used. Andy
Reply by Vadim Borshchev May 28, 20042004-05-28
On Fri, 28 May 2004 16:28:13 +0100, Ken Barlow 
<ken_barlow@hotmail.com.NOSPAM> wrote:

> Is there a way of forcing all alignment onto four byte boundaries? I've > looked through the GCC and LD docs and can find switches for other > targets, but not the ARM.
Compiler does this automatically. If you, say, have the structure struct { uint8_t one; uint32_t two; } foo; then foo.two will always be word aligned. What are your trying to do? If you would post a snippet of your data structure it might be easier to help. Vadim
Reply by Ken Barlow May 28, 20042004-05-28
> > The code generated to load R0 is: LDR R0, [R2,#0004] > > where R2 in this case has the same value as R4 in the previous case -
but
> > the value loaded into R0 is 0x25400006 - which is all the correct digits > > but in the wrong order! > > Check that R2 is word aligned. If it is not, the loaded value will be > rotated. > > Your address seems to have bit 0 set. If this is the case -- the compiler > is doing something really nasty. > > HTH, > Vadim
Thanks for the advice - the variable being assigned is actually part of a structure (I simplified the example). Ensuring the variable started on a 4byte boundary fixed the problem. Pointer alignment troubles! Is there a way of forcing all alignment onto four byte boundaries? I've looked through the GCC and LD docs and can find switches for other targets, but not the ARM. Thanks again!
Reply by Vadim Borshchev May 28, 20042004-05-28
On Fri, 28 May 2004 10:33:56 +0100, Ken Barlow 
<ken_barlow@hotmail.com.NOSPAM> wrote:

> The code generated to load R0 is: LDR R0, [R2,#0004] > where R2 in this case has the same value as R4 in the previous case - but > the value loaded into R0 is 0x25400006 - which is all the correct digits > but in the wrong order!
Check that R2 is word aligned. If it is not, the loaded value will be rotated. Your address seems to have bit 0 set. If this is the case -- the compiler is doing something really nasty. HTH, Vadim