mirror of
https://github.com/golang/go
synced 2024-11-22 04:34:39 -07:00
arm: prop up software floating point
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
This commit is contained in:
parent
f16b6b14d8
commit
69188ad9bb
@ -21,7 +21,8 @@ OFILES=\
|
||||
ggen.$O\
|
||||
gsubr.$O\
|
||||
cgen.$O\
|
||||
cgen64.$O
|
||||
cgen64.$O\
|
||||
cplx.$O\
|
||||
|
||||
LIB=\
|
||||
../gc/gc.a\
|
||||
|
@ -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) {
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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+=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
|
||||
NOTEST+=strconv # floating point
|
||||
NOTEST+=syslog # unix syslog
|
||||
NOTEST+=xml # floating point
|
||||
endif
|
||||
|
||||
TEST=\
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user