On Wed, Aug 28, 2002 at 11:19:11AM -0700, Chris Ring wrote:
> Using prc tools (gcc), is there a way to ensure (#pragma perhaps?)
> that some of my stack variables are aligned on 4 byte boundaries?
If you suspect there may be such a pragma, you can find out for yourself
one way or the other via the simple expedient of reading the manual :-).
If you do that, you'll quickly find __attribute__ ((aligned (N))), and
soon after that you'll probably find that it doesn't have the effect
you'd like on auto variables on the stack.
> int fxn() {
> // Err retVal;
> UInt32 foo;
>
> <snip>
> }
>
> Something as simple as uncommenting the retVal declaration will shift
> the location of foo back/forward 16 bits and can cause mis-alignment.
Something even simpler than that will change the alignment of foo. The
m68k stack is only kept aligned to 16 bits; your foo will be 16-bit
aligned, but its 32-bit alignedness will vary randomly depending on what
32-bit alignment state the stack is in on entry to your function.
There's really no static decision-free way to control this, because you
don't have control over the compilation of all your callers. (Consider
a callback function, for example, called directly from the ROM.)
Well, okay, you could control your callers by ensuring that all entry
points to your app go through an assembly stub that conditions the stack
pointer (by adding 2 if necessary) and then yourself try to ensure that
you maintain the alignment in all your functions, but IMHO it'd be more
trouble than it'd be worth.
> I'm one of the fortunate souls with real 5.0 hardware, and I need the
> variables to be 32 bit aligned because they're being passed down to an
> armlet, and the arm crashes when it tries to access non-32-bit aligned
> memory.
I would have thought that the usual answer to this would be for your ARM
code to avoid accessing foo as a 32-bit datum. For example, if you're
byte-swapping it anyway, you might do that a byte at a time, and thus
solve both the byte-swapping and the lack-of-alignment issues at once.
OTOH you can certainly control the 32-bit alignment of global variables
(with __attribute__ ((aligned))). And if you really want to control the
32-bit alignment of variables on the m68k stack, I would suggest writing
it out explicitly:
int fxn () {
union { UInt32 a; struct { UInt16 pad; UInt32 b; } s; } u;
UInt32 &foo = ((long)&u & 3)? u.s.b : u.a;
[...]
> If the current tools don't support this, it might be a very nice
> feature to add to the prc/code warrior compilers ASAP as 5.0 devices
> start showing up and people start writing armlets.
The "allocate overly large [here 6 bytes instead of 4] buffer, test %sp,
pick the appropriate pointer into the buffer" approach above is what a
compiler extension would have to do in order to guarantee 32-bit
alignment for an auto variable when compiling a solitary function.
IMHO the feature would involve an amount of extra runtime code large
enough that such a compiler feature would not be "in the spirit of C".
IMHO there are adequate work-arounds: don't access the data as
32-bit data from the ARM side; use a global buffer; use a malloced
(MemPtrNew'd, the alignment of which I'm sure has come up on
palm-dev-forum before :-), and it's "adequate") buffer; or, do it
yourself manually as above.
John
--
For information on using the Palm Developer Forums, or to unsubscribe, please see
http://www.palmos.com/dev/support/forums/