diff options
Diffstat (limited to 'src/cmd/8g')
-rw-r--r-- | src/cmd/8g/cgen.c | 88 | ||||
-rw-r--r-- | src/cmd/8g/galign.c | 8 | ||||
-rw-r--r-- | src/cmd/8g/gg.h | 1 | ||||
-rw-r--r-- | src/cmd/8g/ggen.c | 49 | ||||
-rw-r--r-- | src/cmd/8g/gsubr.c | 26 | ||||
-rw-r--r-- | src/cmd/8g/opt.h | 20 | ||||
-rw-r--r-- | src/cmd/8g/peep.c | 4 | ||||
-rw-r--r-- | src/cmd/8g/reg.c | 6 |
8 files changed, 148 insertions, 54 deletions
diff --git a/src/cmd/8g/cgen.c b/src/cmd/8g/cgen.c index d626c2eb0..2735fb6a5 100644 --- a/src/cmd/8g/cgen.c +++ b/src/cmd/8g/cgen.c @@ -242,7 +242,6 @@ cgen(Node *n, Node *res) case OOR: case OXOR: case OADD: - case OADDPTR: case OMUL: a = optoas(n->op, nl->type); if(a == AIMULB) { @@ -347,8 +346,11 @@ cgen(Node *n, Node *res) if(istype(nl->type, TCHAN)) { // chan has cap in the second 32-bit word. // a zero pointer means zero length - regalloc(&n1, types[tptr], res); + tempname(&n1, types[tptr]); cgen(nl, &n1); + regalloc(&n2, types[tptr], N); + gmove(&n1, &n2); + n1 = n2; nodconst(&n2, types[tptr], 0); gins(optoas(OCMP, types[tptr]), &n1, &n2); @@ -1324,7 +1326,7 @@ sgen(Node *n, Node *res, int64 w) p = gins(ADUFFCOPY, N, N); p->to.type = D_ADDR; p->to.sym = linksym(pkglookup("duffcopy", runtimepkg)); - // 10 and 128 = magic constants: see ../../pkg/runtime/asm_386.s + // 10 and 128 = magic constants: see ../../runtime/asm_386.s p->to.offset = 10*(128-q); } else while(q > 0) { @@ -1364,7 +1366,10 @@ int componentgen(Node *nr, Node *nl) { Node nodl, nodr; + Type *t; int freel, freer; + vlong fldcount; + vlong loffset, roffset; freel = 0; freer = 0; @@ -1374,8 +1379,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; @@ -1396,7 +1426,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. @@ -1406,8 +1436,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); @@ -1419,7 +1466,7 @@ componentgen(Node *nr, Node *nl) gmove(&nodr, &nodl); nodl.xoffset += Array_nel-Array_array; - nodl.type = types[TUINT32]; + nodl.type = types[simtype[TUINT]]; if(nr != N) { nodr.xoffset += Array_nel-Array_array; @@ -1429,7 +1476,7 @@ componentgen(Node *nr, Node *nl) gmove(&nodr, &nodl); nodl.xoffset += Array_cap-Array_nel; - nodl.type = types[TUINT32]; + nodl.type = types[simtype[TUINT]]; if(nr != N) { nodr.xoffset += Array_cap-Array_nel; @@ -1454,7 +1501,7 @@ componentgen(Node *nr, Node *nl) gmove(&nodr, &nodl); nodl.xoffset += Array_nel-Array_array; - nodl.type = types[TUINT32]; + nodl.type = types[simtype[TUINT]]; if(nr != N) { nodr.xoffset += Array_nel-Array_array; @@ -1489,6 +1536,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/8g/galign.c b/src/cmd/8g/galign.c index fbd2e9ad3..a0eb34937 100644 --- a/src/cmd/8g/galign.c +++ b/src/cmd/8g/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/8g/gg.h b/src/cmd/8g/gg.h index bdefa93b5..238f92765 100644 --- a/src/cmd/8g/gg.h +++ b/src/cmd/8g/gg.h @@ -114,7 +114,6 @@ void split64(Node*, Node*, Node*); void splitclean(void); void nswap(Node*, Node*); void gtrack(Sym*); -void gargsize(int32); /* * cplx.c */ diff --git a/src/cmd/8g/ggen.c b/src/cmd/8g/ggen.c index 5e3140480..6333a60bb 100644 --- a/src/cmd/8g/ggen.c +++ b/src/cmd/8g/ggen.c @@ -157,7 +157,7 @@ void clearfat(Node *nl) { uint32 w, c, q; - Node n1; + Node n1, z; Prog *p; /* clear a fat object */ @@ -172,6 +172,32 @@ clearfat(Node *nl) c = w % 4; // bytes q = w / 4; // quads + if(q < 4) { + // Write sequence of MOV 0, off(base) instead of using STOSL. + // The hope is that although the code will be slightly longer, + // the MOVs will have no dependencies and pipeline better + // than the unrolled STOSL loop. + // NOTE: Must use agen, not igen, so that optimizer sees address + // being taken. We are not writing on field boundaries. + regalloc(&n1, types[tptr], N); + agen(nl, &n1); + n1.op = OINDREG; + nodconst(&z, types[TUINT64], 0); + while(q-- > 0) { + n1.type = z.type; + gins(AMOVL, &z, &n1); + n1.xoffset += 4; + } + nodconst(&z, types[TUINT8], 0); + while(c-- > 0) { + n1.type = z.type; + gins(AMOVB, &z, &n1); + n1.xoffset++; + } + regfree(&n1); + return; + } + nodreg(&n1, types[tptr], D_DI); agen(nl, &n1); gconreg(AMOVL, 0, D_AX); @@ -184,7 +210,7 @@ clearfat(Node *nl) p = gins(ADUFFZERO, N, N); p->to.type = D_ADDR; p->to.sym = linksym(pkglookup("duffzero", runtimepkg)); - // 1 and 128 = magic constants: see ../../pkg/runtime/asm_386.s + // 1 and 128 = magic constants: see ../../runtime/asm_386.s p->to.offset = 1*(128-q); } else while(q > 0) { @@ -210,28 +236,12 @@ clearfat(Node *nl) void ginscall(Node *f, int proc) { - int32 arg; Prog *p; Node reg, 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 += 2*widthptr; - } - - if(arg != -1) - gargsize(arg); - switch(proc) { default: fatal("ginscall: bad proc %d", proc); @@ -293,9 +303,6 @@ ginscall(Node *f, int proc) } break; } - - if(arg != -1) - gargsize(-1); } /* diff --git a/src/cmd/8g/gsubr.c b/src/cmd/8g/gsubr.c index 2f3cb28c8..3077e0ad9 100644 --- a/src/cmd/8g/gsubr.c +++ b/src/cmd/8g/gsubr.c @@ -31,14 +31,15 @@ #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 8l 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. uint32 unmappedzero = 4096; #define CASE(a,b) (((a)<<16)|((b)<<0)) +/*c2go int CASE(int, int);*/ void clearp(Prog *p) @@ -205,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; @@ -226,10 +217,7 @@ ggloblsym(Sym *s, int32 width, int dupok, int rodata) p->to.type = D_CONST; p->to.index = D_NONE; p->to.offset = width; - if(dupok) - p->from.scale |= DUPOK; - if(rodata) - p->from.scale |= RODATA; + p->from.scale = flags; } void @@ -432,7 +420,6 @@ optoas(int op, Type *t) case CASE(OADD, TINT32): case CASE(OADD, TUINT32): case CASE(OADD, TPTR32): - case CASE(OADDPTR, TPTR32): a = AADDL; break; @@ -697,6 +684,7 @@ optoas(int op, Type *t) } #define FCASE(a, b, c) (((a)<<16)|((b)<<8)|(c)) +/*c2go int FCASE(int, int, int); */ int foptoas(int op, Type *t, int flg) { @@ -950,7 +938,7 @@ regalloc(Node *n, Type *t, Node *o) fprint(2, "registers allocated at\n"); for(i=D_AX; i<=D_DI; i++) fprint(2, "\t%R\t%#lux\n", i, regpc[i]); - yyerror("out of fixed registers"); + fatal("out of fixed registers"); goto err; case TFLOAT32: diff --git a/src/cmd/8g/opt.h b/src/cmd/8g/opt.h index 77a69e13a..09f58c40a 100644 --- a/src/cmd/8g/opt.h +++ b/src/cmd/8g/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. @@ -84,8 +102,10 @@ struct Reg Prog* prog; // actual instruction }; #define R ((Reg*)0) +/*c2go extern Reg *R; */ #define NRGN 600 +/*c2go enum { NRGN = 600 }; */ struct Rgn { Reg* enter; diff --git a/src/cmd/8g/peep.c b/src/cmd/8g/peep.c index e2f3a003d..91a91d20d 100644 --- a/src/cmd/8g/peep.c +++ b/src/cmd/8g/peep.c @@ -33,7 +33,9 @@ #include "gg.h" #include "opt.h" -#define REGEXT 0 +enum { + REGEXT = 0, +}; static void conprop(Flow *r); static void elimshortmov(Graph*); diff --git a/src/cmd/8g/reg.c b/src/cmd/8g/reg.c index fd610f87a..302b273a1 100644 --- a/src/cmd/8g/reg.c +++ b/src/cmd/8g/reg.c @@ -35,6 +35,11 @@ #define NREGVAR 16 /* 8 integer + 8 floating */ #define REGBITS ((uint32)0xffff) +/*c2go enum { + NREGVAR = 16, + REGBITS = (1<<NREGVAR) - 1, +}; +*/ static Reg* firstr; static int first = 1; @@ -1163,6 +1168,7 @@ void addreg(Adr *a, int rn) { a->sym = nil; + a->node = nil; a->offset = 0; a->type = rn; |