mirror of
https://github.com/golang/go
synced 2024-11-26 04:07:59 -07:00
fix fat copy of overlapping data
R=r OCL=14417 CL=14417
This commit is contained in:
parent
2d697d67dc
commit
30fd44cf9d
@ -282,13 +282,6 @@ agen(Node *n, Node *res)
|
|||||||
fatal("agen: unknown op %N", n);
|
fatal("agen: unknown op %N", n);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case ONAME:
|
|
||||||
// regalloc(&n1, types[tptr], res);
|
|
||||||
// gins(optoas(OADDR, types[tptr]), n, &n1);
|
|
||||||
// gmove(&n1, res);
|
|
||||||
// regfree(&n1);
|
|
||||||
// break;
|
|
||||||
|
|
||||||
case OCALLMETH:
|
case OCALLMETH:
|
||||||
cgen_callmeth(n, 0);
|
cgen_callmeth(n, 0);
|
||||||
cgen_aret(n, res);
|
cgen_aret(n, res);
|
||||||
@ -330,8 +323,6 @@ agen(Node *n, Node *res)
|
|||||||
agen_inter(n, res);
|
agen_inter(n, res);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case OINDREG:
|
|
||||||
|
|
||||||
case OINDEX:
|
case OINDEX:
|
||||||
w = n->type->width;
|
w = n->type->width;
|
||||||
if(nr->addable)
|
if(nr->addable)
|
||||||
@ -585,11 +576,27 @@ ret:
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32
|
||||||
|
stkof(Node *n)
|
||||||
|
{
|
||||||
|
switch(n->op) {
|
||||||
|
case OS2I:
|
||||||
|
return 2*widthptr;
|
||||||
|
case OI2I:
|
||||||
|
return 1*widthptr;
|
||||||
|
case OINDREG:
|
||||||
|
return n->xoffset;
|
||||||
|
}
|
||||||
|
// botch - probably failing to recognize address
|
||||||
|
// arithmetic on the above. eg INDEX and DOT
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sgen(Node *n, Node *ns, uint32 w)
|
sgen(Node *n, Node *ns, uint32 w)
|
||||||
{
|
{
|
||||||
Node nodl, nodr;
|
Node nodl, nodr;
|
||||||
int32 c;
|
int32 c, q, odst, osrc;
|
||||||
|
|
||||||
if(debug['g']) {
|
if(debug['g']) {
|
||||||
dump("\nsgen-res", ns);
|
dump("\nsgen-res", ns);
|
||||||
@ -601,6 +608,14 @@ sgen(Node *n, Node *ns, uint32 w)
|
|||||||
fatal("sgen UINF");
|
fatal("sgen UINF");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// offset on the stack
|
||||||
|
odst = stkof(ns);
|
||||||
|
osrc = stkof(n);
|
||||||
|
if(osrc < 0)
|
||||||
|
odst = odst;
|
||||||
|
if(odst < 0)
|
||||||
|
osrc = odst;
|
||||||
|
|
||||||
nodreg(&nodl, types[tptr], D_DI);
|
nodreg(&nodl, types[tptr], D_DI);
|
||||||
nodreg(&nodr, types[tptr], D_SI);
|
nodreg(&nodr, types[tptr], D_SI);
|
||||||
|
|
||||||
@ -611,20 +626,52 @@ sgen(Node *n, Node *ns, uint32 w)
|
|||||||
agen(ns, &nodl);
|
agen(ns, &nodl);
|
||||||
agen(n, &nodr);
|
agen(n, &nodr);
|
||||||
}
|
}
|
||||||
gins(ACLD, N, N); // clear direction flag
|
|
||||||
|
|
||||||
c = w / 8;
|
c = w % 8; // bytes
|
||||||
if(c > 0) {
|
q = w / 8; // quads
|
||||||
gconreg(AMOVQ, c, D_CX);
|
|
||||||
gins(AREP, N, N); // repeat
|
// if we are copying forward on the stack and
|
||||||
gins(AMOVSQ, N, N); // MOVQ *(SI)+,*(DI)+
|
// the src and dst overlap, then reverse direction
|
||||||
|
if(odst > osrc && odst-osrc < w) {
|
||||||
|
// reverse direction
|
||||||
|
gins(ASTD, N, N); // set direction flag
|
||||||
|
if(c > 0) {
|
||||||
|
gconreg(AADDQ, w-1, D_SI);
|
||||||
|
gconreg(AADDQ, w-1, D_DI);
|
||||||
|
|
||||||
|
gconreg(AMOVQ, c, D_CX);
|
||||||
|
gins(AREP, N, N); // repeat
|
||||||
|
gins(AMOVSB, N, N); // MOVB *(SI)-,*(DI)-
|
||||||
|
}
|
||||||
|
|
||||||
|
if(q > 0) {
|
||||||
|
if(c > 0) {
|
||||||
|
gconreg(AADDQ, -7, D_SI);
|
||||||
|
gconreg(AADDQ, -7, D_DI);
|
||||||
|
} else {
|
||||||
|
gconreg(AADDQ, w-8, D_SI);
|
||||||
|
gconreg(AADDQ, w-8, D_DI);
|
||||||
|
}
|
||||||
|
gconreg(AMOVQ, q, D_CX);
|
||||||
|
gins(AREP, N, N); // repeat
|
||||||
|
gins(AMOVSQ, N, N); // MOVQ *(SI)-,*(DI)-
|
||||||
|
}
|
||||||
|
// for future optimization
|
||||||
|
// we leave with the flag clear
|
||||||
|
gins(ACLD, N, N);
|
||||||
|
} else {
|
||||||
|
// normal direction
|
||||||
|
gins(ACLD, N, N); // clear direction flag
|
||||||
|
if(q > 0) {
|
||||||
|
gconreg(AMOVQ, q, D_CX);
|
||||||
|
gins(AREP, N, N); // repeat
|
||||||
|
gins(AMOVSQ, N, N); // MOVQ *(SI)+,*(DI)+
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c > 0) {
|
||||||
|
gconreg(AMOVQ, c, D_CX);
|
||||||
|
gins(AREP, N, N); // repeat
|
||||||
|
gins(AMOVSB, N, N); // MOVB *(SI)+,*(DI)+
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c = w % 8;
|
|
||||||
if(c > 0) {
|
|
||||||
gconreg(AMOVQ, c, D_CX);
|
|
||||||
gins(AREP, N, N); // repeat
|
|
||||||
gins(AMOVSB, N, N); // MOVB *(SI)+,*(DI)+
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
%token LLSH LRSH LINC LDEC LSEND LRECV
|
%token LLSH LRSH LINC LDEC LSEND LRECV
|
||||||
%token LIGNORE
|
%token LIGNORE
|
||||||
|
|
||||||
%type <sym> sym sym1 sym2 key1 key2 laconst lname latype
|
%type <sym> sym sym1 sym2 key laconst lname latype
|
||||||
%type <lint> chandir
|
%type <lint> chandir
|
||||||
%type <node> xdcl xdcl_list_r oxdcl_list
|
%type <node> xdcl xdcl_list_r oxdcl_list
|
||||||
%type <node> common_dcl Acommon_dcl Bcommon_dcl
|
%type <node> common_dcl Acommon_dcl Bcommon_dcl
|
||||||
@ -836,18 +836,17 @@ sym:
|
|||||||
|
|
||||||
sym1:
|
sym1:
|
||||||
sym
|
sym
|
||||||
| key1
|
| key
|
||||||
|
|
||||||
sym2:
|
sym2:
|
||||||
sym
|
sym
|
||||||
| key1
|
| key
|
||||||
| key2
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* keywords that we can
|
* keywords that we can
|
||||||
* use as variable/type names
|
* use as variable/type names
|
||||||
*/
|
*/
|
||||||
key1:
|
key:
|
||||||
LNIL
|
LNIL
|
||||||
| LTRUE
|
| LTRUE
|
||||||
| LFALSE
|
| LFALSE
|
||||||
@ -858,38 +857,7 @@ key1:
|
|||||||
| LNEW
|
| LNEW
|
||||||
| LBASETYPE
|
| LBASETYPE
|
||||||
| LTYPEOF
|
| LTYPEOF
|
||||||
|
|
||||||
/*
|
|
||||||
* keywords that we can
|
|
||||||
* use as field names
|
|
||||||
*/
|
|
||||||
key2:
|
|
||||||
LPACKAGE
|
|
||||||
| LIMPORT
|
|
||||||
| LEXPORT
|
|
||||||
| LMAP
|
|
||||||
| LCHAN
|
|
||||||
| LINTERFACE
|
|
||||||
| LFUNC
|
|
||||||
| LSTRUCT
|
|
||||||
| LFALL
|
|
||||||
| LRETURN
|
|
||||||
| LVAR
|
|
||||||
| LTYPE
|
|
||||||
| LCONST
|
|
||||||
| LCONVERT
|
| LCONVERT
|
||||||
| LSELECT
|
|
||||||
| LFOR
|
|
||||||
| LIF
|
|
||||||
| LELSE
|
|
||||||
| LSWITCH
|
|
||||||
| LCASE
|
|
||||||
| LDEFAULT
|
|
||||||
| LBREAK
|
|
||||||
| LCONTINUE
|
|
||||||
| LGO
|
|
||||||
| LGOTO
|
|
||||||
| LRANGE
|
|
||||||
|
|
||||||
name:
|
name:
|
||||||
lname
|
lname
|
||||||
|
Loading…
Reference in New Issue
Block a user