summary refs log tree commit diff
path: root/amd64/isel.c
diff options
context:
space:
mode:
Diffstat (limited to 'amd64/isel.c')
-rw-r--r--amd64/isel.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/amd64/isel.c b/amd64/isel.c
index a562441..8c89378 100644
--- a/amd64/isel.c
+++ b/amd64/isel.c
@@ -63,7 +63,8 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn)
 {
 	char buf[32];
 	Addr a, *m;
-	Ref r0, r1;
+	Con cc, *c;
+	Ref r0, r1, r2, r3;
 	int s, n, op;
 
 	r1 = r0 = *r;
@@ -121,6 +122,28 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn)
 			m->offset.type = CUndef;
 			m->base = r0;
 		}
+	} else if (T.apple && rtype(r0) == RCon
+	&& (c = &fn->con[r0.val])->type == CAddr
+	&& c->reloc == RelThr) {
+		r1 = newtmp("isel", Kl, fn);
+		if (c->bits.i) {
+			r2 = newtmp("isel", Kl, fn);
+			cc = (Con){.type = CBits};
+			cc.bits.i = c->bits.i;
+			r3 = newcon(&cc, fn);
+			emit(Oadd, Kl, r1, r2, r3);
+		} else
+			r2 = r1;
+		emit(Ocopy, Kl, r2, TMP(RAX), R);
+		r2 = newtmp("isel", Kl, fn);
+		r3 = newtmp("isel", Kl, fn);
+		emit(Ocall, 0, R, r3, CALL(17));
+		emit(Ocopy, Kl, TMP(RDI), r2, R);
+		emit(Oload, Kl, r3, r2, R);
+		cc = *c;
+		cc.bits.i = 0;
+		r3 = newcon(&cc, fn);
+		emit(Oload, Kl, r2, r3, R);
 	}
 	*r = r1;
 }