Commit 8fffa1d6 authored by Russ Cox's avatar Russ Cox

bug190.

also eliminate float80 dregs

R=ken
OCL=35894
CL=35896
parent 4db52d4f
...@@ -245,7 +245,6 @@ regalloc(Node *n, Type *t, Node *o) ...@@ -245,7 +245,6 @@ regalloc(Node *n, Type *t, Node *o)
case TFLOAT32: case TFLOAT32:
case TFLOAT64: case TFLOAT64:
case TFLOAT80:
if(o != N && o->op == OREGISTER) { if(o != N && o->op == OREGISTER) {
i = o->val.u.reg; i = o->val.u.reg;
if(i >= REGALLOC_F0 && i <= REGALLOC_FMAX) if(i >= REGALLOC_F0 && i <= REGALLOC_FMAX)
......
...@@ -275,7 +275,6 @@ regalloc(Node *n, Type *t, Node *o) ...@@ -275,7 +275,6 @@ regalloc(Node *n, Type *t, Node *o)
case TFLOAT32: case TFLOAT32:
case TFLOAT64: case TFLOAT64:
case TFLOAT80:
if(o != N && o->op == OREGISTER) { if(o != N && o->op == OREGISTER) {
i = o->val.u.reg; i = o->val.u.reg;
if(i >= D_X0 && i <= D_X7) if(i >= D_X0 && i <= D_X7)
......
...@@ -1172,7 +1172,6 @@ allreg(uint32 b, Rgn *r) ...@@ -1172,7 +1172,6 @@ allreg(uint32 b, Rgn *r)
case TFLOAT32: case TFLOAT32:
case TFLOAT64: case TFLOAT64:
case TFLOAT80:
case TFLOAT: case TFLOAT:
i = BtoF(~b); i = BtoF(~b);
if(i && r->cost > 0) { if(i && r->cost > 0) {
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
* (see ../6g/align.c). * (see ../6g/align.c).
*/ */
static int defercalc;
uint32 uint32
rnd(uint32 o, uint32 r) rnd(uint32 o, uint32 r)
{ {
...@@ -98,6 +100,7 @@ dowidth(Type *t) ...@@ -98,6 +100,7 @@ dowidth(Type *t)
int32 et; int32 et;
uint32 w; uint32 w;
int lno; int lno;
Type *t1;
if(maxround == 0 || widthptr == 0) if(maxround == 0 || widthptr == 0)
fatal("dowidth without betypeinit"); fatal("dowidth without betypeinit");
...@@ -117,6 +120,9 @@ dowidth(Type *t) ...@@ -117,6 +120,9 @@ dowidth(Type *t)
return; return;
} }
// defer checkwidth calls until after we're done
defercalc++;
lno = lineno; lno = lineno;
lineno = t->lineno; lineno = t->lineno;
t->width = -2; t->width = -2;
...@@ -155,33 +161,36 @@ dowidth(Type *t) ...@@ -155,33 +161,36 @@ dowidth(Type *t)
case TINT32: case TINT32:
case TUINT32: case TUINT32:
case TFLOAT32: case TFLOAT32:
case TPTR32: // note lack of recursion
w = 4; w = 4;
break; break;
case TINT64: case TINT64:
case TUINT64: case TUINT64:
case TFLOAT64: case TFLOAT64:
case TPTR64: // note lack of recursion
w = 8; w = 8;
break; break;
case TFLOAT80: case TPTR32:
w = 10; w = 4;
checkwidth(t->type);
break;
case TPTR64:
w = 8;
checkwidth(t->type);
break; break;
case TDDD: case TDDD:
w = 2*widthptr; w = 2*widthptr;
break; break;
case TINTER: // implemented as 2 pointers case TINTER: // implemented as 2 pointers
offmod(t);
w = 2*widthptr; w = 2*widthptr;
offmod(t);
break; break;
case TCHAN: // implemented as pointer case TCHAN: // implemented as pointer
dowidth(t->type);
dowidth(t->down);
w = widthptr; w = widthptr;
checkwidth(t->type);
break; break;
case TMAP: // implemented as pointer case TMAP: // implemented as pointer
dowidth(t->type);
w = widthptr; w = widthptr;
checkwidth(t->type);
checkwidth(t->down);
break; break;
case TFORW: // should have been filled in case TFORW: // should have been filled in
case TANY: case TANY:
...@@ -198,15 +207,18 @@ dowidth(Type *t) ...@@ -198,15 +207,18 @@ dowidth(Type *t)
case TARRAY: case TARRAY:
if(t->type == T) if(t->type == T)
break; break;
dowidth(t->type); if(t->bound >= 0) {
if(t->bound >= 0) dowidth(t->type);
w = t->bound * t->type->width; w = t->bound * t->type->width;
else if(t->bound == -1) if(w == 0)
w = maxround;
}
else if(t->bound == -1) {
w = sizeof_Array; w = sizeof_Array;
checkwidth(t->type);
}
else else
fatal("dowidth %T", t); // probably [...]T fatal("dowidth %T", t); // probably [...]T
if(w == 0)
w = maxround;
break; break;
case TSTRUCT: case TSTRUCT:
...@@ -218,20 +230,118 @@ dowidth(Type *t) ...@@ -218,20 +230,118 @@ dowidth(Type *t)
break; break;
case TFUNC: case TFUNC:
// function is 3 cated structures; // make fake type to check later to
// compute their widths as side-effect. // trigger function argument computation.
w = widstruct(*getthis(t), 0, 0); t1 = typ(TFUNCARGS);
w = widstruct(*getinarg(t), w, 1); t1->type = t;
w = widstruct(*getoutarg(t), w, 1); checkwidth(t1);
t->argwid = w;
// but width of func type is pointer // width of func type is pointer
w = widthptr; w = widthptr;
break; break;
case TFUNCARGS:
// function is 3 cated structures;
// compute their widths as side-effect.
t1 = t->type;
w = widstruct(*getthis(t1), 0, 0);
w = widstruct(*getinarg(t1), w, 1);
w = widstruct(*getoutarg(t1), w, 1);
t1->argwid = w;
break;
} }
t->width = w; t->width = w;
lineno = lno; lineno = lno;
if(defercalc == 1)
resumecheckwidth();
else
--defercalc;
}
/*
* when a type's width should be known, we call checkwidth
* to compute it. during a declaration like
*
* type T *struct { next T }
*
* it is necessary to defer the calculation of the struct width
* until after T has been initialized to be a pointer to that struct.
* similarly, during import processing structs may be used
* before their definition. in those situations, calling
* defercheckwidth() stops width calculations until
* resumecheckwidth() is called, at which point all the
* checkwidths that were deferred are executed.
* dowidth should only be called when the type's size
* is needed immediately. checkwidth makes sure the
* size is evaluated eventually.
*/
typedef struct TypeList TypeList;
struct TypeList {
Type *t;
TypeList *next;
};
static TypeList *tlfree;
static TypeList *tlq;
void
checkwidth(Type *t)
{
TypeList *l;
if(t == T)
return;
// function arg structs should not be checked
// outside of the enclosing function.
if(t->funarg)
fatal("checkwidth %T", t);
if(!defercalc) {
dowidth(t);
return;
}
if(t->deferwidth)
return;
t->deferwidth = 1;
l = tlfree;
if(l != nil)
tlfree = l->next;
else
l = mal(sizeof *l);
l->t = t;
l->next = tlq;
tlq = l;
}
void
defercheckwidth(void)
{
// we get out of sync on syntax errors, so don't be pedantic.
// if(defercalc)
// fatal("defercheckwidth");
defercalc = 1;
}
void
resumecheckwidth(void)
{
TypeList *l;
if(!defercalc)
fatal("resumecheckwidth");
for(l = tlq; l != nil; l = tlq) {
l->t->deferwidth = 0;
tlq = l->next;
dowidth(l->t);
l->next = tlfree;
tlfree = l;
}
defercalc = 0;
} }
void void
...@@ -263,7 +373,7 @@ typeinit(void) ...@@ -263,7 +373,7 @@ typeinit(void)
isint[TUINT] = 1; isint[TUINT] = 1;
isint[TUINTPTR] = 1; isint[TUINTPTR] = 1;
for(i=TFLOAT32; i<=TFLOAT80; i++) for(i=TFLOAT32; i<=TFLOAT64; i++)
isfloat[i] = 1; isfloat[i] = 1;
isfloat[TFLOAT] = 1; isfloat[TFLOAT] = 1;
......
...@@ -553,7 +553,6 @@ cgen_as(Node *nl, Node *nr) ...@@ -553,7 +553,6 @@ cgen_as(Node *nl, Node *nr)
case TFLOAT32: case TFLOAT32:
case TFLOAT64: case TFLOAT64:
case TFLOAT80:
nr->val.u.fval = mal(sizeof(*nr->val.u.fval)); nr->val.u.fval = mal(sizeof(*nr->val.u.fval));
mpmovecflt(nr->val.u.fval, 0.0); mpmovecflt(nr->val.u.fval, 0.0);
nr->val.ctype = CTFLT; nr->val.ctype = CTFLT;
......
...@@ -406,7 +406,6 @@ enum ...@@ -406,7 +406,6 @@ enum
TFLOAT32, // 12 TFLOAT32, // 12
TFLOAT64, TFLOAT64,
TFLOAT80,
TFLOAT, TFLOAT,
TBOOL, // 16 TBOOL, // 16
...@@ -430,6 +429,9 @@ enum ...@@ -430,6 +429,9 @@ enum
TIDEAL, TIDEAL,
TNIL, TNIL,
TBLANK, TBLANK,
// pseudo-type for frame layout
TFUNCARGS,
NTYPE, NTYPE,
}; };
......
...@@ -1207,7 +1207,6 @@ static struct ...@@ -1207,7 +1207,6 @@ static struct
"float32", LNAME, TFLOAT32, OXXX, "float32", LNAME, TFLOAT32, OXXX,
"float64", LNAME, TFLOAT64, OXXX, "float64", LNAME, TFLOAT64, OXXX,
"float80", LNAME, TFLOAT80, OXXX,
"bool", LNAME, TBOOL, OXXX, "bool", LNAME, TBOOL, OXXX,
"byte", LNAME, TUINT8, OXXX, "byte", LNAME, TUINT8, OXXX,
......
...@@ -687,8 +687,7 @@ dumptypestructs(void) ...@@ -687,8 +687,7 @@ dumptypestructs(void)
// but using runtime means fewer copies in .6 files. // but using runtime means fewer copies in .6 files.
if(strcmp(package, "runtime") == 0) { if(strcmp(package, "runtime") == 0) {
for(i=1; i<=TBOOL; i++) for(i=1; i<=TBOOL; i++)
if(i != TFLOAT80) dtypesym(ptrto(types[i]));
dtypesym(ptrto(types[i]));
dtypesym(ptrto(types[TSTRING])); dtypesym(ptrto(types[TSTRING]));
dtypesym(typ(TDDD)); dtypesym(typ(TDDD));
dtypesym(ptrto(pkglookup("Pointer", "unsafe")->def->type)); dtypesym(ptrto(pkglookup("Pointer", "unsafe")->def->type));
......
...@@ -899,7 +899,6 @@ etnames[] = ...@@ -899,7 +899,6 @@ etnames[] =
[TFLOAT] = "FLOAT", [TFLOAT] = "FLOAT",
[TFLOAT32] = "FLOAT32", [TFLOAT32] = "FLOAT32",
[TFLOAT64] = "FLOAT64", [TFLOAT64] = "FLOAT64",
[TFLOAT80] = "FLOAT80",
[TBOOL] = "BOOL", [TBOOL] = "BOOL",
[TPTR32] = "PTR32", [TPTR32] = "PTR32",
[TPTR64] = "PTR64", [TPTR64] = "PTR64",
...@@ -1044,7 +1043,6 @@ basicnames[] = ...@@ -1044,7 +1043,6 @@ basicnames[] =
[TFLOAT] = "float", [TFLOAT] = "float",
[TFLOAT32] = "float32", [TFLOAT32] = "float32",
[TFLOAT64] = "float64", [TFLOAT64] = "float64",
[TFLOAT80] = "float80",
[TBOOL] = "bool", [TBOOL] = "bool",
[TANY] = "any", [TANY] = "any",
[TDDD] = "...", [TDDD] = "...",
...@@ -3073,87 +3071,6 @@ structcount(Type *t) ...@@ -3073,87 +3071,6 @@ structcount(Type *t)
return v; return v;
} }
/*
* when a type's width should be known, we call checkwidth
* to compute it. during a declaration like
*
* type T *struct { next T }
*
* it is necessary to defer the calculation of the struct width
* until after T has been initialized to be a pointer to that struct.
* similarly, during import processing structs may be used
* before their definition. in those situations, calling
* defercheckwidth() stops width calculations until
* resumecheckwidth() is called, at which point all the
* checkwidths that were deferred are executed.
* sometimes it is okay to
*/
typedef struct TypeList TypeList;
struct TypeList {
Type *t;
TypeList *next;
};
static TypeList *tlfree;
static TypeList *tlq;
static int defercalc;
void
checkwidth(Type *t)
{
TypeList *l;
// function arg structs should not be checked
// outside of the enclosing function.
if(t->funarg)
fatal("checkwidth %T", t);
if(!defercalc) {
dowidth(t);
return;
}
if(t->deferwidth)
return;
t->deferwidth = 1;
l = tlfree;
if(l != nil)
tlfree = l->next;
else
l = mal(sizeof *l);
l->t = t;
l->next = tlq;
tlq = l;
}
void
defercheckwidth(void)
{
// we get out of sync on syntax errors, so don't be pedantic.
// if(defercalc)
// fatal("defercheckwidth");
defercalc = 1;
}
void
resumecheckwidth(void)
{
TypeList *l;
if(!defercalc)
fatal("restartcheckwidth");
defercalc = 0;
for(l = tlq; l != nil; l = tlq) {
l->t->deferwidth = 0;
dowidth(l->t);
tlq = l->next;
l->next = tlfree;
tlfree = l;
}
}
/* /*
* return power of 2 of the constant * return power of 2 of the constant
* operand. -1 if it is not a power of 2. * operand. -1 if it is not a power of 2.
......
...@@ -150,15 +150,6 @@ BUG: should fail ...@@ -150,15 +150,6 @@ BUG: should fail
=========== bugs/bug169.go =========== bugs/bug169.go
BUG: errchk: command succeeded unexpectedly BUG: errchk: command succeeded unexpectedly
=========== bugs/bug190.go
bugs/bug190.go:11: invalid recursive type []S
bugs/bug190.go:13: invalid recursive type chan S
bugs/bug190.go:15: invalid recursive type func(S) (S)
bugs/bug190.go:16: invalid recursive type S
bugs/bug190.go:16: invalid recursive type S
bugs/bug190.go:16: invalid recursive type S
BUG: should compile
=========== bugs/bug193.go =========== bugs/bug193.go
BUG: errchk: bugs/bug193.go:14: missing expected error: 'shift' BUG: errchk: bugs/bug193.go:14: missing expected error: 'shift'
...@@ -167,9 +158,5 @@ too many calls: 5 ...@@ -167,9 +158,5 @@ too many calls: 5
panic PC=xxx panic PC=xxx
BUG: bug196 BUG: bug196
=========== bugs/bug210.go
bugs/bug210.go:10: invalid recursive type []T
BUG: should compile
=========== bugs/bug211.go =========== bugs/bug211.go
BUG: errchk: command succeeded unexpectedly BUG: errchk: command succeeded unexpectedly
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment