Commit cb49a999 authored by Russ Cox's avatar Russ Cox

move static init code from 6g into gc.

hook up to 8g and 5g too.

R=ken
OCL=34768
CL=34768
parent 44b0f591
......@@ -490,53 +490,3 @@ clearfat(Node *nl)
regfree(&nz);
}
int
getlit(Node *lit)
{
if(smallintconst(lit))
return mpgetfix(lit->val.u.xval);
return -1;
}
int
stataddr(Node *nam, Node *n)
{
int l;
if(n == N)
goto no;
switch(n->op) {
case ONAME:
*nam = *n;
return n->addable;
case ODOT:
if(!stataddr(nam, n->left))
break;
nam->xoffset += n->xoffset;
nam->type = n->type;
return 1;
case OINDEX:
if(n->left->type->bound < 0)
break;
if(!stataddr(nam, n->left))
break;
l = getlit(n->right);
if(l < 0)
break;
nam->xoffset += l*n->type->width;
nam->type = n->type;
return 1;
}
no:
return 0;
}
int
gen_as_init(Node *n)
{
return 0;
}
......@@ -477,6 +477,44 @@ datagostring(Strlit *sval, Addr *a)
text();
}
void
gdata(Node *nam, Node *nr, int wid)
{
Prog *p;
vlong v;
if(wid == 8 && is64(nr->type)) {
v = mpgetfix(nr->val.u.xval);
p = gins(ADATA, nam, nodintconst(v));
p->reg = 4;
p = gins(ADATA, nam, nodintconst(v>>32));
p->reg = 4;
p->from.offset += 4;
return;
}
p = gins(ADATA, nam, nr);
p->reg = wid;
}
void
gdatastring(Node *nam, Strlit *sval)
{
Prog *p;
Node nod1;
p = gins(ADATA, nam, N);
datastring(sval->s, sval->len, &p->to);
p->reg = types[tptr]->width;
p->to.type = D_CONST;
p->to.etype = TINT32;
//print("%P\n", p);
nodconst(&nod1, types[TINT32], sval->len);
p = gins(ADATA, nam, &nod1);
p->reg = types[TINT32]->width;
p->from.offset += types[tptr]->width;
}
int
dstringptr(Sym *s, int off, char *str)
{
......
......@@ -1029,174 +1029,6 @@ clearfat(Node *nl)
restx(&ax, &oldax);
}
int
getlit(Node *lit)
{
if(smallintconst(lit))
return mpgetfix(lit->val.u.xval);
return -1;
}
int
stataddr(Node *nam, Node *n)
{
int l;
if(n == N)
goto no;
switch(n->op) {
case ONAME:
*nam = *n;
return n->addable;
case ODOT:
if(!stataddr(nam, n->left))
break;
nam->xoffset += n->xoffset;
nam->type = n->type;
return 1;
case OINDEX:
if(n->left->type->bound < 0)
break;
if(!stataddr(nam, n->left))
break;
l = getlit(n->right);
if(l < 0)
break;
nam->xoffset += l*n->type->width;
nam->type = n->type;
return 1;
}
no:
return 0;
}
int
gen_as_init(Node *n)
{
Node *nr, *nl;
Node nam, nod1;
Prog *p;
if(n->dodata == 0)
goto no;
nr = n->right;
nl = n->left;
if(nr == N) {
if(!stataddr(&nam, nl))
goto no;
if(nam.class != PEXTERN)
goto no;
goto yes;
}
if(nr->type == T || !eqtype(nl->type, nr->type))
goto no;
if(!stataddr(&nam, nl))
goto no;
if(nam.class != PEXTERN)
goto no;
switch(nr->op) {
default:
goto no;
case OCONVSLICE:
goto slice;
case OLITERAL:
break;
}
switch(nr->type->etype) {
default:
goto no;
case TBOOL:
case TINT8:
case TUINT8:
case TINT16:
case TUINT16:
case TINT32:
case TUINT32:
case TINT64:
case TUINT64:
case TINT:
case TUINT:
case TUINTPTR:
case TPTR32:
case TPTR64:
case TFLOAT32:
case TFLOAT64:
case TFLOAT:
p = gins(ANOP, N, N); // in case the data is the dest of a goto
p = gins(ADATA, &nam, nr);
p->from.scale = nr->type->width;
break;
case TSTRING:
gins(ANOP, N, N); // in case the data is the dest of a goto
p = gins(ADATA, &nam, N);
datastring(nr->val.u.sval->s, nr->val.u.sval->len, &p->to);
p->from.scale = types[tptr]->width;
p->to.index = p->to.type;
p->to.type = D_ADDR;
//print("%P\n", p);
nodconst(&nod1, types[TINT32], nr->val.u.sval->len);
p = gins(ADATA, &nam, &nod1);
p->from.scale = types[TINT32]->width;
p->from.offset += types[tptr]->width;
//print("%P\n", p);
break;
}
yes:
return 1;
slice:
p = gins(ANOP, N, N); // in case the data is the dest of a goto
nr = n->right->left;
if(nr == N || nr->op != OADDR)
goto no;
nr = nr->left;
if(nr == N || nr->op != ONAME)
goto no;
// nr is the array being converted to a slice
if(nr->type == T || nr->type->etype != TARRAY || nr->type->bound < 0)
goto no;
nam.xoffset += Array_array;
p = gins(ADATA, &nam, n->right->left);
p->from.scale = types[tptr]->width;
nam.xoffset += Array_nel-Array_array;
nodconst(&nod1, types[TINT32], nr->type->bound);
p = gins(ADATA, &nam, &nod1);
p->from.scale = types[TINT32]->width;
nam.xoffset += Array_cap-Array_nel;
p = gins(ADATA, &nam, &nod1);
p->from.scale = types[TINT32]->width;
goto yes;
no:
if(n->dodata == 2) {
dump("\ngen_as_init", n);
fatal("gen_as_init couldnt make data statement");
}
return 0;
}
static int
regcmp(const void *va, const void *vb)
{
......
......@@ -485,6 +485,35 @@ datagostring(Strlit *sval, Addr *a)
text();
}
void
gdata(Node *nam, Node *nr, int wid)
{
Prog *p;
p = gins(ADATA, nam, nr);
p->from.scale = wid;
}
void
gdatastring(Node *nam, Strlit *sval)
{
Prog *p;
Node nod1;
p = gins(ADATA, nam, N);
datastring(sval->s, sval->len, &p->to);
p->from.scale = types[tptr]->width;
p->to.index = p->to.type;
p->to.type = D_ADDR;
//print("%P\n", p);
nodconst(&nod1, types[TINT32], sval->len);
p = gins(ADATA, nam, &nod1);
p->from.scale = types[TINT32]->width;
p->from.offset += types[tptr]->width;
}
int
dstringptr(Sym *s, int off, char *str)
{
......
......@@ -739,53 +739,4 @@ cgen_bmul(int op, Node *nl, Node *nr, Node *res)
regfree(&n2b);
}
int
getlit(Node *lit)
{
if(smallintconst(lit))
return mpgetfix(lit->val.u.xval);
return -1;
}
int
stataddr(Node *nam, Node *n)
{
int l;
if(n == N)
goto no;
switch(n->op) {
case ONAME:
*nam = *n;
return n->addable;
case ODOT:
if(!stataddr(nam, n->left))
break;
nam->xoffset += n->xoffset;
nam->type = n->type;
return 1;
case OINDEX:
if(n->left->type->bound < 0)
break;
if(!stataddr(nam, n->left))
break;
l = getlit(n->right);
if(l < 0)
break;
nam->xoffset += l*n->type->width;
nam->type = n->type;
return 1;
}
no:
return 0;
}
int
gen_as_init(Node *n)
{
return 0;
}
......@@ -483,6 +483,44 @@ datagostring(Strlit *sval, Addr *a)
text();
}
void
gdata(Node *nam, Node *nr, int wid)
{
Prog *p;
vlong v;
if(wid == 8 && is64(nr->type)) {
v = mpgetfix(nr->val.u.xval);
p = gins(ADATA, nam, nodintconst(v));
p->from.scale = 4;
p = gins(ADATA, nam, nodintconst(v>>32));
p->from.scale = 4;
p->from.offset += 4;
return;
}
p = gins(ADATA, nam, nr);
p->from.scale = wid;
}
void
gdatastring(Node *nam, Strlit *sval)
{
Prog *p;
Node nod1;
p = gins(ADATA, nam, N);
datastring(sval->s, sval->len, &p->to);
p->from.scale = types[tptr]->width;
p->to.index = p->to.type;
p->to.type = D_ADDR;
//print("%P\n", p);
nodconst(&nod1, types[TINT32], sval->len);
p = gins(ADATA, nam, &nod1);
p->from.scale = types[TINT32]->width;
p->from.offset += types[tptr]->width;
}
int
dstringptr(Sym *s, int off, char *str)
{
......
......@@ -1160,7 +1160,10 @@ void cgen_ret(Node *n);
int isfat(Type*);
void clearfat(Node *n);
void cgen(Node*, Node*);
struct Prog;
void gused(Node*);
void gdata(Node*, Node*, int);
void gdatastring(Node*, Strlit*);
void dumptypestructs(void);
void dumpfuncs(void);
void dumpdata(void);
......
......@@ -634,3 +634,156 @@ initctxt:
n->op = OEMPTY;
return 1;
}
int
getlit(Node *lit)
{
if(smallintconst(lit))
return mpgetfix(lit->val.u.xval);
return -1;
}
int
stataddr(Node *nam, Node *n)
{
int l;
if(n == N)
goto no;
switch(n->op) {
case ONAME:
*nam = *n;
return n->addable;
case ODOT:
if(!stataddr(nam, n->left))
break;
nam->xoffset += n->xoffset;
nam->type = n->type;
return 1;
case OINDEX:
if(n->left->type->bound < 0)
break;
if(!stataddr(nam, n->left))
break;
l = getlit(n->right);
if(l < 0)
break;
nam->xoffset += l*n->type->width;
nam->type = n->type;
return 1;
}
no:
return 0;
}
int
gen_as_init(Node *n)
{
Node *nr, *nl;
Node nam, nod1;
if(n->dodata == 0)
goto no;
nr = n->right;
nl = n->left;
if(nr == N) {
if(!stataddr(&nam, nl))
goto no;
if(nam.class != PEXTERN)
goto no;
goto yes;
}
if(nr->type == T || !eqtype(nl->type, nr->type))
goto no;
if(!stataddr(&nam, nl))
goto no;
if(nam.class != PEXTERN)
goto no;
switch(nr->op) {
default:
goto no;
case OCONVSLICE:
goto slice;
case OLITERAL:
break;
}
switch(nr->type->etype) {
default:
goto no;
case TBOOL:
case TINT8:
case TUINT8:
case TINT16:
case TUINT16:
case TINT32:
case TUINT32:
case TINT64:
case TUINT64:
case TINT:
case TUINT:
case TUINTPTR:
case TPTR32:
case TPTR64:
case TFLOAT32:
case TFLOAT64:
case TFLOAT:
gused(N); // in case the data is the dest of a goto
gdata(&nam, nr, nr->type->width);
break;
case TSTRING:
gused(N); // in case the data is the dest of a goto
gdatastring(&nam, nr->val.u.sval);
break;
}
yes:
return 1;
slice:
gused(N); // in case the data is the dest of a goto
nr = n->right->left;
if(nr == N || nr->op != OADDR)
goto no;
nr = nr->left;
if(nr == N || nr->op != ONAME)
goto no;
// nr is the array being converted to a slice
if(nr->type == T || nr->type->etype != TARRAY || nr->type->bound < 0)
goto no;
nam.xoffset += Array_array;
gdata(&nam, n->right->left, types[tptr]->width);
nam.xoffset += Array_nel-Array_array;
nodconst(&nod1, types[TINT32], nr->type->bound);
gdata(&nam, &nod1, types[TINT32]->width);
nam.xoffset += Array_cap-Array_nel;
gdata(&nam, &nod1, types[TINT32]->width);
goto yes;
no:
if(n->dodata == 2) {
dump("\ngen_as_init", n);
fatal("gen_as_init couldnt make data statement");
}
return 0;
}
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