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