summary refs log tree commit diff
path: root/amd64
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2021-10-17 20:56:25 +0200
committerQuentin Carbonneaux <quentin@c9x.me>2021-10-17 21:03:03 +0200
commit503c672d47695afe62fdf3439732ec96a68903b0 (patch)
tree6a96cbb912b0b68b58a869ec1bc41757a439d43d /amd64
parent462e49fd5c8ff82a341212d9a66621727c70fe1d (diff)
downloadroux-503c672d47695afe62fdf3439732ec96a68903b0.tar.gz
amd64/sysv: unbreak env calls
Env calls were disfunctional from the
start. This fixes them on amd64, but
they remain to do on arm64. A new
test shows how to use them.
Diffstat (limited to 'amd64')
-rw-r--r--amd64/sysv.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/amd64/sysv.c b/amd64/sysv.c
index 045ec85..842f645 100644
--- a/amd64/sysv.c
+++ b/amd64/sysv.c
@@ -203,7 +203,7 @@ argsclass(Ins *i0, Ins *i1, AClass *ac, int op, AClass *aret, Ref *env)
 			break;
 		}
 
-	return ((6-nint) << 4) | ((8-nsse) << 8);
+	return (!req(R, *env) << 12) | ((6-nint) << 4) | ((8-nsse) << 8);
 }
 
 int amd64_sysv_rsave[] = {
@@ -362,7 +362,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap)
 	varc = i1->op == Ovacall;
 	if (varc && envc)
 		err("sysv abi does not support variadic env calls");
-	ca |= (varc | envc) << 12;
+	ca |= varc << 12; /* envc set in argsclass() */
 	emit(Ocall, i1->cls, R, i1->arg[0], CALL(ca));
 	if (envc)
 		emit(Ocopy, Kl, TMP(RAX), env, R);
@@ -373,7 +373,7 @@ selcall(Fn *fn, Ins *i0, Ins *i1, RAlloc **rap)
 	if (ra && aret.inmem)
 		emit(Ocopy, Kl, rarg(Kl, &ni, &ns), ra->i.to, R); /* pass hidden argument */
 	for (i=i0, a=ac; i<i1; i++, a++) {
-		if (a->inmem)
+		if (a->inmem || i->op == Oarge)
 			continue;
 		r1 = rarg(a->cls[0], &ni, &ns);
 		if (i->op == Oargc) {
@@ -466,6 +466,8 @@ selpar(Fn *fn, Ins *i0, Ins *i1)
 			s += 2;
 			continue;
 		}
+		if (i->op == Opare)
+			continue;
 		r = rarg(a->cls[0], &ni, &ns);
 		if (i->op == Oparc) {
 			emit(Ocopy, a->cls[0], a->ref[0], r, R);