1 #ifndef lint 2 static char *sccsid ="@(#)order.c 1.18 (Berkeley) 05/11/88"; 3 #endif lint 4 5 # include "pass2.h" 6 7 int maxargs = { -1 }; 8 9 /*ARGSUSED*/ 10 stoasg( p, o ) NODE *p; { 11 /* should the assignment op p be stored, 12 given that it lies as the right operand of o 13 (or the left, if o==UNARY MUL) */ 14 } 15 16 deltest( p ) register NODE *p; { 17 /* should we delay the INCR or DECR operation p */ 18 p = p->in.left; 19 return( p->in.op == REG || p->in.op == NAME || p->in.op == OREG ); 20 } 21 22 autoincr( p ) NODE *p; { 23 register NODE *q = p->in.left; 24 register TWORD t; 25 26 if( q->in.op != INCR || 27 q->in.left->in.op != REG || 28 !ISPTR(q->in.type) ) 29 return(0); 30 t = q->in.type; 31 q->in.type = DECREF(t); 32 if( tlen(p) != tlen(q) ) { /* side effects okay? */ 33 q->in.type = t; 34 return(0); 35 } 36 q->in.type = t; 37 if( tlen(p) != q->in.right->tn.lval ) 38 return(0); 39 40 return(1); 41 } 42 43 mkadrs(p) register NODE *p; { 44 register int o; 45 46 o = p->in.op; 47 48 if( asgop(o) ){ 49 if( p->in.left->in.su >= p->in.right->in.su ){ 50 if( p->in.left->in.op == UNARY MUL ){ 51 SETSTO( p->in.left->in.left, INTEMP ); 52 } 53 else if( p->in.left->in.op == FLD && p->in.left->in.left->in.op == UNARY MUL ){ 54 SETSTO( p->in.left->in.left->in.left, INTEMP ); 55 } 56 else { /* should be only structure assignment */ 57 SETSTO( p->in.left, INTEMP ); 58 } 59 } 60 else SETSTO( p->in.right, INTEMP ); 61 } 62 else { 63 if( p->in.left->in.su > p->in.right->in.su ){ 64 SETSTO( p->in.left, INTEMP ); 65 } 66 else { 67 SETSTO( p->in.right, INTEMP ); 68 } 69 } 70 } 71 72 /*ARGSUSED*/ 73 notoff( t, r, off, cp) TWORD t; CONSZ off; char *cp; { 74 /* is it legal to make an OREG or NAME entry which has an 75 /* offset of off, (from a register of r), if the 76 /* resulting thing had type t */ 77 78 return(0); /* YES */ 79 } 80 81 # define max(x,y) ((x)<(y)?(y):(x)) 82 83 sucomp( p ) register NODE *p; { 84 85 /* set the su field in the node to the sethi-ullman 86 number, or local equivalent */ 87 88 register int o, ty, sul, sur, r; 89 int szr; 90 NODE *temp; 91 92 o = p->in.op; 93 ty = optype( o ); 94 p->in.su = szty( p->in.type ); /* 2 for double, else 1 */; 95 96 if( ty == LTYPE ){ 97 if( o == OREG ){ 98 r = p->tn.rval; 99 /* oreg cost is (worst case) 1 + number of temp registers used */ 100 if( R2TEST(r) ){ 101 if( R2UPK1(r)!=100 && istreg(R2UPK1(r)) ) ++p->in.su; 102 if( istreg(R2UPK2(r)) ) ++p->in.su; 103 } 104 else { 105 if( istreg( r ) ) ++p->in.su; 106 } 107 } 108 if( p->in.su == szty(p->in.type) && 109 (p->in.op!=REG || !istreg(p->tn.rval)) && 110 (p->in.type==INT || 111 p->in.type==UNSIGNED || 112 #if defined(FORT) || defined(SPRECC) 113 p->in.type==FLOAT || 114 #endif 115 p->in.type==DOUBLE || 116 ISPTR(p->in.type) || 117 ISARY(p->in.type)) ) 118 p->in.su = 0; 119 return; 120 } 121 122 else if( ty == UTYPE ){ 123 switch( o ) { 124 case UNARY CALL: 125 case UNARY STCALL: 126 p->in.su = fregs; /* all regs needed */ 127 return; 128 129 default: 130 p->in.su = p->in.left->in.su + (szty( p->in.type ) > 1 ? 2 : 0) ; 131 return; 132 } 133 } 134 135 136 /* If rhs needs n, lhs needs m, regular su computation */ 137 138 sul = p->in.left->in.su; 139 sur = p->in.right->in.su; 140 szr = szty( p->in.right->in.type ); 141 if( szty( p->in.type ) > szr && szr >= 1 ) { 142 /* implicit conversion in rhs */ 143 szr = szty( p->in.type ); 144 sur = max( szr, sur ); 145 } 146 147 if( o == ASSIGN ){ 148 /* computed by doing right, then left (if not in mem), then doing it */ 149 p->in.su = max(sur,sul+1); 150 return; 151 } 152 153 if( o == CALL || o == STCALL ){ 154 /* in effect, takes all free registers */ 155 p->in.su = fregs; 156 return; 157 } 158 159 if( o == STASG ){ 160 /* right, then left */ 161 p->in.su = max( max( 1+sul, sur), fregs ); 162 return; 163 } 164 165 switch( o ){ 166 case DIV: 167 case ASG DIV: 168 case MOD: 169 case ASG MOD: 170 /* EDIV instructions require reg pairs */ 171 if( p->in.left->in.type == UNSIGNED && 172 p->in.right->in.op == ICON && 173 p->in.right->tn.name[0] == '\0' && 174 (unsigned) p->in.right->tn.lval < 0x80000000 ) { 175 p->in.su = sul + 2; 176 return; 177 } 178 break; 179 } 180 181 if( asgop(o) ){ 182 /* computed by doing right, doing left address, doing left, op, and store */ 183 p->in.su = max(sur,sul+2); 184 return; 185 } 186 187 switch( o ){ 188 case ANDAND: 189 case OROR: 190 case QUEST: 191 case COLON: 192 case COMOP: 193 p->in.su = max( max(sul,sur), 1); 194 return; 195 196 case PLUS: 197 case MUL: 198 case OR: 199 case ER: 200 /* commutative ops; put harder on left */ 201 if( p->in.right->in.su > p->in.left->in.su && !istnode(p->in.left) ){ 202 temp = p->in.left; 203 p->in.left = p->in.right; 204 p->in.right = temp; 205 sul = p->in.left->in.su; 206 sur = p->in.right->in.su; 207 szr = szty( p->in.right->in.type ); 208 if( szty( p->in.type ) > szr && szr >= 1 ) { 209 /* implicit conversion in rhs */ 210 szr = szty( p->in.type ); 211 sur = max( szr, sur ); 212 } 213 } 214 break; 215 } 216 /* binary op, computed by left, then right, then do op */ 217 p->in.su = max(sul,szr+sur); 218 219 } 220 221 int radebug = 0; 222 223 rallo( p, down ) NODE *p; { 224 /* do register allocation */ 225 register int o, down1, down2, ty; 226 227 if( radebug ) printf( "rallo( %o, %d )\n", p, down ); 228 229 down2 = NOPREF; 230 p->in.rall = down; 231 down1 = ( down &= ~MUSTDO ); 232 233 ty = optype( o = p->in.op ); 234 switch( o ) { 235 case ASSIGN: 236 down1 = NOPREF; 237 down2 = down; 238 break; 239 240 case CALL: 241 case STASG: 242 case EQ: 243 case NE: 244 case GT: 245 case GE: 246 case LT: 247 case LE: 248 case NOT: 249 case ANDAND: 250 case OROR: 251 down1 = NOPREF; 252 break; 253 254 case FORCE: 255 down1 = R0|MUSTDO; 256 break; 257 258 } 259 260 if( ty != LTYPE ) rallo( p->in.left, down1 ); 261 if( ty == BITYPE ) rallo( p->in.right, down2 ); 262 263 } 264 265 offstar( p ) register NODE *p; { 266 if( p->in.op == PLUS ) { 267 /* try to create index expressions */ 268 if( p->in.left->in.op==LS && 269 p->in.left->in.left->in.op!=REG && 270 p->in.left->in.right->in.op==ICON && 271 p->in.left->in.right->tn.lval<=3 ){ 272 order( p->in.left->in.left, INTAREG|INAREG ); 273 return; 274 } 275 if( p->in.left->in.su == fregs ) { 276 order( p->in.left, INTAREG|INAREG ); 277 return; 278 } 279 if( p->in.right->in.op==LS && 280 p->in.right->in.left->in.op!=REG && 281 p->in.right->in.right->in.op==ICON && 282 p->in.right->in.right->tn.lval<=3 ){ 283 order( p->in.right->in.left, INTAREG|INAREG ); 284 return; 285 } 286 if( p->in.right->in.su == fregs ) { 287 order( p->in.right, INTAREG|INAREG ); 288 return; 289 } 290 if( p->in.type == (PTR|CHAR) || p->in.type == (PTR|UCHAR) ) { 291 if( p->in.left->in.op!=REG || tlen(p->in.left)!=SZINT/SZCHAR ) { 292 order( p->in.left, INTAREG|INAREG ); 293 return; 294 } 295 else if( p->in.right->in.op!=REG || tlen(p->in.right)!=SZINT/SZCHAR ) { 296 order(p->in.right, INTAREG|INAREG); 297 return; 298 } 299 } 300 } 301 if( p->in.op == PLUS || p->in.op == MINUS ){ 302 if( p->in.right->in.op == ICON ){ 303 p = p->in.left; 304 order( p , INTAREG|INAREG); 305 return; 306 } 307 } 308 309 if( p->in.op == UNARY MUL && !canaddr(p) ) { 310 offstar( p->in.left ); 311 return; 312 } 313 314 order( p, INTAREG|INAREG ); 315 } 316 317 setincr( p ) register NODE *p; { 318 p = p->in.left; 319 if( p->in.op == UNARY MUL ){ 320 offstar( p->in.left ); 321 return( 1 ); 322 } 323 return( 0 ); 324 } 325 326 setbin( p ) register NODE *p; { 327 register int ro, rt; 328 329 rt = p->in.right->in.type; 330 ro = p->in.right->in.op; 331 332 if( canaddr( p->in.left ) && !canaddr( p->in.right ) ) { /* address rhs */ 333 if( ro == UNARY MUL ) { 334 offstar( p->in.right->in.left ); 335 return(1); 336 } else { 337 order( p->in.right, INAREG|INTAREG|SOREG ); 338 return(1); 339 } 340 } 341 if( !istnode( p->in.left) ) { /* try putting LHS into a reg */ 342 order( p->in.left, INAREG|INTAREG|INBREG|INTBREG|SOREG ); 343 return(1); 344 } 345 else if( ro == UNARY MUL && rt != CHAR && rt != UCHAR ){ 346 offstar( p->in.right->in.left ); 347 return(1); 348 } 349 else if( rt == CHAR || rt == UCHAR || rt == SHORT || rt == USHORT || 350 #ifndef SPRECC 351 rt == FLOAT || 352 #endif 353 (ro != REG && ro != NAME && ro != OREG && ro != ICON ) ){ 354 order( p->in.right, INAREG|INBREG ); 355 return(1); 356 } 357 return(0); 358 } 359 360 setstr( p ) register NODE *p; { /* structure assignment */ 361 if( p->in.right->in.op != REG ){ 362 order( p->in.right, INTAREG ); 363 return(1); 364 } 365 p = p->in.left; 366 if( p->in.op != NAME && p->in.op != OREG ){ 367 if( p->in.op != UNARY MUL ) cerror( "bad setstr" ); 368 order( p->in.left, INTAREG ); 369 return( 1 ); 370 } 371 return( 0 ); 372 } 373 374 setasg( p ) register NODE *p; { 375 /* setup for assignment operator */ 376 377 if( !canaddr(p->in.right) ) { 378 if( p->in.right->in.op == UNARY MUL ) 379 offstar(p->in.right->in.left); 380 else 381 order( p->in.right, INAREG|INBREG|SOREG ); 382 return(1); 383 } 384 if( p->in.left->in.op == UNARY MUL ) { 385 offstar( p->in.left->in.left ); 386 return(1); 387 } 388 if( p->in.left->in.op == FLD && p->in.left->in.left->in.op == UNARY MUL ){ 389 offstar( p->in.left->in.left->in.left ); 390 return(1); 391 } 392 /* FLD patch */ 393 if( p->in.left->in.op == FLD && !(p->in.right->in.type==INT || p->in.right->in.type==UNSIGNED)) { 394 order( p->in.right, INAREG); 395 return(1); 396 } 397 /* end of FLD patch */ 398 return(0); 399 } 400 401 setasop( p ) register NODE *p; { 402 /* setup for =ops */ 403 register int rt, ro; 404 405 rt = p->in.right->in.type; 406 ro = p->in.right->in.op; 407 408 if( ro == UNARY MUL && rt != CHAR ){ 409 offstar( p->in.right->in.left ); 410 return(1); 411 } 412 if( rt == CHAR || rt == SHORT || rt == UCHAR || rt == USHORT || 413 #ifndef SPRECC 414 rt == FLOAT || 415 #endif 416 ( ro != REG && ro != ICON && ro != NAME && ro != OREG ) ){ 417 order( p->in.right, INAREG|INBREG ); 418 return(1); 419 } 420 421 422 p = p->in.left; 423 if( p->in.op == FLD ) p = p->in.left; 424 425 switch( p->in.op ){ 426 427 case REG: 428 case ICON: 429 case NAME: 430 case OREG: 431 return(0); 432 433 case UNARY MUL: 434 if( p->in.left->in.op==OREG ) 435 return(0); 436 else 437 offstar( p->in.left ); 438 return(1); 439 440 } 441 cerror( "illegal setasop" ); 442 /*NOTREACHED*/ 443 } 444 445 int crslab = 99999; /* VAX */ 446 447 getlab(){ 448 return( crslab-- ); 449 } 450 451 #ifndef deflab 452 deflab( l ){ 453 printf( "L%d:\n", l ); 454 } 455 #endif 456 457 genargs( p ) register NODE *p; { 458 register NODE *pasg; 459 register int align; 460 register int size; 461 int count; 462 463 /* generate code for the arguments */ 464 465 /* first, do the arguments on the right */ 466 while( p->in.op == CM ){ 467 genargs( p->in.right ); 468 p->in.op = FREE; 469 p = p->in.left; 470 } 471 472 if( p->in.op == STARG ){ /* structure valued argument */ 473 474 size = p->stn.stsize; 475 align = p->stn.stalign; 476 if( p->in.left->in.op == ICON ){ 477 p->in.op = FREE; 478 p = p->in.left; 479 } 480 else { 481 /* make it look beautiful... */ 482 p->in.op = UNARY MUL; 483 canon( p ); /* turn it into an oreg */ 484 for( count = 0; p->in.op != OREG && count < 10; ++count ){ 485 offstar( p->in.left ); 486 canon( p ); 487 } 488 if( p->in.op != OREG ) cerror( "stuck starg" ); 489 } 490 491 pasg = talloc(); 492 pasg->in.op = STARG; 493 pasg->in.rall = NOPREF; 494 pasg->stn.stsize = size; 495 pasg->stn.stalign = align; 496 pasg->in.left = p; 497 498 order( pasg, FORARG ); 499 return; 500 } 501 502 /* ordinary case */ 503 504 order( p, FORARG ); 505 } 506 507 argsize( p ) register NODE *p; { 508 register int t; 509 t = 0; 510 if( p->in.op == CM ){ 511 t = argsize( p->in.left ); 512 p = p->in.right; 513 } 514 if( p->in.type == DOUBLE || p->in.type == FLOAT ){ 515 SETOFF( t, 4 ); 516 return( t+8 ); 517 } 518 else if( p->in.op == STARG ){ 519 SETOFF( t, 4 ); /* alignment */ 520 return( t + ((p->stn.stsize+3)/4)*4 ); /* size */ 521 } 522 else { 523 SETOFF( t, 4 ); 524 return( t+4 ); 525 } 526 } 527