mirror of
https://github.com/golang/go
synced 2024-11-21 18:14:42 -07:00
bug190.
also eliminate float80 dregs R=ken OCL=35894 CL=35896
This commit is contained in:
parent
4db52d4ff8
commit
8fffa1d698
@ -245,7 +245,6 @@ regalloc(Node *n, Type *t, Node *o)
|
||||
|
||||
case TFLOAT32:
|
||||
case TFLOAT64:
|
||||
case TFLOAT80:
|
||||
if(o != N && o->op == OREGISTER) {
|
||||
i = o->val.u.reg;
|
||||
if(i >= REGALLOC_F0 && i <= REGALLOC_FMAX)
|
||||
|
@ -275,7 +275,6 @@ regalloc(Node *n, Type *t, Node *o)
|
||||
|
||||
case TFLOAT32:
|
||||
case TFLOAT64:
|
||||
case TFLOAT80:
|
||||
if(o != N && o->op == OREGISTER) {
|
||||
i = o->val.u.reg;
|
||||
if(i >= D_X0 && i <= D_X7)
|
||||
|
@ -1172,7 +1172,6 @@ allreg(uint32 b, Rgn *r)
|
||||
|
||||
case TFLOAT32:
|
||||
case TFLOAT64:
|
||||
case TFLOAT80:
|
||||
case TFLOAT:
|
||||
i = BtoF(~b);
|
||||
if(i && r->cost > 0) {
|
||||
|
@ -11,6 +11,8 @@
|
||||
* (see ../6g/align.c).
|
||||
*/
|
||||
|
||||
static int defercalc;
|
||||
|
||||
uint32
|
||||
rnd(uint32 o, uint32 r)
|
||||
{
|
||||
@ -98,6 +100,7 @@ dowidth(Type *t)
|
||||
int32 et;
|
||||
uint32 w;
|
||||
int lno;
|
||||
Type *t1;
|
||||
|
||||
if(maxround == 0 || widthptr == 0)
|
||||
fatal("dowidth without betypeinit");
|
||||
@ -117,6 +120,9 @@ dowidth(Type *t)
|
||||
return;
|
||||
}
|
||||
|
||||
// defer checkwidth calls until after we're done
|
||||
defercalc++;
|
||||
|
||||
lno = lineno;
|
||||
lineno = t->lineno;
|
||||
t->width = -2;
|
||||
@ -155,33 +161,36 @@ dowidth(Type *t)
|
||||
case TINT32:
|
||||
case TUINT32:
|
||||
case TFLOAT32:
|
||||
case TPTR32: // note lack of recursion
|
||||
w = 4;
|
||||
break;
|
||||
case TINT64:
|
||||
case TUINT64:
|
||||
case TFLOAT64:
|
||||
case TPTR64: // note lack of recursion
|
||||
w = 8;
|
||||
break;
|
||||
case TFLOAT80:
|
||||
w = 10;
|
||||
case TPTR32:
|
||||
w = 4;
|
||||
checkwidth(t->type);
|
||||
break;
|
||||
case TPTR64:
|
||||
w = 8;
|
||||
checkwidth(t->type);
|
||||
break;
|
||||
case TDDD:
|
||||
w = 2*widthptr;
|
||||
break;
|
||||
case TINTER: // implemented as 2 pointers
|
||||
offmod(t);
|
||||
w = 2*widthptr;
|
||||
offmod(t);
|
||||
break;
|
||||
case TCHAN: // implemented as pointer
|
||||
dowidth(t->type);
|
||||
dowidth(t->down);
|
||||
w = widthptr;
|
||||
checkwidth(t->type);
|
||||
break;
|
||||
case TMAP: // implemented as pointer
|
||||
dowidth(t->type);
|
||||
w = widthptr;
|
||||
checkwidth(t->type);
|
||||
checkwidth(t->down);
|
||||
break;
|
||||
case TFORW: // should have been filled in
|
||||
case TANY:
|
||||
@ -198,15 +207,18 @@ dowidth(Type *t)
|
||||
case TARRAY:
|
||||
if(t->type == T)
|
||||
break;
|
||||
dowidth(t->type);
|
||||
if(t->bound >= 0)
|
||||
if(t->bound >= 0) {
|
||||
dowidth(t->type);
|
||||
w = t->bound * t->type->width;
|
||||
else if(t->bound == -1)
|
||||
if(w == 0)
|
||||
w = maxround;
|
||||
}
|
||||
else if(t->bound == -1) {
|
||||
w = sizeof_Array;
|
||||
checkwidth(t->type);
|
||||
}
|
||||
else
|
||||
fatal("dowidth %T", t); // probably [...]T
|
||||
if(w == 0)
|
||||
w = maxround;
|
||||
break;
|
||||
|
||||
case TSTRUCT:
|
||||
@ -218,20 +230,118 @@ dowidth(Type *t)
|
||||
break;
|
||||
|
||||
case TFUNC:
|
||||
// make fake type to check later to
|
||||
// trigger function argument computation.
|
||||
t1 = typ(TFUNCARGS);
|
||||
t1->type = t;
|
||||
checkwidth(t1);
|
||||
|
||||
// width of func type is pointer
|
||||
w = widthptr;
|
||||
break;
|
||||
|
||||
case TFUNCARGS:
|
||||
// function is 3 cated structures;
|
||||
// compute their widths as side-effect.
|
||||
w = widstruct(*getthis(t), 0, 0);
|
||||
w = widstruct(*getinarg(t), w, 1);
|
||||
w = widstruct(*getoutarg(t), w, 1);
|
||||
t->argwid = w;
|
||||
|
||||
// but width of func type is pointer
|
||||
w = widthptr;
|
||||
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;
|
||||
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
|
||||
@ -263,7 +373,7 @@ typeinit(void)
|
||||
isint[TUINT] = 1;
|
||||
isint[TUINTPTR] = 1;
|
||||
|
||||
for(i=TFLOAT32; i<=TFLOAT80; i++)
|
||||
for(i=TFLOAT32; i<=TFLOAT64; i++)
|
||||
isfloat[i] = 1;
|
||||
isfloat[TFLOAT] = 1;
|
||||
|
||||
|
@ -553,7 +553,6 @@ cgen_as(Node *nl, Node *nr)
|
||||
|
||||
case TFLOAT32:
|
||||
case TFLOAT64:
|
||||
case TFLOAT80:
|
||||
nr->val.u.fval = mal(sizeof(*nr->val.u.fval));
|
||||
mpmovecflt(nr->val.u.fval, 0.0);
|
||||
nr->val.ctype = CTFLT;
|
||||
|
@ -406,7 +406,6 @@ enum
|
||||
|
||||
TFLOAT32, // 12
|
||||
TFLOAT64,
|
||||
TFLOAT80,
|
||||
TFLOAT,
|
||||
|
||||
TBOOL, // 16
|
||||
@ -430,6 +429,9 @@ enum
|
||||
TIDEAL,
|
||||
TNIL,
|
||||
TBLANK,
|
||||
|
||||
// pseudo-type for frame layout
|
||||
TFUNCARGS,
|
||||
|
||||
NTYPE,
|
||||
};
|
||||
|
@ -1207,7 +1207,6 @@ static struct
|
||||
|
||||
"float32", LNAME, TFLOAT32, OXXX,
|
||||
"float64", LNAME, TFLOAT64, OXXX,
|
||||
"float80", LNAME, TFLOAT80, OXXX,
|
||||
|
||||
"bool", LNAME, TBOOL, OXXX,
|
||||
"byte", LNAME, TUINT8, OXXX,
|
||||
|
@ -687,8 +687,7 @@ dumptypestructs(void)
|
||||
// but using runtime means fewer copies in .6 files.
|
||||
if(strcmp(package, "runtime") == 0) {
|
||||
for(i=1; i<=TBOOL; i++)
|
||||
if(i != TFLOAT80)
|
||||
dtypesym(ptrto(types[i]));
|
||||
dtypesym(ptrto(types[i]));
|
||||
dtypesym(ptrto(types[TSTRING]));
|
||||
dtypesym(typ(TDDD));
|
||||
dtypesym(ptrto(pkglookup("Pointer", "unsafe")->def->type));
|
||||
|
@ -899,7 +899,6 @@ etnames[] =
|
||||
[TFLOAT] = "FLOAT",
|
||||
[TFLOAT32] = "FLOAT32",
|
||||
[TFLOAT64] = "FLOAT64",
|
||||
[TFLOAT80] = "FLOAT80",
|
||||
[TBOOL] = "BOOL",
|
||||
[TPTR32] = "PTR32",
|
||||
[TPTR64] = "PTR64",
|
||||
@ -1044,7 +1043,6 @@ basicnames[] =
|
||||
[TFLOAT] = "float",
|
||||
[TFLOAT32] = "float32",
|
||||
[TFLOAT64] = "float64",
|
||||
[TFLOAT80] = "float80",
|
||||
[TBOOL] = "bool",
|
||||
[TANY] = "any",
|
||||
[TDDD] = "...",
|
||||
@ -3073,87 +3071,6 @@ structcount(Type *t)
|
||||
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
|
||||
* operand. -1 if it is not a power of 2.
|
||||
|
@ -150,15 +150,6 @@ BUG: should fail
|
||||
=========== bugs/bug169.go
|
||||
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
|
||||
BUG: errchk: bugs/bug193.go:14: missing expected error: 'shift'
|
||||
|
||||
@ -167,9 +158,5 @@ too many calls: 5
|
||||
panic PC=xxx
|
||||
BUG: bug196
|
||||
|
||||
=========== bugs/bug210.go
|
||||
bugs/bug210.go:10: invalid recursive type []T
|
||||
BUG: should compile
|
||||
|
||||
=========== bugs/bug211.go
|
||||
BUG: errchk: command succeeded unexpectedly
|
||||
|
Loading…
Reference in New Issue
Block a user