diff options
author | Quentin Carbonneaux <quentin@c9x.me> | 2019-03-12 17:44:14 +0100 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2019-03-12 17:44:50 +0100 |
commit | c37347a4630fda601b4c40585ca25fff42f756c6 (patch) | |
tree | 230428f14d96324bd504ae84b37dab780b56fa30 | |
parent | ec1b18634325cfd47f6228b5164e14cf64e583bb (diff) | |
download | roux-c37347a4630fda601b4c40585ca25fff42f756c6.tar.gz |
emit valid code for mem->mem copies
-rw-r--r-- | amd64/emit.c | 14 | ||||
-rw-r--r-- | test/spill1.ssa (renamed from test/_phispill.ssa) | 0 |
2 files changed, 11 insertions, 3 deletions
diff --git a/amd64/emit.c b/amd64/emit.c index 653c548..ac7a1f3 100644 --- a/amd64/emit.c +++ b/amd64/emit.c @@ -360,7 +360,7 @@ emitins(Ins i, Fn *fn, FILE *f) { Ref r; int64_t val; - int o; + int o, t0; switch (i.op) { default: @@ -434,19 +434,27 @@ emitins(Ins i, Fn *fn, FILE *f) * also, we can use a trick to load 64-bits * registers, it's detailed in my note below * http://c9x.me/art/notes.html?09/19/2015 */ + t0 = rtype(i.arg[0]); if (req(i.to, R) || req(i.arg[0], R)) break; if (isreg(i.to) - && rtype(i.arg[0]) == RCon + && t0 == RCon && i.cls == Kl && fn->con[i.arg[0].val].type == CBits && (val = fn->con[i.arg[0].val].bits.i) >= 0 && val <= UINT32_MAX) { emitf("movl %W0, %W=", &i, fn, f); } else if (isreg(i.to) - && rtype(i.arg[0]) == RCon + && t0 == RCon && fn->con[i.arg[0].val].type == CAddr) { emitf("lea%k %M0, %=", &i, fn, f); + } else if (rtype(i.to) == RSlot + && (t0 == RSlot || t0 == RMem)) { + i.cls = KWIDE(i.cls) ? Kd : Ks; + i.arg[1] = TMP(XMM0+15); + emitf("mov%k %0, %1", &i, fn, f); + emitf("mov%k %1, %=", &i, fn, f); + } else if (!req(i.arg[0], i.to)) emitf("mov%k %0, %=", &i, fn, f); break; diff --git a/test/_phispill.ssa b/test/spill1.ssa index 21e98c2..21e98c2 100644 --- a/test/_phispill.ssa +++ b/test/spill1.ssa |