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