1 #ifndef lint 2 static char *sccsid ="@(#)order.c 1.20 (Berkeley) 05/31/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 == ICON || 292 p->in.left->in.op == NAME) && 293 p->in.right->in.op != REG ) { 294 order(p->in.right, INTAREG|INAREG); 295 return; 296 } 297 if( p->in.left->in.op!=REG ) { 298 order( p->in.left, INTAREG|INAREG ); 299 return; 300 } 301 if( p->in.right->in.op!=REG ) { 302 order(p->in.right, INTAREG|INAREG); 303 return; 304 } 305 } 306 } 307 if( p->in.op == PLUS || p->in.op == MINUS ){ 308 if( p->in.right->in.op == ICON ){ 309 p = p->in.left; 310 order( p , INTAREG|INAREG); 311 return; 312 } 313 } 314 315 if( p->in.op == UNARY MUL && !canaddr(p) ) { 316 offstar( p->in.left ); 317 return; 318 } 319 320 order( p, INTAREG|INAREG ); 321 } 322 323 setincr( p ) register NODE *p; { 324 p = p->in.left; 325 if( p->in.op == UNARY MUL ){ 326 offstar( p->in.left ); 327 return( 1 ); 328 } 329 return( 0 ); 330 } 331 332 setbin( p ) register NODE *p; { 333 register int ro, rt; 334 335 rt = p->in.right->in.type; 336 ro = p->in.right->in.op; 337 338 if( canaddr( p->in.left ) && !canaddr( p->in.right ) ) { /* address rhs */ 339 if( ro == UNARY MUL ) { 340 offstar( p->in.right->in.left ); 341 return(1); 342 } else { 343 order( p->in.right, INAREG|INTAREG|SOREG ); 344 return(1); 345 } 346 } 347 if( !istnode( p->in.left) ) { /* try putting LHS into a reg */ 348 order( p->in.left, INAREG|INTAREG|INBREG|INTBREG|SOREG ); 349 return(1); 350 } 351 else if( ro == UNARY MUL && rt != CHAR && rt != UCHAR ){ 352 offstar( p->in.right->in.left ); 353 return(1); 354 } 355 else if( rt == CHAR || rt == UCHAR || rt == SHORT || rt == USHORT || 356 #ifndef SPRECC 357 rt == FLOAT || 358 #endif 359 (ro != REG && ro != NAME && ro != OREG && ro != ICON ) ){ 360 order( p->in.right, INAREG|INBREG ); 361 return(1); 362 } 363 return(0); 364 } 365 366 setstr( p ) register NODE *p; { /* structure assignment */ 367 if( p->in.right->in.op != REG ){ 368 order( p->in.right, INTAREG ); 369 return(1); 370 } 371 p = p->in.left; 372 if( p->in.op != NAME && p->in.op != OREG ){ 373 if( p->in.op != UNARY MUL ) cerror( "bad setstr" ); 374 order( p->in.left, INTAREG ); 375 return( 1 ); 376 } 377 return( 0 ); 378 } 379 380 setasg( p ) register NODE *p; { 381 /* setup for assignment operator */ 382 383 if( !canaddr(p->in.right) ) { 384 if( p->in.right->in.op == UNARY MUL ) 385 offstar(p->in.right->in.left); 386 else 387 order( p->in.right, INAREG|INBREG|SOREG ); 388 return(1); 389 } 390 if( p->in.left->in.op == UNARY MUL ) { 391 offstar( p->in.left->in.left ); 392 return(1); 393 } 394 if( p->in.left->in.op == FLD && p->in.left->in.left->in.op == UNARY MUL ){ 395 offstar( p->in.left->in.left->in.left ); 396 return(1); 397 } 398 /* FLD patch */ 399 if( p->in.left->in.op == FLD && !(p->in.right->in.type==INT || p->in.right->in.type==UNSIGNED)) { 400 order( p->in.right, INAREG); 401 return(1); 402 } 403 /* end of FLD patch */ 404 return(0); 405 } 406 407 setasop( p ) register NODE *p; { 408 /* setup for =ops */ 409 register int rt, ro; 410 411 rt = p->in.right->in.type; 412 ro = p->in.right->in.op; 413 414 if( ro == UNARY MUL && rt != CHAR ){ 415 offstar( p->in.right->in.left ); 416 return(1); 417 } 418 if( rt == CHAR || rt == SHORT || rt == UCHAR || rt == USHORT || 419 #ifndef SPRECC 420 rt == FLOAT || 421 #endif 422 ( ro != REG && ro != ICON && ro != NAME && ro != OREG ) ){ 423 order( p->in.right, INAREG|INBREG ); 424 return(1); 425 } 426 427 428 p = p->in.left; 429 if( p->in.op == FLD ) p = p->in.left; 430 431 switch( p->in.op ){ 432 433 case REG: 434 case ICON: 435 case NAME: 436 case OREG: 437 return(0); 438 439 case UNARY MUL: 440 if( p->in.left->in.op==OREG ) 441 return(0); 442 else 443 offstar( p->in.left ); 444 return(1); 445 446 } 447 cerror( "illegal setasop" ); 448 /*NOTREACHED*/ 449 } 450 451 int crslab = 99999; /* VAX */ 452 453 getlab(){ 454 return( crslab-- ); 455 } 456 457 deflab( l ){ 458 if (nerrors) return; 459 printf( "L%d:\n", l ); 460 } 461 462 genargs( p ) register NODE *p; { 463 register NODE *pasg; 464 register int align; 465 register int size; 466 int count; 467 468 /* generate code for the arguments */ 469 470 /* first, do the arguments on the right */ 471 while( p->in.op == CM ){ 472 genargs( p->in.right ); 473 p->in.op = FREE; 474 p = p->in.left; 475 } 476 477 if( p->in.op == STARG ){ /* structure valued argument */ 478 479 size = p->stn.stsize; 480 align = p->stn.stalign; 481 if( p->in.left->in.op == ICON ){ 482 p->in.op = FREE; 483 p = p->in.left; 484 } 485 else { 486 /* make it look beautiful... */ 487 p->in.op = UNARY MUL; 488 canon( p ); /* turn it into an oreg */ 489 for( count = 0; p->in.op != OREG && count < 10; ++count ){ 490 offstar( p->in.left ); 491 canon( p ); 492 } 493 if( p->in.op != OREG ) cerror( "stuck starg" ); 494 } 495 496 pasg = talloc(); 497 pasg->in.op = STARG; 498 pasg->in.rall = NOPREF; 499 pasg->stn.stsize = size; 500 pasg->stn.stalign = align; 501 pasg->in.left = p; 502 503 order( pasg, FORARG ); 504 return; 505 } 506 507 /* ordinary case */ 508 509 order( p, FORARG ); 510 } 511 512 argsize( p ) register NODE *p; { 513 register int t; 514 t = 0; 515 if( p->in.op == CM ){ 516 t = argsize( p->in.left ); 517 p = p->in.right; 518 } 519 if( p->in.type == DOUBLE || p->in.type == FLOAT ){ 520 SETOFF( t, 4 ); 521 return( t+8 ); 522 } 523 else if( p->in.op == STARG ){ 524 SETOFF( t, 4 ); /* alignment */ 525 return( t + ((p->stn.stsize+3)/4)*4 ); /* size */ 526 } 527 else { 528 SETOFF( t, 4 ); 529 return( t+4 ); 530 } 531 } 532