diff options
| author | 2023-06-20 20:47:32 +0200 | |
|---|---|---|
| committer | 2023-06-20 20:47:32 +0200 | |
| commit | 7fa68005dde6d1468ac7611c513a492292c48992 (patch) | |
| tree | 26334ededa3580d43d9a8ae9085426636010fae5 /amd64/emit.c | |
| parent | fdf047b7d1f737ce8b892b08370ac9a1bedcda73 (diff) | |
amd64: conform to ABI for varargs func calls
Diffstat (limited to 'amd64/emit.c')
| -rw-r--r-- | amd64/emit.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/amd64/emit.c b/amd64/emit.c index 7e9bbd3..d3dad9c 100644 --- a/amd64/emit.c +++ b/amd64/emit.c @@ -765,6 +765,15 @@ emitinstr(uchar **pcode, struct function *fn, struct block *blk, int curi, struc gencopy(pcode, cls, blk, curi, dst, ins->l); break; case Ocall: + if (calltab.p[ins->r.i].vararg >= 0) { + struct call *call = &calltab.p[ins->r.i]; + /* variadic functions need the caller to write num of args in sse regs to %al */ + int n = 0; + for (int i = 0; i < call->narg; ++i) + n += call->abiarg[i].reg >= XMM0; + if (!n) DS("\x31\xC0"); /* XOR EAX, EAX */ + else B(0xB0), B(n); /* MOV AL, n */ + } Xcall(pcode, KPTR, ref2oper(ins->l)); break; } |