aboutsummaryrefslogtreecommitdiffhomepage
path: root/amd64/emit.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2023-06-20 20:47:32 +0200
committerlemon <lsof@mailbox.org>2023-06-20 20:47:32 +0200
commit7fa68005dde6d1468ac7611c513a492292c48992 (patch)
tree26334ededa3580d43d9a8ae9085426636010fae5 /amd64/emit.c
parentfdf047b7d1f737ce8b892b08370ac9a1bedcda73 (diff)
amd64: conform to ABI for varargs func calls
Diffstat (limited to 'amd64/emit.c')
-rw-r--r--amd64/emit.c9
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;
}