Closed kernigh closed 7 years ago
Yup, definitely broken. Thanks for the report.
I've fixed them and pushed the change to dtrg-experimental-mcgg.
The first bug was because the PowerPC stack frame handling was basically mangled and wrong --- I changed it to be simpler and more consistent. (You also get a much more useful stack map in the comment at the top of each procedure.)
The second one was a combination of the PowerPC table never asking for the outputs to be in the right registers in the first place, and a much more subtle problem where the register allocator was unable to allocate the output register because the output register is volatile and the patterns for the call instructions mark the volatile registers as being corrupted. I tweaked the allocator to allow outputs to go into corrupted registers.
I found two bugs in how mcg (commit 4ba409e) compiles
plat/linux/libsys/write.c
. The function being compiled isThe output of
ack -mlinuxppc -O6 -c.so write.c
isFirst bug: The saved r31 overwrites the saved r2. We have allocated 12 bytes of stack space, saved r2 in 4(sp), saved lr in 8(sp), but now save r31 in 4(sp), because
addi fp, sp, 4
causes 0(fp) to be the same word as 4(sp).Second bug: Functions seem to store their return values in r3 but load them from r31. This wrong
mr r3, r31
is destroying the return value.This is the first bug again. It's now restoring the caller's r31 from 0(r2) and the caller's r2 from 0(r2), but we lost the value of r2. In my test program, r31 held zero, and r2 held the frame pointer of main(). When main() tried to use the frame pointer, it segfaulted.