xref: /csrg-svn/old/pcc/mip/allo.c (revision 32790)
117743Sralph #ifndef lint
2*32790Sdonn static char *sccsid ="@(#)allo.c	4.10 (Berkeley) 12/09/87";
317743Sralph #endif lint
417743Sralph 
518390Sralph # include "pass2.h"
616176Sralph 
716176Sralph NODE resc[3];
816176Sralph 
916176Sralph int busy[REGSZ];
1016176Sralph 
1116176Sralph int maxa, mina, maxb, minb;
1216176Sralph 
1316176Sralph # ifndef ALLO0
allo0()1416176Sralph allo0(){ /* free everything */
1516176Sralph 
1616176Sralph 	register i;
1716176Sralph 
1816176Sralph 	maxa = maxb = -1;
1916176Sralph 	mina = minb = 0;
2016176Sralph 
2116176Sralph 	REGLOOP(i){
2216176Sralph 		busy[i] = 0;
2316176Sralph 		if( rstatus[i] & STAREG ){
2416176Sralph 			if( maxa<0 ) mina = i;
2516176Sralph 			maxa = i;
2616176Sralph 			}
2716176Sralph 		if( rstatus[i] & STBREG ){
2816176Sralph 			if( maxb<0 ) minb = i;
2916176Sralph 			maxb = i;
3016176Sralph 			}
3116176Sralph 		}
3216176Sralph 	}
3316176Sralph # endif
3416176Sralph 
3516176Sralph # ifndef ALLO
allo(p,q)3616176Sralph allo( p, q ) NODE *p; struct optab *q; {
3716176Sralph 
3816176Sralph 	register n, i, j;
3916176Sralph 	int either;
4016176Sralph 
4116176Sralph 	n = q->needs;
4216176Sralph 	either = ( EITHER & n );
4316176Sralph 	i = 0;
4416176Sralph 
4516176Sralph 	while( n & NACOUNT ){
4616176Sralph 		resc[i].in.op = REG;
4729883Ssam 		resc[i].tn.rval = freereg( p, n&(NAMASK|NEVEN) );
4816176Sralph 		resc[i].tn.lval = 0;
4916176Sralph #ifdef FLEXNAMES
5016176Sralph 		resc[i].in.name = "";
5116176Sralph #else
5216176Sralph 		resc[i].in.name[0] = '\0';
5316176Sralph #endif
5429883Ssam 		n &= ~NEVEN;		/* only used for first need */
5516176Sralph 		n -= NAREG;
5616176Sralph 		++i;
5716176Sralph 		}
5816176Sralph 
5916176Sralph 	if (either) { /* all or nothing at all */
6016176Sralph 		for( j = 0; j < i; j++ )
6116176Sralph 			if( resc[j].tn.rval < 0 ) { /* nothing */
6216176Sralph 				i = 0;
6316176Sralph 				break;
6416176Sralph 				}
6516176Sralph 		if( i != 0 ) goto ok; /* all */
6616176Sralph 		}
6716176Sralph 
6816176Sralph 	while( n & NBCOUNT ){
6916176Sralph 		resc[i].in.op = REG;
7016176Sralph 		resc[i].tn.rval = freereg( p, n&NBMASK );
7116176Sralph 		resc[i].tn.lval = 0;
7216176Sralph #ifdef FLEXNAMES
7316176Sralph 		resc[i].in.name = "";
7416176Sralph #else
7516176Sralph 		resc[i].in.name[0] = '\0';
7616176Sralph #endif
7716176Sralph 		n -= NBREG;
7816176Sralph 		++i;
7916176Sralph 		}
8016176Sralph 	if (either) { /* all or nothing at all */
8116176Sralph 		for( j = 0; j < i; j++ )
8216176Sralph 			if( resc[j].tn.rval < 0 ) { /* nothing */
8316176Sralph 				i = 0;
8416176Sralph 				break;
8516176Sralph 				}
8616176Sralph 		if( i != 0 ) goto ok; /* all */
8716176Sralph 		}
8816176Sralph 
8916176Sralph 	if( n & NTMASK ){
9016176Sralph 		resc[i].in.op = OREG;
9116176Sralph 		resc[i].tn.rval = TMPREG;
9216176Sralph 		if( p->in.op == STCALL || p->in.op == STARG || p->in.op == UNARY STCALL || p->in.op == STASG ){
9316176Sralph 			resc[i].tn.lval = freetemp( (SZCHAR*p->stn.stsize + (SZINT-1))/SZINT );
9416176Sralph 			}
9516176Sralph 		else {
9616176Sralph 			resc[i].tn.lval = freetemp( (n&NTMASK)/NTEMP );
9716176Sralph 			}
9816176Sralph #ifdef FLEXNAMES
9916176Sralph 		resc[i].in.name = "";
10016176Sralph #else
10116176Sralph 		resc[i].in.name[0] = '\0';
10216176Sralph #endif
10316176Sralph 
10416176Sralph 		resc[i].tn.lval = BITOOR(resc[i].tn.lval);
10516176Sralph 		++i;
10616176Sralph 		}
10716176Sralph 
10816176Sralph 	/* turn off "temporarily busy" bit */
10916176Sralph 
11016176Sralph 	ok:
11116176Sralph 	REGLOOP(j){
11216176Sralph 		busy[j] &= ~TBUSY;
11316176Sralph 		}
11416176Sralph 
11516176Sralph 	for( j=0; j<i; ++j ) if( resc[j].tn.rval < 0 ) return(0);
11616176Sralph 	return(1);
11716176Sralph 
11816176Sralph 	}
11916176Sralph # endif
12016176Sralph 
12116176Sralph extern unsigned int offsz;
freetemp(k)12216176Sralph freetemp( k ){ /* allocate k integers worth of temp space */
12316176Sralph 	/* we also make the convention that, if the number of words is more than 1,
12416176Sralph 	/* it must be aligned for storing doubles... */
12516176Sralph 
12616176Sralph # ifndef BACKTEMP
12716176Sralph 	int t;
12816176Sralph 
12916176Sralph 	if( k>1 ){
13016176Sralph 		SETOFF( tmpoff, ALDOUBLE );
13116176Sralph 		}
13216176Sralph 
13316176Sralph 	t = tmpoff;
13416176Sralph 	tmpoff += k*SZINT;
13516176Sralph 	if( tmpoff > maxoff ) maxoff = tmpoff;
13616176Sralph 	if( tmpoff >= offsz )
13716176Sralph 		cerror( "stack overflow" );
13816176Sralph 	if( tmpoff-baseoff > maxtemp ) maxtemp = tmpoff-baseoff;
13916176Sralph 	return(t);
14016176Sralph 
14116176Sralph # else
14216176Sralph 	tmpoff += k*SZINT;
14316176Sralph 	if( k>1 ) {
14416176Sralph 		SETOFF( tmpoff, ALDOUBLE );
14516176Sralph 		}
14616176Sralph 	if( tmpoff > maxoff ) maxoff = tmpoff;
14716176Sralph 	if( tmpoff >= offsz )
14816176Sralph 		cerror( "stack overflow" );
14916176Sralph 	if( tmpoff-baseoff > maxtemp ) maxtemp = tmpoff-baseoff;
15016176Sralph 	return( -tmpoff );
15116176Sralph # endif
15216176Sralph 	}
15316176Sralph 
freereg(p,n)15416176Sralph freereg( p, n ) NODE *p; {
15516176Sralph 	/* allocate a register of type n */
15616176Sralph 	/* p gives the type, if floating */
15716176Sralph 
15816176Sralph 	register j;
15916176Sralph 
16016176Sralph 	/* not general; means that only one register (the result) OK for call */
16116176Sralph 	if( callop(p->in.op) ){
16216176Sralph 		j = callreg(p);
16316176Sralph 		if( usable( p, n, j ) ) return( j );
16416176Sralph 		/* have allocated callreg first */
16516176Sralph 		}
16616176Sralph 	j = p->in.rall & ~MUSTDO;
16716176Sralph 	if( j!=NOPREF && usable(p,n,j) ){ /* needed and not allocated */
16816176Sralph 		return( j );
16916176Sralph 		}
17016176Sralph 	if( n&NAMASK ){
17116176Sralph 		for( j=mina; j<=maxa; ++j ) if( rstatus[j]&STAREG ){
17216176Sralph 			if( usable(p,n,j) ){
17316176Sralph 				return( j );
17416176Sralph 				}
17516176Sralph 			}
17616176Sralph 		}
17716176Sralph 	else if( n &NBMASK ){
17816176Sralph 		for( j=minb; j<=maxb; ++j ) if( rstatus[j]&STBREG ){
17916176Sralph 			if( usable(p,n,j) ){
18016176Sralph 				return(j);
18116176Sralph 				}
18216176Sralph 			}
18316176Sralph 		}
18416176Sralph 
18516176Sralph 	return( -1 );
18616176Sralph 	}
18716176Sralph 
18816176Sralph # ifndef USABLE
usable(p,n,r)18916176Sralph usable( p, n, r ) NODE *p; {
19016176Sralph 	/* decide if register r is usable in tree p to satisfy need n */
19116176Sralph 
19216176Sralph 	/* checks, for the moment */
19316176Sralph 	if( !istreg(r) ) cerror( "usable asked about nontemp register" );
19416176Sralph 
195*32790Sdonn 	if( ISBUSY(r) ) return(0);
19616176Sralph 	if( isbreg(r) ){
19716176Sralph 		if( n&NAMASK ) return(0);
19816176Sralph 		}
19916176Sralph 	else {
20016176Sralph 		if( n & NBMASK ) return(0);
20116176Sralph 		}
20217865Sralph 	/*
20325747Sdonn 	 * Some special cases that require register pairs...
20425747Sdonn 	 * Have to check for ==, <=, etc. because the result is type int
20525747Sdonn 	 * but need a register pair temp if either side is wide.
20625747Sdonn 	 * For +=, *= etc. where lhs is narrow and rhs is wide, the temp
20725747Sdonn 	 * register must be wide.
20817865Sralph 	 */
20925747Sdonn 	if( (n&NAMASK) &&
21029883Ssam 	    (szty(p->in.type) == 2 || (n&NEVEN) ||
21125747Sdonn 	     (logop(p->in.op) && (szty(p->in.left->in.type) == 2 ||
21225747Sdonn 	      szty(p->in.right->in.type) == 2)) ||
21325747Sdonn 	     (asgop(p->in.op) && szty(p->in.right->in.type) == 2 &&
21425747Sdonn 	      szty(p->in.left->in.type) == 1))
21525747Sdonn 	){
21616177Sralph #ifndef NOEVENODD
21716176Sralph 		if( r&01 ) return(0);
21816177Sralph #endif
21916176Sralph 		if( !istreg(r+1) ) return( 0 );
22016176Sralph 		if( busy[r+1] > 1 ) return( 0 );
22116176Sralph 		if( busy[r] == 0 && busy[r+1] == 0  ||
222*32790Sdonn 		    (busy[r+1] == 0 || (busy[r] & PBUSY)) &&
223*32790Sdonn 			shareit( p, r, n ) ||
22416176Sralph 		    busy[r] == 0 && shareit( p, r+1, n ) ){
22516176Sralph 			busy[r] |= TBUSY;
22616176Sralph 			busy[r+1] |= TBUSY;
22716176Sralph 			return(1);
22816176Sralph 			}
22916176Sralph 		else return(0);
23016176Sralph 		}
23116176Sralph 	if( busy[r] == 0 ) {
23216176Sralph 		busy[r] |= TBUSY;
23316176Sralph 		return(1);
23416176Sralph 		}
23516176Sralph 
23616176Sralph 	/* busy[r] is 1: is there chance for sharing */
23716176Sralph 	return( shareit( p, r, n ) );
23816176Sralph 
23916176Sralph 	}
24016176Sralph # endif
24116176Sralph 
shareit(p,r,n)24216176Sralph shareit( p, r, n ) NODE *p; {
24316176Sralph 	/* can we make register r available by sharing from p
24416176Sralph 	   given that the need is n */
24516176Sralph 	if( (n&(NASL|NBSL)) && ushare( p, 'L', r ) ) return(1);
24616176Sralph 	if( (n&(NASR|NBSR)) && ushare( p, 'R', r ) ) return(1);
24716176Sralph 	return(0);
24816176Sralph 	}
24916176Sralph 
ushare(p,f,r)25016176Sralph ushare( p, f, r ) NODE *p; {
25116176Sralph 	/* can we find a register r to share on the left or right
25216176Sralph 		(as f=='L' or 'R', respectively) of p */
25316176Sralph 	p = getlr( p, f );
25416176Sralph 	if( p->in.op == UNARY MUL ) p = p->in.left;
25516176Sralph 	if( p->in.op == OREG ){
25616176Sralph 		if( R2TEST(p->tn.rval) ){
25716176Sralph 			return( r==R2UPK1(p->tn.rval) || r==R2UPK2(p->tn.rval) );
25816176Sralph 			}
25916176Sralph 		else return( r == p->tn.rval );
26016176Sralph 		}
26116176Sralph 	if( p->in.op == REG ){
26216176Sralph 		return( r == p->tn.rval || ( szty(p->in.type) == 2 && r==p->tn.rval+1 ) );
26316176Sralph 		}
26416176Sralph 	return(0);
26516176Sralph 	}
26616176Sralph 
recl2(p)26716176Sralph recl2( p ) register NODE *p; {
26816176Sralph 	register r = p->tn.rval;
26916176Sralph #ifndef OLD
27016176Sralph 	int op = p->in.op;
27116176Sralph 	if (op == REG && r >= REGSZ)
27216176Sralph 		op = OREG;
27316176Sralph 	if( op == REG ) rfree( r, p->in.type );
27416176Sralph 	else if( op == OREG ) {
27516176Sralph 		if( R2TEST( r ) ) {
27616176Sralph 			if( R2UPK1( r ) != 100 ) rfree( R2UPK1( r ), PTR+INT );
27716176Sralph 			rfree( R2UPK2( r ), INT );
27816176Sralph 			}
27916176Sralph 		else {
28016176Sralph 			rfree( r, PTR+INT );
28116176Sralph 			}
28216176Sralph 		}
28316176Sralph #else
28416176Sralph 	if( p->in.op == REG ) rfree( r, p->in.type );
28516176Sralph 	else if( p->in.op == OREG ) {
28616176Sralph 		if( R2TEST( r ) ) {
28716176Sralph 			if( R2UPK1( r ) != 100 ) rfree( R2UPK1( r ), PTR+INT );
28816176Sralph 			rfree( R2UPK2( r ), INT );
28916176Sralph 			}
29016176Sralph 		else {
29116176Sralph 			rfree( r, PTR+INT );
29216176Sralph 			}
29316176Sralph 		}
29416176Sralph #endif
29516176Sralph 	}
29616176Sralph 
29716176Sralph int rdebug = 0;
29816176Sralph 
29916176Sralph # ifndef RFREE
rfree(r,t)30016176Sralph rfree( r, t ) TWORD t; {
30116176Sralph 	/* mark register r free, if it is legal to do so */
30216176Sralph 	/* t is the type */
30316176Sralph 
30416176Sralph # ifndef BUG3
30516176Sralph 	if( rdebug ){
30616176Sralph 		printf( "rfree( %s ), size %d\n", rnames[r], szty(t) );
30716176Sralph 		}
30816176Sralph # endif
30916176Sralph 
31016176Sralph 	if( istreg(r) ){
31116176Sralph 		if( --busy[r] < 0 ) cerror( "register overfreed");
312*32790Sdonn 		if( busy[r] == PBUSY )
313*32790Sdonn 			busy[r] = 0;
31416176Sralph 		if( szty(t) == 2 ){
31516177Sralph #ifdef NOEVENODD
31616177Sralph 			if( istreg(r) ^ istreg(r+1) ) cerror( "illegal free" );
31716177Sralph #else
31816176Sralph 			if( (r&01) || (istreg(r)^istreg(r+1)) ) cerror( "illegal free" );
31916177Sralph #endif
32016176Sralph 			if( --busy[r+1] < 0 ) cerror( "register overfreed" );
32116176Sralph 			}
32216176Sralph 		}
32316176Sralph 	}
32416176Sralph # endif
32516176Sralph 
32616176Sralph # ifndef RBUSY
rbusy(r,t)32716176Sralph rbusy(r,t) TWORD t; {
32816176Sralph 	/* mark register r busy */
32916176Sralph 	/* t is the type */
33016176Sralph 
33116176Sralph # ifndef BUG3
33216176Sralph 	if( rdebug ){
33316176Sralph 		printf( "rbusy( %s ), size %d\n", rnames[r], szty(t) );
33416176Sralph 		}
33516176Sralph # endif
33616176Sralph 
33716176Sralph 	if( istreg(r) ) ++busy[r];
33816176Sralph 	if( szty(t) == 2 ){
339*32790Sdonn 		if( istreg(r+1) ) {
340*32790Sdonn 			++busy[r+1];
341*32790Sdonn 			busy[r] |= PBUSY;
342*32790Sdonn 			}
34316177Sralph #ifdef NOEVENODD
34416177Sralph 		if( istreg(r) ^ istreg(r+1) ) cerror( "illegal register pair freed" );
34516177Sralph #else
34616176Sralph 		if( (r&01) || (istreg(r)^istreg(r+1)) ) cerror( "illegal register pair freed" );
34716177Sralph #endif
34816176Sralph 		}
34916176Sralph 	}
35016176Sralph # endif
35116176Sralph 
35216176Sralph # ifndef BUG3
rwprint(rw)35316176Sralph rwprint( rw ){ /* print rewriting rule */
35416176Sralph 	register i, flag;
35516176Sralph 	static char * rwnames[] = {
35616176Sralph 
35716176Sralph 		"RLEFT",
35816176Sralph 		"RRIGHT",
35916176Sralph 		"RESC1",
36016176Sralph 		"RESC2",
36116176Sralph 		"RESC3",
36216176Sralph 		0,
36316176Sralph 		};
36416176Sralph 
36516176Sralph 	if( rw == RNULL ){
36616176Sralph 		printf( "RNULL" );
36716176Sralph 		return;
36816176Sralph 		}
36916176Sralph 
37016176Sralph 	if( rw == RNOP ){
37116176Sralph 		printf( "RNOP" );
37216176Sralph 		return;
37316176Sralph 		}
37416176Sralph 
37516176Sralph 	flag = 0;
37616176Sralph 	for( i=0; rwnames[i]; ++i ){
37716176Sralph 		if( rw & (1<<i) ){
37816176Sralph 			if( flag ) printf( "|" );
37916176Sralph 			++flag;
38016176Sralph 			printf( rwnames[i] );
38116176Sralph 			}
38216176Sralph 		}
38316176Sralph 	}
38416176Sralph # endif
38516176Sralph 
reclaim(p,rw,cookie)38616176Sralph reclaim( p, rw, cookie ) NODE *p; {
38716176Sralph 	register NODE **qq;
38816176Sralph 	register NODE *q;
38916176Sralph 	register i;
39016176Sralph 	NODE *recres[5];
39116176Sralph 	struct respref *r;
39216176Sralph 
39316176Sralph 	/* get back stuff */
39416176Sralph 
39516176Sralph # ifndef BUG3
39616176Sralph 	if( rdebug ){
39716176Sralph 		printf( "reclaim( %o, ", p );
39816176Sralph 		rwprint( rw );
39916176Sralph 		printf( ", " );
40016176Sralph 		prcook( cookie );
40116176Sralph 		printf( " )\n" );
40216176Sralph 		}
40316176Sralph # endif
40416176Sralph 
40516176Sralph 	if( rw == RNOP || ( p->in.op==FREE && rw==RNULL ) ) return;  /* do nothing */
40616176Sralph 
40716176Sralph 	walkf( p, recl2 );
40816176Sralph 
40916176Sralph 	if( callop(p->in.op) ){
41016176Sralph 		/* check that all scratch regs are free */
41116176Sralph 		callchk(p);  /* ordinarily, this is the same as allchk() */
41216176Sralph 		}
41316176Sralph 
41416176Sralph 	if( rw == RNULL || (cookie&FOREFF) ){ /* totally clobber, leaving nothing */
41516176Sralph 		tfree(p);
41616176Sralph 		return;
41716176Sralph 		}
41816176Sralph 
41916176Sralph 	/* handle condition codes specially */
42016176Sralph 
42116176Sralph 	if( (cookie & FORCC) && (rw&RESCC)) {
42216176Sralph 		/* result is CC register */
42316176Sralph 		tfree(p);
42416176Sralph 		p->in.op = CCODES;
42516176Sralph 		p->tn.lval = 0;
42616176Sralph 		p->tn.rval = 0;
42716176Sralph 		return;
42816176Sralph 		}
42916176Sralph 
43016176Sralph 	/* locate results */
43116176Sralph 
43216176Sralph 	qq = recres;
43316176Sralph 
43416176Sralph 	if( rw&RLEFT) *qq++ = getlr( p, 'L' );;
43516176Sralph 	if( rw&RRIGHT ) *qq++ = getlr( p, 'R' );
43616176Sralph 	if( rw&RESC1 ) *qq++ = &resc[0];
43716176Sralph 	if( rw&RESC2 ) *qq++ = &resc[1];
43816176Sralph 	if( rw&RESC3 ) *qq++ = &resc[2];
43916176Sralph 
44016176Sralph 	if( qq == recres ){
44116176Sralph 		cerror( "illegal reclaim");
44216176Sralph 		}
44316176Sralph 
44416176Sralph 	*qq = NIL;
44516176Sralph 
44616176Sralph 	/* now, select the best result, based on the cookie */
44716176Sralph 
44816176Sralph 	for( r=respref; r->cform; ++r ){
44916176Sralph 		if( cookie & r->cform ){
45016176Sralph 			for( qq=recres; (q= *qq) != NIL; ++qq ){
45116176Sralph 				if( tshape( q, r->mform ) ) goto gotit;
45216176Sralph 				}
45316176Sralph 			}
45416176Sralph 		}
45516176Sralph 
45616176Sralph 	/* we can't do it; die */
45716176Sralph 	cerror( "cannot reclaim");
45816176Sralph 
45916176Sralph 	gotit:
46016176Sralph 
46116176Sralph 	if( p->in.op == STARG ) p = p->in.left;  /* STARGs are still STARGS */
46216176Sralph 
46316176Sralph 	q->in.type = p->in.type;  /* to make multi-register allocations work */
46416176Sralph 		/* maybe there is a better way! */
46516176Sralph 	q = tcopy(q);
46616176Sralph 
46716176Sralph 	tfree(p);
46816176Sralph 
46916176Sralph 	p->in.op = q->in.op;
47016176Sralph 	p->tn.lval = q->tn.lval;
47116176Sralph 	p->tn.rval = q->tn.rval;
47216176Sralph #ifdef FLEXNAMES
47316176Sralph 	p->in.name = q->in.name;
47416176Sralph #ifdef ONEPASS
47516176Sralph 	p->in.stalign = q->in.stalign;
47616176Sralph #endif
47716176Sralph #else
47816176Sralph 	for( i=0; i<NCHNAM; ++i )
47916176Sralph 		p->in.name[i] = q->in.name[i];
48016176Sralph #endif
48116176Sralph 
48216176Sralph 	q->in.op = FREE;
48316176Sralph 
48416176Sralph 	/* if the thing is in a register, adjust the type */
48516176Sralph 
48616176Sralph 	switch( p->in.op ){
48716176Sralph 
48816176Sralph 	case REG:
48916176Sralph 		if( !rtyflg ){
49016176Sralph 			/* the C language requires intermediate results to change type */
49116176Sralph 			/* this is inefficient or impossible on some machines */
49216176Sralph 			/* the "T" command in match supresses this type changing */
49316176Sralph 			if( p->in.type == CHAR || p->in.type == SHORT ) p->in.type = INT;
49416176Sralph 			else if( p->in.type == UCHAR || p->in.type == USHORT ) p->in.type = UNSIGNED;
49517743Sralph #if !defined(FORT) && !defined(SPRECC)
49616176Sralph 			else if( p->in.type == FLOAT ) p->in.type = DOUBLE;
49716177Sralph #endif
49816176Sralph 			}
49916176Sralph 		if( ! (p->in.rall & MUSTDO ) ) return;  /* unless necessary, ignore it */
50016176Sralph 		i = p->in.rall & ~MUSTDO;
50116176Sralph 		if( i & NOPREF ) return;
50216176Sralph 		if( i != p->tn.rval ){
50316176Sralph 			if( busy[i] || ( szty(p->in.type)==2 && busy[i+1] ) ){
50416176Sralph 				cerror( "faulty register move" );
50516176Sralph 				}
50616176Sralph 			rbusy( i, p->in.type );
50716176Sralph 			rfree( p->tn.rval, p->in.type );
50816176Sralph 			rmove( i, p->tn.rval, p->in.type );
50916176Sralph 			p->tn.rval = i;
51016176Sralph 			}
51116176Sralph 
51216176Sralph 	case OREG:
51316176Sralph 		if( p->in.op == REG || !R2TEST(p->tn.rval) ) {
514*32790Sdonn 			if( ISBUSY(p->tn.rval) && istreg(p->tn.rval) ) cerror( "potential register overwrite");
51516176Sralph 			}
51616176Sralph 		else
517*32790Sdonn 			if( (R2UPK1(p->tn.rval) != 100 && ISBUSY(R2UPK1(p->tn.rval)) && istreg(R2UPK1(p->tn.rval)) )
518*32790Sdonn 				|| (ISBUSY(R2UPK2(p->tn.rval)) && istreg(R2UPK2(p->tn.rval)) ) )
51916176Sralph 			   cerror( "potential register overwrite");
52016176Sralph 		}
52116176Sralph 
52216176Sralph 	}
52316176Sralph 
52424400Smckusick #ifndef ncopy
ncopy(q,p)52516176Sralph ncopy( q, p ) NODE *p, *q; {
52616176Sralph 	/* copy the contents of p into q, without any feeling for
52716176Sralph 	   the contents */
52816176Sralph 	/* this code assume that copying rval and lval does the job;
52916176Sralph 	   in general, it might be necessary to special case the
53016176Sralph 	   operator types */
53116176Sralph 	register i;
53216176Sralph 
53316176Sralph 	q->in.op = p->in.op;
53416176Sralph 	q->in.rall = p->in.rall;
53516176Sralph 	q->in.type = p->in.type;
53616176Sralph 	q->tn.lval = p->tn.lval;
53716176Sralph 	q->tn.rval = p->tn.rval;
53816176Sralph #ifdef FLEXNAMES
53916176Sralph 	q->in.name = p->in.name;
54016176Sralph #ifdef ONEPASS
54116176Sralph 	q->in.stalign = p->in.stalign;
54216176Sralph #endif
54316176Sralph #else
54416176Sralph 	for( i=0; i<NCHNAM; ++i ) q->in.name[i]  = p->in.name[i];
54516176Sralph #endif
54616176Sralph 
54716176Sralph 	}
54824400Smckusick #endif
54916176Sralph 
55016176Sralph NODE *
tcopy(p)55116176Sralph tcopy( p ) register NODE *p; {
55216176Sralph 	/* make a fresh copy of p */
55316176Sralph 
55416176Sralph 	register NODE *q;
55516176Sralph 	register r;
55616176Sralph 
55716176Sralph 	ncopy( q=talloc(), p );
55816176Sralph 
55916176Sralph 	r = p->tn.rval;
56016176Sralph 	if( p->in.op == REG ) rbusy( r, p->in.type );
56116176Sralph 	else if( p->in.op == OREG ) {
56216176Sralph 		if( R2TEST(r) ){
56316176Sralph 			if( R2UPK1(r) != 100 ) rbusy( R2UPK1(r), PTR+INT );
56416176Sralph 			rbusy( R2UPK2(r), INT );
56516176Sralph 			}
56616176Sralph 		else {
56716176Sralph 			rbusy( r, PTR+INT );
56816176Sralph 			}
56916176Sralph 		}
57016176Sralph 
57116176Sralph 	switch( optype(q->in.op) ){
57216176Sralph 
57316176Sralph 	case BITYPE:
57416176Sralph 		q->in.right = tcopy(p->in.right);
57516176Sralph 	case UTYPE:
57616176Sralph 		q->in.left = tcopy(p->in.left);
57716176Sralph 		}
57816176Sralph 
57916176Sralph 	return(q);
58016176Sralph 	}
58116176Sralph 
allchk()58216176Sralph allchk(){
58316176Sralph 	/* check to ensure that all register are free */
58416176Sralph 
58516176Sralph 	register i;
58616176Sralph 
58716176Sralph 	REGLOOP(i){
58816176Sralph 		if( istreg(i) && busy[i] ){
58916176Sralph 			cerror( "register allocation error");
59016176Sralph 			}
59116176Sralph 		}
59216176Sralph 
59316176Sralph 	}
594