From 41b5fb47612d35606db29d5b740c5ea40b29a0c5 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 25 Oct 2010 16:18:16 -0700 Subject: [PATCH] 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 --- src/cmd/5c/txt.c | 51 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/src/cmd/5c/txt.c b/src/cmd/5c/txt.c index 9dac0312f4..1ba8ae2c4e 100644 --- a/src/cmd/5c/txt.c +++ b/src/cmd/5c/txt.c @@ -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);