summary refs log tree commit diff
path: root/amd64
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2019-04-26 12:05:47 +0200
committerQuentin Carbonneaux <quentin@c9x.me>2019-04-26 12:05:47 +0200
commit82f5ba58cf76bc431afe0c738cdcfe1f5998ae95 (patch)
treebc2da23db0330bff79a2096f4ca7b62085da6b20 /amd64
parentb4a98c3fa8b880f58b04f5d632ab89ad15725bd4 (diff)
downloadroux-82f5ba58cf76bc431afe0c738cdcfe1f5998ae95.tar.gz
restore some code from b4a98c
I had forgotten that %rip can only be
used as base when there is no index.

I also added a test which stresses
addressing selection with and without
constants.
Diffstat (limited to 'amd64')
-rw-r--r--amd64/isel.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/amd64/isel.c b/amd64/isel.c
index ce0c98f..e5202cb 100644
--- a/amd64/isel.c
+++ b/amd64/isel.c
@@ -62,7 +62,7 @@ static void
 fixarg(Ref *r, int k, int op, Fn *fn)
 {
 	char buf[32];
-	Addr a;
+	Addr a, *m;
 	Ref r0, r1;
 	int s, n, cpy, mem;
 
@@ -110,6 +110,22 @@ fixarg(Ref *r, int k, int op, Fn *fn)
 		r1 = newtmp("isel", Kl, fn);
 		emit(Oaddr, Kl, r1, r0, R);
 	}
+	else if (rtype(r0) == RMem) {
+		/* eliminate memory operands of
+		 * the form $foo(%rip, ...)
+		 */
+		m = &fn->mem[r0.val];
+		if (req(m->base, R))
+		if (m->offset.type == CAddr) {
+			n = fn->ncon;
+			vgrow(&fn->con, ++fn->ncon);
+			fn->con[n] = m->offset;
+			m->offset.type = CUndef;
+			r0 = newtmp("isel", Kl, fn);
+			emit(Oaddr, Kl, r0, CON(n), R);
+			m->base = r0;
+		}
+	}
 	*r = r1;
 }