diff options
Diffstat (limited to 'src/cmd')
| -rw-r--r-- | src/cmd/5g/gsubr.c | 58 | ||||
| -rw-r--r-- | src/cmd/6g/gsubr.c | 38 | ||||
| -rw-r--r-- | src/cmd/8g/gsubr.c | 38 | ||||
| -rw-r--r-- | src/cmd/gc/dcl.c | 5 | ||||
| -rw-r--r-- | src/cmd/gc/gen.c | 1 | ||||
| -rw-r--r-- | src/cmd/gc/go.h | 3 | 
6 files changed, 143 insertions, 0 deletions
| diff --git a/src/cmd/5g/gsubr.c b/src/cmd/5g/gsubr.c index 83a9949d6..57cb56a64 100644 --- a/src/cmd/5g/gsubr.c +++ b/src/cmd/5g/gsubr.c @@ -125,6 +125,64 @@ newplist(void)  }  void +clearstk(void) +{ +	Plist *pl; +	Prog *p, *p1, *p2, *p3; +	Node dst, end, zero, con; + +	if(plast->firstpc->to.offset <= 0) +		return; + +	// reestablish context for inserting code +	// at beginning of function. +	pl = plast; +	p1 = pl->firstpc; +	p2 = p1->link; +	pc = mal(sizeof(*pc)); +	clearp(pc); +	p1->link = pc; +	 +	// zero stack frame + +	// MOVW $4(SP), R1 +	nodreg(&dst, types[tptr], 1); +	p = gins(AMOVW, N, &dst); +	p->from.type = D_CONST; +	p->from.reg = REGSP; +	p->from.offset = 4; + +	// MOVW $n(R1), R2 +	nodreg(&end, types[tptr], 2); +	p = gins(AMOVW, N, &end); +	p->from.type = D_CONST; +	p->from.reg = 1; +	p->from.offset = p1->to.offset; +	 +	// MOVW $0, R3 +	nodreg(&zero, types[TUINT32], 3); +	nodconst(&con, types[TUINT32], 0); +	gmove(&con, &zero); + +	// L: +	//	MOVW.P R3, 0(R1) +4 +	//	CMP R1, R2 +	//	BNE L +	p = gins(AMOVW, &zero, &dst); +	p->to.type = D_OREG; +	p->to.offset = 4; +	p->scond |= C_PBIT; +	p3 = p; +	p = gins(ACMP, &dst, N); +	raddr(&end, p); +	patch(gbranch(ABNE, T), p3); + +	// continue with original code. +	gins(ANOP, N, N)->link = p2; +	pc = P; +}	 + +void  gused(Node *n)  {  	gins(ANOP, n, N);	// used diff --git a/src/cmd/6g/gsubr.c b/src/cmd/6g/gsubr.c index c3dac1fdc..78b8c4351 100644 --- a/src/cmd/6g/gsubr.c +++ b/src/cmd/6g/gsubr.c @@ -121,6 +121,44 @@ newplist(void)  }  void +clearstk(void) +{ +	Plist *pl; +	Prog *p1, *p2; +	Node sp, di, cx, con, ax; + +	if((uint32)plast->firstpc->to.offset <= 0) +		return; + +	// reestablish context for inserting code +	// at beginning of function. +	pl = plast; +	p1 = pl->firstpc; +	p2 = p1->link; +	pc = mal(sizeof(*pc)); +	clearp(pc); +	p1->link = pc; +	 +	// zero stack frame +	nodreg(&sp, types[tptr], D_SP); +	nodreg(&di, types[tptr], D_DI); +	nodreg(&cx, types[TUINT64], D_CX); +	nodconst(&con, types[TUINT64], (uint32)p1->to.offset / widthptr); +	gins(ACLD, N, N); +	gins(AMOVQ, &sp, &di); +	gins(AMOVQ, &con, &cx); +	nodconst(&con, types[TUINT64], 0); +	nodreg(&ax, types[TUINT64], D_AX); +	gins(AMOVQ, &con, &ax); +	gins(AREP, N, N); +	gins(ASTOSQ, N, N); + +	// continue with original code. +	gins(ANOP, N, N)->link = p2; +	pc = P; +}	 + +void  gused(Node *n)  {  	gins(ANOP, n, N);	// used diff --git a/src/cmd/8g/gsubr.c b/src/cmd/8g/gsubr.c index 8ed7e5564..ae9901eeb 100644 --- a/src/cmd/8g/gsubr.c +++ b/src/cmd/8g/gsubr.c @@ -123,6 +123,44 @@ newplist(void)  }  void +clearstk(void) +{ +	Plist *pl; +	Prog *p1, *p2; +	Node sp, di, cx, con, ax; + +	if(plast->firstpc->to.offset <= 0) +		return; + +	// reestablish context for inserting code +	// at beginning of function. +	pl = plast; +	p1 = pl->firstpc; +	p2 = p1->link; +	pc = mal(sizeof(*pc)); +	clearp(pc); +	p1->link = pc; +	 +	// zero stack frame +	nodreg(&sp, types[tptr], D_SP); +	nodreg(&di, types[tptr], D_DI); +	nodreg(&cx, types[TUINT32], D_CX); +	nodconst(&con, types[TUINT32], p1->to.offset / widthptr); +	gins(ACLD, N, N); +	gins(AMOVL, &sp, &di); +	gins(AMOVL, &con, &cx); +	nodconst(&con, types[TUINT32], 0); +	nodreg(&ax, types[TUINT32], D_AX); +	gins(AMOVL, &con, &ax); +	gins(AREP, N, N); +	gins(ASTOSL, N, N); + +	// continue with original code. +	gins(ANOP, N, N)->link = p2; +	pc = P; +}	 + +void  gused(Node *n)  {  	gins(ANOP, n, N);	// used diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c index 99af18d9f..8e790ef08 100644 --- a/src/cmd/gc/dcl.c +++ b/src/cmd/gc/dcl.c @@ -1233,9 +1233,14 @@ funccompile(Node *n, int isclosure)  	stksize = 0;  	dclcontext = PAUTO;  	funcdepth = n->funcdepth + 1; +	hasgoto = 0;  	compile(n); +	if(hasgoto) +		clearstk();  	curfn = nil;  	funcdepth = 0;  	dclcontext = PEXTERN;  } + + diff --git a/src/cmd/gc/gen.c b/src/cmd/gc/gen.c index 8ad6c437d..857fcbef9 100644 --- a/src/cmd/gc/gen.c +++ b/src/cmd/gc/gen.c @@ -205,6 +205,7 @@ gen(Node *n)  		break;  	case OGOTO: +		hasgoto = 1;  		newlab(OGOTO, n, N);  		gjmp(P);  		break; diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index f58b76789..4b4e8fcd1 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -1246,3 +1246,6 @@ void	zhist(Biobuf *b, int line, vlong offset);  void	zname(Biobuf *b, Sym *s, int t);  void	data(void);  void	text(void); + +EXTERN	int	hasgoto; +void	clearstk(void); | 
