void gdata(Node *nam, Node *nr, int wid) { Prog *p; vlong v; if(nr->op == OLITERAL) { switch(nr->val.ctype) { case CTCPLX: gdatacomplex(nam, nr->val.u.cval); return; case CTSTR: gdatastring(nam, nr->val.u.sval); return; } } 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; }
void gdata(Node *nam, Node *nr, int wid) { Prog *p; if(nr->op == OLITERAL) { switch(nr->val.ctype) { case CTCPLX: gdatacomplex(nam, nr->val.u.cval); return; case CTSTR: gdatastring(nam, nr->val.u.sval); return; } } p = gins(ADATA, nam, nr); p->from.scale = wid; }
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 OCONVNOP: nr = nr->left; if(nr == N || nr->op != OSLICEARR) goto no; // fall through case OSLICEARR: if(nr->right->op == OKEY && nr->right->left == N && nr->right->right == N) { nr = nr->left; goto slice; } goto no; 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: gused(N); // in case the data is the dest of a goto gdata(&nam, nr, nr->type->width); break; case TCOMPLEX64: case TCOMPLEX128: gused(N); // in case the data is the dest of a goto gdatacomplex(&nam, nr->val.u.cval); 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 nl = nr; 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, nl, 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; }