mirror of https://github.com/golang/go.git
parent
e653280cad
commit
9bf597a210
|
|
@ -35,6 +35,10 @@ cgen(Node *n, Node *res)
|
||||||
if(initflag && gen_as_init(n, res))
|
if(initflag && gen_as_init(n, res))
|
||||||
goto ret;
|
goto ret;
|
||||||
|
|
||||||
|
// inline slices
|
||||||
|
if(cgen_inline(n, res))
|
||||||
|
goto ret;
|
||||||
|
|
||||||
if(n->ullman >= UINF) {
|
if(n->ullman >= UINF) {
|
||||||
if(n->op == OINDREG)
|
if(n->op == OINDREG)
|
||||||
fatal("cgen: this is going to misscompile");
|
fatal("cgen: this is going to misscompile");
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,7 @@ Prog* gins(int, Node*, Node*);
|
||||||
int samaddr(Node*, Node*);
|
int samaddr(Node*, Node*);
|
||||||
void naddr(Node*, Addr*);
|
void naddr(Node*, Addr*);
|
||||||
void cgen_aret(Node*, Node*);
|
void cgen_aret(Node*, Node*);
|
||||||
|
int cgen_inline(Node*, Node*);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* gsubr.c
|
* gsubr.c
|
||||||
|
|
|
||||||
|
|
@ -1172,3 +1172,171 @@ yes:
|
||||||
//print("%P\n", p);
|
//print("%P\n", p);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
getargs(NodeList *nn, Node *reg, int n)
|
||||||
|
{
|
||||||
|
NodeList *l;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
l = nn;
|
||||||
|
for(i=0; i<n; i++) {
|
||||||
|
if(!smallintconst(l->n->right)) {
|
||||||
|
regalloc(reg+i, l->n->right->type, N);
|
||||||
|
cgen(l->n->right, reg+i);
|
||||||
|
} else
|
||||||
|
reg[i] = *l->n->right;
|
||||||
|
l = l->next;
|
||||||
|
}
|
||||||
|
// botch - need second pass to sort by offset
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cmpandthrow(Node *nodes, int l, int r)
|
||||||
|
{
|
||||||
|
vlong cl, cr;
|
||||||
|
Prog *p1;
|
||||||
|
int op, c;
|
||||||
|
|
||||||
|
op = OLE;
|
||||||
|
if(smallintconst(nodes+l)) {
|
||||||
|
cl = mpgetfix((nodes+l)->val.u.xval);
|
||||||
|
if(cl == 0)
|
||||||
|
return;
|
||||||
|
if(smallintconst(nodes+r)) {
|
||||||
|
cr = mpgetfix((nodes+r)->val.u.xval);
|
||||||
|
if(cl > cr)
|
||||||
|
ginscall(throwindex, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// put the constant on the right
|
||||||
|
op = brrev(op);
|
||||||
|
c = l;
|
||||||
|
l = r;
|
||||||
|
r = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
gins(optoas(OCMP, types[TUINT32]), nodes+l, nodes+r);
|
||||||
|
p1 = gbranch(optoas(op, types[TUINT32]), T);
|
||||||
|
ginscall(throwindex, 0);
|
||||||
|
patch(p1, pc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate inline code for
|
||||||
|
// slicearray
|
||||||
|
// sliceslice
|
||||||
|
// arraytoslice
|
||||||
|
int
|
||||||
|
cgen_inline(Node *n, Node *res)
|
||||||
|
{
|
||||||
|
Node nodes[10];
|
||||||
|
Node n1, n2;
|
||||||
|
vlong v;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(n->op != OCALLFUNC)
|
||||||
|
goto no;
|
||||||
|
if(n->left->op != ONAME)
|
||||||
|
goto no;
|
||||||
|
if(!res->addable)
|
||||||
|
goto no;
|
||||||
|
if(strcmp(n->left->sym->package, "sys") != 0)
|
||||||
|
goto no;
|
||||||
|
if(strcmp(n->left->sym->name, "slicearray") == 0)
|
||||||
|
goto slicearray;
|
||||||
|
if(strcmp(n->left->sym->name, "sliceslice") == 0)
|
||||||
|
goto sliceslice;
|
||||||
|
if(strcmp(n->left->sym->name, "arraytoslice") == 0)
|
||||||
|
goto arraytoslice;
|
||||||
|
goto no;
|
||||||
|
|
||||||
|
slicearray:
|
||||||
|
getargs(n->list, nodes, 5);
|
||||||
|
|
||||||
|
// if(hb[3] > nel[1]) goto throw
|
||||||
|
cmpandthrow(nodes, 3, 1);
|
||||||
|
|
||||||
|
// if(lb[2] > hb[3]) goto throw
|
||||||
|
cmpandthrow(nodes, 2, 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);
|
||||||
|
nodconst(&n1, types[TUINT32], v);
|
||||||
|
gins(optoas(OAS, types[TUINT32]), &n1, &n2);
|
||||||
|
} else {
|
||||||
|
regalloc(&n1, types[TUINT32], nodes+3);
|
||||||
|
gmove(nodes+3, &n1);
|
||||||
|
gins(optoas(OSUB, types[TUINT32]), nodes+2, &n1);
|
||||||
|
gins(optoas(OAS, types[TUINT32]), &n1, &n2);
|
||||||
|
regfree(&n1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cap = nel[1] - lb[2] (destroys nel)
|
||||||
|
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);
|
||||||
|
nodconst(&n1, types[TUINT32], v);
|
||||||
|
gins(optoas(OAS, types[TUINT32]), &n1, &n2);
|
||||||
|
} else {
|
||||||
|
regalloc(&n1, types[TUINT32], nodes+1);
|
||||||
|
gmove(nodes+1, &n1);
|
||||||
|
gins(optoas(OSUB, types[TUINT32]), nodes+2, &n1);
|
||||||
|
gins(optoas(OAS, types[TUINT32]), &n1, &n2);
|
||||||
|
regfree(&n1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ary = old[0] + (lb[2] * width[4]) (destroys old)
|
||||||
|
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);
|
||||||
|
nodconst(&n1, types[tptr], v);
|
||||||
|
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);
|
||||||
|
regfree(&n1);
|
||||||
|
}
|
||||||
|
gins(optoas(OAS, types[tptr]), nodes+0, &n2);
|
||||||
|
|
||||||
|
// ret.len = hb[3]-lb[2];
|
||||||
|
// ret.cap = nel[1]-lb[2];
|
||||||
|
// ret.array = old[0] + lb[3]*width[4];
|
||||||
|
for(i=0; i<5; i++) {
|
||||||
|
if(!smallintconst(nodes+i))
|
||||||
|
regfree(nodes+i);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
sliceslice:
|
||||||
|
// if(hb > old.cap) goto throw;
|
||||||
|
// if(lb > hb) goto throw;
|
||||||
|
// ret.len = hb-lb;
|
||||||
|
// ret.cap = old.cap - lb;
|
||||||
|
// ret.array = old.array + lb*width;
|
||||||
|
goto no;
|
||||||
|
|
||||||
|
arraytoslice:
|
||||||
|
// ret.len = nel;
|
||||||
|
// ret.cap = nel;
|
||||||
|
// ret.array = old;
|
||||||
|
goto no;
|
||||||
|
|
||||||
|
no:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,127 @@
|
||||||
|
// $G $D/$F.go && $L $F.$A && ./$A.out
|
||||||
|
|
||||||
|
// Copyright 2009 The Go Authors. All rights reserved.
|
||||||
|
// 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
|
||||||
|
var by []byte;
|
||||||
|
var fx [10]float
|
||||||
|
var fy []float;
|
||||||
|
var lb,hb int
|
||||||
|
var t int
|
||||||
|
|
||||||
|
func
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
// width 1 (byte)
|
||||||
|
lb = 0; hb = 10;
|
||||||
|
by = bx[lb:hb]; tstb();
|
||||||
|
by = bx[lb:10]; tstb();
|
||||||
|
by = bx[0:hb]; tstb();
|
||||||
|
by = bx[0:10]; tstb();
|
||||||
|
|
||||||
|
lb = 2; hb = 10;
|
||||||
|
by = bx[lb:hb]; tstb();
|
||||||
|
by = bx[lb:10]; tstb();
|
||||||
|
by = bx[2:hb]; tstb();
|
||||||
|
by = bx[2:10]; tstb();
|
||||||
|
|
||||||
|
lb = 0; hb = 8;
|
||||||
|
by = bx[lb:hb]; tstb();
|
||||||
|
by = bx[lb:8]; tstb();
|
||||||
|
by = bx[0:hb]; tstb();
|
||||||
|
by = bx[0:8]; tstb();
|
||||||
|
|
||||||
|
lb = 2; hb = 8;
|
||||||
|
by = bx[lb:hb]; tstb();
|
||||||
|
by = bx[lb:8]; tstb();
|
||||||
|
by = bx[2:hb]; tstb();
|
||||||
|
by = bx[2:8]; tstb();
|
||||||
|
|
||||||
|
// width 4 (float)
|
||||||
|
lb = 0; hb = 10;
|
||||||
|
fy = fx[lb:hb]; tstf();
|
||||||
|
fy = fx[lb:10]; tstf();
|
||||||
|
fy = fx[0:hb]; tstf();
|
||||||
|
fy = fx[0:10]; tstf();
|
||||||
|
|
||||||
|
lb = 2; hb = 10;
|
||||||
|
fy = fx[lb:hb]; tstf();
|
||||||
|
fy = fx[lb:10]; tstf();
|
||||||
|
fy = fx[2:hb]; tstf();
|
||||||
|
fy = fx[2:10]; tstf();
|
||||||
|
|
||||||
|
lb = 0; hb = 8;
|
||||||
|
fy = fx[lb:hb]; tstf();
|
||||||
|
fy = fx[lb:8]; tstf();
|
||||||
|
fy = fx[0:hb]; tstf();
|
||||||
|
fy = fx[0:8]; tstf();
|
||||||
|
|
||||||
|
lb = 2; hb = 8;
|
||||||
|
fy = fx[lb:hb]; tstf();
|
||||||
|
fy = fx[lb:8]; tstf();
|
||||||
|
fy = fx[2:hb]; tstf();
|
||||||
|
fy = fx[2:8]; tstf();
|
||||||
|
}
|
||||||
|
|
||||||
|
func
|
||||||
|
tstb()
|
||||||
|
{
|
||||||
|
t++;
|
||||||
|
if len(by) != hb-lb {
|
||||||
|
panicln("t=", t, "lb=", lb, "hb=", hb,
|
||||||
|
"len=", len(by), "hb-lb=", hb-lb);
|
||||||
|
}
|
||||||
|
if cap(by) != len(bx)-lb {
|
||||||
|
panicln("t=", t, "lb=", lb, "hb=", hb,
|
||||||
|
"cap=", cap(by), "len(bx)-lb=", len(bx)-lb);
|
||||||
|
}
|
||||||
|
for i:=lb; i<hb; i++ {
|
||||||
|
if bx[i] != by[i-lb] {
|
||||||
|
panicln("t=", t, "lb=", lb, "hb=", hb,
|
||||||
|
"bx[", i, "]=", bx[i],
|
||||||
|
"by[", i-lb, "]=", by[i-lb]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
by = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
func
|
||||||
|
tstf()
|
||||||
|
{
|
||||||
|
t++;
|
||||||
|
if len(fy) != hb-lb {
|
||||||
|
panicln("t=", t, "lb=", lb, "hb=", hb,
|
||||||
|
"len=", len(fy), "hb-lb=", hb-lb);
|
||||||
|
}
|
||||||
|
if cap(fy) != len(fx)-lb {
|
||||||
|
panicln("t=", t, "lb=", lb, "hb=", hb,
|
||||||
|
"cap=", cap(fy), "len(fx)-lb=", len(fx)-lb);
|
||||||
|
}
|
||||||
|
for i:=lb; i<hb; i++ {
|
||||||
|
if fx[i] != fy[i-lb] {
|
||||||
|
panicln("t=", t, "lb=", lb, "hb=", hb,
|
||||||
|
"fx[", i, "]=", fx[i],
|
||||||
|
"fy[", i-lb, "]=", fy[i-lb]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fy = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
func
|
||||||
|
init()
|
||||||
|
{
|
||||||
|
for i:=0; i<len(bx); i++ {
|
||||||
|
bx[i] = byte(i+20);
|
||||||
|
}
|
||||||
|
by = nil;
|
||||||
|
|
||||||
|
for i:=0; i<len(fx); i++ {
|
||||||
|
fx[i] = float(i+20);
|
||||||
|
}
|
||||||
|
fy = nil;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue