void gextern(Sym *s, Node *a, int32_t o, int32_t w) { if(0 && a->op == OCONST && typev[a->type->etype]) { gpseudo(ADATA, s, lo64(a)); p->from.offset += o; p->from.scale = 4; gpseudo(ADATA, s, hi64(a)); p->from.offset += o + 4; p->from.scale = 4; return; } gpseudo(ADATA, s, a); p->from.offset += o; p->from.scale = w; switch(p->to.type) { default: p->to.index = p->to.type; p->to.type = D_ADDR; case D_CONST: case D_FCONST: case D_ADDR: break; } }
void codgen(Node *n, Node *nn) { Prog *sp; argoff = 0; inargs = 0; for(;; nn = nn->left) { if(nn == Z) { diag(Z, "cant find function name"); return; } if(nn->op == ONAME) break; } nearln = nn->lineno; gpseudo(ATEXT, nn->sym, D_CONST, stkoff); sp = p; retok = 0; gen(n); if(!retok) if(thisfn->link->etype != TVOID) warn(Z, "no return at end of function: %s", nn->sym->name); noretval(3); gbranch(ORETURN); if(!debug['N'] || debug['R'] || debug['P']) regopt(sp); }
void codgen(Node *n, Node *nn) { Prog *sp; Node *n1, nod, nod1; cursafe = 0; curarg = 0; maxargsafe = 0; /* * isolate name */ for(n1 = nn;; n1 = n1->left) { if(n1 == Z) { diag(nn, "cant find function name"); return; } if(n1->op == ONAME) break; } nearln = nn->lineno; gpseudo(ATEXT, n1->sym, nodconst(stkoff)); sp = p; sp->reg |= ALLTHUMBS; /* denotes thumb code */ /* * isolate first argument */ if(REGARG >= 0) { if(typesuv[thisfn->link->etype]) { nod1 = *nodret->left; nodreg(&nod, &nod1, REGARG); gopcode(OAS, &nod, Z, &nod1); } else if(firstarg && typechlp[firstargtype->etype]) { nod1 = *nodret->left; nod1.sym = firstarg; nod1.type = firstargtype; nod1.xoffset = align(0, firstargtype, Aarg1); nod1.etype = firstargtype->etype; nodreg(&nod, &nod1, REGARG); gopcode(OAS, &nod, Z, &nod1); } } retok = 0; gen(n); if(!retok) if(thisfn->link->etype != TVOID) warn(Z, "no return at end of function: %s", n1->sym->name); noretval(3); gbranch(ORETURN); if(!debug['N'] || debug['R'] || debug['P']) regopt(sp); sp->to.offset += maxargsafe; }
Prog* gtext(Sym *s, int32 stkoff) { gpseudo(ATEXT, s, nodconst(stkoff)); p->to.type = D_CONST2; p->to.offset2 = argsize(); return p; }
void gextern(Sym *s, Node *a, long o, long w) { if(a->op == OCONST && typev[a->type->etype]) { if(align(0, types[TCHAR], Aarg1)) /* isbigendian */ gpseudo(ADATA, s, nod32const(a->vconst>>32)); else gpseudo(ADATA, s, nod32const(a->vconst)); p->from.offset += o; p->reg = 4; if(align(0, types[TCHAR], Aarg1)) /* isbigendian */ gpseudo(ADATA, s, nod32const(a->vconst)); else gpseudo(ADATA, s, nod32const(a->vconst>>32)); p->from.offset += o + 4; p->reg = 4; return; }
void gextern(Sym *s, Node *a, int32 o, int32 w) { if(a->op == OCONST && typev[a->type->etype]) { if(isbigendian) gpseudo(ADATA, s, nod32const(a->vconst>>32)); else gpseudo(ADATA, s, nod32const(a->vconst)); p->from.offset += o; p->reg = 4; if(isbigendian) gpseudo(ADATA, s, nod32const(a->vconst)); else gpseudo(ADATA, s, nod32const(a->vconst>>32)); p->from.offset += o + 4; p->reg = 4; return; }
void sextern(Sym *s, Node *a, long o, long w) { long e, lw; for(e=0; e<w; e+=NSNAME) { lw = NSNAME; if(w-e < lw) lw = w-e; gpseudo(ADATA, s, nodconst(0)); p->from.offset += o+e; p->reg = lw; p->to.type = D_SCONST; memmove(p->to.sval, a->cstring+e, lw); } }
void sextern(Sym *s, Node *a, int32 o, int32 w) { int32 e, lw; for(e=0; e<w; e+=NSNAME) { lw = NSNAME; if(w-e < lw) lw = w-e; gpseudo(ADATA, s, nodconst(0L)); p->from.offset += o+e; p->from.scale = lw; p->to.type = D_SCONST; memmove(p->to.u.sval, a->cstring+e, lw); } }
long outstring(char *s, long n) { long r; r = nstring; while(n) { string[mnstring] = *s++; mnstring++; nstring++; if(mnstring >= NSNAME) { gpseudo(ADATA, symstring, D_SCONST, 0L); memmove(p->to.sval, string, NSNAME); p->from.offset = nstring - NSNAME; p->from.displace = NSNAME; mnstring = 0; } n--; } return r; }
int32_t outstring(char *s, int32_t n) { int32_t r; r = nstring; while(n) { string[mnstring] = *s++; mnstring++; nstring++; if(mnstring >= NSNAME) { gpseudo(ADATA, symstring, nodconst(0L)); p->from.offset += nstring - NSNAME; p->reg = NSNAME; p->to.type = D_SCONST; memmove(p->to.sval, string, NSNAME); mnstring = 0; } n--; } return r; }
int32 outstring(char *s, int32 n) { int32 r; if(suppress) return nstring; r = nstring; while(n) { string[mnstring] = *s++; mnstring++; nstring++; if(mnstring >= NSNAME) { gpseudo(ADATA, symstring, nodconst(0L)); p->from.offset += nstring - NSNAME; p->from.scale = NSNAME; p->to.type = D_SCONST; memmove(p->to.u.sval, string, NSNAME); mnstring = 0; } n--; } return r; }
/* else binary */ void swit1(C1 *q, int nc, long def, int g, Node *n) { C1 *r, *s; int i, l, m, y; long v, range; Prog *sp1, *sp2; /* note that g and g+1 are not allocated */ if(nc <= N1) goto linear; y = 23*nc/100 + 5; /* number of cases needed to make */ if(y < N2) /* direct switch worthwile */ y = N2; /* try to do better than n**2 here */ for(m=nc; m>=y; m--) { /* m is number of cases */ s = q+nc; r = s-m; for(l=nc-m; l>=0; l--) { /* l is base of contig cases */ s--; range = s->val - r->val; if(range > 0 && range <= N3*m) goto direct; r--; } } /* * divide and conquer */ i = nc / 2; r = q+i; v = r->val; /* compare median */ if(v >= -128 && v < 128) { gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n); gopcode(OEQ, n->type, g, n, g+1, n); } else gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v)); gbranch(OLT); sp1 = p; gbranch(OGT); sp2 = p; gbranch(OGOTO); patch(p, r->label); patch(sp1, pc); swit1(q, i, def, g, n); patch(sp2, pc); swit1(r+1, nc-i-1, def, g, n); return; direct: /* compare low bound */ v = r->val; if(v >= -128 && v < 128) { gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n); gopcode(OEQ, n->type, g, n, g+1, n); } else gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v)); gbranch(OLT); sp1 = p; /* compare high bound */ v = s->val; if(v >= -128 && v < 128) { gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n); gopcode(OEQ, n->type, g, n, g+1, n); } else gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v)); gbranch(OGT); sp2 = p; /* switch */ v = r->val; gpseudo(AMOVW, symstatic, D_R0, 0L); p->from.offset = nstatic - v*2; p->from.index = g|I_INDEX1; p->from.scale = 5; nextpc(); p->as = ACASEW; /* table */ for(i=0; i<=range; i++) { gbranch(OCASE); if(v == r->val) { patch(p, r->label); r++; } else patch(p, def); p->from.type = D_STATIC; p->from.sym = symstatic; p->from.offset = nstatic; nstatic += types[TSHORT]->width; v++; } gbranch(OGOTO); patch(p, def); if(r != s+1) print("smelly direct switch\n"); if(l > 0) { patch(sp1, pc); swit1(q, l, def, g, n); } else patch(sp1, def); m += l; if(m < nc) { patch(sp2, pc); swit1(q+m, nc-m, def, g, n); } else patch(sp2, def); return; linear: for(i=0; i<nc; i++) { v = q->val; if(v >= -128 && v < 128) { gopcode(OAS, n->type, D_CONST, nodconst(v), g+1, n); gopcode(OEQ, n->type, g+1, n, g, n); } else gopcode(OEQ, n->type, g, n, D_CONST, nodconst(v)); gbranch(OEQ); patch(p, q->label); q++; } gbranch(OGOTO); patch(p, def); }