]> Cypherpunks repositories - gostls13.git/commitdiff
arm: prop up software floating point
authorRuss Cox <rsc@golang.org>
Thu, 21 Oct 2010 04:56:20 +0000 (06:56 +0200)
committerRuss Cox <rsc@golang.org>
Thu, 21 Oct 2010 04:56:20 +0000 (06:56 +0200)
Just enough to make mov instructions work,
which in turn is enough to make strconv work
when it avoids any floating point calculations.
That makes a bunch of other packages pass
their tests.

Should suffice until hardware floating point
is available.

Enable package tests that now pass
(some due to earlier fixes).

Looks like there is a new integer math bug
exposed in the fmt and json tests.

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

src/cmd/5g/Makefile
src/cmd/5g/cgen.c
src/cmd/5g/gsubr.c
src/cmd/8g/cgen.c
src/cmd/ld/data.c
src/pkg/Makefile
src/pkg/runtime/arm/softfloat.c
src/pkg/strconv/atof.go
src/pkg/strconv/ftoa.go
src/pkg/strconv/internal_test.go

index 762b7c5275956e375fb779cbb2ba52be0618afb9..f1fabe6a49c5faa58dfb8fbb599716ae84f54ddd 100644 (file)
@@ -21,7 +21,8 @@ OFILES=\
        ggen.$O\
        gsubr.$O\
        cgen.$O\
-       cgen64.$O
+       cgen64.$O\
+       cplx.$O\
 
 LIB=\
        ../gc/gc.a\
index 9185aa5acd3ea37680aadf58f5f76d41216b9689..3d96000c8a96e1172f1a70d7a26bed093044e1ee 100644 (file)
@@ -28,12 +28,6 @@ cgen(Node *n, Node *res)
        if(res == N || res->type == T)
                fatal("cgen: res nil");
 
-       // TODO compile complex
-       if(n != N && n->type != T && iscomplex[n->type->etype])
-               return;
-       if(res != N && res->type != T && iscomplex[res->type->etype])
-               return;
-
        while(n->op == OCONVNOP)
                n = n->left;
 
@@ -53,6 +47,7 @@ cgen(Node *n, Node *res)
                goto ret;
        }
 
+
        // update addressability for string, slice
        // can't do in walk because n->left->addable
        // changes if n->left is an escaping local variable.
