Hi,
I've been playing around with QBE on my M1 Macbook Pro using the apple-m1 branch (commit c8cd2824ea).
I kept failing to get correct output with the 'minic' compiler.
Here were the commands I used:
./minic < test/euler9.c > euler9.qbe
../qbe -tarm64 -Gm -o euler9.s euler9.qbe
clang euler9.s -o euler9
This printed some garbage instead of the correct solution I had for the Euler 9 problem (website shows the answer after you solve it).
I assumed this was an ABI problem, but it turns out this is an issue with the IR output from minic.
The varadic specifier `...` in the printf call is placed incorrectly.
Correcting `call $printf(l $glo1, w %t44, ...)` to `call $printf(l $glo1, ..., w %t44)` completely fixes the problem.
Here is a link to the generated QBE file: https://paste.sr.ht/~techcable/e208d7190ef746b82f0930ab5260505edc6be536#euler9.qbe-L63
According to the IR reference, correct placement of `...` is required by the QBE spec (so this is definitely minic's fault)
Interestingly enough, this is *not* a problem on x64 macs. I checked by cross-compiling and running in an emulator. There is a good chance this is also not a problem on x64 Linux (pretty sure x86_64 ABI is standard).
Looking into the `minic` sources, it doesn't seem to track function arguments very carefully.
I'm not sure there's an easy fix for this problem in `minic`.......
Anyways, thanks for your work on QBE (and porting to M1 Macs) ,
- Techcable
On Sun, Aug 28, 2022, at 12:11, Techcable wrote:
> I've been playing around with QBE on my M1 Macbook Pro using the
> apple-m1 branch (commit c8cd2824ea).
Excellent! Note that c8cd2824ea is the last commit on master,
and does not have any support for m1 implemented. Maybe it's
a typo on your side, but you have to "git checkout apple-m1"
to access the latest work.
> The varadic specifier `...` in the printf call is placed incorrectly.
Good diagnosing! I'd assume this is indeed the root cause for
your trouble.
> Interestingly enough, this is *not* a problem on x64 macs. I checked by
> cross-compiling and running in an emulator. There is a good chance this
> is also not a problem on x64 Linux (pretty sure x86_64 ABI is standard).
Indeed. Technically, a good share of ABIs pass extra arguments to
variadic functions (almost) as if they were part of the prototype.
That is why minic gets by ignoring function prototypes. That being
said, the Apple ABI (and the risc-v one) does not work that way,
and extra arguments never end up in registers and are pushed on
the stack. So the placement of '...' really is critical for this
target.
> Looking into the `minic` sources, it doesn't seem to track function
> arguments very carefully.
> I'm not sure there's an easy fix for this problem in `minic`.......
minic is intentionally minimalist; I think we could simply hardcode
the '...' placement for printf so that the examples work, and add
a note that variadic calls are not expected to work otherwise.
> Anyways, thanks for your work on QBE (and porting to M1 Macs)
You're welcome! I'm looking forward to merging the branch in
master!