summaryrefslogtreecommitdiff
path: root/src/cmd/8g
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/8g')
-rw-r--r--src/cmd/8g/cgen.c88
-rw-r--r--src/cmd/8g/galign.c8
-rw-r--r--src/cmd/8g/gg.h1
-rw-r--r--src/cmd/8g/ggen.c49
-rw-r--r--src/cmd/8g/gsubr.c26
-rw-r--r--src/cmd/8g/opt.h20
-rw-r--r--src/cmd/8g/peep.c4
-rw-r--r--src/cmd/8g/reg.c6
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;