summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Thompson <ken@golang.org>2009-08-28 15:44:24 -0700
committerKen Thompson <ken@golang.org>2009-08-28 15:44:24 -0700
commit4ae4a6f822069081728876451b2bac024f45b0ed (patch)
treef93b70fb011f1c64820edeeb13b42e230dcaff80
parent34b3a883750dbedf4a9c2c48c0263ea82611ffc7 (diff)
downloadgolang-4ae4a6f822069081728876451b2bac024f45b0ed.tar.gz
arraytoslice and some cleanup
R=rsc OCL=34058 CL=34058
-rw-r--r--src/cmd/6g/ggen.c168
-rw-r--r--test/ken/slicearray.go7
2 files changed, 107 insertions, 68 deletions
diff --git a/src/cmd/6g/ggen.c b/src/cmd/6g/ggen.c
index acbb30321..788e6daa5 100644
--- a/src/cmd/6g/ggen.c
+++ b/src/cmd/6g/ggen.c
@@ -1180,12 +1180,16 @@ regcmp(Node *ra, Node *rb)
return ra->local - rb->local;
}
+static Prog* throwpc;
+
void
getargs(NodeList *nn, Node *reg, int n)
{
NodeList *l;
int i;
+ throwpc = nil;
+
l = nn;
for(i=0; i<n; i++) {
if(!smallintconst(l->n->right) && !isslice(l->n->right->type)) {
@@ -1218,8 +1222,13 @@ cmpandthrow(Node *nl, Node *nr)
return;
if(smallintconst(nr)) {
cr = mpgetfix(nr->val.u.xval);
- if(cl > cr)
- ginscall(throwslice, 0);
+ if(cl > cr) {
+ if(throwpc == nil) {
+ throwpc = pc;
+ ginscall(throwslice, 0);
+ } else
+ patch(gbranch(AJMP, T), throwpc);
+ }
return;
}
@@ -1231,9 +1240,16 @@ cmpandthrow(Node *nl, Node *nr)
}
gins(optoas(OCMP, types[TUINT32]), nl, nr);
- p1 = gbranch(optoas(op, types[TUINT32]), T);
- ginscall(throwslice, 0);
- patch(p1, pc);
+ if(throwpc == nil) {
+ p1 = gbranch(optoas(op, types[TUINT32]), T);
+ throwpc = pc;
+ ginscall(throwslice, 0);
+ patch(p1, pc);
+ } else {
+ op = brcom(op);
+ p1 = gbranch(optoas(op, types[TUINT32]), T);
+ patch(p1, throwpc);
+ }
}
int
@@ -1253,7 +1269,7 @@ sleasy(Node *n)
int
cgen_inline(Node *n, Node *res)
{
- Node nodes[10];
+ Node nodes[5];
Node n1, n2;
vlong v;
int i;
@@ -1278,25 +1294,25 @@ slicearray:
getargs(n->list, nodes, 5);
// if(hb[3] > nel[1]) goto throw
- cmpandthrow(nodes+3, nodes+1);
+ cmpandthrow(&nodes[3], &nodes[1]);
// if(lb[2] > hb[3]) goto throw
- cmpandthrow(nodes+2, nodes+3);
+ cmpandthrow(&nodes[2], &nodes[3]);
// len = hb[3] - lb[2] (destroys hb)
n2 = *res;
n2.xoffset += Array_nel;
- if(smallintconst(nodes+3) && smallintconst(nodes+2)) {
- v = mpgetfix((nodes+3)->val.u.xval) -
- mpgetfix((nodes+2)->val.u.xval);
+ if(smallintconst(&nodes[3]) && smallintconst(&nodes[2])) {
+ v = mpgetfix(nodes[3].val.u.xval) -
+ mpgetfix(nodes[2].val.u.xval);
nodconst(&n1, types[TUINT32], v);
gins(optoas(OAS, types[TUINT32]), &n1, &n2);
} else {
- regalloc(&n1, types[TUINT32], nodes+3);
- gmove(nodes+3, &n1);
- if(!smallintconst(nodes+2) || mpgetfix((nodes+2)->val.u.xval) != 0)
- gins(optoas(OSUB, types[TUINT32]), nodes+2, &n1);
+ regalloc(&n1, types[TUINT32], &nodes[3]);
+ gmove(&nodes[3], &n1);
+ if(!smallintconst(&nodes[2]) || mpgetfix(nodes[2].val.u.xval) != 0)
+ gins(optoas(OSUB, types[TUINT32]), &nodes[2], &n1);
gins(optoas(OAS, types[TUINT32]), &n1, &n2);
regfree(&n1);
}
@@ -1305,16 +1321,16 @@ slicearray:
n2 = *res;
n2.xoffset += Array_cap;
- if(smallintconst(nodes+1) && smallintconst(nodes+2)) {
- v = mpgetfix((nodes+1)->val.u.xval) -
- mpgetfix((nodes+2)->val.u.xval);
+ if(smallintconst(&nodes[1]) && smallintconst(&nodes[2])) {
+ v = mpgetfix(nodes[1].val.u.xval) -
+ mpgetfix(nodes[2].val.u.xval);
nodconst(&n1, types[TUINT32], v);
gins(optoas(OAS, types[TUINT32]), &n1, &n2);
} else {
- regalloc(&n1, types[TUINT32], nodes+1);
- gmove(nodes+1, &n1);
- if(!smallintconst(nodes+2) || mpgetfix((nodes+2)->val.u.xval) != 0)
- gins(optoas(OSUB, types[TUINT32]), nodes+2, &n1);
+ regalloc(&n1, types[TUINT32], &nodes[1]);
+ gmove(&nodes[1], &n1);
+ if(!smallintconst(&nodes[2]) || mpgetfix(nodes[2].val.u.xval) != 0)
+ gins(optoas(OSUB, types[TUINT32]), &nodes[2], &n1);
gins(optoas(OAS, types[TUINT32]), &n1, &n2);
regfree(&n1);
}
@@ -1323,73 +1339,97 @@ slicearray:
n2 = *res;
n2.xoffset += Array_array;
- if(smallintconst(nodes+2) && smallintconst(nodes+4)) {
- v = mpgetfix((nodes+2)->val.u.xval) *
- mpgetfix((nodes+4)->val.u.xval);
+ 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);
+ gins(optoas(OADD, types[tptr]), &n1, &nodes[0]);
}
} else {
- regalloc(&n1, types[tptr], nodes+2);
- gmove(nodes+2, &n1);
- if(!smallintconst(nodes+4) || mpgetfix((nodes+4)->val.u.xval) != 1)
- gins(optoas(OMUL, types[tptr]), nodes+4, &n1);
- gins(optoas(OADD, types[tptr]), &n1, nodes+0);
+ regalloc(&n1, types[tptr], &nodes[2]);
+ gmove(&nodes[2], &n1);
+ if(!smallintconst(&nodes[4]) || mpgetfix(nodes[4].val.u.xval) != 1)
+ gins(optoas(OMUL, types[tptr]), &nodes[4], &n1);
+ gins(optoas(OADD, types[tptr]), &n1, &nodes[0]);
regfree(&n1);
}
- gins(optoas(OAS, types[tptr]), nodes+0, &n2);
+ gins(optoas(OAS, types[tptr]), &nodes[0], &n2);
for(i=0; i<5; i++) {
- if((nodes+i)->op == OREGISTER)
- regfree(nodes+i);
+ if(nodes[i].op == OREGISTER)
+ regfree(&nodes[i]);
+ }
+ return 1;
+
+arraytoslice:
+ getargs(n->list, nodes, 2);
+
+ // ret.len = nel[1];
+ n2 = *res;
+ n2.xoffset += Array_nel;
+ gins(optoas(OAS, types[TUINT32]), &nodes[1], &n2);
+
+ // ret.cap = nel[1];
+ n2 = *res;
+ n2.xoffset += Array_cap;
+ gins(optoas(OAS, types[TUINT32]), &nodes[1], &n2);
+
+ // ret.array = old[0];
+ n2 = *res;
+ n2.xoffset += Array_array;
+ gins(optoas(OAS, types[tptr]), &nodes[0], &n2);
+
+ for(i=0; i<2; i++) {
+ if(nodes[i].op == OREGISTER)
+ regfree(&nodes[i]);
}
return 1;
sliceslice:
getargs(n->list, nodes, 4);
- if(!sleasy(nodes+0)) {
+ if(!sleasy(&nodes[0])) {
for(i=0; i<4; i++) {
- if((nodes+i)->op == OREGISTER)
- regfree(nodes+i);
+ if(nodes[i].op == OREGISTER)
+ regfree(&nodes[i]);
}
goto no;
}
// if(hb[2] > old.cap[0]) goto throw;
- n2 = *(nodes+0);
+ n2 = nodes[0];
n2.xoffset += Array_cap;
- cmpandthrow(nodes+2, &n2);
+ cmpandthrow(&nodes[2], &n2);
// if(lb[1] > hb[2]) goto throw;
- cmpandthrow(nodes+1, nodes+2);
+ cmpandthrow(&nodes[1], &nodes[2]);
// ret.len = hb[2]-lb[1]; (destroys hb[2])
n2 = *res;
n2.xoffset += Array_nel;
- if(smallintconst(nodes+2) && smallintconst(nodes+1)) {
- v = mpgetfix((nodes+2)->val.u.xval) -
- mpgetfix((nodes+1)->val.u.xval);
+ if(smallintconst(&nodes[2]) && smallintconst(&nodes[1])) {
+ v = mpgetfix(nodes[2].val.u.xval) -
+ mpgetfix(nodes[1].val.u.xval);
nodconst(&n1, types[TUINT32], v);
gins(optoas(OAS, types[TUINT32]), &n1, &n2);
} else {
- regalloc(&n1, types[TUINT32], nodes+2);
- gmove(nodes+2, &n1);
- if(!smallintconst(nodes+1) || mpgetfix((nodes+1)->val.u.xval) != 0)
- gins(optoas(OSUB, types[TUINT32]), nodes+1, &n1);
+ regalloc(&n1, types[TUINT32], &nodes[2]);
+ gmove(&nodes[2], &n1);
+ if(!smallintconst(&nodes[1]) || mpgetfix(nodes[1].val.u.xval) != 0)
+ gins(optoas(OSUB, types[TUINT32]), &nodes[1], &n1);
gins(optoas(OAS, types[TUINT32]), &n1, &n2);
regfree(&n1);
}
// ret.cap = old.cap[0]-lb[1]; (uses hb[2])
- n2 = *(nodes+0);
+ n2 = nodes[0];
n2.xoffset += Array_cap;
- regalloc(&n1, types[TUINT32], nodes+2);
+ regalloc(&n1, types[TUINT32], &nodes[2]);
gins(optoas(OAS, types[TUINT32]), &n2, &n1);
- if(!smallintconst(nodes+1) || mpgetfix((nodes+1)->val.u.xval) != 0)
- gins(optoas(OSUB, types[TUINT32]), nodes+1, &n1);
+ if(!smallintconst(&nodes[1]) || mpgetfix(nodes[1].val.u.xval) != 0)
+ gins(optoas(OSUB, types[TUINT32]), &nodes[1], &n1);
n2 = *res;
n2.xoffset += Array_cap;
@@ -1397,22 +1437,22 @@ sliceslice:
regfree(&n1);
// ret.array = old.array[0]+lb[1]*width[3]; (uses lb[1])
- n2 = *(nodes+0);
+ n2 = nodes[0];
n2.xoffset += Array_array;
- regalloc(&n1, types[tptr], nodes+1);
- if(smallintconst(nodes+1) && smallintconst(nodes+3)) {
+ regalloc(&n1, types[tptr], &nodes[1]);
+ if(smallintconst(&nodes[1]) && smallintconst(&nodes[3])) {
gins(optoas(OAS, types[tptr]), &n2, &n1);
- v = mpgetfix((nodes+1)->val.u.xval) *
- mpgetfix((nodes+3)->val.u.xval);
+ 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);
}
} else {
- gmove(nodes+1, &n1);
- if(!smallintconst(nodes+3) || mpgetfix((nodes+3)->val.u.xval) != 1)
- gins(optoas(OMUL, types[tptr]), nodes+3, &n1);
+ gmove(&nodes[1], &n1);
+ if(!smallintconst(&nodes[3]) || mpgetfix(nodes[3].val.u.xval) != 1)
+ gins(optoas(OMUL, types[tptr]), &nodes[3], &n1);
gins(optoas(OADD, types[tptr]), &n2, &n1);
}
@@ -1422,17 +1462,11 @@ sliceslice:
regfree(&n1);
for(i=0; i<4; i++) {
- if((nodes+i)->op == OREGISTER)
- regfree(nodes+i);
+ if(nodes[i].op == OREGISTER)
+ regfree(&nodes[i]);
}
return 1;
-arraytoslice:
- // ret.len = nel;
- // ret.cap = nel;
- // ret.array = old;
- goto no;
-
no:
return 0;
}
diff --git a/test/ken/slicearray.go b/test/ken/slicearray.go
index 31faa9c78..8e03cb3f4 100644
--- a/test/ken/slicearray.go
+++ b/test/ken/slicearray.go
@@ -4,7 +4,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-
package main
var bx [10]byte
@@ -17,6 +16,12 @@ var t int
func
main()
{
+ lb = 0; hb = 10;
+ by = &bx; tstb();
+
+ lb = 0; hb = 10;
+ fy = &fx; tstf();
+
// width 1 (byte)
lb = 0; hb = 10;
by = bx[lb:hb]; tstb();