diff options
Diffstat (limited to 'src/cmd/5g')
-rw-r--r-- | src/cmd/5g/cgen.c | 81 | ||||
-rw-r--r-- | src/cmd/5g/galign.c | 8 | ||||
-rw-r--r-- | src/cmd/5g/gg.h | 12 | ||||
-rw-r--r-- | src/cmd/5g/ggen.c | 25 | ||||
-rw-r--r-- | src/cmd/5g/gsubr.c | 27 | ||||
-rw-r--r-- | src/cmd/5g/opt.h | 20 | ||||
-rw-r--r-- | src/cmd/5g/peep.c | 6 | ||||
-rw-r--r-- | src/cmd/5g/reg.c | 12 |
8 files changed, 133 insertions, 58 deletions
diff --git a/src/cmd/5g/cgen.c b/src/cmd/5g/cgen.c index 9011b2022..c535cfbef 100644 --- a/src/cmd/5g/cgen.c +++ b/src/cmd/5g/cgen.c @@ -254,7 +254,6 @@ cgen(Node *n, Node *res) case OOR: case OXOR: case OADD: - case OADDPTR: case OMUL: a = optoas(n->op, nl->type); goto sbop; @@ -1107,11 +1106,10 @@ bgen(Node *n, int true, int likely, Prog *to) { int et, a; Node *nl, *nr, *r; - Node n1, n2, n3, n4, tmp; + Node n1, n2, n3, tmp; NodeList *ll; Prog *p1, *p2; - USED(n4); // in unreachable code below if(debug['g']) { dump("\nbgen", n); } @@ -1497,7 +1495,7 @@ sgen(Node *n, Node *res, int64 w) if(osrc < odst && odst < osrc+w) dir = -dir; - if(op == AMOVW && dir > 0 && c >= 4 && c <= 128) { + if(op == AMOVW && !nacl && dir > 0 && c >= 4 && c <= 128) { r0.op = OREGISTER; r0.val.u.reg = REGALLOC_R0; r1.op = OREGISTER; @@ -1524,7 +1522,7 @@ sgen(Node *n, Node *res, int64 w) f = sysfunc("duffcopy"); p = gins(ADUFFCOPY, N, f); afunclit(&p->to, f); - // 8 and 128 = magic constants: see ../../pkg/runtime/asm_arm.s + // 8 and 128 = magic constants: see ../../runtime/asm_arm.s p->to.offset = 8*(128-c); regfree(&tmp); @@ -1636,7 +1634,10 @@ int componentgen(Node *nr, Node *nl) { Node nodl, nodr, tmp; + Type *t; int freel, freer; + vlong fldcount; + vlong loffset, roffset; freel = 0; freer = 0; @@ -1646,8 +1647,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 > 4) goto no; + + break; + case TSTRING: case TINTER: break; @@ -1675,6 +1701,7 @@ componentgen(Node *nr, Node *nl) freer = 1; } + // nl and nr are 'cadable' which basically means they are names (variables) now. // If they are the same variable, don't generate any code, because the // VARDEF we generate will mark the old value as dead incorrectly. @@ -1684,8 +1711,25 @@ componentgen(Node *nr, Node *nl) switch(nl->type->etype) { case TARRAY: + // componentgen for arrays. if(nl->op == ONAME) gvardef(nl); + 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); @@ -1760,6 +1804,31 @@ componentgen(Node *nr, Node *nl) gmove(&nodr, &nodl); goto yes; + + case TSTRUCT: + if(nl->op == ONAME) + gvardef(nl); + loffset = nodl.xoffset; + roffset = nodr.xoffset; + // funarg structs may not begin at offset zero. + if(nl->type->etype == TSTRUCT && nl->type->funarg && nl->type->type) + loffset -= nl->type->type->width; + if(nr != N && nr->type->etype == TSTRUCT && nr->type->funarg && nr->type->type) + roffset -= nr->type->type->width; + + 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: diff --git a/src/cmd/5g/galign.c b/src/cmd/5g/galign.c index a62102ef8..b4c45da69 100644 --- a/src/cmd/5g/galign.c +++ b/src/cmd/5g/galign.c @@ -23,10 +23,10 @@ vlong MAXWIDTH = (1LL<<32) - 1; */ Typedef typedefs[] = { - "int", TINT, TINT32, - "uint", TUINT, TUINT32, - "uintptr", TUINTPTR, TUINT32, - 0 + {"int", TINT, TINT32}, + {"uint", TUINT, TUINT32}, + {"uintptr", TUINTPTR, TUINT32}, + {0} }; void diff --git a/src/cmd/5g/gg.h b/src/cmd/5g/gg.h index 413e93c24..00914bfa3 100644 --- a/src/cmd/5g/gg.h +++ b/src/cmd/5g/gg.h @@ -11,10 +11,13 @@ #define TEXTFLAG reg -#define REGALLOC_R0 0 -#define REGALLOC_RMAX REGEXT -#define REGALLOC_F0 NREG -#define REGALLOC_FMAX (REGALLOC_F0 + FREGEXT) +enum +{ + REGALLOC_R0 = 0, + REGALLOC_RMAX = REGEXT, + REGALLOC_F0 = NREG, + REGALLOC_FMAX = REGALLOC_F0 + FREGEXT, +}; EXTERN int32 dynloc; EXTERN uchar reg[REGALLOC_FMAX+1]; @@ -106,7 +109,6 @@ void split64(Node*, Node*, Node*); void splitclean(void); Node* ncon(uint32 i); void gtrack(Sym*); -void gargsize(int32); /* * obj.c diff --git a/src/cmd/5g/ggen.c b/src/cmd/5g/ggen.c index fb32c2f36..53cddb760 100644 --- a/src/cmd/5g/ggen.c +++ b/src/cmd/5g/ggen.c @@ -76,7 +76,7 @@ zerorange(Prog *p, vlong frame, vlong lo, vlong hi, uint32 *r0) if(cnt < 4*widthptr) { for(i = 0; i < cnt; i += widthptr) p = appendpp(p, AMOVW, D_REG, 0, 0, D_OREG, REGSP, 4+frame+lo+i); - } else if(cnt <= 128*widthptr) { + } else if(!nacl && (cnt <= 128*widthptr)) { p = appendpp(p, AADD, D_CONST, NREG, 4+frame+lo, D_REG, 1, 0); p->reg = REGSP; p = appendpp(p, ADUFFZERO, D_NONE, NREG, 0, D_OREG, NREG, 0); @@ -179,28 +179,12 @@ fixautoused(Prog* p) void ginscall(Node *f, int proc) { - int32 arg; Prog *p; Node n1, r, r1, con; if(f->type != T) setmaxarg(f->type); - arg = -1; - // Most functions have a fixed-size argument block, so traceback uses that during unwind. - // Not all, though: there are some variadic functions in package runtime, - // and for those we emit call-specific metadata recorded by caller. - // Reflect generates functions with variable argsize (see reflect.methodValueCall/makeFuncStub), - // so we do this for all indirect calls as well. - if(f->type != T && (f->sym == S || (f->sym != S && f->sym->pkg == runtimepkg) || proc == 1 || proc == 2)) { - arg = f->type->argwid; - if(proc == 1 || proc == 2) - arg += 3*widthptr; - } - - if(arg != -1) - gargsize(arg); - switch(proc) { default: fatal("ginscall: bad proc %d", proc); @@ -297,9 +281,6 @@ ginscall(Node *f, int proc) } break; } - - if(arg != -1) - gargsize(-1); } /* @@ -906,11 +887,11 @@ clearfat(Node *nl) patch(gbranch(ABNE, T, 0), pl); regfree(&end); - } else if(q >= 4) { + } else if(q >= 4 && !nacl) { f = sysfunc("duffzero"); p = gins(ADUFFZERO, N, f); afunclit(&p->to, f); - // 4 and 128 = magic constants: see ../../pkg/runtime/asm_arm.s + // 4 and 128 = magic constants: see ../../runtime/asm_arm.s p->to.offset = 4*(128-q); } else while(q > 0) { diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c index f66c87b5a..06e274e14 100644 --- a/src/cmd/5g/gsubr.c +++ b/src/cmd/5g/gsubr.c @@ -31,11 +31,11 @@ #include <u.h> #include <libc.h> #include "gg.h" -#include "../../pkg/runtime/funcdata.h" +#include "../../runtime/funcdata.h" // TODO(rsc): Can make this bigger if we move // the text segment up higher in 5l for all GOOS. -// At the same time, can raise StackBig in ../../pkg/runtime/stack.h. +// At the same time, can raise StackBig in ../../runtime/stack.h. long unmappedzero = 4096; void @@ -206,17 +206,7 @@ ggloblnod(Node *nam) } void -gargsize(int32 size) -{ - Node n1, n2; - - nodconst(&n1, types[TINT32], PCDATA_ArgSize); - nodconst(&n2, types[TINT32], size); - gins(APCDATA, &n1, &n2); -} - -void -ggloblsym(Sym *s, int32 width, int dupok, int rodata) +ggloblsym(Sym *s, int32 width, int8 flags) { Prog *p; @@ -227,10 +217,7 @@ ggloblsym(Sym *s, int32 width, int dupok, int rodata) p->to.type = D_CONST; p->to.name = D_NONE; p->to.offset = width; - if(dupok) - p->reg |= DUPOK; - if(rodata) - p->reg |= RODATA; + p->reg = flags; } void @@ -374,7 +361,7 @@ regalloc(Node *n, Type *t, Node *o) print("registers allocated at\n"); for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++) print("%d %p\n", i, regpc[i]); - yyerror("out of fixed registers"); + fatal("out of fixed registers"); goto err; case TFLOAT32: @@ -387,7 +374,7 @@ regalloc(Node *n, Type *t, Node *o) for(i=REGALLOC_F0; i<=REGALLOC_FMAX; i++) if(reg[i] == 0) goto out; - yyerror("out of floating point registers"); + fatal("out of floating point registers"); goto err; case TCOMPLEX64: @@ -636,6 +623,7 @@ splitclean(void) } #define CASE(a,b) (((a)<<16)|((b)<<0)) +/*c2go int CASE(int, int); */ void gmove(Node *f, Node *t) @@ -1601,7 +1589,6 @@ optoas(int op, Type *t) case CASE(OADD, TINT32): case CASE(OADD, TUINT32): case CASE(OADD, TPTR32): - case CASE(OADDPTR, TPTR32): a = AADD; break; diff --git a/src/cmd/5g/opt.h b/src/cmd/5g/opt.h index e3e3f78ed..1946c1d33 100644 --- a/src/cmd/5g/opt.h +++ b/src/cmd/5g/opt.h @@ -49,6 +49,24 @@ typedef struct Reg Reg; typedef struct Rgn Rgn; +/*c2go +extern Node *Z; +enum +{ + D_HI = D_NONE, + D_LO = D_NONE, + CLOAD = 5, + CREF = 5, + CINF = 1000, + LOOP = 3, +}; + +uint32 BLOAD(Reg*); +uint32 BSTORE(Reg*); +uint32 LOAD(Reg*); +uint32 STORE(Reg*); +*/ + // A Reg is a wrapper around a single Prog (one instruction) that holds // register optimization information while the optimizer runs. // r->prog is the instruction. @@ -71,8 +89,10 @@ struct Reg int32 regu; // register used bitmap }; #define R ((Reg*)0) +/*c2go extern Reg *R; */ #define NRGN 600 +/*c2go enum { NRGN = 600 }; */ struct Rgn { Reg* enter; diff --git a/src/cmd/5g/peep.c b/src/cmd/5g/peep.c index 4aa645206..639f4c5f6 100644 --- a/src/cmd/5g/peep.c +++ b/src/cmd/5g/peep.c @@ -564,6 +564,8 @@ gotit: * .. */ #define FAIL(msg) { if(debug['P']) print("\t%s; FAILURE\n", msg); return 0; } +/*c2go void FAIL(char*); */ + int shiftprop(Flow *r) { @@ -875,11 +877,15 @@ xtramodes(Graph *g, Flow *r, Adr *a) switch (p1->from.type) { case D_REG: /* register offset */ + if(nacl) + return 0; a->type = D_SHIFT; a->offset = p1->from.reg; break; case D_SHIFT: /* scaled register offset */ + if(nacl) + return 0; a->type = D_SHIFT; case D_CONST: /* immediate offset */ diff --git a/src/cmd/5g/reg.c b/src/cmd/5g/reg.c index 4762df506..b78c268df 100644 --- a/src/cmd/5g/reg.c +++ b/src/cmd/5g/reg.c @@ -36,6 +36,11 @@ #define NREGVAR 32 #define REGBITS ((uint32)0xffffffff) +/*c2go enum { + NREGVAR = 32, + REGBITS = 0xffffffff, +}; +*/ void addsplits(void); static Reg* firstr; @@ -194,7 +199,7 @@ regopt(Prog *firstp) proginfo(&info, p); // Avoid making variables for direct-called functions. - if(p->as == ABL && p->to.type == D_EXTERN) + if(p->as == ABL && p->to.name == D_EXTERN) continue; bit = mkvar(r, &p->from); @@ -222,6 +227,10 @@ regopt(Prog *firstp) for(z=0; z<BITS; z++) r->set.b[z] |= bit.b[z]; } + + /* the mod/div runtime routines smash R12 */ + if(p->as == ADIV || p->as == ADIVU || p->as == AMOD || p->as == AMODU) + r->set.b[0] |= RtoB(12); } if(firstr == R) return; @@ -1306,6 +1315,7 @@ void addreg(Adr *a, int rn) { a->sym = nil; + a->node = nil; a->name = D_NONE; a->type = D_REG; a->reg = rn; |