On Wed, Feb 05, 2003 at 08:05:10AM +0000, Sean Charles wrote:
> in the run up to the main blitter code I was actually doing things
> like this,
>
> asm("move.w %0, %%d1" : : "g" (p->width*p->height)... );
>
> and because the compiler had to generate some code to do the
> multiplication, it *used some registers* that I had already loaded in
> previous asm() statements, causing the problem.
Well, yes, I was going to comment on your wacky use of multiple separate
adjacent asm()s :-), but I thought it was just going to be a distraction.
asm("move.l %0, %%a0" : : "g" (ptrScreen));
asm("move.l %0, %%a1" : : "g" (pBitmapData));
asm("move.l %0, %%a2" : : "g" (pAddresses));
asm("move.b %0, %%d0" : : "g" (transparentIndex));
asm("move.w %0, %%d1" : : "g" (xpos));
asm("move.w %0, %%d7" : : "g" (xpos));
asm("move.w %0, %%d2" : : "g" (ypos));
asm("move.w %0, %%d3" : : "g" (width));
asm("move.w %0, %%d4" : : "g" (height));
Quite apart from the particular example you found, there's no particular
reason to assume that the compiler won't delay or hoist other code into
the middle of this sequence of asm()s. In a case like this it's probably
fairly unlikely; but it is not prevented by the specification, so your
code is a weird bug waiting to happen.
Your asm()s also fail to tell the compiler that they're clobbering all
those registers. So if you had some C code in the same function before
and after these asm()s, you'd likely get incorrect generated code because
the optimizer would assume that it could cache values across the asm()s
in the registers that you haven't told it you're using.
There is no way to tell the compiler to preserve registers from one
asm() to another (other than using -ffixed-<reg> to reserve them over
the whole translation unit, which of course you don't want to do).
The thing to do instead is to use a *single* asm():
asm ("move.l %0, %%a0
move.l %1, %%a1
move.l %2, %%a2
..." : : "g" (ptrScreen), "g" (pBitmapData),
"g" (pAddresses), ...);
And in fact the really natural way to write this is to let the asm()
choose and load the registers, and explicitly write only the interesting
code:
asm ("move.w %4,%5
<blitter code using %0, %1, %2 etc>" : :
"a" (ptrScreen), "a", (pBitmapData), "a" (pAddresses),
"d" (transparentIndex), "d" (xpos), "d" (0), "d" (ypos),
"d" (width), "d" (height));
(That's just off the top of my head; there's surely a better way to get
two copies of xpos. You'd probably need more constraints (in the "d"
string) to ensure that CSE doesn't put both copies of xpos in the same
register. Exercise for the reader.)
John
--
For information on using the Palm Developer Forums, or to unsubscribe, please see
http://www.palmos.com/dev/support/forums/