From e81d015e3cc2cb0c352792d0cac12f1594281bc2 Mon Sep 17 00:00:00 2001 From: Xavier Leroy Date: Sun, 10 Jan 2021 14:34:58 +0100 Subject: RISC-V: wrong fixup code generated for vararg calls with fixed FP args This is a follow-up to 2076a3bb3. Integer registers were wrongly reserved for fixed FP arguments, causing variadic FP arguments to end up in the wrong integer registers. Added regression test in test/regression/varargs2.c --- test/regression/varargs2.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'test/regression/varargs2.c') diff --git a/test/regression/varargs2.c b/test/regression/varargs2.c index b96d1940..32140d5c 100644 --- a/test/regression/varargs2.c +++ b/test/regression/varargs2.c @@ -104,6 +104,17 @@ void miniprintf_extra(int i1, int i2, int i3, int i4, va_end(va); } +/* Add a few dummy FP arguments to test passing of variadic FP arguments + in integer registers (mostly relevant for RISC-V) */ + +void miniprintf_float(double f1, double f2, const char * fmt, ...) +{ + va_list va; + va_start(va, fmt); + minivprintf(fmt, va); + va_end(va); +} + /* Test va_list compatibility with the C library */ void printf_compat(const char * fmt, ...) @@ -143,6 +154,11 @@ int main() 123456789012345LL, 3.141592654, 2.71828182); + miniprintf_float(0.0, 1.0, + "With extra FP args: %l & %e & %f\n", + 123456789012345LL, + 3.141592654, + 2.71828182); printf_compat("va_list compatibility: %c & %s & %d & %lld & %.10g & %.10g\n", 'x', "Hello, world!", -- cgit From 88567ce6d247562a9fa9151eaa32f7ad63ea37c0 Mon Sep 17 00:00:00 2001 From: Xavier Leroy Date: Mon, 11 Jan 2021 18:04:25 +0100 Subject: RISC-V: fix FP calling conventions This is a follow-up to e81d015e3. In the RISC-V ABI, FP arguments to functions are passed in integer registers (or pairs of integer registers) in two cases: 1- the FP argument is a variadic argument 2- the FP argument is a fixed argument but all 8 FP registers reserved for parameter passing have been used already. The previous implementation handled only case 1, with some problems. This commit implements both 1 and 2. To this end, 8 extra FP caller-save registers are used to hold the values of the FP arguments that must be passed in integer registers. Fixup code moves these FP registers to integer registers / register pairs. Symmetrically, at function entry, the integer registers / register pairs are moved back to the FP registers. 8 extra FP registers is enough because there are only 8 integer registers used for parameter passing, so at most 8 FP arguments may need to be moved to integer registers. --- test/regression/varargs2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'test/regression/varargs2.c') diff --git a/test/regression/varargs2.c b/test/regression/varargs2.c index 32140d5c..d64509e5 100644 --- a/test/regression/varargs2.c +++ b/test/regression/varargs2.c @@ -154,11 +154,11 @@ int main() 123456789012345LL, 3.141592654, 2.71828182); - miniprintf_float(0.0, 1.0, - "With extra FP args: %l & %e & %f\n", - 123456789012345LL, + miniprintf_float(0.0, 0.5, + "With extra FP args: %e & %f & %e & %e & %e & %e & %e & %e & %e & %e & %d\n", 3.141592654, - 2.71828182); + 2.71828182, + 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 42); printf_compat("va_list compatibility: %c & %s & %d & %lld & %.10g & %.10g\n", 'x', "Hello, world!", -- cgit