mirror of https://github.com/golang/go.git
cmd/6g: extend componentgen to small arrays and structs.
Fixes #4092. R=golang-dev, dave, rsc CC=golang-dev https://golang.org/cl/6819083
This commit is contained in:
parent
eb4f4d16ae
commit
16072c7497
|
|
@ -1458,6 +1458,8 @@ cadable(Node *n)
|
|||
/*
|
||||
* copy a composite value by moving its individual components.
|
||||
* Slices, strings and interfaces are supported.
|
||||
* Small structs or arrays with elements of basic type are
|
||||
* also supported.
|
||||
* nr is N when assigning a zero value.
|
||||
* return 1 if can do, 0 if cant.
|
||||
*/
|
||||
|
|
@ -1465,7 +1467,10 @@ int
|
|||
componentgen(Node *nr, Node *nl)
|
||||
{
|
||||
Node nodl, nodr;
|
||||
Type *t;
|
||||
int freel, freer;
|
||||
vlong fldcount;
|
||||
vlong loffset, roffset;
|
||||
|
||||
freel = 0;
|
||||
freer = 0;
|
||||
|
|
@ -1475,8 +1480,33 @@ componentgen(Node *nr, Node *nl)
|
|||
goto no;
|
||||
|
||||
case TARRAY:
|
||||
if(!isslice(nl->type))
|
||||
t = nl->type;
|
||||
|
||||
// Slices are ok.
|
||||
if(isslice(t))
|
||||
break;
|
||||
// Small arrays are ok.
|
||||
if(t->bound > 0 && t->bound <= 3 && !isfat(t->type))
|
||||
break;
|
||||
|
||||
goto no;
|
||||
|
||||
case TSTRUCT:
|
||||
// Small structs with non-fat types are ok.
|
||||
// Zero-sized structs are treated separately elsewhere.
|
||||
fldcount = 0;
|
||||
for(t=nl->type->type; t; t=t->down) {
|
||||
if(isfat(t->type))
|
||||
goto no;
|
||||
if(t->etype != TFIELD)
|
||||
fatal("componentgen: not a TFIELD: %lT", t);
|
||||
fldcount++;
|
||||
}
|
||||
if(fldcount == 0 || fldcount > 3)
|
||||
goto no;
|
||||
|
||||
break;
|
||||
|
||||
case TSTRING:
|
||||
case TINTER:
|
||||
break;
|
||||
|
|
@ -1500,6 +1530,23 @@ componentgen(Node *nr, Node *nl)
|
|||
|
||||
switch(nl->type->etype) {
|
||||
case TARRAY:
|
||||
// componentgen for arrays.
|
||||
t = nl->type;
|
||||
if(!isslice(t)) {
|
||||
nodl.type = t->type;
|
||||
nodr.type = nodl.type;
|
||||
for(fldcount=0; fldcount < t->bound; fldcount++) {
|
||||
if(nr == N)
|
||||
clearslim(&nodl);
|
||||
else
|
||||
gmove(&nodr, &nodl);
|
||||
nodl.xoffset += t->type->width;
|
||||
nodr.xoffset += t->type->width;
|
||||
}
|
||||
goto yes;
|
||||
}
|
||||
|
||||
// componentgen for slices.
|
||||
nodl.xoffset += Array_array;
|
||||
nodl.type = ptrto(nl->type->type);
|
||||
|
||||
|
|
@ -1577,6 +1624,23 @@ componentgen(Node *nr, Node *nl)
|
|||
gmove(&nodr, &nodl);
|
||||
|
||||
goto yes;
|
||||
|
||||
case TSTRUCT:
|
||||
loffset = nodl.xoffset;
|
||||
roffset = nodr.xoffset;
|
||||
for(t=nl->type->type; t; t=t->down) {
|
||||
nodl.xoffset = loffset + t->width;
|
||||
nodl.type = t->type;
|
||||
|
||||
if(nr == N)
|
||||
clearslim(&nodl);
|
||||
else {
|
||||
nodr.xoffset = roffset + t->width;
|
||||
nodr.type = nodl.type;
|
||||
gmove(&nodr, &nodl);
|
||||
}
|
||||
}
|
||||
goto yes;
|
||||
}
|
||||
|
||||
no:
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@ void allocparams(void);
|
|||
void checklabels();
|
||||
void ginscall(Node*, int);
|
||||
int gen_as_init(Node*);
|
||||
void clearslim(Node*);
|
||||
|
||||
/*
|
||||
* cgen.c
|
||||
|
|
|
|||
126
src/cmd/gc/gen.c
126
src/cmd/gc/gen.c
|
|
@ -632,6 +632,67 @@ cgen_discard(Node *nr)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* clearslim generates code to zero a slim node.
|
||||
*/
|
||||
void
|
||||
clearslim(Node *n)
|
||||
{
|
||||
Node z;
|
||||
Mpflt zero;
|
||||
|
||||
memset(&z, 0, sizeof(z));
|
||||
z.op = OLITERAL;
|
||||
z.type = n->type;
|
||||
z.addable = 1;
|
||||
|
||||
switch(simtype[n->type->etype]) {
|
||||
case TCOMPLEX64:
|
||||
case TCOMPLEX128:
|
||||
z.val.u.cval = mal(sizeof(z.val.u.cval));
|
||||
mpmovecflt(&z.val.u.cval->real, 0.0);
|
||||
mpmovecflt(&z.val.u.cval->imag, 0.0);
|
||||
break;
|
||||
|
||||
case TFLOAT32:
|
||||
case TFLOAT64:
|
||||
mpmovecflt(&zero, 0.0);
|
||||
z.val.ctype = CTFLT;
|
||||
z.val.u.fval = &zero;
|
||||
break;
|
||||
|
||||
case TPTR32:
|
||||
case TPTR64:
|
||||
case TCHAN:
|
||||
case TMAP:
|
||||
z.val.ctype = CTNIL;
|
||||
break;
|
||||
|
||||
case TBOOL:
|
||||
z.val.ctype = CTBOOL;
|
||||
break;
|
||||
|
||||
case TINT8:
|
||||
case TINT16:
|
||||
case TINT32:
|
||||
case TINT64:
|
||||
case TUINT8:
|
||||
case TUINT16:
|
||||
case TUINT32:
|
||||
case TUINT64:
|
||||
z.val.ctype = CTINT;
|
||||
z.val.u.xval = mal(sizeof(z.val.u.xval));
|
||||
mpmovecfix(z.val.u.xval, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("clearslim called on type %T", n->type);
|
||||
}
|
||||
|
||||
ullmancalc(&z);
|
||||
cgen(&z, n);
|
||||
}
|
||||
|
||||
/*
|
||||
* generate assignment:
|
||||
* nl = nr
|
||||
|
|
@ -640,9 +701,7 @@ cgen_discard(Node *nr)
|
|||
void
|
||||
cgen_as(Node *nl, Node *nr)
|
||||
{
|
||||
Node nc;
|
||||
Type *tl;
|
||||
int iszer;
|
||||
|
||||
if(debug['g']) {
|
||||
dump("cgen_as", nl);
|
||||
|
|
@ -657,7 +716,6 @@ cgen_as(Node *nl, Node *nr)
|
|||
return;
|
||||
}
|
||||
|
||||
iszer = 0;
|
||||
if(nr == N || isnil(nr)) {
|
||||
// externals and heaps should already be clear
|
||||
if(nr == N) {
|
||||
|
|
@ -672,59 +730,12 @@ cgen_as(Node *nl, Node *nr)
|
|||
return;
|
||||
if(isfat(tl)) {
|
||||
clearfat(nl);
|
||||
goto ret;
|
||||
return;
|
||||
}
|
||||
|
||||
/* invent a "zero" for the rhs */
|
||||
iszer = 1;
|
||||
nr = &nc;
|
||||
memset(nr, 0, sizeof(*nr));
|
||||
switch(simtype[tl->etype]) {
|
||||
default:
|
||||
fatal("cgen_as: tl %T", tl);
|
||||
break;
|
||||
|
||||
case TINT8:
|
||||
case TUINT8:
|
||||
case TINT16:
|
||||
case TUINT16:
|
||||
case TINT32:
|
||||
case TUINT32:
|
||||
case TINT64:
|
||||
case TUINT64:
|
||||
nr->val.u.xval = mal(sizeof(*nr->val.u.xval));
|
||||
mpmovecfix(nr->val.u.xval, 0);
|
||||
nr->val.ctype = CTINT;
|
||||
break;
|
||||
|
||||
case TFLOAT32:
|
||||
case TFLOAT64:
|
||||
nr->val.u.fval = mal(sizeof(*nr->val.u.fval));
|
||||
mpmovecflt(nr->val.u.fval, 0.0);
|
||||
nr->val.ctype = CTFLT;
|
||||
break;
|
||||
|
||||
case TBOOL:
|
||||
nr->val.u.bval = 0;
|
||||
nr->val.ctype = CTBOOL;
|
||||
break;
|
||||
|
||||
case TPTR32:
|
||||
case TPTR64:
|
||||
nr->val.ctype = CTNIL;
|
||||
break;
|
||||
|
||||
case TCOMPLEX64:
|
||||
case TCOMPLEX128:
|
||||
nr->val.u.cval = mal(sizeof(*nr->val.u.cval));
|
||||
mpmovecflt(&nr->val.u.cval->real, 0.0);
|
||||
mpmovecflt(&nr->val.u.cval->imag, 0.0);
|
||||
break;
|
||||
}
|
||||
nr->op = OLITERAL;
|
||||
nr->type = tl;
|
||||
nr->addable = 1;
|
||||
ullmancalc(nr);
|
||||
clearslim(nl);
|
||||
if(nl->addable)
|
||||
gused(nl);
|
||||
return;
|
||||
}
|
||||
|
||||
tl = nl->type;
|
||||
|
|
@ -732,11 +743,6 @@ cgen_as(Node *nl, Node *nr)
|
|||
return;
|
||||
|
||||
cgen(nr, nl);
|
||||
if(iszer && nl->addable)
|
||||
gused(nl);
|
||||
|
||||
ret:
|
||||
;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue