1
0
mirror of https://github.com/golang/go synced 2024-10-01 13:18:33 -06:00

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
This commit is contained in:
Russ Cox 2010-10-25 16:18:16 -07:00
parent 6e87a0abc9
commit 41b5fb4761

View 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);