]> Cypherpunks repositories - gostls13.git/commitdiff
5c: implement uint32 -> float
authorRuss Cox <rsc@golang.org>
Mon, 25 Oct 2010 23:18:16 +0000 (16:18 -0700)
committerRuss Cox <rsc@golang.org>
Mon, 25 Oct 2010 23:18:16 +0000 (16:18 -0700)
There are other missing conversion cases
still but they do not show up in my tests.
This one is needed for vlrt.c's _v2d (int64, uint64 -> float).

Thankfully, VFP has a single instruction to do this.

R=ken2
CC=golang-dev
https://golang.org/cl/2726041

src/cmd/5c/txt.c

index 9dac0312f4f99c2b00dc4bc94cb4faf45170fe9e..1ba8ae2c4e1ae4b3c04cf33866e745546e54ac02 100644 (file)
@@ -580,7 +580,8 @@ void
 gmove(Node *f, Node *t)
 {
        int ft, tt, a;
-       Node nod;
+       Node nod, nod1;
+       Prog *p1;
 
        ft = f->type->etype;
        tt = t->type->etype;
@@ -709,21 +710,53 @@ gmove(Node *f, Node *t)
                }
                break;
        case TUINT:
-       case TINT:
        case TULONG:
+               if(tt == TFLOAT || tt == TDOUBLE) {
+                       // ugly and probably longer than necessary,
+                       // but vfp has a single instruction for this,
+                       // so hopefully it won't last long.
+                       //
+                       //      tmp = f
+                       //      tmp1 = tmp & 0x80000000
+                       //      tmp ^= tmp1
+                       //      t = float(int32(tmp))
+                       //      if(tmp1)
+                       //              t += 2147483648.
+                       //
+                       regalloc(&nod, f, Z);
+                       regalloc(&nod1, f, Z);
+                       gins(AMOVW, f, &nod);
+                       gins(AMOVW, &nod, &nod1);
+                       gins(AAND, nodconst(0x80000000), &nod1);
+                       gins(AEOR, &nod1, &nod);
+                       if(tt == TFLOAT)
+                               gins(AMOVWF, &nod, t);
+                       else
+                               gins(AMOVWD, &nod, t);
+                       gins(ACMP, nodconst(0), Z);
+                       raddr(&nod1, p);
+                       gins(ABEQ, Z, Z);
+                       regfree(&nod);
+                       regfree(&nod1);
+                       p1 = p;
+                       regalloc(&nod, t, Z);
+                       gins(AMOVF, nodfconst(2147483648.), &nod);
+                       gins(AADDF, &nod, t);
+                       regfree(&nod);
+                       patch(p1, pc);
+                       return;
+               }
+               // fall through
+       
+       case TINT:
        case TLONG:
        case TIND:
                switch(tt) {
                case TDOUBLE:
-               case TVLONG:
                        gins(AMOVWD, f, t);
-                       if(ft == TULONG) {
-                       }
                        return;
                case TFLOAT:
                        gins(AMOVWF, f, t);
-                       if(ft == TULONG) {
-                       }
                        return;
                case TINT:
                case TUINT:
@@ -741,7 +774,6 @@ gmove(Node *f, Node *t)
        case TSHORT:
                switch(tt) {
                case TDOUBLE:
-               case TVLONG:
                        regalloc(&nod, f, Z);
                        gins(AMOVH, f, &nod);
                        gins(AMOVWD, &nod, t);
@@ -771,7 +803,6 @@ gmove(Node *f, Node *t)
        case TUSHORT:
                switch(tt) {
                case TDOUBLE:
-               case TVLONG:
                        regalloc(&nod, f, Z);
                        gins(AMOVHU, f, &nod);
                        gins(AMOVWD, &nod, t);
@@ -801,7 +832,6 @@ gmove(Node *f, Node *t)
        case TCHAR:
                switch(tt) {
                case TDOUBLE:
-               case TVLONG:
                        regalloc(&nod, f, Z);
                        gins(AMOVB, f, &nod);
                        gins(AMOVWD, &nod, t);
@@ -831,7 +861,6 @@ gmove(Node *f, Node *t)
        case TUCHAR:
                switch(tt) {
                case TDOUBLE:
-               case TVLONG:
                        regalloc(&nod, f, Z);
                        gins(AMOVBU, f, &nod);
                        gins(AMOVWD, &nod, t);