@@ -69,7 +64,9 @@ cgen(Node *n, Node *res)
 
        // if both are addressable, move
        if(n->addable && res->addable) {
-               if (is64(n->type) || is64(res->type) || n->op == OREGISTER || res->op == OREGISTER) {
+               if(is64(n->type) || is64(res->type) ||
+                  n->op == OREGISTER || res->op == OREGISTER ||
+                  iscomplex[n->type->etype] || iscomplex[res->type->etype]) {
                        gmove(n, res);
                } else {
                        regalloc(&n1, n->type, N);
@@ -99,8 +96,13 @@ cgen(Node *n, Node *res)
                return;
        }
 
+       if(complexop(n, res)) {
+               complexgen(n, res);
+               return;
+       }
+
        // if n is sudoaddable generate addr and move
-       if (!is64(n->type) && !is64(res->type)) {
+       if (!is64(n->type) && !is64(res->type) && !iscomplex[n->type->etype] && !iscomplex[res->type->etype]) {
                a = optoas(OAS, n->type);
                if(sudoaddable(a, n, &addr, &w)) {
                        if (res->op != OREGISTER) {
index b96e30cea7959c640fc0b3718dc7c6eee8a1ec4b..3b68ac1bc277918edf31f3cd9cd6f942de0348ab 100644 (file)
@@ -539,6 +539,11 @@ gmove(Node *f, Node *t)
        tt = simsimtype(t->type);
        cvt = t->type;
 
+       if(iscomplex[ft] || iscomplex[tt]) {
+               complexmove(f, t);
+               return;
+       }
+
        // cannot have two memory operands;
        // except 64-bit, which always copies via registers anyway.
        if(!is64(f->type) && !is64(t->type) && ismem(f) && ismem(t))
index b0fd9917493c82915d953a0f0904e2b414bdfe87..810ad4da64c6e941ca0eb022c4d92ee447a22beb 100644 (file)
@@ -175,7 +175,7 @@ cgen(Node *n, Node *res)
        case OREAL:
        case OIMAG:
        case OCMPLX:
-               // TODO compile complex
+               fatal("unexpected complex");
                return;
 
        // these call bgen to get a bool value
index ea806c9107d036ac031c7b00364b0c5cf470619c..461a39950b33f25dd3782e2ababc16c88d35abcb 100644 (file)
@@ -387,13 +387,13 @@ codeblk(int32 addr, int32 size)
                        break;
 
                if(addr < sym->value) {
-                       Bprint(&bso, "%-20s %.8llux|", "_", addr);
+                       Bprint(&bso, "%-20s %.8llux|", "_", (vlong)addr);
                        for(; addr < sym->value; addr++)
                                Bprint(&bso, " %.2ux", 0);
                        Bprint(&bso, "\n");
                }
                p = sym->text;
-               Bprint(&bso, "%.6llux\t%-20s | %P\n", addr, sym->name, p);
+               Bprint(&bso, "%.6llux\t%-20s | %P\n", (vlong)addr, sym->name, p);
                for(p = p->link; p != P; p = p->link) {
                        if(p->link != P)
                                epc = p->link->pc;
@@ -408,7 +408,7 @@ codeblk(int32 addr, int32 size)
        }
 
        if(addr < eaddr) {
-               Bprint(&bso, "%-20s %.8llux|", "_", addr);
+               Bprint(&bso, "%-20s %.8llux|", "_", (vlong)addr);
                for(; addr < eaddr; addr++)
                        Bprint(&bso, " %.2ux", 0);
        }
index 81cd1f80b8080734f2adc1c9d74935e461812593..151dec9d5de90336768ec519d9165d8125458e4a 100644 (file)
@@ -204,22 +204,14 @@ endif
 ifeq ($(GOARCH),arm)
 # Tests that fail, probably 5g bugs.
 # Disable so that dashboard all.bash can catch regressions.
-NOTEST+=cmath  # floating point
-NOTEST+=crypto/block  # weird bit error
-NOTEST+=encoding/binary  # floating point?
-NOTEST+=exp/datafmt  # crash
-NOTEST+=exp/eval  # crash
-NOTEST+=flag  # floating point
-NOTEST+=fmt  # floating point
-NOTEST+=go/printer  # crash
-NOTEST+=gob  # floating point
-NOTEST+=image/png  # bit errors
-NOTEST+=json  # floating point
-NOTEST+=math  # floating point
-NOTEST+=os/signal  # crash
-NOTEST+=strconv  # floating point
-NOTEST+=syslog  # unix syslog
-NOTEST+=xml  # floating point
+NOTEST+=cmath        # software floating point (lack of) accuracy
+NOTEST+=math         # software floating point (lack of) accuracy
+NOTEST+=strconv      # software floating point (lack of) accuracy
+
+NOTEST+=fmt          # spurious uint overflow
+NOTEST+=gob          # something involving complex
+NOTEST+=json         # spurious uint overflow
+NOTEST+=os/signal    # crash
 endif
 
 TEST=\
index 096cc6da6870c8084a857c6cf10f0ef096b6c9fc..396072fc9fa913f724aa90300cf185565223aa8b 100644 (file)
@@ -169,7 +169,7 @@ s2d(uint32 s)
                return DNINF;
        if ((s & ~(1ul << 31)) == FNAN)
                return DNAN;
-       return (uint64)(s & 0x80000000) << 63 | // sign
+       return (uint64)(s & 0x80000000) << 32 | // sign
                (uint64)((s >> 23 &0xff) + (DOUBLE_EXPBIAS - SINGLE_EXPBIAS)) << 52  |  // exponent
                (uint64)(s & 0x7fffff) << 29;   // mantissa
 }
@@ -211,7 +211,10 @@ dataprocess(uint32* pc)
        if (unary) {
                switch (opcode) {
                case 0: // mvf
-                       m->freg[dest] = frhs(rhs);
+                       fd = frhs(rhs);
+                       if(prec == 0)
+                               fd = s2d(d2s(fd));
+                       m->freg[dest] = fd;
                        goto ret;
                default:
                        goto undef;
index 262a8b53c7259b668756b4402888afea41ae7b9f..1e548012b4c801770ffb5fe9f2b733fc629fd954 100644 (file)
@@ -15,9 +15,11 @@ package strconv
 import (
        "math"
        "os"
+       "runtime"
 )
 
-var optimize = true // can change for testing
+// TODO(rsc): remove "arm" check
+var optimize = runtime.GOARCH != "arm" // can change for testing
 
 // TODO(rsc): Better truncation handling.
 func stringToDecimal(s string) (neg bool, d *decimal, trunc bool, ok bool) {
index 3659243c79054beb2bb3bdc0a953d65cc385a420..2e0c0438b8727c817841a852457cc3b471bbc0e7 100644 (file)
@@ -11,6 +11,7 @@
 package strconv
 
 import "math"
+import "runtime"
 
 // TODO: move elsewhere?
 type floatInfo struct {
@@ -23,6 +24,9 @@ var float32info = floatInfo{23, 8, -127}
 var float64info = floatInfo{52, 11, -1023}
 
 func floatsize() int {
+       if runtime.GOARCH == "arm" { // TODO(rsc): remove
+               return 32
+       }
        // Figure out whether float is float32 or float64.
        // 1e-35 is representable in both, but 1e-70
        // is too small for a float32.
index 9a7f4f0867c5d53f79fe007e4364491ec4d186a9..142fbe1a89a78fb61198078e5ce2d6c3c4dbea77 100644 (file)
@@ -6,9 +6,17 @@
 
 package strconv
 
+import "runtime"
+
 func NewDecimal(i uint64) *decimal { return newDecimal(i) }
 
 func SetOptimize(b bool) bool {
+       if runtime.GOARCH == "arm" {
+               // optimize is always false on arm,
+               // because the software floating point
+               // has such terrible multiplication.
+               return false
+       }
        old := optimize
        optimize = b
        return old