mirror of
git://c9x.me/qbe.git
synced 2026-04-05 09:59:47 +00:00
Different architectures use different types for va_list:
x86_64 uses an 1-length array of struct type[0]:
typedef struct {
unsigned int gp_offset;
unsigned int fp_offset;
void *overflow_arg_area;
void *reg_save_area;
} va_list[1];
aarch64 uses a struct type[1]
typedef struct {
void *__stack;
void *__gr_top;
void *__vr_top;
int __gr_offs;
int __vr_offs;
} va_list;
Consequently, C functions which takes a va_list as an argument,
such as vprintf, may pass va_list in different ways depending on
the architecture.
On x86_64, va_list is an array type, so parameter decays to a pointer
and passing the address of the va_list is correct.
On aarch64, the va_list struct is passed by value, but since it is
larger than 16 bytes, the parameter is replaced with a pointer to
caller-allocated memory. Thus, passing the address as an l argument
happens to work.
However, this pattern of passing the address of the va_list to
vprintf doesn't extend to other architectures. On riscv64, va_list
is defined as
typedef void *va_list;
which is *not* passed by reference. This means that tests that call
vprintf using the address of a va_list (vararg1 and vararg2) will
not work on riscv.
To fix this while keeping the tests architecture-neutral, add a
small wrapper function to the driver which takes a va_list *, and
let the C compiler deal with the details of passing va_list by
value.
[0] https://c9x.me/compile/bib/abi-x64.pdf#figure.3.34
[1] https://c9x.me/compile/bib/abi-arm64.pdf#%5B%7B%22num%22%3A63%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C52%2C757%2C0%5D
[2] https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-cc.adoc#va_list-va_start-and-va_arg$
|
||
|---|---|---|
| .. | ||
| _alt.ssa | ||
| _bf99.ssa | ||
| _bfmandel.ssa | ||
| _dragon.ssa | ||
| _fix1.ssa | ||
| _fix2.ssa | ||
| _fix3.ssa | ||
| _fix4.ssa | ||
| _live.ssa | ||
| _rpo.ssa | ||
| _slow.qbe | ||
| _spill1.ssa | ||
| _spill2.ssa | ||
| _spill3.ssa | ||
| abi1.ssa | ||
| abi2.ssa | ||
| abi3.ssa | ||
| abi4.ssa | ||
| abi5.ssa | ||
| abi6.ssa | ||
| abi7.ssa | ||
| align.ssa | ||
| cmp1.ssa | ||
| collatz.ssa | ||
| conaddr.ssa | ||
| cprime.ssa | ||
| cup.ssa | ||
| dark.ssa | ||
| double.ssa | ||
| dynalloc.ssa | ||
| echo.ssa | ||
| eucl.ssa | ||
| euclc.ssa | ||
| fixarg.ssa | ||
| fold1.ssa | ||
| fpcnv.ssa | ||
| isel1.ssa | ||
| isel2.ssa | ||
| ldbits.ssa | ||
| ldhoist.ssa | ||
| load1.ssa | ||
| loop.ssa | ||
| mandel.ssa | ||
| max.ssa | ||
| philv.ssa | ||
| prime.ssa | ||
| puts10.ssa | ||
| queen.ssa | ||
| rega1.ssa | ||
| spill1.ssa | ||
| strcmp.ssa | ||
| strspn.ssa | ||
| sum.ssa | ||
| vararg1.ssa | ||
| vararg2.ssa | ||