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