summaryrefslogtreecommitdiff
path: root/src/cmd/6g
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/6g')
-rw-r--r--src/cmd/6g/Makefile21
-rw-r--r--src/cmd/6g/cgen.c257
-rw-r--r--src/cmd/6g/galign.c1
-rw-r--r--src/cmd/6g/gg.h2
-rw-r--r--src/cmd/6g/ggen.c85
-rw-r--r--src/cmd/6g/gobj.c4
-rw-r--r--src/cmd/6g/gsubr.c149
-rw-r--r--src/cmd/6g/list.c18
-rw-r--r--src/cmd/6g/reg.c20
9 files changed, 417 insertions, 140 deletions
diff --git a/src/cmd/6g/Makefile b/src/cmd/6g/Makefile
index 712cfc60c..023f5d111 100644
--- a/src/cmd/6g/Makefile
+++ b/src/cmd/6g/Makefile
@@ -2,10 +2,10 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
-include ../../Make.conf
+include ../../Make.inc
+O:=$(HOST_O)
-TARG=\
- 6g
+TARG=6g
HFILES=\
../gc/go.h\
@@ -26,18 +26,9 @@ OFILES=\
../6l/enam.$O\
LIB=\
- ../gc/gc.a$O
+ ../gc/gc.a\
-$(TARG): $(OFILES) $(LIB)
- $(LD) -o $(TARG) -L"$(GOROOT)"/lib $(OFILES) $(LIB) -lbio -l9 -lm
-
-$(OFILES): $(HFILES)
-
-clean:
- rm -f $(TARG) enam.c 6.out a.out *.$O *.6
-
-install: $(TARG)
- cp $(TARG) "$(GOBIN)"/$(TARG)
+include ../../Make.ccmd
%.$O: ../gc/%.c
- $(CC) $(CFLAGS) -c -I. -o $@ ../gc/$*.c
+ $(HOST_CC) $(HOST_CFLAGS) -c -I. -o $@ ../gc/$*.c
diff --git a/src/cmd/6g/cgen.c b/src/cmd/6g/cgen.c
index aacc0d06f..d4d22fd61 100644
--- a/src/cmd/6g/cgen.c
+++ b/src/cmd/6g/cgen.c
@@ -418,7 +418,7 @@ void
agen(Node *n, Node *res)
{
Node *nl, *nr;
- Node n1, n2, n3, tmp, n4;
+ Node n1, n2, n3, tmp, n4, n5;
Prog *p1;
uint32 w;
uint64 v;
@@ -477,8 +477,10 @@ agen(Node *n, Node *res)
regalloc(&n1, nr->type, N);
cgen(nr, &n1);
}
- regalloc(&n3, types[tptr], res);
- agen(nl, &n3);
+ if(!isconst(nl, CTSTR)) {
+ regalloc(&n3, types[tptr], res);
+ agen(nl, &n3);
+ }
goto index;
}
tempname(&tmp, nr->type);
@@ -486,8 +488,10 @@ agen(Node *n, Node *res)
nr = &tmp;
irad:
- regalloc(&n3, types[tptr], res);
- agen(nl, &n3);
+ if(!isconst(nl, CTSTR)) {
+ regalloc(&n3, types[tptr], res);
+ agen(nl, &n3);
+ }
if(!isconst(nr, CTINT)) {
regalloc(&n1, nr->type, N);
cgen(nr, &n1);
@@ -501,7 +505,7 @@ agen(Node *n, Node *res)
// explicit check for nil if array is large enough
// that we might derive too big a pointer.
- if(!isslice(nl->type) && nl->type->width >= unmappedzero) {
+ if(isfixedarray(nl->type) && nl->type->width >= unmappedzero) {
regalloc(&n4, types[tptr], &n3);
gmove(&n3, &n4);
n4.op = OINDREG;
@@ -516,15 +520,16 @@ agen(Node *n, Node *res)
// constant index
if(isconst(nr, CTINT)) {
+ if(isconst(nl, CTSTR))
+ fatal("constant string constant index"); // front end should handle
v = mpgetfix(nr->val.u.xval);
- if(isslice(nl->type)) {
-
+ if(isslice(nl->type) || nl->type->etype == TSTRING) {
if(!debug['B'] && !n->etype) {
n1 = n3;
n1.op = OINDREG;
n1.type = types[tptr];
n1.xoffset = Array_nel;
- nodconst(&n2, types[TUINT64], v);
+ nodconst(&n2, types[TUINT32], v);
gins(optoas(OCMP, types[TUINT32]), &n1, &n2);
p1 = gbranch(optoas(OGT, types[TUINT32]), T);
ginscall(panicindex, 0);
@@ -536,18 +541,9 @@ agen(Node *n, Node *res)
n1.type = types[tptr];
n1.xoffset = Array_array;
gmove(&n1, &n3);
- } else
- if(!debug['B'] && !n->etype) {
- if(v < 0)
- yyerror("out of bounds on array");
- else
- if(v >= nl->type->bound)
- yyerror("out of bounds on array");
}
- nodconst(&n2, types[tptr], v*w);
- gins(optoas(OADD, types[tptr]), &n2, &n3);
-
+ ginscon(optoas(OADD, types[tptr]), v*w, &n3);
gmove(&n3, res);
regfree(&n3);
break;
@@ -564,20 +560,43 @@ agen(Node *n, Node *res)
if(!debug['B'] && !n->etype) {
// check bounds
- if(isslice(nl->type)) {
+ n5.op = OXXX;
+ t = types[TUINT32];
+ if(is64(nr->type))
+ t = types[TUINT64];
+ if(isconst(nl, CTSTR)) {
+ nodconst(&n1, t, nl->val.u.sval->len);
+ } else if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3;
n1.op = OINDREG;
- n1.type = types[tptr];
+ n1.type = types[TUINT32];
n1.xoffset = Array_nel;
- } else
- nodconst(&n1, types[TUINT64], nl->type->bound);
- gins(optoas(OCMP, types[TUINT32]), &n2, &n1);
- p1 = gbranch(optoas(OLT, types[TUINT32]), T);
+ if(is64(nr->type)) {
+ regalloc(&n5, t, N);
+ gmove(&n1, &n5);
+ n1 = n5;
+ }
+ } else {
+ nodconst(&n1, t, nl->type->bound);
+ }
+ gins(optoas(OCMP, t), &n2, &n1);
+ p1 = gbranch(optoas(OLT, t), T);
+ if(n5.op != OXXX)
+ regfree(&n5);
ginscall(panicindex, 0);
patch(p1, pc);
}
- if(isslice(nl->type)) {
+ if(isconst(nl, CTSTR)) {
+ regalloc(&n3, types[tptr], res);
+ p1 = gins(ALEAQ, N, &n3);
+ datastring(nl->val.u.sval->s, nl->val.u.sval->len, &p1->from);
+ p1->from.scale = 1;
+ p1->from.index = n2.val.u.reg;
+ goto indexdone;
+ }
+
+ if(isslice(nl->type) || nl->type->etype == TSTRING) {
n1 = n3;
n1.op = OINDREG;
n1.type = types[tptr];
@@ -591,12 +610,12 @@ agen(Node *n, Node *res)
p1->from.index = p1->from.type;
p1->from.type = p1->to.type + D_INDIR;
} else {
- nodconst(&n1, t, w);
- gins(optoas(OMUL, t), &n1, &n2);
+ ginscon(optoas(OMUL, t), w, &n2);
gins(optoas(OADD, types[tptr]), &n2, &n3);
gmove(&n3, res);
}
+ indexdone:
gmove(&n3, res);
regfree(&n2);
regfree(&n3);
@@ -616,10 +635,8 @@ agen(Node *n, Node *res)
fatal("agen: bad ONAME class %#x", n->class);
}
cgen(n->heapaddr, res);
- if(n->xoffset != 0) {
- nodconst(&n1, types[TINT64], n->xoffset);
- gins(optoas(OADD, types[tptr]), &n1, res);
- }
+ if(n->xoffset != 0)
+ ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
break;
case OIND:
@@ -628,10 +645,8 @@ agen(Node *n, Node *res)
case ODOT:
agen(nl, res);
- if(n->xoffset != 0) {
- nodconst(&n1, types[TINT64], n->xoffset);
- gins(optoas(OADD, types[tptr]), &n1, res);
- }
+ if(n->xoffset != 0)
+ ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
break;
case ODOTPTR:
@@ -648,8 +663,7 @@ agen(Node *n, Node *res)
gins(ATESTB, nodintconst(0), &n1);
regfree(&n1);
}
- nodconst(&n1, types[TINT64], n->xoffset);
- gins(optoas(OADD, types[tptr]), &n1, res);
+ ginscon(optoas(OADD, types[tptr]), n->xoffset, res);
}
break;
}
@@ -694,6 +708,9 @@ bgen(Node *n, int true, Prog *to)
if(n == N)
n = nodbool(1);
+ if(n->ninit != nil)
+ genlist(n->ninit);
+
nl = n->left;
nr = n->right;
@@ -1006,6 +1023,10 @@ sgen(Node *n, Node *ns, int32 w)
if(w < 0)
fatal("sgen copy %d", w);
+ if(w == 16)
+ if(componentgen(n, ns))
+ return;
+
// offset on the stack
osrc = stkof(n);
odst = stkof(ns);
@@ -1099,3 +1120,163 @@ sgen(Node *n, Node *ns, int32 w)
restx(&nodr, &oldr);
restx(&cx, &oldcx);
}
+
+static int
+cadable(Node *n)
+{
+ if(!n->addable) {
+ // dont know how it happens,
+ // but it does
+ return 0;
+ }
+
+ switch(n->op) {
+ case ONAME:
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * copy a structure component by component
+ * return 1 if can do, 0 if cant.
+ * nr is N for copy zero
+ */
+int
+componentgen(Node *nr, Node *nl)
+{
+ Node nodl, nodr;
+ int freel, freer;
+
+ freel = 0;
+ freer = 0;
+
+ switch(nl->type->etype) {
+ default:
+ goto no;
+
+ case TARRAY:
+ if(!isslice(nl->type))
+ goto no;
+ case TSTRING:
+ case TINTER:
+ break;
+ }
+
+ nodl = *nl;
+ if(!cadable(nl)) {
+ if(nr == N || !cadable(nr))
+ goto no;
+ igen(nl, &nodl, N);
+ freel = 1;
+ }
+
+ if(nr != N) {
+ nodr = *nr;
+ if(!cadable(nr)) {
+ igen(nr, &nodr, N);
+ freer = 1;
+ }
+ }
+
+ switch(nl->type->etype) {
+ case TARRAY:
+ if(!isslice(nl->type))
+ goto no;
+
+ nodl.xoffset += Array_array;
+ nodl.type = ptrto(nl->type->type);
+
+ if(nr != N) {
+ nodr.xoffset += Array_array;
+ nodr.type = nodl.type;
+ } else
+ nodconst(&nodr, nodl.type, 0);
+ gmove(&nodr, &nodl);
+
+ nodl.xoffset += Array_nel-Array_array;
+ nodl.type = types[TUINT32];
+
+ if(nr != N) {
+ nodr.xoffset += Array_nel-Array_array;
+ nodr.type = nodl.type;
+ } else
+ nodconst(&nodr, nodl.type, 0);
+ gmove(&nodr, &nodl);
+
+ nodl.xoffset += Array_cap-Array_nel;
+ nodl.type = types[TUINT32];
+
+ if(nr != N) {
+ nodr.xoffset += Array_cap-Array_nel;
+ nodr.type = nodl.type;
+ } else
+ nodconst(&nodr, nodl.type, 0);
+ gmove(&nodr, &nodl);
+
+ goto yes;
+
+ case TSTRING:
+ nodl.xoffset += Array_array;
+ nodl.type = ptrto(types[TUINT8]);
+
+ if(nr != N) {
+ nodr.xoffset += Array_array;
+ nodr.type = nodl.type;
+ } else
+ nodconst(&nodr, nodl.type, 0);
+ gmove(&nodr, &nodl);
+
+ nodl.xoffset += Array_nel-Array_array;
+ nodl.type = types[TUINT32];
+
+ if(nr != N) {
+ nodr.xoffset += Array_nel-Array_array;
+ nodr.type = nodl.type;
+ } else
+ nodconst(&nodr, nodl.type, 0);
+ gmove(&nodr, &nodl);
+
+ goto yes;
+
+ case TINTER:
+ nodl.xoffset += Array_array;
+ nodl.type = ptrto(types[TUINT8]);
+
+ if(nr != N) {
+ nodr.xoffset += Array_array;
+ nodr.type = nodl.type;
+ } else
+ nodconst(&nodr, nodl.type, 0);
+ gmove(&nodr, &nodl);
+
+ nodl.xoffset += Array_nel-Array_array;
+ nodl.type = ptrto(types[TUINT8]);
+
+ if(nr != N) {
+ nodr.xoffset += Array_nel-Array_array;
+ nodr.type = nodl.type;
+ } else
+ nodconst(&nodr, nodl.type, 0);
+ gmove(&nodr, &nodl);
+
+ goto yes;
+
+ case TSTRUCT:
+ goto no;
+ }
+
+no:
+ if(freer)
+ regfree(&nodr);
+ if(freel)
+ regfree(&nodl);
+ return 0;
+
+yes:
+ if(freer)
+ regfree(&nodr);
+ if(freel)
+ regfree(&nodl);
+ return 1;
+}
diff --git a/src/cmd/6g/galign.c b/src/cmd/6g/galign.c
index 68647e21b..bdfc9947e 100644
--- a/src/cmd/6g/galign.c
+++ b/src/cmd/6g/galign.c
@@ -25,7 +25,6 @@ Typedef typedefs[] =
void
betypeinit(void)
{
- maxround = 8;
widthptr = 8;
zprog.link = P;
diff --git a/src/cmd/6g/gg.h b/src/cmd/6g/gg.h
index 353a86dcd..7efb2c252 100644
--- a/src/cmd/6g/gg.h
+++ b/src/cmd/6g/gg.h
@@ -99,6 +99,7 @@ void cgen_aret(Node*, Node*);
int cgen_inline(Node*, Node*);
void restx(Node*, Node*);
void savex(int, Node*, Node*, Node*, Type*);
+int componentgen(Node*, Node*);
/*
* gsubr.c
@@ -122,6 +123,7 @@ Node* nodarg(Type*, int);
void nodreg(Node*, Type*, int);
void nodindreg(Node*, Type*, int);
void gconreg(int, vlong, int);
+void ginscon(int, vlong, Node*);
void buildtxt(void);
Plist* newplist(void);
int isfat(Type*);
diff --git a/src/cmd/6g/ggen.c b/src/cmd/6g/ggen.c
index 59a6d529d..d9fa1793c 100644
--- a/src/cmd/6g/ggen.c
+++ b/src/cmd/6g/ggen.c
@@ -62,6 +62,8 @@ compile(Node *fn)
pl = newplist();
pl->name = curfn->nname;
+ setlineno(curfn);
+
nodconst(&nod1, types[TINT32], 0);
ptxt = gins(ATEXT, curfn->nname, &nod1);
afunclit(&ptxt->from);
@@ -83,6 +85,8 @@ compile(Node *fn)
checklabels();
if(nerrors != 0)
goto ret;
+ if(curfn->endlineno)
+ lineno = curfn->endlineno;
if(curfn->type->outtuple != 0)
ginscall(throwreturn, 0);
@@ -90,13 +94,13 @@ compile(Node *fn)
if(pret)
patch(pret, pc);
ginit();
+ if(hasdefer)
+ ginscall(deferreturn, 0);
if(curfn->exit)
genlist(curfn->exit);
gclean();
if(nerrors != 0)
goto ret;
- if(hasdefer)
- ginscall(deferreturn, 0);
pc->as = ARET; // overwrite AEND
pc->lineno = lineno;
@@ -105,11 +109,11 @@ compile(Node *fn)
}
// fill in argument size
- ptxt->to.offset = rnd(curfn->type->argwid, maxround);
+ ptxt->to.offset = rnd(curfn->type->argwid, widthptr);
// fill in final stack size
ptxt->to.offset <<= 32;
- ptxt->to.offset |= rnd(stksize+maxarg, maxround);
+ ptxt->to.offset |= rnd(stksize+maxarg, widthptr);
if(debug['f'])
frame(0);
@@ -1041,7 +1045,12 @@ clearfat(Node *nl)
if(debug['g'])
dump("\nclearfat", nl);
+
w = nl->type->width;
+ if(w == 16)
+ if(componentgen(N, nl))
+ return;
+
c = w % 8; // bytes
q = w / 8; // quads
@@ -1115,44 +1124,64 @@ getargs(NodeList *nn, Node *reg, int n)
void
cmpandthrow(Node *nl, Node *nr)
{
- vlong cl, cr;
+ vlong cl;
Prog *p1;
int op;
Node *c;
+ Type *t;
+ Node n1;
+
+ if(nl->op == OCONV && is64(nl->type))
+ nl = nl->left;
+ if(nr->op == OCONV && is64(nr->type))
+ nr = nr->left;
op = OLE;
if(smallintconst(nl)) {
cl = mpgetfix(nl->val.u.xval);
if(cl == 0)
return;
- if(smallintconst(nr)) {
- cr = mpgetfix(nr->val.u.xval);
- if(cl > cr) {
- if(throwpc == nil) {
- throwpc = pc;
- ginscall(panicslice, 0);
- } else
- patch(gbranch(AJMP, T), throwpc);
- }
+ if(smallintconst(nr))
return;
- }
-
// put the constant on the right
op = brrev(op);
c = nl;
nl = nr;
nr = c;
}
-
- gins(optoas(OCMP, types[TUINT32]), nl, nr);
+ if(is64(nr->type) && smallintconst(nr))
+ nr->type = types[TUINT32];
+
+ n1.op = OXXX;
+ t = types[TUINT32];
+ if(nl->type->width != t->width || nr->type->width != t->width) {
+ if((is64(nl->type) && nl->op != OLITERAL) || (is64(nr->type) && nr->op != OLITERAL))
+ t = types[TUINT64];
+
+ // Check if we need to use a temporary.
+ // At least one of the arguments is 32 bits
+ // (the len or cap) so one temporary suffices.
+ if(nl->type->width != t->width && nl->op != OLITERAL) {
+ regalloc(&n1, t, nl);
+ gmove(nl, &n1);
+ nl = &n1;
+ } else if(nr->type->width != t->width && nr->op != OLITERAL) {
+ regalloc(&n1, t, nr);
+ gmove(nr, &n1);
+ nr = &n1;
+ }
+ }
+ gins(optoas(OCMP, t), nl, nr);
+ if(n1.op != OXXX)
+ regfree(&n1);
if(throwpc == nil) {
- p1 = gbranch(optoas(op, types[TUINT32]), T);
+ p1 = gbranch(optoas(op, t), T);
throwpc = pc;
ginscall(panicslice, 0);
patch(p1, pc);
} else {
op = brcom(op);
- p1 = gbranch(optoas(op, types[TUINT32]), T);
+ p1 = gbranch(optoas(op, t), T);
patch(p1, throwpc);
}
}
@@ -1183,6 +1212,8 @@ cgen_inline(Node *n, Node *res)
goto no;
if(!n->left->addable)
goto no;
+ if(n->left->sym == S)
+ goto no;
if(n->left->sym->pkg != runtimepkg)
goto no;
if(strcmp(n->left->sym->name, "slicearray") == 0)
@@ -1261,10 +1292,8 @@ slicearray:
if(smallintconst(&nodes[2]) && smallintconst(&nodes[4])) {
v = mpgetfix(nodes[2].val.u.xval) *
mpgetfix(nodes[4].val.u.xval);
- if(v != 0) {
- nodconst(&n1, types[tptr], v);
- gins(optoas(OADD, types[tptr]), &n1, &nodes[0]);
- }
+ if(v != 0)
+ ginscon(optoas(OADD, types[tptr]), v, &nodes[0]);
} else {
regalloc(&n1, types[tptr], &nodes[2]);
gmove(&nodes[2], &n1);
@@ -1310,6 +1339,7 @@ sliceslice:
// if(lb[1] > old.nel[0]) goto throw;
n2 = nodes[0];
n2.xoffset += Array_nel;
+ n2.type = types[TUINT32];
cmpandthrow(&nodes[1], &n2);
// ret.nel = old.nel[0]-lb[1];
@@ -1329,6 +1359,7 @@ sliceslice:
// if(hb[2] > old.cap[0]) goto throw;
n2 = nodes[0];
n2.xoffset += Array_cap;
+ n2.type = types[TUINT32];
cmpandthrow(&nodes[2], &n2);
// if(lb[1] > hb[2]) goto throw;
@@ -1376,10 +1407,8 @@ sliceslice:
gins(optoas(OAS, types[tptr]), &n2, &n1);
v = mpgetfix(nodes[1].val.u.xval) *
mpgetfix(nodes[3].val.u.xval);
- if(v != 0) {
- nodconst(&n2, types[tptr], v);
- gins(optoas(OADD, types[tptr]), &n2, &n1);
- }
+ if(v != 0)
+ ginscon(optoas(OADD, types[tptr]), v, &n1);
} else {
gmove(&nodes[1], &n1);
if(!smallintconst(&nodes[3]) || mpgetfix(nodes[3].val.u.xval) != 1)
diff --git a/src/cmd/6g/gobj.c b/src/cmd/6g/gobj.c
index 7c05054b7..b667ae48a 100644
--- a/src/cmd/6g/gobj.c
+++ b/src/cmd/6g/gobj.c
@@ -633,7 +633,7 @@ dsymptr(Sym *s, int off, Sym *x, int xoff)
}
void
-genembedtramp(Type *rcvr, Type *method, Sym *newnam)
+genembedtramp(Type *rcvr, Type *method, Sym *newnam, int iface)
{
Sym *e;
int c, d, o, mov, add, loaded;
@@ -732,7 +732,7 @@ out:
p = pc;
gins(AJMP, N, N);
p->to.type = D_EXTERN;
- p->to.sym = methodsym(method->sym, ptrto(f->type));
+ p->to.sym = methodsym(method->sym, ptrto(f->type), 0);
//print("6. %P\n", p);
pc->as = ARET; // overwrite AEND
diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c
index 52ff6fdea..ebb61ea94 100644
--- a/src/cmd/6g/gsubr.c
+++ b/src/cmd/6g/gsubr.c
@@ -147,6 +147,8 @@ ggloblnod(Node *nam, int32 width)
p->to.sym = S;
p->to.type = D_CONST;
p->to.offset = width;
+ if(nam->readonly)
+ p->from.scale = RODATA;
}
void
@@ -163,6 +165,7 @@ ggloblsym(Sym *s, int32 width, int dupok)
p->to.offset = width;
if(dupok)
p->from.scale = DUPOK;
+ p->from.scale |= RODATA;
}
int
@@ -427,11 +430,33 @@ fatal("shouldnt be used");
void
gconreg(int as, vlong c, int reg)
{
- Node n1, n2;
+ Node nr;
+
+ nodreg(&nr, types[TINT64], reg);
+ ginscon(as, c, &nr);
+}
+
+/*
+ * generate
+ * as $c, n
+ */
+void
+ginscon(int as, vlong c, Node *n2)
+{
+ Node n1, ntmp;
nodconst(&n1, types[TINT64], c);
- nodreg(&n2, types[TINT64], reg);
- gins(as, &n1, &n2);
+
+ if(as != AMOVQ && (c < -1LL<<31 || c >= 1LL<<31)) {
+ // cannot have 64-bit immediokate in ADD, etc.
+ // instead, MOV into register first.
+ regalloc(&ntmp, types[TINT64], N);
+ gins(AMOVQ, &n1, &ntmp);
+ gins(as, &ntmp, n2);
+ regfree(&ntmp);
+ return;
+ }
+ gins(as, &n1, n2);
}
#define CASE(a,b) (((a)<<16)|((b)<<0))
@@ -1683,12 +1708,28 @@ optoas(int op, Type *t)
enum
{
- ODynam = 1<<0,
+ ODynam = 1<<0,
+ OAddable = 1<<1,
};
static Node clean[20];
static int cleani = 0;
+int
+xgen(Node *n, Node *a, int o)
+{
+ regalloc(a, types[tptr], N);
+
+ if(o & ODynam)
+ if(n->addable)
+ if(n->op != OINDREG)
+ if(n->op != OREGISTER)
+ return 1;
+
+ agen(n, a);
+ return 0;
+}
+
void
sudoclean(void)
{
@@ -1716,7 +1757,7 @@ sudoaddable(int as, Node *n, Addr *a)
int o, i, w;
int oary[10];
int64 v;
- Node n1, n2, n3, *nn, *l, *r;
+ Node n1, n2, n3, n4, *nn, *l, *r;
Node *reg, *reg1;
Prog *p1;
Type *t;
@@ -1743,6 +1784,8 @@ sudoaddable(int as, Node *n, Addr *a)
goto odot;
case OINDEX:
+ if(n->left->type->etype == TSTRING)
+ return 0;
goto oindex;
}
return 0;
@@ -1820,7 +1863,7 @@ oindex:
if(l->type->etype != TARRAY)
fatal("not ary");
if(l->type->bound < 0)
- o += ODynam;
+ o |= ODynam;
w = n->type->width;
if(isconst(r, CTINT))
@@ -1836,9 +1879,6 @@ oindex:
break;
}
-// if(sudoaddable(as, l, a))
-// goto oindex_sudo;
-
cleani += 2;
reg = &clean[cleani-1];
reg1 = &clean[cleani-2];
@@ -1847,8 +1887,8 @@ oindex:
// load the array (reg)
if(l->ullman > r->ullman) {
- regalloc(reg, types[tptr], N);
- agen(l, reg);
+ if(xgen(l, reg, o))
+ o |= OAddable;
}
// load the index (reg1)
@@ -1863,49 +1903,89 @@ oindex:
// load the array (reg)
if(l->ullman <= r->ullman) {
- regalloc(reg, types[tptr], N);
- agen(l, reg);
+ if(xgen(l, reg, o))
+ o |= OAddable;
}
if(!(o & ODynam) && l->type->width >= unmappedzero && l->op == OIND) {
// cannot rely on page protections to
// catch array ptr == 0, so dereference.
n2 = *reg;
+ n2.xoffset = 0;
n2.op = OINDREG;
n2.type = types[TUINT8];
- n2.xoffset = 0;
gins(ATESTB, nodintconst(0), &n2);
}
// check bounds
if(!debug['B'] && !n->etype) {
+ // check bounds
+ n4.op = OXXX;
+ t = types[TUINT32];
if(o & ODynam) {
- n2 = *reg;
- n2.op = OINDREG;
- n2.type = types[tptr];
- n2.xoffset = Array_nel;
+ if(o & OAddable) {
+ n2 = *l;
+ n2.xoffset += Array_nel;
+ n2.type = types[TUINT32];
+ if(is64(r->type)) {
+ t = types[TUINT64];
+ regalloc(&n4, t, N);
+ gmove(&n2, &n4);
+ n2 = n4;
+ }
+ } else {
+ n2 = *reg;
+ n2.xoffset = Array_nel;
+ n2.op = OINDREG;
+ n2.type = types[TUINT32];
+ if(is64(r->type)) {
+ t = types[TUINT64];
+ regalloc(&n4, t, N);
+ gmove(&n2, &n4);
+ n2 = n4;
+ }
+ }
} else {
+ if(is64(r->type))
+ t = types[TUINT64];
nodconst(&n2, types[TUINT64], l->type->bound);
}
- gins(optoas(OCMP, types[TUINT32]), reg1, &n2);
- p1 = gbranch(optoas(OLT, types[TUINT32]), T);
+ gins(optoas(OCMP, t), reg1, &n2);
+ p1 = gbranch(optoas(OLT, t), T);
+ if(n4.op != OXXX)
+ regfree(&n4);
ginscall(panicindex, 0);
patch(p1, pc);
}
if(o & ODynam) {
- n2 = *reg;
- n2.op = OINDREG;
- n2.type = types[tptr];
- n2.xoffset = Array_array;
- gmove(&n2, reg);
+ if(o & OAddable) {
+ n2 = *l;
+ n2.xoffset += Array_array;
+ n2.type = types[TUINT64];
+ gmove(&n2, reg);
+ } else {
+ n2 = *reg;
+ n2.xoffset = Array_array;
+ n2.op = OINDREG;
+ n2.type = types[tptr];
+ gmove(&n2, reg);
+ }
}
- naddr(reg1, a, 1);
- a->offset = 0;
- a->scale = w;
- a->index = a->type;
- a->type = reg->val.u.reg + D_INDIR;
+ if(o & OAddable) {
+ naddr(reg1, a, 1);
+ a->offset = 0;
+ a->scale = w;
+ a->index = a->type;
+ a->type = reg->val.u.reg + D_INDIR;
+ } else {
+ naddr(reg1, a, 1);
+ a->offset = 0;
+ a->scale = w;
+ a->index = a->type;
+ a->type = reg->val.u.reg + D_INDIR;
+ }
goto yes;
@@ -1915,15 +1995,6 @@ oindex_const:
// can multiply by width statically
v = mpgetfix(r->val.u.xval);
- if(!debug['B'] && (o & ODynam) == 0) {
- // array indexed by a constant bounds check
- if(v < 0) {
- yyerror("out of bounds on array");
- } else
- if(v >= l->type->bound) {
- yyerror("out of bounds on array");
- }
- }
if(sudoaddable(as, l, a))
goto oindex_const_sudo;
diff --git a/src/cmd/6g/list.c b/src/cmd/6g/list.c
index 9194b1dab..c8077c97a 100644
--- a/src/cmd/6g/list.c
+++ b/src/cmd/6g/list.c
@@ -47,24 +47,28 @@ Pconv(Fmt *fp)
{
char str[STRINGSZ];
Prog *p;
+ char scale[40];
p = va_arg(fp->args, Prog*);
sconsize = 8;
+ scale[0] = '\0';
+ if(p->from.scale != 0 && (p->as == AGLOBL || p->as == ATEXT))
+ snprint(scale, sizeof scale, "%d,", p->from.scale);
switch(p->as) {
default:
- snprint(str, sizeof(str), "%.4ld (%L) %-7A %D,%D",
- p->loc, p->lineno, p->as, &p->from, &p->to);
+ snprint(str, sizeof(str), "%.4d (%L) %-7A %D,%s%D",
+ p->loc, p->lineno, p->as, &p->from, scale, &p->to);
break;
case ADATA:
sconsize = p->from.scale;
- snprint(str, sizeof(str), "%.4ld (%L) %-7A %D/%d,%D",
+ snprint(str, sizeof(str), "%.4d (%L) %-7A %D/%d,%D",
p->loc, p->lineno, p->as, &p->from, sconsize, &p->to);
break;
case ATEXT:
- snprint(str, sizeof(str), "%.4ld (%L) %-7A %D,%lD",
- p->loc, p->lineno, p->as, &p->from, &p->to);
+ snprint(str, sizeof(str), "%.4d (%L) %-7A %D,%s%lD",
+ p->loc, p->lineno, p->as, &p->from, scale, &p->to);
break;
}
return fmtstrcpy(fp, str);
@@ -104,7 +108,7 @@ Dconv(Fmt *fp)
if(a->branch == nil)
snprint(str, sizeof(str), "<nil>");
else
- snprint(str, sizeof(str), "%ld", a->branch->loc);
+ snprint(str, sizeof(str), "%d", a->branch->loc);
break;
case D_EXTERN:
@@ -127,7 +131,7 @@ Dconv(Fmt *fp)
if(fp->flags & FmtLong) {
d1 = a->offset & 0xffffffffLL;
d2 = (a->offset>>32) & 0xffffffffLL;
- snprint(str, sizeof(str), "$%lud-%lud", (ulong)d1, (ulong)d2);
+ snprint(str, sizeof(str), "$%ud-%ud", (ulong)d1, (ulong)d2);
break;
}
snprint(str, sizeof(str), "$%lld", a->offset);
diff --git a/src/cmd/6g/reg.c b/src/cmd/6g/reg.c
index e92740e04..464627066 100644
--- a/src/cmd/6g/reg.c
+++ b/src/cmd/6g/reg.c
@@ -682,17 +682,17 @@ brk:
print("\nstats\n");
if(ostats.ncvtreg)
- print(" %4ld cvtreg\n", ostats.ncvtreg);
+ print(" %4d cvtreg\n", ostats.ncvtreg);
if(ostats.nspill)
- print(" %4ld spill\n", ostats.nspill);
+ print(" %4d spill\n", ostats.nspill);
if(ostats.nreload)
- print(" %4ld reload\n", ostats.nreload);
+ print(" %4d reload\n", ostats.nreload);
if(ostats.ndelmov)
- print(" %4ld delmov\n", ostats.ndelmov);
+ print(" %4d delmov\n", ostats.ndelmov);
if(ostats.nvar)
- print(" %4ld delmov\n", ostats.nvar);
+ print(" %4d delmov\n", ostats.nvar);
if(ostats.naddr)
- print(" %4ld delmov\n", ostats.naddr);
+ print(" %4d delmov\n", ostats.naddr);
memset(&ostats, 0, sizeof(ostats));
}
@@ -1268,7 +1268,7 @@ regset(Reg *r, uint32 bb)
while(b = bb & ~(bb-1)) {
v.type = b & 0xFFFF? BtoR(b): BtoF(b);
if(v.type == 0)
- fatal("zero v.type for %#lux", b);
+ fatal("zero v.type for %#ux", b);
c = copyu(r->prog, &v, A);
if(c == 3)
set |= b;
@@ -1486,7 +1486,7 @@ dumpone(Reg *r)
int z;
Bits bit;
- print("%ld:%P", r->loop, r->prog);
+ print("%d:%P", r->loop, r->prog);
for(z=0; z<BITS; z++)
bit.b[z] =
r->set.b[z] |
@@ -1535,14 +1535,14 @@ dumpit(char *str, Reg *r0)
if(r1 != R) {
print(" pred:");
for(; r1 != R; r1 = r1->p2link)
- print(" %.4lud", r1->prog->loc);
+ print(" %.4ud", r1->prog->loc);
print("\n");
}
// r1 = r->s1;
// if(r1 != R) {
// print(" succ:");
// for(; r1 != R; r1 = r1->s1)
-// print(" %.4lud", r1->prog->loc);
+// print(" %.4ud", r1->prog->loc);
// print("\n");
// }
}