Commit 41b5fb47 authored by Russ Cox's avatar Russ Cox

5c: implement uint32 -> float

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
parent 6e87a0ab
...@@ -580,7 +580,8 @@ void ...@@ -580,7 +580,8 @@ void
gmove(Node *f, Node *t) gmove(Node *f, Node *t)
{ {
int ft, tt, a; int ft, tt, a;
Node nod; Node nod, nod1;
Prog *p1;
ft = f->type->etype; ft = f->type->etype;
tt = t->type->etype; tt = t->type->etype;
...@@ -709,21 +710,53 @@ gmove(Node *f, Node *t) ...@@ -709,21 +710,53 @@ gmove(Node *f, Node *t)
} }
break; break;
case TUINT: case TUINT:
case TINT:
case TULONG: 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 TLONG:
case TIND: case TIND:
switch(tt) { switch(tt) {
case TDOUBLE: case TDOUBLE:
case TVLONG:
gins(AMOVWD, f, t); gins(AMOVWD, f, t);
if(ft == TULONG) {
}
return; return;
case TFLOAT: case TFLOAT:
gins(AMOVWF, f, t); gins(AMOVWF, f, t);
if(ft == TULONG) {
}
return; return;
case TINT: case TINT:
case TUINT: case TUINT:
...@@ -741,7 +774,6 @@ gmove(Node *f, Node *t) ...@@ -741,7 +774,6 @@ gmove(Node *f, Node *t)
case TSHORT: case TSHORT:
switch(tt) { switch(tt) {
case TDOUBLE: case TDOUBLE:
case TVLONG:
regalloc(&nod, f, Z); regalloc(&nod, f, Z);
gins(AMOVH, f, &nod); gins(AMOVH, f, &nod);
gins(AMOVWD, &nod, t); gins(AMOVWD, &nod, t);
...@@ -771,7 +803,6 @@ gmove(Node *f, Node *t) ...@@ -771,7 +803,6 @@ gmove(Node *f, Node *t)
case TUSHORT: case TUSHORT:
switch(tt) { switch(tt) {
case TDOUBLE: case TDOUBLE:
case TVLONG:
regalloc(&nod, f, Z); regalloc(&nod, f, Z);
gins(AMOVHU, f, &nod); gins(AMOVHU, f, &nod);
gins(AMOVWD, &nod, t); gins(AMOVWD, &nod, t);
...@@ -801,7 +832,6 @@ gmove(Node *f, Node *t) ...@@ -801,7 +832,6 @@ gmove(Node *f, Node *t)
case TCHAR: case TCHAR:
switch(tt) { switch(tt) {
case TDOUBLE: case TDOUBLE:
case TVLONG:
regalloc(&nod, f, Z); regalloc(&nod, f, Z);
gins(AMOVB, f, &nod); gins(AMOVB, f, &nod);
gins(AMOVWD, &nod, t); gins(AMOVWD, &nod, t);
...@@ -831,7 +861,6 @@ gmove(Node *f, Node *t) ...@@ -831,7 +861,6 @@ gmove(Node *f, Node *t)
case TUCHAR: case TUCHAR:
switch(tt) { switch(tt) {
case TDOUBLE: case TDOUBLE:
case TVLONG:
regalloc(&nod, f, Z); regalloc(&nod, f, Z);
gins(AMOVBU, f, &nod); gins(AMOVBU, f, &nod);
gins(AMOVWD, &nod, t); gins(AMOVWD, &nod, t);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment