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
ggen.$O\
gsubr.$O\
cgen.$O\
- cgen64.$O
+ cgen64.$O\
+ cplx.$O\
LIB=\
../gc/gc.a\
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;
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.
// 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);
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) {
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))
case OREAL:
case OIMAG:
case OCMPLX:
- // TODO compile complex
+ fatal("unexpected complex");
return;
// these call bgen to get a bool value
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;
}
if(addr < eaddr) {
- Bprint(&bso, "%-20s %.8llux|", "_", addr);
+ Bprint(&bso, "%-20s %.8llux|", "_", (vlong)addr);
for(; addr < eaddr; addr++)
Bprint(&bso, " %.2ux", 0);
}
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=\
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
}
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;
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) {
package strconv
import "math"
+import "runtime"
// TODO: move elsewhere?
type floatInfo struct {
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.
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