diff options
author | Quentin Carbonneaux <quentin@c9x.me> | 2019-04-26 12:05:47 +0200 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2019-04-26 12:05:47 +0200 |
commit | 82f5ba58cf76bc431afe0c738cdcfe1f5998ae95 (patch) | |
tree | bc2da23db0330bff79a2096f4ca7b62085da6b20 /amd64/isel.c | |
parent | b4a98c3fa8b880f58b04f5d632ab89ad15725bd4 (diff) | |
download | roux-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/isel.c')
-rw-r--r-- | amd64/isel.c | 18 |
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; } |