xref: /original-bsd/old/pcc/mip/allo.c (revision 2ed9fee1)
1*2ed9fee1Sralph static char *sccsid ="@(#)allo.c	4.2 (Berkeley) 03/14/84";
2140ba13dSralph # include "mfile2"
3140ba13dSralph 
4140ba13dSralph NODE resc[3];
5140ba13dSralph 
6140ba13dSralph int busy[REGSZ];
7140ba13dSralph 
8140ba13dSralph int maxa, mina, maxb, minb;
9140ba13dSralph 
10140ba13dSralph # ifndef ALLO0
11140ba13dSralph allo0(){ /* free everything */
12140ba13dSralph 
13140ba13dSralph 	register i;
14140ba13dSralph 
15140ba13dSralph 	maxa = maxb = -1;
16140ba13dSralph 	mina = minb = 0;
17140ba13dSralph 
18140ba13dSralph 	REGLOOP(i){
19140ba13dSralph 		busy[i] = 0;
20140ba13dSralph 		if( rstatus[i] & STAREG ){
21140ba13dSralph 			if( maxa<0 ) mina = i;
22140ba13dSralph 			maxa = i;
23140ba13dSralph 			}
24140ba13dSralph 		if( rstatus[i] & STBREG ){
25140ba13dSralph 			if( maxb<0 ) minb = i;
26140ba13dSralph 			maxb = i;
27140ba13dSralph 			}
28140ba13dSralph 		}
29140ba13dSralph 	}
30140ba13dSralph # endif
31140ba13dSralph 
32140ba13dSralph # define TBUSY 01000
33140ba13dSralph 
34140ba13dSralph # ifndef ALLO
35140ba13dSralph allo( p, q ) NODE *p; struct optab *q; {
36140ba13dSralph 
37140ba13dSralph 	register n, i, j;
38140ba13dSralph 	int either;
39140ba13dSralph 
40140ba13dSralph 	n = q->needs;
41140ba13dSralph 	either = ( EITHER & n );
42140ba13dSralph 	i = 0;
43140ba13dSralph 
44140ba13dSralph 	while( n & NACOUNT ){
45140ba13dSralph 		resc[i].in.op = REG;
46140ba13dSralph 		resc[i].tn.rval = freereg( p, n&NAMASK );
47140ba13dSralph 		resc[i].tn.lval = 0;
48140ba13dSralph #ifdef FLEXNAMES
49140ba13dSralph 		resc[i].in.name = "";
50140ba13dSralph #else
51140ba13dSralph 		resc[i].in.name[0] = '\0';
52140ba13dSralph #endif
53140ba13dSralph 		n -= NAREG;
54140ba13dSralph 		++i;
55140ba13dSralph 		}
56140ba13dSralph 
57140ba13dSralph 	if (either) { /* all or nothing at all */
58140ba13dSralph 		for( j = 0; j < i; j++ )
59140ba13dSralph 			if( resc[j].tn.rval < 0 ) { /* nothing */
60140ba13dSralph 				i = 0;
61140ba13dSralph 				break;
62140ba13dSralph 				}
63140ba13dSralph 		if( i != 0 ) goto ok; /* all */
64140ba13dSralph 		}
65140ba13dSralph 
66140ba13dSralph 	while( n & NBCOUNT ){
67140ba13dSralph 		resc[i].in.op = REG;
68140ba13dSralph 		resc[i].tn.rval = freereg( p, n&NBMASK );
69140ba13dSralph 		resc[i].tn.lval = 0;
70140ba13dSralph #ifdef FLEXNAMES
71140ba13dSralph 		resc[i].in.name = "";
72140ba13dSralph #else
73140ba13dSralph 		resc[i].in.name[0] = '\0';
74140ba13dSralph #endif
75140ba13dSralph 		n -= NBREG;
76140ba13dSralph 		++i;
77140ba13dSralph 		}
78140ba13dSralph 	if (either) { /* all or nothing at all */
79140ba13dSralph 		for( j = 0; j < i; j++ )
80140ba13dSralph 			if( resc[j].tn.rval < 0 ) { /* nothing */
81140ba13dSralph 				i = 0;
82140ba13dSralph 				break;
83140ba13dSralph 				}
84140ba13dSralph 		if( i != 0 ) goto ok; /* all */
85140ba13dSralph 		}
86140ba13dSralph 
87140ba13dSralph 	if( n & NTMASK ){
88140ba13dSralph 		resc[i].in.op = OREG;
89140ba13dSralph 		resc[i].tn.rval = TMPREG;
90140ba13dSralph 		if( p->in.op == STCALL || p->in.op == STARG || p->in.op == UNARY STCALL || p->in.op == STASG ){
91140ba13dSralph 			resc[i].tn.lval = freetemp( (SZCHAR*p->stn.stsize + (SZINT-1))/SZINT );
92140ba13dSralph 			}
93140ba13dSralph 		else {
94140ba13dSralph 			resc[i].tn.lval = freetemp( (n&NTMASK)/NTEMP );
95140ba13dSralph 			}
96140ba13dSralph #ifdef FLEXNAMES
97140ba13dSralph 		resc[i].in.name = "";
98140ba13dSralph #else
99140ba13dSralph 		resc[i].in.name[0] = '\0';
100140ba13dSralph #endif
101140ba13dSralph 
102140ba13dSralph 		resc[i].tn.lval = BITOOR(resc[i].tn.lval);
103140ba13dSralph 		++i;
104140ba13dSralph 		}
105140ba13dSralph 
106140ba13dSralph 	/* turn off "temporarily busy" bit */
107140ba13dSralph 
108140ba13dSralph 	ok:
109140ba13dSralph 	REGLOOP(j){
110140ba13dSralph 		busy[j] &= ~TBUSY;
111140ba13dSralph 		}
112140ba13dSralph 
113140ba13dSralph 	for( j=0; j<i; ++j ) if( resc[j].tn.rval < 0 ) return(0);
114140ba13dSralph 	return(1);
115140ba13dSralph 
116140ba13dSralph 	}
117140ba13dSralph # endif
118140ba13dSralph 
119140ba13dSralph extern unsigned int offsz;
120140ba13dSralph freetemp( k ){ /* allocate k integers worth of temp space */
121140ba13dSralph 	/* we also make the convention that, if the number of words is more than 1,
122140ba13dSralph 	/* it must be aligned for storing doubles... */
123140ba13dSralph 
124140ba13dSralph # ifndef BACKTEMP
125140ba13dSralph 	int t;
126140ba13dSralph 
127140ba13dSralph 	if( k>1 ){
128140ba13dSralph 		SETOFF( tmpoff, ALDOUBLE );
129140ba13dSralph 		}
130140ba13dSralph 
131140ba13dSralph 	t = tmpoff;
132140ba13dSralph 	tmpoff += k*SZINT;
133140ba13dSralph 	if( tmpoff > maxoff ) maxoff = tmpoff;
134140ba13dSralph 	if( tmpoff >= offsz )
135140ba13dSralph 		cerror( "stack overflow" );
136140ba13dSralph 	if( tmpoff-baseoff > maxtemp ) maxtemp = tmpoff-baseoff;
137140ba13dSralph 	return(t);
138140ba13dSralph 
139140ba13dSralph # else
140140ba13dSralph 	tmpoff += k*SZINT;
141140ba13dSralph 	if( k>1 ) {
142140ba13dSralph 		SETOFF( tmpoff, ALDOUBLE );
143140ba13dSralph 		}
144140ba13dSralph 	if( tmpoff > maxoff ) maxoff = tmpoff;
145140ba13dSralph 	if( tmpoff >= offsz )
146140ba13dSralph 		cerror( "stack overflow" );
147140ba13dSralph 	if( tmpoff-baseoff > maxtemp ) maxtemp = tmpoff-baseoff;
148140ba13dSralph 	return( -tmpoff );
149140ba13dSralph # endif
150140ba13dSralph 	}
151140ba13dSralph 
152140ba13dSralph freereg( p, n ) NODE *p; {
153140ba13dSralph 	/* allocate a register of type n */
154140ba13dSralph 	/* p gives the type, if floating */
155140ba13dSralph 
156140ba13dSralph 	register j;
157140ba13dSralph 
158140ba13dSralph 	/* not general; means that only one register (the result) OK for call */
159140ba13dSralph 	if( callop(p->in.op) ){
160140ba13dSralph 		j = callreg(p);
161140ba13dSralph 		if( usable( p, n, j ) ) return( j );
162140ba13dSralph 		/* have allocated callreg first */
163140ba13dSralph 		}
164140ba13dSralph 	j = p->in.rall & ~MUSTDO;
165140ba13dSralph 	if( j!=NOPREF && usable(p,n,j) ){ /* needed and not allocated */
166140ba13dSralph 		return( j );
167140ba13dSralph 		}
168140ba13dSralph 	if( n&NAMASK ){
169140ba13dSralph 		for( j=mina; j<=maxa; ++j ) if( rstatus[j]&STAREG ){
170140ba13dSralph 			if( usable(p,n,j) ){
171140ba13dSralph 				return( j );
172140ba13dSralph 				}
173140ba13dSralph 			}
174140ba13dSralph 		}
175140ba13dSralph 	else if( n &NBMASK ){
176140ba13dSralph 		for( j=minb; j<=maxb; ++j ) if( rstatus[j]&STBREG ){
177140ba13dSralph 			if( usable(p,n,j) ){
178140ba13dSralph 				return(j);
179140ba13dSralph 				}
180140ba13dSralph 			}
181140ba13dSralph 		}
182140ba13dSralph 
183140ba13dSralph 	return( -1 );
184140ba13dSralph 	}
185140ba13dSralph 
186140ba13dSralph # ifndef USABLE
187140ba13dSralph usable( p, n, r ) NODE *p; {
188140ba13dSralph 	/* decide if register r is usable in tree p to satisfy need n */
189140ba13dSralph 
190140ba13dSralph 	/* checks, for the moment */
191140ba13dSralph 	if( !istreg(r) ) cerror( "usable asked about nontemp register" );
192140ba13dSralph 
193140ba13dSralph 	if( busy[r] > 1 ) return(0);
194140ba13dSralph 	if( isbreg(r) ){
195140ba13dSralph 		if( n&NAMASK ) return(0);
196140ba13dSralph 		}
197140ba13dSralph 	else {
198140ba13dSralph 		if( n & NBMASK ) return(0);
199140ba13dSralph 		}
200140ba13dSralph 	if( (n&NAMASK) && (szty(p->in.type) == 2) ){ /* only do the pairing for real regs */
201*2ed9fee1Sralph #ifndef NOEVENODD
202140ba13dSralph 		if( r&01 ) return(0);
203*2ed9fee1Sralph #endif
204140ba13dSralph 		if( !istreg(r+1) ) return( 0 );
205140ba13dSralph 		if( busy[r+1] > 1 ) return( 0 );
206140ba13dSralph 		if( busy[r] == 0 && busy[r+1] == 0  ||
207140ba13dSralph 		    busy[r+1] == 0 && shareit( p, r, n ) ||
208140ba13dSralph 		    busy[r] == 0 && shareit( p, r+1, n ) ){
209140ba13dSralph 			busy[r] |= TBUSY;
210140ba13dSralph 			busy[r+1] |= TBUSY;
211140ba13dSralph 			return(1);
212140ba13dSralph 			}
213140ba13dSralph 		else return(0);
214140ba13dSralph 		}
215140ba13dSralph 	if( busy[r] == 0 ) {
216140ba13dSralph 		busy[r] |= TBUSY;
217140ba13dSralph 		return(1);
218140ba13dSralph 		}
219140ba13dSralph 
220140ba13dSralph 	/* busy[r] is 1: is there chance for sharing */
221140ba13dSralph 	return( shareit( p, r, n ) );
222140ba13dSralph 
223140ba13dSralph 	}
224140ba13dSralph # endif
225140ba13dSralph 
226140ba13dSralph shareit( p, r, n ) NODE *p; {
227140ba13dSralph 	/* can we make register r available by sharing from p
228140ba13dSralph 	   given that the need is n */
229140ba13dSralph 	if( (n&(NASL|NBSL)) && ushare( p, 'L', r ) ) return(1);
230140ba13dSralph 	if( (n&(NASR|NBSR)) && ushare( p, 'R', r ) ) return(1);
231140ba13dSralph 	return(0);
232140ba13dSralph 	}
233140ba13dSralph 
234140ba13dSralph ushare( p, f, r ) NODE *p; {
235140ba13dSralph 	/* can we find a register r to share on the left or right
236140ba13dSralph 		(as f=='L' or 'R', respectively) of p */
237140ba13dSralph 	p = getlr( p, f );
238140ba13dSralph 	if( p->in.op == UNARY MUL ) p = p->in.left;
239140ba13dSralph 	if( p->in.op == OREG ){
240140ba13dSralph 		if( R2TEST(p->tn.rval) ){
241140ba13dSralph 			return( r==R2UPK1(p->tn.rval) || r==R2UPK2(p->tn.rval) );
242140ba13dSralph 			}
243140ba13dSralph 		else return( r == p->tn.rval );
244140ba13dSralph 		}
245140ba13dSralph 	if( p->in.op == REG ){
246140ba13dSralph 		return( r == p->tn.rval || ( szty(p->in.type) == 2 && r==p->tn.rval+1 ) );
247140ba13dSralph 		}
248140ba13dSralph 	return(0);
249140ba13dSralph 	}
250140ba13dSralph 
251140ba13dSralph recl2( p ) register NODE *p; {
252140ba13dSralph 	register r = p->tn.rval;
253140ba13dSralph #ifndef OLD
254140ba13dSralph 	int op = p->in.op;
255140ba13dSralph 	if (op == REG && r >= REGSZ)
256140ba13dSralph 		op = OREG;
257140ba13dSralph 	if( op == REG ) rfree( r, p->in.type );
258140ba13dSralph 	else if( op == OREG ) {
259140ba13dSralph 		if( R2TEST( r ) ) {
260140ba13dSralph 			if( R2UPK1( r ) != 100 ) rfree( R2UPK1( r ), PTR+INT );
261140ba13dSralph 			rfree( R2UPK2( r ), INT );
262140ba13dSralph 			}
263140ba13dSralph 		else {
264140ba13dSralph 			rfree( r, PTR+INT );
265140ba13dSralph 			}
266140ba13dSralph 		}
267140ba13dSralph #else
268140ba13dSralph 	if( p->in.op == REG ) rfree( r, p->in.type );
269140ba13dSralph 	else if( p->in.op == OREG ) {
270140ba13dSralph 		if( R2TEST( r ) ) {
271140ba13dSralph 			if( R2UPK1( r ) != 100 ) rfree( R2UPK1( r ), PTR+INT );
272140ba13dSralph 			rfree( R2UPK2( r ), INT );
273140ba13dSralph 			}
274140ba13dSralph 		else {
275140ba13dSralph 			rfree( r, PTR+INT );
276140ba13dSralph 			}
277140ba13dSralph 		}
278140ba13dSralph #endif
279140ba13dSralph 	}
280140ba13dSralph 
281140ba13dSralph int rdebug = 0;
282140ba13dSralph 
283140ba13dSralph # ifndef RFREE
284140ba13dSralph rfree( r, t ) TWORD t; {
285140ba13dSralph 	/* mark register r free, if it is legal to do so */
286140ba13dSralph 	/* t is the type */
287140ba13dSralph 
288140ba13dSralph # ifndef BUG3
289140ba13dSralph 	if( rdebug ){
290140ba13dSralph 		printf( "rfree( %s ), size %d\n", rnames[r], szty(t) );
291140ba13dSralph 		}
292140ba13dSralph # endif
293140ba13dSralph 
294140ba13dSralph 	if( istreg(r) ){
295140ba13dSralph 		if( --busy[r] < 0 ) cerror( "register overfreed");
296140ba13dSralph 		if( szty(t) == 2 ){
297*2ed9fee1Sralph #ifdef NOEVENODD
298*2ed9fee1Sralph 			if( istreg(r) ^ istreg(r+1) ) cerror( "illegal free" );
299*2ed9fee1Sralph #else
300140ba13dSralph 			if( (r&01) || (istreg(r)^istreg(r+1)) ) cerror( "illegal free" );
301*2ed9fee1Sralph #endif
302140ba13dSralph 			if( --busy[r+1] < 0 ) cerror( "register overfreed" );
303140ba13dSralph 			}
304140ba13dSralph 		}
305140ba13dSralph 	}
306140ba13dSralph # endif
307140ba13dSralph 
308140ba13dSralph # ifndef RBUSY
309140ba13dSralph rbusy(r,t) TWORD t; {
310140ba13dSralph 	/* mark register r busy */
311140ba13dSralph 	/* t is the type */
312140ba13dSralph 
313140ba13dSralph # ifndef BUG3
314140ba13dSralph 	if( rdebug ){
315140ba13dSralph 		printf( "rbusy( %s ), size %d\n", rnames[r], szty(t) );
316140ba13dSralph 		}
317140ba13dSralph # endif
318140ba13dSralph 
319140ba13dSralph 	if( istreg(r) ) ++busy[r];
320140ba13dSralph 	if( szty(t) == 2 ){
321140ba13dSralph 		if( istreg(r+1) ) ++busy[r+1];
322*2ed9fee1Sralph #ifdef NOEVENODD
323*2ed9fee1Sralph 		if( istreg(r) ^ istreg(r+1) ) cerror( "illegal register pair freed" );
324*2ed9fee1Sralph #else
325140ba13dSralph 		if( (r&01) || (istreg(r)^istreg(r+1)) ) cerror( "illegal register pair freed" );
326*2ed9fee1Sralph #endif
327140ba13dSralph 		}
328140ba13dSralph 	}
329140ba13dSralph # endif
330140ba13dSralph 
331140ba13dSralph # ifndef BUG3
332140ba13dSralph rwprint( rw ){ /* print rewriting rule */
333140ba13dSralph 	register i, flag;
334140ba13dSralph 	static char * rwnames[] = {
335140ba13dSralph 
336140ba13dSralph 		"RLEFT",
337140ba13dSralph 		"RRIGHT",
338140ba13dSralph 		"RESC1",
339140ba13dSralph 		"RESC2",
340140ba13dSralph 		"RESC3",
341140ba13dSralph 		0,
342140ba13dSralph 		};
343140ba13dSralph 
344140ba13dSralph 	if( rw == RNULL ){
345140ba13dSralph 		printf( "RNULL" );
346140ba13dSralph 		return;
347140ba13dSralph 		}
348140ba13dSralph 
349140ba13dSralph 	if( rw == RNOP ){
350140ba13dSralph 		printf( "RNOP" );
351140ba13dSralph 		return;
352140ba13dSralph 		}
353140ba13dSralph 
354140ba13dSralph 	flag = 0;
355140ba13dSralph 	for( i=0; rwnames[i]; ++i ){
356140ba13dSralph 		if( rw & (1<<i) ){
357140ba13dSralph 			if( flag ) printf( "|" );
358140ba13dSralph 			++flag;
359140ba13dSralph 			printf( rwnames[i] );
360140ba13dSralph 			}
361140ba13dSralph 		}
362140ba13dSralph 	}
363140ba13dSralph # endif
364140ba13dSralph 
365140ba13dSralph reclaim( p, rw, cookie ) NODE *p; {
366140ba13dSralph 	register NODE **qq;
367140ba13dSralph 	register NODE *q;
368140ba13dSralph 	register i;
369140ba13dSralph 	NODE *recres[5];
370140ba13dSralph 	struct respref *r;
371140ba13dSralph 
372140ba13dSralph 	/* get back stuff */
373140ba13dSralph 
374140ba13dSralph # ifndef BUG3
375140ba13dSralph 	if( rdebug ){
376140ba13dSralph 		printf( "reclaim( %o, ", p );
377140ba13dSralph 		rwprint( rw );
378140ba13dSralph 		printf( ", " );
379140ba13dSralph 		prcook( cookie );
380140ba13dSralph 		printf( " )\n" );
381140ba13dSralph 		}
382140ba13dSralph # endif
383140ba13dSralph 
384140ba13dSralph 	if( rw == RNOP || ( p->in.op==FREE && rw==RNULL ) ) return;  /* do nothing */
385140ba13dSralph 
386140ba13dSralph 	walkf( p, recl2 );
387140ba13dSralph 
388140ba13dSralph 	if( callop(p->in.op) ){
389140ba13dSralph 		/* check that all scratch regs are free */
390140ba13dSralph 		callchk(p);  /* ordinarily, this is the same as allchk() */
391140ba13dSralph 		}
392140ba13dSralph 
393140ba13dSralph 	if( rw == RNULL || (cookie&FOREFF) ){ /* totally clobber, leaving nothing */
394140ba13dSralph 		tfree(p);
395140ba13dSralph 		return;
396140ba13dSralph 		}
397140ba13dSralph 
398140ba13dSralph 	/* handle condition codes specially */
399140ba13dSralph 
400140ba13dSralph 	if( (cookie & FORCC) && (rw&RESCC)) {
401140ba13dSralph 		/* result is CC register */
402140ba13dSralph 		tfree(p);
403140ba13dSralph 		p->in.op = CCODES;
404140ba13dSralph 		p->tn.lval = 0;
405140ba13dSralph 		p->tn.rval = 0;
406140ba13dSralph 		return;
407140ba13dSralph 		}
408140ba13dSralph 
409140ba13dSralph 	/* locate results */
410140ba13dSralph 
411140ba13dSralph 	qq = recres;
412140ba13dSralph 
413140ba13dSralph 	if( rw&RLEFT) *qq++ = getlr( p, 'L' );;
414140ba13dSralph 	if( rw&RRIGHT ) *qq++ = getlr( p, 'R' );
415140ba13dSralph 	if( rw&RESC1 ) *qq++ = &resc[0];
416140ba13dSralph 	if( rw&RESC2 ) *qq++ = &resc[1];
417140ba13dSralph 	if( rw&RESC3 ) *qq++ = &resc[2];
418140ba13dSralph 
419140ba13dSralph 	if( qq == recres ){
420140ba13dSralph 		cerror( "illegal reclaim");
421140ba13dSralph 		}
422140ba13dSralph 
423140ba13dSralph 	*qq = NIL;
424140ba13dSralph 
425140ba13dSralph 	/* now, select the best result, based on the cookie */
426140ba13dSralph 
427140ba13dSralph 	for( r=respref; r->cform; ++r ){
428140ba13dSralph 		if( cookie & r->cform ){
429140ba13dSralph 			for( qq=recres; (q= *qq) != NIL; ++qq ){
430140ba13dSralph 				if( tshape( q, r->mform ) ) goto gotit;
431140ba13dSralph 				}
432140ba13dSralph 			}
433140ba13dSralph 		}
434140ba13dSralph 
435140ba13dSralph 	/* we can't do it; die */
436140ba13dSralph 	cerror( "cannot reclaim");
437140ba13dSralph 
438140ba13dSralph 	gotit:
439140ba13dSralph 
440140ba13dSralph 	if( p->in.op == STARG ) p = p->in.left;  /* STARGs are still STARGS */
441140ba13dSralph 
442140ba13dSralph 	q->in.type = p->in.type;  /* to make multi-register allocations work */
443140ba13dSralph 		/* maybe there is a better way! */
444140ba13dSralph 	q = tcopy(q);
445140ba13dSralph 
446140ba13dSralph 	tfree(p);
447140ba13dSralph 
448140ba13dSralph 	p->in.op = q->in.op;
449140ba13dSralph 	p->tn.lval = q->tn.lval;
450140ba13dSralph 	p->tn.rval = q->tn.rval;
451140ba13dSralph #ifdef FLEXNAMES
452140ba13dSralph 	p->in.name = q->in.name;
453140ba13dSralph #ifdef ONEPASS
454140ba13dSralph 	p->in.stalign = q->in.stalign;
455140ba13dSralph #endif
456140ba13dSralph #else
457140ba13dSralph 	for( i=0; i<NCHNAM; ++i )
458140ba13dSralph 		p->in.name[i] = q->in.name[i];
459140ba13dSralph #endif
460140ba13dSralph 
461140ba13dSralph 	q->in.op = FREE;
462140ba13dSralph 
463140ba13dSralph 	/* if the thing is in a register, adjust the type */
464140ba13dSralph 
465140ba13dSralph 	switch( p->in.op ){
466140ba13dSralph 
467140ba13dSralph 	case REG:
468140ba13dSralph 		if( !rtyflg ){
469140ba13dSralph 			/* the C language requires intermediate results to change type */
470140ba13dSralph 			/* this is inefficient or impossible on some machines */
471140ba13dSralph 			/* the "T" command in match supresses this type changing */
472140ba13dSralph 			if( p->in.type == CHAR || p->in.type == SHORT ) p->in.type = INT;
473140ba13dSralph 			else if( p->in.type == UCHAR || p->in.type == USHORT ) p->in.type = UNSIGNED;
474*2ed9fee1Sralph #ifndef FORT
475140ba13dSralph 			else if( p->in.type == FLOAT ) p->in.type = DOUBLE;
476*2ed9fee1Sralph #endif
477140ba13dSralph 			}
478140ba13dSralph 		if( ! (p->in.rall & MUSTDO ) ) return;  /* unless necessary, ignore it */
479140ba13dSralph 		i = p->in.rall & ~MUSTDO;
480140ba13dSralph 		if( i & NOPREF ) return;
481140ba13dSralph 		if( i != p->tn.rval ){
482140ba13dSralph 			if( busy[i] || ( szty(p->in.type)==2 && busy[i+1] ) ){
483140ba13dSralph 				cerror( "faulty register move" );
484140ba13dSralph 				}
485140ba13dSralph 			rbusy( i, p->in.type );
486140ba13dSralph 			rfree( p->tn.rval, p->in.type );
487140ba13dSralph 			rmove( i, p->tn.rval, p->in.type );
488140ba13dSralph 			p->tn.rval = i;
489140ba13dSralph 			}
490140ba13dSralph 
491140ba13dSralph 	case OREG:
492140ba13dSralph 		if( p->in.op == REG || !R2TEST(p->tn.rval) ) {
493140ba13dSralph 			if( busy[p->tn.rval]>1 && istreg(p->tn.rval) ) cerror( "potential register overwrite");
494140ba13dSralph 			}
495140ba13dSralph 		else
496140ba13dSralph 			if( (R2UPK1(p->tn.rval) != 100 && busy[R2UPK1(p->tn.rval)]>1 && istreg(R2UPK1(p->tn.rval)) )
497140ba13dSralph 				|| (busy[R2UPK2(p->tn.rval)]>1 && istreg(R2UPK2(p->tn.rval)) ) )
498140ba13dSralph 			   cerror( "potential register overwrite");
499140ba13dSralph 		}
500140ba13dSralph 
501140ba13dSralph 	}
502140ba13dSralph 
503140ba13dSralph ncopy( q, p ) NODE *p, *q; {
504140ba13dSralph 	/* copy the contents of p into q, without any feeling for
505140ba13dSralph 	   the contents */
506140ba13dSralph 	/* this code assume that copying rval and lval does the job;
507140ba13dSralph 	   in general, it might be necessary to special case the
508140ba13dSralph 	   operator types */
509140ba13dSralph 	register i;
510140ba13dSralph 
511140ba13dSralph 	q->in.op = p->in.op;
512140ba13dSralph 	q->in.rall = p->in.rall;
513140ba13dSralph 	q->in.type = p->in.type;
514140ba13dSralph 	q->tn.lval = p->tn.lval;
515140ba13dSralph 	q->tn.rval = p->tn.rval;
516140ba13dSralph #ifdef FLEXNAMES
517140ba13dSralph 	q->in.name = p->in.name;
518140ba13dSralph #ifdef ONEPASS
519140ba13dSralph 	q->in.stalign = p->in.stalign;
520140ba13dSralph #endif
521140ba13dSralph #else
522140ba13dSralph 	for( i=0; i<NCHNAM; ++i ) q->in.name[i]  = p->in.name[i];
523140ba13dSralph #endif
524140ba13dSralph 
525140ba13dSralph 	}
526140ba13dSralph 
527140ba13dSralph NODE *
528140ba13dSralph tcopy( p ) register NODE *p; {
529140ba13dSralph 	/* make a fresh copy of p */
530140ba13dSralph 
531140ba13dSralph 	register NODE *q;
532140ba13dSralph 	register r;
533140ba13dSralph 
534140ba13dSralph 	ncopy( q=talloc(), p );
535140ba13dSralph 
536140ba13dSralph 	r = p->tn.rval;
537140ba13dSralph 	if( p->in.op == REG ) rbusy( r, p->in.type );
538140ba13dSralph 	else if( p->in.op == OREG ) {
539140ba13dSralph 		if( R2TEST(r) ){
540140ba13dSralph 			if( R2UPK1(r) != 100 ) rbusy( R2UPK1(r), PTR+INT );
541140ba13dSralph 			rbusy( R2UPK2(r), INT );
542140ba13dSralph 			}
543140ba13dSralph 		else {
544140ba13dSralph 			rbusy( r, PTR+INT );
545140ba13dSralph 			}
546140ba13dSralph 		}
547140ba13dSralph 
548140ba13dSralph 	switch( optype(q->in.op) ){
549140ba13dSralph 
550140ba13dSralph 	case BITYPE:
551140ba13dSralph 		q->in.right = tcopy(p->in.right);
552140ba13dSralph 	case UTYPE:
553140ba13dSralph 		q->in.left = tcopy(p->in.left);
554140ba13dSralph 		}
555140ba13dSralph 
556140ba13dSralph 	return(q);
557140ba13dSralph 	}
558140ba13dSralph 
559140ba13dSralph allchk(){
560140ba13dSralph 	/* check to ensure that all register are free */
561140ba13dSralph 
562140ba13dSralph 	register i;
563140ba13dSralph 
564140ba13dSralph 	REGLOOP(i){
565140ba13dSralph 		if( istreg(i) && busy[i] ){
566140ba13dSralph 			cerror( "register allocation error");
567140ba13dSralph 			}
568140ba13dSralph 		}
569140ba13dSralph 
570140ba13dSralph 	}
571