diff options
Diffstat (limited to 'src/cmd/5g/gsubr.c')
-rw-r--r-- | src/cmd/5g/gsubr.c | 62 |
1 files changed, 40 insertions, 22 deletions
diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c index f0a1b2485..df175349f 100644 --- a/src/cmd/5g/gsubr.c +++ b/src/cmd/5g/gsubr.c @@ -514,7 +514,7 @@ splitclean(void) void gmove(Node *f, Node *t) { - int a, ft, tt; + int a, ft, tt, fa, ta; Type *cvt; Node r1, r2, flo, fhi, tlo, thi, con; Prog *p1; @@ -526,9 +526,9 @@ gmove(Node *f, Node *t) tt = simsimtype(t->type); cvt = t->type; - // cannot have two integer memory operands; + // cannot have two memory operands; // except 64-bit, which always copies via registers anyway. - if(isint[ft] && isint[tt] && !is64(f->type) && !is64(t->type) && ismem(f) && ismem(t)) + if(!is64(f->type) && !is64(t->type) && ismem(f) && ismem(t)) goto hard; // convert constant to desired type @@ -538,10 +538,6 @@ gmove(Node *f, Node *t) convconst(&con, t->type, &f->val); break; - case TFLOAT32: - convconst(&con, types[TFLOAT64], &f->val); - break; - case TINT16: case TINT8: convconst(&con, types[TINT32], &f->val); @@ -752,8 +748,10 @@ gmove(Node *f, Node *t) case CASE(TFLOAT32, TUINT8): case CASE(TFLOAT32, TUINT16): case CASE(TFLOAT32, TUINT32): + fa = AMOVF; a = AMOVFW; - break; + ta = AMOVW; + goto fltconv; case CASE(TFLOAT64, TINT8): case CASE(TFLOAT64, TINT16): @@ -761,14 +759,14 @@ gmove(Node *f, Node *t) case CASE(TFLOAT64, TUINT8): case CASE(TFLOAT64, TUINT16): case CASE(TFLOAT64, TUINT32): + fa = AMOVD; a = AMOVDW; - break; + ta = AMOVW; + goto fltconv; - case CASE(TFLOAT32, TINT64): case CASE(TFLOAT32, TUINT64): - case CASE(TFLOAT64, TINT64): case CASE(TFLOAT64, TUINT64): - fatal("gmove TFLOAT, INT64 not implemented"); + fatal("gmove TFLOAT, UINT64 not implemented"); return; /* @@ -780,8 +778,10 @@ gmove(Node *f, Node *t) case CASE(TUINT8, TFLOAT32): case CASE(TUINT16, TFLOAT32): case CASE(TUINT32, TFLOAT32): + fa = AMOVW; a = AMOVWF; - break; + ta = AMOVF; + goto fltconv; case CASE(TINT8, TFLOAT64): case CASE(TINT16, TFLOAT64): @@ -789,14 +789,14 @@ gmove(Node *f, Node *t) case CASE(TUINT8, TFLOAT64): case CASE(TUINT16, TFLOAT64): case CASE(TUINT32, TFLOAT64): + fa = AMOVW; a = AMOVWD; - break; + ta = AMOVW; + goto fltconv;; - case CASE(TINT64, TFLOAT32): - case CASE(TINT64, TFLOAT64): case CASE(TUINT64, TFLOAT32): case CASE(TUINT64, TFLOAT64): - fatal("gmove INT64, TFLOAT not implemented"); + fatal("gmove UINT64, TFLOAT not implemented"); return; @@ -812,12 +812,20 @@ gmove(Node *f, Node *t) break; case CASE(TFLOAT32, TFLOAT64): - a = AMOVFD; - break; + regalloc(&r1, types[TFLOAT64], t); + gins(AMOVF, f, &r1); + gins(AMOVFD, &r1, &r1); + gins(AMOVD, &r1, t); + regfree(&r1); + return; case CASE(TFLOAT64, TFLOAT32): - a = AMOVDF; - break; + regalloc(&r1, types[TFLOAT64], t); + gins(AMOVD, f, &r1); + gins(AMOVDF, &r1, &r1); + gins(AMOVF, &r1, t); + regfree(&r1); + return; } gins(a, f, t); @@ -835,7 +843,7 @@ rdst: hard: // requires register intermediate - regalloc(&r1, cvt, N); + regalloc(&r1, cvt, t); gmove(f, &r1); gmove(&r1, t); regfree(&r1); @@ -851,6 +859,16 @@ trunc64: splitclean(); return; +fltconv: + regalloc(&r1, types[ft], f); + regalloc(&r2, types[tt], t); + gins(fa, f, &r1); + gins(a, &r1, &r2); + gins(ta, &r2, t); + regfree(&r1); + regfree(&r2); + return; + fatal: // should not happen fatal("gmove %N -> %N", f, t); |