summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--amd64/isel.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/amd64/isel.c b/amd64/isel.c
index 214dbec..3d5d5a9 100644
--- a/amd64/isel.c
+++ b/amd64/isel.c
@@ -58,6 +58,21 @@ rslot(Ref r, Fn *fn)
 	return fn->tmp[r.val].slot;
 }
 
+static int
+hascon(Ref r, Con **pc, Fn *fn)
+{
+	switch (rtype(r)) {
+	case RCon:
+		*pc = &fn->con[r.val];
+		return 1;
+	case RMem:
+		*pc = &fn->mem[r.val].offset;
+		return 1;
+	default:
+		return 0;
+	}
+}
+
 static void
 fixarg(Ref *r, int k, Ins *i, Fn *fn)
 {
@@ -100,9 +115,8 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn)
 		r1 = newtmp("isel", Kl, fn);
 		emit(Oaddr, Kl, r1, SLOT(s), R);
 	}
-	else if (T.apple && rtype(r0) == RCon
-	&& (c = &fn->con[r0.val])->type == CAddr
-	&& c->sym.type == SThr) {
+	else if (T.apple && hascon(r0, &c, fn)
+	&& c->type == CAddr && c->sym.type == SThr) {
 		r1 = newtmp("isel", Kl, fn);
 		if (c->bits.i) {
 			r2 = newtmp("isel", Kl, fn);
@@ -122,6 +136,12 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn)
 		cc.bits.i = 0;
 		r3 = newcon(&cc, fn);
 		emit(Oload, Kl, r2, r3, R);
+		if (rtype(r0) == RMem) {
+			m = &fn->mem[r0.val];
+			m->offset.type = CUndef;
+			m->base = r1;
+			r1 = r0;
+		}
 	}
 	else if (!(isstore(op) && r == &i->arg[1])
 	&& !isload(op) && op != Ocall && rtype(r0) == RCon