Commit e667e8a4 authored by Ken Thompson's avatar Ken Thompson

arraytoslice and some cleanup

R=rsc
OCL=34058
CL=34058
parent d11a4b0d
...@@ -1180,12 +1180,16 @@ regcmp(Node *ra, Node *rb) ...@@ -1180,12 +1180,16 @@ regcmp(Node *ra, Node *rb)
return ra->local - rb->local; return ra->local - rb->local;
} }
static Prog* throwpc;
void void
getargs(NodeList *nn, Node *reg, int n) getargs(NodeList *nn, Node *reg, int n)
{ {
NodeList *l; NodeList *l;
int i; int i;
throwpc = nil;
l = nn; l = nn;
for(i=0; i<n; i++) { for(i=0; i<n; i++) {
if(!smallintconst(l->n->right) && !isslice(l->n->right->type)) { if(!smallintconst(l->n->right) && !isslice(l->n->right->type)) {
...@@ -1218,8 +1222,13 @@ cmpandthrow(Node *nl, Node *nr) ...@@ -1218,8 +1222,13 @@ cmpandthrow(Node *nl, Node *nr)
return; return;
if(smallintconst(nr)) { if(smallintconst(nr)) {
cr = mpgetfix(nr->val.u.xval); cr = mpgetfix(nr->val.u.xval);
if(cl > cr) if(cl > cr) {
ginscall(throwslice, 0); if(throwpc == nil) {
throwpc = pc;
ginscall(throwslice, 0);
} else
patch(gbranch(AJMP, T), throwpc);
}
return; return;
} }
...@@ -1231,9 +1240,16 @@ cmpandthrow(Node *nl, Node *nr) ...@@ -1231,9 +1240,16 @@ cmpandthrow(Node *nl, Node *nr)
} }
gins(optoas(OCMP, types[TUINT32]), nl, nr); gins(optoas(OCMP, types[TUINT32]), nl, nr);
p1 = gbranch(optoas(op, types[TUINT32]), T); if(throwpc == nil) {
ginscall(throwslice, 0); p1 = gbranch(optoas(op, types[TUINT32]), T);
patch(p1, pc); throwpc = pc;
ginscall(throwslice, 0);
patch(p1, pc);
} else {
op = brcom(op);
p1 = gbranch(optoas(op, types[TUINT32]), T);
patch(p1, throwpc);
}
} }
int int
...@@ -1253,7 +1269,7 @@ sleasy(Node *n) ...@@ -1253,7 +1269,7 @@ sleasy(Node *n)
int int
cgen_inline(Node *n, Node *res) cgen_inline(Node *n, Node *res)
{ {
Node nodes[10]; Node nodes[5];
Node n1, n2; Node n1, n2;
vlong v; vlong v;
int i; int i;
...@@ -1278,25 +1294,25 @@ slicearray: ...@@ -1278,25 +1294,25 @@ slicearray:
getargs(n->list, nodes, 5); getargs(n->list, nodes, 5);
// if(hb[3] > nel[1]) goto throw // if(hb[3] > nel[1]) goto throw
cmpandthrow(nodes+3, nodes+1); cmpandthrow(&nodes[3], &nodes[1]);
// if(lb[2] > hb[3]) goto throw // if(lb[2] > hb[3]) goto throw
cmpandthrow(nodes+2, nodes+3); cmpandthrow(&nodes[2], &nodes[3]);
// len = hb[3] - lb[2] (destroys hb) // len = hb[3] - lb[2] (destroys hb)
n2 = *res; n2 = *res;
n2.xoffset += Array_nel; n2.xoffset += Array_nel;
if(smallintconst(nodes+3) && smallintconst(nodes+2)) { if(smallintconst(&nodes[3]) && smallintconst(&nodes[2])) {
v = mpgetfix((nodes+3)->val.u.xval) - v = mpgetfix(nodes[3].val.u.xval) -
mpgetfix((nodes+2)->val.u.xval); mpgetfix(nodes[2].val.u.xval);
nodconst(&n1, types[TUINT32], v); nodconst(&n1, types[TUINT32], v);
gins(optoas(OAS, types[TUINT32]), &n1, &n2); gins(optoas(OAS, types[TUINT32]), &n1, &n2);
} else { } else {
regalloc(&n1, types[TUINT32], nodes+3); regalloc(&n1, types[TUINT32], &nodes[3]);
gmove(nodes+3, &n1); gmove(&nodes[3], &n1);
if(!smallintconst(nodes+2) || mpgetfix((nodes+2)->val.u.xval) != 0) if(!smallintconst(&nodes[2]) || mpgetfix(nodes[2].val.u.xval) != 0)
gins(optoas(OSUB, types[TUINT32]), nodes+2, &n1); gins(optoas(OSUB, types[TUINT32]), &nodes[2], &n1);
gins(optoas(OAS, types[TUINT32]), &n1, &n2); gins(optoas(OAS, types[TUINT32]), &n1, &n2);
regfree(&n1); regfree(&n1);
} }
...@@ -1305,16 +1321,16 @@ slicearray: ...@@ -1305,16 +1321,16 @@ slicearray:
n2 = *res; n2 = *res;
n2.xoffset += Array_cap; n2.xoffset += Array_cap;
if(smallintconst(nodes+1) && smallintconst(nodes+2)) { if(smallintconst(&nodes[1]) && smallintconst(&nodes[2])) {
v = mpgetfix((nodes+1)->val.u.xval) - v = mpgetfix(nodes[1].val.u.xval) -
mpgetfix((nodes+2)->val.u.xval); mpgetfix(nodes[2].val.u.xval);
nodconst(&n1, types[TUINT32], v); nodconst(&n1, types[TUINT32], v);
gins(optoas(OAS, types[TUINT32]), &n1, &n2); gins(optoas(OAS, types[TUINT32]), &n1, &n2);
} else { } else {
regalloc(&n1, types[TUINT32], nodes+1); regalloc(&n1, types[TUINT32], &nodes[1]);
gmove(nodes+1, &n1); gmove(&nodes[1], &n1);
if(!smallintconst(nodes+2) || mpgetfix((nodes+2)->val.u.xval) != 0) if(!smallintconst(&nodes[2]) || mpgetfix(nodes[2].val.u.xval) != 0)
gins(optoas(OSUB, types[TUINT32]), nodes+2, &n1); gins(optoas(OSUB, types[TUINT32]), &nodes[2], &n1);
gins(optoas(OAS, types[TUINT32]), &n1, &n2); gins(optoas(OAS, types[TUINT32]), &n1, &n2);
regfree(&n1); regfree(&n1);
} }
...@@ -1323,73 +1339,97 @@ slicearray: ...@@ -1323,73 +1339,97 @@ slicearray:
n2 = *res; n2 = *res;
n2.xoffset += Array_array; n2.xoffset += Array_array;
if(smallintconst(nodes+2) && smallintconst(nodes+4)) { if(smallintconst(&nodes[2]) && smallintconst(&nodes[4])) {
v = mpgetfix((nodes+2)->val.u.xval) * v = mpgetfix(nodes[2].val.u.xval) *
mpgetfix((nodes+4)->val.u.xval); mpgetfix(nodes[4].val.u.xval);
if(v != 0) { if(v != 0) {
nodconst(&n1, types[tptr], v); nodconst(&n1, types[tptr], v);
gins(optoas(OADD, types[tptr]), &n1, nodes+0); gins(optoas(OADD, types[tptr]), &n1, &nodes[0]);
} }
} else { } else {
regalloc(&n1, types[tptr], nodes+2); regalloc(&n1, types[tptr], &nodes[2]);
gmove(nodes+2, &n1); gmove(&nodes[2], &n1);
if(!smallintconst(nodes+4) || mpgetfix((nodes+4)->val.u.xval) != 1) if(!smallintconst(&nodes[4]) || mpgetfix(nodes[4].val.u.xval) != 1)
gins(optoas(OMUL, types[tptr]), nodes+4, &n1); gins(optoas(OMUL, types[tptr]), &nodes[4], &n1);
gins(optoas(OADD, types[tptr]), &n1, nodes+0); gins(optoas(OADD, types[tptr]), &n1, &nodes[0]);
regfree(&n1); regfree(&n1);
} }
gins(optoas(OAS, types[tptr]), nodes+0, &n2); gins(optoas(OAS, types[tptr]), &nodes[0], &n2);
for(i=0; i<5; i++) { for(i=0; i<5; i++) {
if((nodes+i)->op == OREGISTER) if(nodes[i].op == OREGISTER)
regfree(nodes+i); 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; return 1;
sliceslice: sliceslice:
getargs(n->list, nodes, 4); getargs(n->list, nodes, 4);
if(!sleasy(nodes+0)) { if(!sleasy(&nodes[0])) {
for(i=0; i<4; i++) { for(i=0; i<4; i++) {
if((nodes+i)->op == OREGISTER) if(nodes[i].op == OREGISTER)
regfree(nodes+i); regfree(&nodes[i]);
} }
goto no; goto no;
} }
// if(hb[2] > old.cap[0]) goto throw; // if(hb[2] > old.cap[0]) goto throw;
n2 = *(nodes+0); n2 = nodes[0];
n2.xoffset += Array_cap; n2.xoffset += Array_cap;
cmpandthrow(nodes+2, &n2); cmpandthrow(&nodes[2], &n2);
// if(lb[1] > hb[2]) goto throw; // 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]) // ret.len = hb[2]-lb[1]; (destroys hb[2])
n2 = *res; n2 = *res;
n2.xoffset += Array_nel; n2.xoffset += Array_nel;
if(smallintconst(nodes+2) && smallintconst(nodes+1)) { if(smallintconst(&nodes[2]) && smallintconst(&nodes[1])) {
v = mpgetfix((nodes+2)->val.u.xval) - v = mpgetfix(nodes[2].val.u.xval) -
mpgetfix((nodes+1)->val.u.xval); mpgetfix(nodes[1].val.u.xval);
nodconst(&n1, types[TUINT32], v); nodconst(&n1, types[TUINT32], v);
gins(optoas(OAS, types[TUINT32]), &n1, &n2); gins(optoas(OAS, types[TUINT32]), &n1, &n2);
} else { } else {
regalloc(&n1, types[TUINT32], nodes+2); regalloc(&n1, types[TUINT32], &nodes[2]);
gmove(nodes+2, &n1); gmove(&nodes[2], &n1);
if(!smallintconst(nodes+1) || mpgetfix((nodes+1)->val.u.xval) != 0) if(!smallintconst(&nodes[1]) || mpgetfix(nodes[1].val.u.xval) != 0)
gins(optoas(OSUB, types[TUINT32]), nodes+1, &n1); gins(optoas(OSUB, types[TUINT32]), &nodes[1], &n1);
gins(optoas(OAS, types[TUINT32]), &n1, &n2); gins(optoas(OAS, types[TUINT32]), &n1, &n2);
regfree(&n1); regfree(&n1);
} }
// ret.cap = old.cap[0]-lb[1]; (uses hb[2]) // ret.cap = old.cap[0]-lb[1]; (uses hb[2])
n2 = *(nodes+0); n2 = nodes[0];
n2.xoffset += Array_cap; n2.xoffset += Array_cap;
regalloc(&n1, types[TUINT32], nodes+2); regalloc(&n1, types[TUINT32], &nodes[2]);
gins(optoas(OAS, types[TUINT32]), &n2, &n1); gins(optoas(OAS, types[TUINT32]), &n2, &n1);
if(!smallintconst(nodes+1) || mpgetfix((nodes+1)->val.u.xval) != 0) if(!smallintconst(&nodes[1]) || mpgetfix(nodes[1].val.u.xval) != 0)
gins(optoas(OSUB, types[TUINT32]), nodes+1, &n1); gins(optoas(OSUB, types[TUINT32]), &nodes[1], &n1);
n2 = *res; n2 = *res;
n2.xoffset += Array_cap; n2.xoffset += Array_cap;
...@@ -1397,22 +1437,22 @@ sliceslice: ...@@ -1397,22 +1437,22 @@ sliceslice:
regfree(&n1); regfree(&n1);
// ret.array = old.array[0]+lb[1]*width[3]; (uses lb[1]) // ret.array = old.array[0]+lb[1]*width[3]; (uses lb[1])
n2 = *(nodes+0); n2 = nodes[0];
n2.xoffset += Array_array; n2.xoffset += Array_array;
regalloc(&n1, types[tptr], nodes+1); regalloc(&n1, types[tptr], &nodes[1]);
if(smallintconst(nodes+1) && smallintconst(nodes+3)) { if(smallintconst(&nodes[1]) && smallintconst(&nodes[3])) {
gins(optoas(OAS, types[tptr]), &n2, &n1); gins(optoas(OAS, types[tptr]), &n2, &n1);
v = mpgetfix((nodes+1)->val.u.xval) * v = mpgetfix(nodes[1].val.u.xval) *
mpgetfix((nodes+3)->val.u.xval); mpgetfix(nodes[3].val.u.xval);
if(v != 0) { if(v != 0) {
nodconst(&n2, types[tptr], v); nodconst(&n2, types[tptr], v);
gins(optoas(OADD, types[tptr]), &n2, &n1); gins(optoas(OADD, types[tptr]), &n2, &n1);
} }
} else { } else {
gmove(nodes+1, &n1); gmove(&nodes[1], &n1);
if(!smallintconst(nodes+3) || mpgetfix((nodes+3)->val.u.xval) != 1) if(!smallintconst(&nodes[3]) || mpgetfix(nodes[3].val.u.xval) != 1)
gins(optoas(OMUL, types[tptr]), nodes+3, &n1); gins(optoas(OMUL, types[tptr]), &nodes[3], &n1);
gins(optoas(OADD, types[tptr]), &n2, &n1); gins(optoas(OADD, types[tptr]), &n2, &n1);
} }
...@@ -1422,17 +1462,11 @@ sliceslice: ...@@ -1422,17 +1462,11 @@ sliceslice:
regfree(&n1); regfree(&n1);
for(i=0; i<4; i++) { for(i=0; i<4; i++) {
if((nodes+i)->op == OREGISTER) if(nodes[i].op == OREGISTER)
regfree(nodes+i); regfree(&nodes[i]);
} }
return 1; return 1;
arraytoslice:
// ret.len = nel;
// ret.cap = nel;
// ret.array = old;
goto no;
no: no:
return 0; return 0;
} }
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package main package main
var bx [10]byte var bx [10]byte
...@@ -17,6 +16,12 @@ var t int ...@@ -17,6 +16,12 @@ var t int
func func
main() main()
{ {
lb = 0; hb = 10;
by = &bx; tstb();
lb = 0; hb = 10;
fy = &fx; tstf();
// width 1 (byte) // width 1 (byte)
lb = 0; hb = 10; lb = 0; hb = 10;
by = bx[lb:hb]; tstb(); by = bx[lb:hb]; tstb();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment