Open rhalkyard opened 9 months ago
I should add, this is easy enough to work around by just 'manually' saving and restoring A5 in the assembly block, but it was definitely a fun issue to track down! Mostly just putting this here to document it - I wouldn't consider it a high priority to fix.
That's an interesting... consequence.
I guess that %a5 is reserved as a fixed register, but it's not actually considered 'used', so it doesn't get saved & restored.
GCC seems to behave similarly on other platforms... on ARM, %x29 is the frame pointer, and....
int foo();
void useFramePointer()
{
foo();
}
void clobberFramePointer()
{
asm volatile(
"add x29, x29, x29"
: : : "x29"
);
}
gives me
useFramePointer():
stp x29, x30, [sp, -16]!
mov x29, sp
bl foo()
ldp x29, x30, [sp], 16
ret
clobberFramePointer():
add x29, x29, x29
ret
... in other words - it's carefully saving and restoring %x29 before it does a function call, but it does nothing to protect it from the asm statement.
So let's leave this ticket here as a warning until there's a piece of documentation that mentions it...
Given an
asm()
block such as:Registers
A3
,A4
, andA5
are marked as 'clobbered' and should be saved and restored. However, the generated code (fromm68k-apple-macos-gcc -S a5test.c
) preservesA3
andA4
, but notA5
:I don't have a copy of mainline GCC 9 to test this against, but m68k GCC 13.2 does not exhibit this behavior, saving and restoring
A5
correctly along with the others: https://godbolt.org/z/r5zese79jI'm assuming that this is a side effect of modifying GCC to avoid using
A5
due to its special nature on the Mac OS, but in this case it has the opposite effect!