mirror of
https://github.com/golang/go
synced 2024-11-22 11:44:41 -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);
|
||||
break;
|
||||
|
||||
// case ONAME:
|
||||
// regalloc(&n1, types[tptr], res);
|
||||
// gins(optoas(OADDR, types[tptr]), n, &n1);
|
||||
// gmove(&n1, res);
|
||||
// regfree(&n1);
|
||||
// break;
|
||||
|
||||
case OCALLMETH:
|
||||
cgen_callmeth(n, 0);
|
||||
cgen_aret(n, res);
|
||||
@ -330,8 +323,6 @@ agen(Node *n, Node *res)
|
||||
agen_inter(n, res);
|
||||
break;
|
||||
|
||||
// case OINDREG:
|
||||
|
||||
case OINDEX:
|
||||
w = n->type->width;
|
||||
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
|
||||
sgen(Node *n, Node *ns, uint32 w)
|
||||
{
|
||||
Node nodl, nodr;
|
||||
int32 c;
|
||||
int32 c, q, odst, osrc;
|
||||
|
||||
if(debug['g']) {
|
||||
dump("\nsgen-res", ns);
|
||||
@ -601,6 +608,14 @@ sgen(Node *n, Node *ns, uint32 w)
|
||||
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(&nodr, types[tptr], D_SI);
|
||||
|
||||
@ -611,20 +626,52 @@ sgen(Node *n, Node *ns, uint32 w)
|
||||
agen(ns, &nodl);
|
||||
agen(n, &nodr);
|
||||
}
|
||||
gins(ACLD, N, N); // clear direction flag
|
||||
|
||||
c = w / 8;
|
||||
if(c > 0) {
|
||||
gconreg(AMOVQ, c, D_CX);
|
||||
gins(AREP, N, N); // repeat
|
||||
gins(AMOVSQ, N, N); // MOVQ *(SI)+,*(DI)+
|
||||
c = w % 8; // bytes
|
||||
q = w / 8; // quads
|
||||
|
||||
// if we are copying forward on the stack and
|
||||
// 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 LIGNORE
|
||||
|
||||
%type <sym> sym sym1 sym2 key1 key2 laconst lname latype
|
||||
%type <sym> sym sym1 sym2 key laconst lname latype
|
||||
%type <lint> chandir
|
||||
%type <node> xdcl xdcl_list_r oxdcl_list
|
||||
%type <node> common_dcl Acommon_dcl Bcommon_dcl
|
||||
@ -836,18 +836,17 @@ sym:
|
||||
|
||||
sym1:
|
||||
sym
|
||||
| key1
|
||||
| key
|
||||
|
||||
sym2:
|
||||
sym
|
||||
| key1
|
||||
| key2
|
||||
| key
|
||||
|
||||
/*
|
||||
* keywords that we can
|
||||
* use as variable/type names
|
||||
*/
|
||||
key1:
|
||||
key:
|
||||
LNIL
|
||||
| LTRUE
|
||||
| LFALSE
|
||||
@ -858,38 +857,7 @@ key1:
|
||||
| LNEW
|
||||
| LBASETYPE
|
||||
| LTYPEOF
|
||||
|
||||
/*
|
||||
* keywords that we can
|
||||
* use as field names
|
||||
*/
|
||||
key2:
|
||||
LPACKAGE
|
||||
| LIMPORT
|
||||
| LEXPORT
|
||||
| LMAP
|
||||
| LCHAN
|
||||
| LINTERFACE
|
||||
| LFUNC
|
||||
| LSTRUCT
|
||||
| LFALL
|
||||
| LRETURN
|
||||
| LVAR
|
||||
| LTYPE
|
||||
| LCONST
|
||||
| LCONVERT
|
||||
| LSELECT
|
||||
| LFOR
|
||||
| LIF
|
||||
| LELSE
|
||||
| LSWITCH
|
||||
| LCASE
|
||||
| LDEFAULT
|
||||
| LBREAK
|
||||
| LCONTINUE
|
||||
| LGO
|
||||
| LGOTO
|
||||
| LRANGE
|
||||
|
||||
name:
|
||||
lname
|
||||
|
Loading…
Reference in New Issue
Block a user