aboutsummaryrefslogtreecommitdiffhomepage
path: root/amd64/isel.c
diff options
context:
space:
mode:
Diffstat (limited to 'amd64/isel.c')
-rw-r--r--amd64/isel.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/amd64/isel.c b/amd64/isel.c
index 98585fa..7bb0a06 100644
--- a/amd64/isel.c
+++ b/amd64/isel.c
@@ -79,21 +79,23 @@ fixarg(union ref *r, struct instr *ins, struct block *blk, int *curi)
uchar data[8];
uint ksiz = cls2siz[con->cls];
union type ctype;
+ /* can't use memory arg in rhs if lhs is memory */
+ bool docopy = &ins->l != r && (oisstore(ins->op) || ins->l.t == RADDR);
if (con->cls <= KPTR && in_range(ins->op, Ocopy, Omove)) /* in this case we can use movabs */
return;
- if (con->cls != KF32) {
- wr64le(data, con->i);
- ctype = mktype(con->cls == KF64 ? TYDOUBLE : TYVLONG);
- } else {
- union { float f; int i; } pun = { con->f };
- wr32le(data, pun.i);
- ctype = mktype(TYFLOAT);
+ else if (!docopy || con->cls >= KF32) {
+ if (con->cls != KF32) {
+ wr64le(data, con->i);
+ ctype = mktype(con->cls == KF64 ? TYDOUBLE : TYVLONG);
+ } else {
+ union { float f; int i; } pun = { con->f };
+ wr32le(data, pun.i);
+ ctype = mktype(TYFLOAT);
+ }
+ *r = mkdatref(NULL, ctype, ksiz, /*align*/ksiz, data, ksiz, /*deref*/1);
}
- *r = mkdatref(NULL, ctype, ksiz, /*align*/ksiz, data, ksiz, /*deref*/1);
- if (&ins->l != r && ins->l.t == RADDR) {
- /* can't use memory arg in rhs if lhs is memory */
+ if (docopy)
*r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, con->cls, *r));
- }
} else if (ins->op != Omove && con->issym && r == &ins->r) {
*r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, mkaddr((struct addr){*r})));
} else if (in_range(op, Odiv, Ourem) && kisint(ins->cls))