Commit e81d015e authored by Xavier Leroy's avatar Xavier Leroy
Browse files

RISC-V: wrong fixup code generated for vararg calls with fixed FP args

This is a follow-up to 2076a3bb.

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
parent 35e2b11d
......@@ -72,27 +72,33 @@ let rec fixup_variadic_call fixed ri rf tyl =
| (Tint | Tany32) :: tyl ->
fixup_variadic_call (fixed - 1) (ri + 1) rf tyl
| Tsingle :: tyl ->
if fixed <= 0 then begin
if fixed > 0 then
fixup_variadic_call (fixed - 1) ri (rf + 1) tyl
else begin
let rs = float_param_regs.(rf)
and rd = int_param_regs.(ri) in
emit (Pfmvxs(rd, rs))
end;
fixup_variadic_call (fixed - 1) (ri + 1) (rf + 1) tyl
emit (Pfmvxs(rd, rs));
fixup_variadic_call (fixed - 1) (ri + 1) (rf + 1) tyl
end
| Tlong :: tyl ->
let ri' = if Archi.ptr64 then ri + 1 else align ri 2 + 2 in
fixup_variadic_call (fixed - 1) ri' rf tyl
| (Tfloat | Tany64) :: tyl ->
if Archi.ptr64 then begin
if fixed <= 0 then begin
if fixed > 0 then
fixup_variadic_call (fixed - 1) ri (rf + 1) tyl
else begin
let rs = float_param_regs.(rf)
and rd = int_param_regs.(ri) in
emit (Pfmvxd(rd, rs))
end;
fixup_variadic_call (fixed - 1) (ri + 1) (rf + 1) tyl
emit (Pfmvxd(rd, rs));
fixup_variadic_call (fixed - 1) (ri + 1) (rf + 1) tyl
end
end else begin
let ri = align ri 2 in
if ri < 8 then begin
if fixed <= 0 then begin
if fixed > 0 then
fixup_variadic_call (fixed - 1) ri (rf + 1) tyl
else begin
let rs = float_param_regs.(rf)
and rd1 = int_param_regs.(ri)
and rd2 = int_param_regs.(ri + 1) in
......@@ -100,9 +106,9 @@ let rec fixup_variadic_call fixed ri rf tyl =
emit (Pfsd(rs, X2, Ofsimm _0));
emit (Plw(rd1, X2, Ofsimm _0));
emit (Plw(rd2, X2, Ofsimm _4));
emit (Paddiw(X2, X X2, _16))
end;
fixup_variadic_call (fixed - 1) (ri + 2) (rf + 1) tyl
emit (Paddiw(X2, X X2, _16));
fixup_variadic_call (fixed - 1) (ri + 2) (rf + 1) tyl
end
end
end
......
......@@ -10,4 +10,5 @@ Twice: -1 1.23
With va_copy: -1 1.23
With va_copy: -1 1.23
With extra args: x & Hello, world! & 42 & 123456789012345 & 3.141592654 & 2.718281746
With extra FP args: 123456789012345 & 3.141592654 & 2.718281746
va_list compatibility: x & Hello, world! & 42 & 123456789012345 & 3.141592654 & 2.718281746
......@@ -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!",
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment