summaryrefslogtreecommitdiff
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;
}