Skip to content

Commit 0c12363

Browse files
committed
arm64: Save func results before struct args
In gfunc_call(), structure members are loaded into registers during argument handling. This operation may overwrite previous function call results stored in registers (e.g., s0). To prevent this, we must save function call results to the stack before processing structure arguments.
1 parent 32b5977 commit 0c12363

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

arm64-gen.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,9 @@ ST_FUNC void gfunc_call(int nb_args)
11011101
// value in floating-point registers
11021102
if ((vtop->type.t & VT_BTYPE) == VT_STRUCT) {
11031103
uint32_t j, sz, n = arm64_hfa(&vtop->type, &sz);
1104+
// save regs because struct may overwrite previous func call result
1105+
save_regs(0);
1106+
11041107
vtop->type.t = VT_PTR;
11051108
gaddrof();
11061109
gv(RC_R30);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <stdio.h>
2+
3+
// arm64-gen.c: gfunc_call() Second pass when struct args may overwrite previous func call result
4+
struct vec {
5+
float x;
6+
float y;
7+
};
8+
9+
void bug(float x, float y) {
10+
printf("x=%f\ny=%f\n", x, y);
11+
}
12+
13+
float dot(struct vec v) {
14+
return 999.5;
15+
}
16+
17+
void main(void) {
18+
struct vec a;
19+
a.x = 33.0f;
20+
a.y = 77.0f;
21+
bug(dot(a), dot(a));
22+
}
23+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
x=999.500000
2+
y=999.500000

0 commit comments

Comments
 (0)