summary refs log tree commit diff
path: root/amd64
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2019-04-25 15:27:25 +0200
committerQuentin Carbonneaux <quentin@c9x.me>2019-04-25 15:27:25 +0200
commitb4a98c3fa8b880f58b04f5d632ab89ad15725bd4 (patch)
tree16d37727a7f810e0357436e533d60557c15f3547 /amd64
parent636568dcba071e212a61c35ce994012b9cb83ec5 (diff)
downloadroux-b4a98c3fa8b880f58b04f5d632ab89ad15725bd4.tar.gz
cleanup amd64 constant addressing
We now emit correct code when the user
refers to a specific constant address.

I also made some comments clearer in
the instruction selection pass and got
rid of some apparently useless code.
Diffstat (limited to 'amd64')
-rw-r--r--amd64/emit.c12
-rw-r--r--amd64/isel.c30
2 files changed, 19 insertions, 23 deletions
diff --git a/amd64/emit.c b/amd64/emit.c
index 1fe141f..91223bd 100644
--- a/amd64/emit.c
+++ b/amd64/emit.c
@@ -292,10 +292,10 @@ Next:
 			if (m->offset.type != CUndef)
 				emitcon(&m->offset, f);
 			fputc('(', f);
-			if (req(m->base, R))
-				fprintf(f, "%%rip");
-			else
+			if (!req(m->base, R))
 				fprintf(f, "%%%s", regtoa(m->base.val, SLong));
+			else if (m->offset.type == CAddr)
+				fprintf(f, "%%rip");
 			if (!req(m->index, R))
 				fprintf(f, ", %%%s, %d",
 					regtoa(m->index.val, SLong),
@@ -333,8 +333,10 @@ Next:
 			fprintf(f, "%d(%%rbp)", slot(ref.val, fn));
 			break;
 		case RCon:
-			emitcon(&fn->con[ref.val], f);
-			fprintf(f, "(%%rip)");
+			off = fn->con[ref.val];
+			emitcon(&off, f);
+			if (off.type == CAddr)
+				fprintf(f, "(%%rip)");
 			break;
 		case RTmp:
 			assert(isreg(ref));
diff --git a/amd64/isel.c b/amd64/isel.c
index cedfdb1..ce0c98f 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, *m;
+	Addr a;
 	Ref r0, r1;
 	int s, n, cpy, mem;
 
@@ -103,23 +103,13 @@ fixarg(Ref *r, int k, int op, Fn *fn)
 	}
 	else if (!mem && rtype(r0) == RCon
 	&& fn->con[r0.val].type == CAddr) {
-		/* apple asm fix */
+		/* apple as does not support 32-bit
+		 * absolute addressing, use a rip-
+		 * relative leaq instead
+		 */
 		r1 = newtmp("isel", Kl, fn);
 		emit(Oaddr, Kl, r1, r0, R);
 	}
-	else if (rtype(r0) == RMem) {
-		/* apple asm fix */
-		m = &fn->mem[r0.val];
-		if (req(m->base, R)) {
-			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;
 }
 
@@ -134,9 +124,13 @@ seladdr(Ref *r, ANum *an, Fn *fn)
 		memset(&a, 0, sizeof a);
 		if (!amatch(&a, r0, an[r0.val].n, an, fn))
 			return;
-		if (a.offset.type == CAddr)
-		if (!req(a.base, R)) {
-			/* apple asm fix */
+		if (!req(a.base, R))
+		if (a.offset.type == CAddr) {
+			/* apple as does not support
+			 * $foo(%r0, %r1, M); try to
+			 * rewrite it or bail out if
+			 * impossible
+			 */
 			if (!req(a.index, R))
 				return;
 			else {