1 static char *sccsid ="@(#)local2.c 1.1 (Berkeley) 12/15/82"; 2 # include "mfile2" 3 # include "ctype.h" 4 # ifdef FORT 5 int ftlab1, ftlab2; 6 # endif 7 /* a lot of the machine dependent parts of the second pass */ 8 9 # define BITMASK(n) ((1L<<n)-1) 10 11 where(c){ 12 fprintf( stderr, "%s, line %d: ", filename, lineno ); 13 } 14 15 lineid( l, fn ) char *fn; { 16 /* identify line l and file fn */ 17 printf( "# line %d, file %s\n", l, fn ); 18 } 19 20 21 eobl2(){ 22 OFFSZ spoff; /* offset from stack pointer */ 23 #ifdef FORT 24 spoff = maxoff; 25 if( spoff >= AUTOINIT ) spoff -= AUTOINIT; 26 spoff /= SZCHAR; 27 SETOFF(spoff,4); 28 #ifndef FLEXNAMES 29 printf( " .set .F%d,%ld\n", ftnno, spoff ); 30 #else 31 /* SHOULD BE L%d ... ftnno but must change pc/f77 */ 32 printf( " .set LF%d,%ld\n", ftnno, spoff ); 33 #endif 34 #else 35 extern int ftlab1, ftlab2; 36 37 spoff = maxoff; 38 if( spoff >= AUTOINIT ) spoff -= AUTOINIT; 39 spoff /= SZCHAR; 40 SETOFF(spoff,4); 41 printf( "L%d:\n", ftlab1); 42 if( spoff!=0 ) 43 if( spoff < 64 ) 44 printf( " subl2 $%ld,sp\n", spoff); 45 else 46 printf( " movab -%ld(sp),sp\n", spoff); 47 printf( " jbr L%d\n", ftlab2); 48 #endif 49 maxargs = -1; 50 } 51 52 struct hoptab { int opmask; char * opstring; } ioptab[] = { 53 54 ASG PLUS, "add", 55 ASG MINUS, "sub", 56 ASG MUL, "mul", 57 ASG DIV, "div", 58 ASG OR, "bis", 59 ASG ER, "xor", 60 ASG AND, "bic", 61 PLUS, "add", 62 MINUS, "sub", 63 MUL, "mul", 64 DIV, "div", 65 OR, "bis", 66 ER, "xor", 67 AND, "bic", 68 -1, "" }; 69 70 hopcode( f, o ){ 71 /* output the appropriate string from the above table */ 72 73 register struct hoptab *q; 74 75 for( q = ioptab; q->opmask>=0; ++q ){ 76 if( q->opmask == o ){ 77 printf( "%s", q->opstring ); 78 /* tbl 79 if( f == 'F' ) printf( "e" ); 80 else if( f == 'D' ) printf( "d" ); 81 tbl */ 82 /* tbl */ 83 switch( f ) { 84 case 'L': 85 case 'W': 86 case 'B': 87 case 'D': 88 case 'F': 89 printf("%c", tolower(f)); 90 break; 91 92 } 93 /* tbl */ 94 return; 95 } 96 } 97 cerror( "no hoptab for %s", opst[o] ); 98 } 99 100 char * 101 rnames[] = { /* keyed to register number tokens */ 102 103 "r0", "r1", 104 "r2", "r3", "r4", "r5", 105 "r6", "r7", "r8", "r9", "r10", "r11", 106 "ap", "fp", "sp", "pc", 107 108 }; 109 110 int rstatus[] = { 111 SAREG|STAREG, SAREG|STAREG, 112 SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, SAREG|STAREG, 113 SAREG, SAREG, SAREG, SAREG, SAREG, SAREG, 114 SAREG, SAREG, SAREG, SAREG, 115 116 }; 117 118 tlen(p) NODE *p; 119 { 120 switch(p->in.type) { 121 case CHAR: 122 case UCHAR: 123 return(1); 124 125 case SHORT: 126 case USHORT: 127 return(2); 128 129 case DOUBLE: 130 return(8); 131 132 default: 133 return(4); 134 } 135 } 136 137 mixtypes(p, q) NODE *p, *q; 138 { 139 register tp, tq; 140 141 tp = p->in.type; 142 tq = q->in.type; 143 144 return( (tp==FLOAT || tp==DOUBLE) != 145 (tq==FLOAT || tq==DOUBLE) ); 146 } 147 148 prtype(n) NODE *n; 149 { 150 switch (n->in.type) 151 { 152 case DOUBLE: 153 printf("d"); 154 return; 155 156 case FLOAT: 157 printf("f"); 158 return; 159 160 case LONG: 161 case ULONG: 162 case INT: 163 case UNSIGNED: 164 printf("l"); 165 return; 166 167 case SHORT: 168 case USHORT: 169 printf("w"); 170 return; 171 172 case CHAR: 173 case UCHAR: 174 printf("b"); 175 return; 176 177 default: 178 if ( !ISPTR( n->in.type ) ) cerror("zzzcode- bad type"); 179 else { 180 printf("l"); 181 return; 182 } 183 } 184 } 185 186 zzzcode( p, c ) register NODE *p; { 187 register m; 188 CONSZ val; 189 switch( c ){ 190 191 case 'N': /* logical ops, turned into 0-1 */ 192 /* use register given by register 1 */ 193 cbgen( 0, m=getlab(), 'I' ); 194 deflab( p->bn.label ); 195 printf( " clrl %s\n", rnames[getlr( p, '1' )->tn.rval] ); 196 deflab( m ); 197 return; 198 199 case 'I': 200 case 'P': 201 cbgen( p->in.op, p->bn.label, c ); 202 return; 203 204 case 'A': 205 { 206 register NODE *l, *r; 207 208 if (xdebug) eprint(p, 0, &val, &val); 209 r = getlr(p, 'R'); 210 if (optype(p->in.op) == LTYPE || p->in.op == UNARY MUL) 211 { 212 l = resc; 213 l->in.type = (r->in.type==FLOAT || r->in.type==DOUBLE ? DOUBLE : INT); 214 } 215 else 216 l = getlr(p, 'L'); 217 if (r->in.op == ICON) 218 if(r->in.name[0] == '\0') 219 { 220 if (r->tn.lval == 0) 221 { 222 printf("clr"); 223 prtype(l); 224 printf(" "); 225 adrput(l); 226 return; 227 } 228 if (r->tn.lval < 0 && r->tn.lval >= -63) 229 { 230 printf("mneg"); 231 prtype(l); 232 r->tn.lval = -r->tn.lval; 233 goto ops; 234 } 235 r->in.type = (r->tn.lval < 0 ? 236 (r->tn.lval >= -128 ? CHAR 237 : (r->tn.lval >= -32768 ? SHORT 238 : INT )) : r->in.type); 239 r->in.type = (r->tn.lval >= 0 ? 240 (r->tn.lval <= 63 ? INT 241 : ( r->tn.lval <= 127 ? CHAR 242 : (r->tn.lval <= 255 ? UCHAR 243 : (r->tn.lval <= 32767 ? SHORT 244 : (r->tn.lval <= 65535 ? USHORT 245 : INT ))))) : r->in.type ); 246 } 247 else 248 { 249 printf("moval"); 250 printf(" "); 251 acon(r); 252 printf(","); 253 adrput(l); 254 return; 255 } 256 257 if (l->in.op == REG && l->in.type != FLOAT && l->in.type != DOUBLE) 258 { 259 if( tlen(l) < tlen(r) ) 260 { 261 if (!mixtypes(l,r)) 262 { 263 !ISUNSIGNED(l->in.type)? 264 printf("cvt"): 265 printf("movz"); 266 prtype(l); 267 printf("l"); 268 goto ops; 269 } 270 else 271 { 272 printf("cvt"); 273 prtype(r); 274 prtype(l); 275 printf(" "); 276 adrput(r); 277 printf(","); 278 adrput(l); 279 printf("cvt"); 280 prtype(l); 281 printf("l"); 282 printf(" "); 283 adrput(l); 284 printf(","); 285 adrput(l); 286 return; 287 } 288 } 289 else 290 { 291 l->in.type = INT; 292 } 293 } 294 if (!mixtypes(l,r)) 295 { 296 if (tlen(l) == tlen(r)) 297 { 298 printf("mov"); 299 prtype(l); 300 goto ops; 301 } 302 else if (tlen(l) > tlen(r) && ISUNSIGNED(r->in.type)) 303 { 304 printf("movz"); 305 } 306 else 307 { 308 printf("cvt"); 309 } 310 } 311 else 312 { 313 printf("cvt"); 314 } 315 prtype(r); 316 prtype(l); 317 ops: 318 printf(" "); 319 adrput(r); 320 printf(","); 321 adrput(l); 322 return; 323 } 324 325 case 'B': /* get oreg value in temp register for left shift */ 326 { 327 register NODE *r; 328 if (xdebug) eprint(p, 0, &val, &val); 329 r = p->in.right; 330 if( tlen(r) == sizeof(int) && r->in.type != FLOAT ) 331 printf("movl"); 332 else { 333 printf("cvt"); 334 prtype(r); 335 printf("l"); 336 } 337 return; 338 } 339 340 case 'C': /* num words pushed on arg stack */ 341 { 342 extern int gc_numbytes; 343 extern int xdebug; 344 345 if (xdebug) printf("->%d<-",gc_numbytes); 346 347 printf("$%d", gc_numbytes/(SZLONG/SZCHAR) ); 348 return; 349 } 350 351 case 'D': /* INCR and DECR */ 352 zzzcode(p->in.left, 'A'); 353 printf("\n "); 354 355 case 'E': /* INCR and DECR, FOREFF */ 356 if (p->in.right->tn.lval == 1) 357 { 358 printf("%s", (p->in.op == INCR ? "inc" : "dec") ); 359 prtype(p->in.left); 360 printf(" "); 361 adrput(p->in.left); 362 return; 363 } 364 printf("%s", (p->in.op == INCR ? "add" : "sub") ); 365 prtype(p->in.left); 366 printf("2 "); 367 adrput(p->in.right); 368 printf(","); 369 adrput(p->in.left); 370 return; 371 372 case 'F': /* register type of right operand */ 373 { 374 register NODE *n; 375 extern int xdebug; 376 register int ty; 377 378 n = getlr( p, 'R' ); 379 ty = n->in.type; 380 381 if (xdebug) printf("->%d<-", ty); 382 383 if ( ty==DOUBLE) printf("d"); 384 else if ( ty==FLOAT ) printf("f"); 385 else printf("l"); 386 return; 387 } 388 389 case 'L': /* type of left operand */ 390 case 'R': /* type of right operand */ 391 { 392 register NODE *n; 393 extern int xdebug; 394 395 n = getlr ( p, c); 396 if (xdebug) printf("->%d<-", n->in.type); 397 398 prtype(n); 399 return; 400 } 401 402 case 'Z': /* complement mask for bit instr */ 403 printf("$%ld", ~p->in.right->tn.lval); 404 return; 405 406 case 'U': /* 32 - n, for unsigned right shifts */ 407 printf("$%d", 32 - p->in.right->tn.lval ); 408 return; 409 410 case 'T': /* rounded structure length for arguments */ 411 { 412 int size; 413 414 size = p->stn.stsize; 415 SETOFF( size, 4); 416 printf("$%d", size); 417 return; 418 } 419 420 case 'S': /* structure assignment */ 421 { 422 register NODE *l, *r; 423 register size; 424 425 if( p->in.op == STASG ){ 426 l = p->in.left; 427 r = p->in.right; 428 429 } 430 else if( p->in.op == STARG ){ /* store an arg into a temporary */ 431 l = getlr( p, '3' ); 432 r = p->in.left; 433 } 434 else cerror( "STASG bad" ); 435 436 if( r->in.op == ICON ) r->in.op = NAME; 437 else if( r->in.op == REG ) r->in.op = OREG; 438 else if( r->in.op != OREG ) cerror( "STASG-r" ); 439 440 size = p->stn.stsize; 441 442 if( size <= 0 || size > 65535 ) 443 cerror("structure size <0=0 or >65535"); 444 445 switch(size) { 446 case 1: 447 printf(" movb "); 448 break; 449 case 2: 450 printf(" movw "); 451 break; 452 case 4: 453 printf(" movl "); 454 break; 455 case 8: 456 printf(" movq "); 457 break; 458 default: 459 printf(" movc3 $%d,", size); 460 break; 461 } 462 adrput(r); 463 printf(","); 464 adrput(l); 465 printf("\n"); 466 467 if( r->in.op == NAME ) r->in.op = ICON; 468 else if( r->in.op == OREG ) r->in.op = REG; 469 470 } 471 break; 472 473 default: 474 cerror( "illegal zzzcode" ); 475 } 476 } 477 478 rmove( rt, rs, t ){ 479 printf( " %s %s,%s\n", 480 (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")), 481 rnames[rs], rnames[rt] ); 482 } 483 484 struct respref 485 respref[] = { 486 INTAREG|INTBREG, INTAREG|INTBREG, 487 INAREG|INBREG, INAREG|INBREG|SOREG|STARREG|STARNM|SNAME|SCON, 488 INTEMP, INTEMP, 489 FORARG, FORARG, 490 INTEMP, INTAREG|INAREG|INTBREG|INBREG|SOREG|STARREG|STARNM, 491 0, 0 }; 492 493 setregs(){ /* set up temporary registers */ 494 fregs = 6; /* tbl- 6 free regs on VAX (0-5) */ 495 ; 496 } 497 498 szty(t){ /* size, in registers, needed to hold thing of type t */ 499 return( (t==DOUBLE||t==FLOAT) ? 2 : 1 ); 500 } 501 502 rewfld( p ) NODE *p; { 503 return(1); 504 } 505 506 callreg(p) NODE *p; { 507 return( R0 ); 508 } 509 510 base( p ) register NODE *p; { 511 register int o = p->in.op; 512 513 if( (o==ICON && p->in.name[0] != '\0')) return( 100 ); /* ie no base reg */ 514 if( o==REG ) return( p->tn.rval ); 515 if( (o==PLUS || o==MINUS) && p->in.left->in.op == REG && p->in.right->in.op==ICON) 516 return( p->in.left->tn.rval ); 517 if( o==OREG && !R2TEST(p->tn.rval) && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) ) 518 return( p->tn.rval + 0200*1 ); 519 if( o==INCR && p->in.left->in.op==REG ) return( p->in.left->tn.rval + 0200*2 ); 520 if( o==ASG MINUS && p->in.left->in.op==REG) return( p->in.left->tn.rval + 0200*4 ); 521 if( o==UNARY MUL && p->in.left->in.op==INCR && p->in.left->in.left->in.op==REG 522 && (p->in.type==INT || p->in.type==UNSIGNED || ISPTR(p->in.type)) ) 523 return( p->in.left->in.left->tn.rval + 0200*(1+2) ); 524 return( -1 ); 525 } 526 527 offset( p, tyl ) register NODE *p; int tyl; { 528 529 if( tyl==1 && p->in.op==REG && (p->in.type==INT || p->in.type==UNSIGNED) ) return( p->tn.rval ); 530 if( (p->in.op==LS && p->in.left->in.op==REG && (p->in.left->in.type==INT || p->in.left->in.type==UNSIGNED) && 531 (p->in.right->in.op==ICON && p->in.right->in.name[0]=='\0') 532 && (1<<p->in.right->tn.lval)==tyl)) 533 return( p->in.left->tn.rval ); 534 return( -1 ); 535 } 536 537 makeor2( p, q, b, o) register NODE *p, *q; register int b, o; { 538 register NODE *t; 539 register int i; 540 NODE *f; 541 542 p->in.op = OREG; 543 f = p->in.left; /* have to free this subtree later */ 544 545 /* init base */ 546 switch (q->in.op) { 547 case ICON: 548 case REG: 549 case OREG: 550 t = q; 551 break; 552 553 case MINUS: 554 q->in.right->tn.lval = -q->in.right->tn.lval; 555 case PLUS: 556 t = q->in.right; 557 break; 558 559 case INCR: 560 case ASG MINUS: 561 t = q->in.left; 562 break; 563 564 case UNARY MUL: 565 t = q->in.left->in.left; 566 break; 567 568 default: 569 cerror("illegal makeor2"); 570 } 571 572 p->tn.lval = t->tn.lval; 573 #ifndef FLEXNAMES 574 for(i=0; i<NCHNAM; ++i) 575 p->in.name[i] = t->in.name[i]; 576 #else 577 p->in.name = t->in.name; 578 #endif 579 580 /* init offset */ 581 p->tn.rval = R2PACK( (b & 0177), o, (b>>7) ); 582 583 tfree(f); 584 return; 585 } 586 587 canaddr( p ) NODE *p; { 588 register int o = p->in.op; 589 590 if( o==NAME || o==REG || o==ICON || o==OREG || (o==UNARY MUL && shumul(p->in.left)) ) return(1); 591 return(0); 592 } 593 594 shltype( o, p ) register NODE *p; { 595 return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UNARY MUL && shumul(p->in.left)) ); 596 } 597 598 flshape( p ) register NODE *p; { 599 return( p->in.op == REG || p->in.op == NAME || p->in.op == ICON || 600 (p->in.op == OREG && (!R2TEST(p->tn.rval) || tlen(p) == 1)) ); 601 } 602 603 shtemp( p ) register NODE *p; { 604 if( p->in.op == STARG ) p = p->in.left; 605 return( p->in.op==NAME || p->in.op ==ICON || p->in.op == OREG || (p->in.op==UNARY MUL && shumul(p->in.left)) ); 606 } 607 608 shumul( p ) register NODE *p; { 609 register o; 610 extern int xdebug; 611 612 if (xdebug) { 613 printf("\nshumul:op=%d,lop=%d,rop=%d", p->in.op, p->in.left->in.op, p->in.right->in.op); 614 printf(" prname=%s,plty=%d, prlval=%D\n", p->in.right->in.name, p->in.left->in.type, p->in.right->tn.lval); 615 } 616 617 618 o = p->in.op; 619 if( o == NAME || (o == OREG && !R2TEST(p->tn.rval)) || o == ICON ) return( STARNM ); 620 621 if( ( o == INCR || o == ASG MINUS ) && 622 ( p->in.left->in.op == REG && p->in.right->in.op == ICON ) && 623 p->in.right->in.name[0] == '\0' ) 624 { 625 switch (p->in.left->in.type) 626 { 627 case CHAR|PTR: 628 case UCHAR|PTR: 629 o = 1; 630 break; 631 632 case SHORT|PTR: 633 case USHORT|PTR: 634 o = 2; 635 break; 636 637 case INT|PTR: 638 case UNSIGNED|PTR: 639 case LONG|PTR: 640 case ULONG|PTR: 641 case FLOAT|PTR: 642 o = 4; 643 break; 644 645 case DOUBLE|PTR: 646 o = 8; 647 break; 648 649 default: 650 if ( ISPTR(p->in.left->in.type) ) { 651 o = 4; 652 break; 653 } 654 else return(0); 655 } 656 return( p->in.right->tn.lval == o ? STARREG : 0); 657 } 658 659 return( 0 ); 660 } 661 662 adrcon( val ) CONSZ val; { 663 printf( "$" ); 664 printf( CONFMT, val ); 665 } 666 667 conput( p ) register NODE *p; { 668 switch( p->in.op ){ 669 670 case ICON: 671 acon( p ); 672 return; 673 674 case REG: 675 printf( "%s", rnames[p->tn.rval] ); 676 return; 677 678 default: 679 cerror( "illegal conput" ); 680 } 681 } 682 683 insput( p ) register NODE *p; { 684 cerror( "insput" ); 685 } 686 687 upput( p ) register NODE *p; { 688 cerror( "upput" ); 689 } 690 691 adrput( p ) register NODE *p; { 692 register int r; 693 /* output an address, with offsets, from p */ 694 695 if( p->in.op == FLD ){ 696 p = p->in.left; 697 } 698 switch( p->in.op ){ 699 700 case NAME: 701 acon( p ); 702 return; 703 704 case ICON: 705 /* addressable value of the constant */ 706 printf( "$" ); 707 acon( p ); 708 return; 709 710 case REG: 711 printf( "%s", rnames[p->tn.rval] ); 712 return; 713 714 case OREG: 715 r = p->tn.rval; 716 if( R2TEST(r) ){ /* double indexing */ 717 register int flags; 718 719 flags = R2UPK3(r); 720 if( flags & 1 ) printf("*"); 721 if( flags & 4 ) printf("-"); 722 if( p->tn.lval != 0 || p->in.name[0] != '\0' ) acon(p); 723 if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] ); 724 if( flags & 2 ) printf("+"); 725 printf( "[%s]", rnames[R2UPK2(r)] ); 726 return; 727 } 728 if( r == AP ){ /* in the argument region */ 729 if( p->tn.lval <= 0 || p->in.name[0] != '\0' ) werror( "bad arg temp" ); 730 printf( CONFMT, p->tn.lval ); 731 printf( "(ap)" ); 732 return; 733 } 734 if( p->tn.lval != 0 || p->in.name[0] != '\0') acon( p ); 735 printf( "(%s)", rnames[p->tn.rval] ); 736 return; 737 738 case UNARY MUL: 739 /* STARNM or STARREG found */ 740 if( tshape(p, STARNM) ) { 741 printf( "*" ); 742 adrput( p->in.left); 743 } 744 else { /* STARREG - really auto inc or dec */ 745 register NODE *q; 746 747 /* tbl 748 p = p->in.left; 749 p->in.left->in.op = OREG; 750 if( p->in.op == INCR ) { 751 adrput( p->in.left ); 752 printf( "+" ); 753 } 754 else { 755 printf( "-" ); 756 adrput( p->in.left ); 757 } 758 tbl */ 759 printf("%s(%s)%s", (p->in.left->in.op==INCR ? "" : "-"), 760 rnames[p->in.left->in.left->tn.rval], 761 (p->in.left->in.op==INCR ? "+" : "") ); 762 p->in.op = OREG; 763 p->tn.rval = p->in.left->in.left->tn.rval; 764 q = p->in.left; 765 p->tn.lval = (p->in.left->in.op == INCR ? -p->in.left->in.right->tn.lval : 0); 766 #ifndef FLEXNAMES 767 p->in.name[0] = '\0'; 768 #else 769 p->in.name = ""; 770 #endif 771 tfree(q); 772 } 773 return; 774 775 default: 776 cerror( "illegal address" ); 777 return; 778 779 } 780 781 } 782 783 acon( p ) register NODE *p; { /* print out a constant */ 784 785 if( p->in.name[0] == '\0' ){ 786 printf( CONFMT, p->tn.lval); 787 } 788 else if( p->tn.lval == 0 ) { 789 #ifndef FLEXNAMES 790 printf( "%.8s", p->in.name ); 791 #else 792 printf( "%s", p->in.name ); 793 #endif 794 } 795 else { 796 #ifndef FLEXNAMES 797 printf( "%.8s+", p->in.name ); 798 #else 799 printf( "%s+", p->in.name ); 800 #endif 801 printf( CONFMT, p->tn.lval ); 802 } 803 } 804 805 /* 806 aacon( p ) register NODE *p; { /* print out a constant */ 807 /* 808 809 if( p->in.name[0] == '\0' ){ 810 printf( CONFMT, p->tn.lval); 811 return( 0 ); 812 } 813 else if( p->tn.lval == 0 ) { 814 #ifndef FLEXNAMES 815 printf( "$%.8s", p->in.name ); 816 #else 817 printf( "$%s", p->in.name ); 818 #endif 819 return( 1 ); 820 } 821 else { 822 printf( "$(" ); 823 printf( CONFMT, p->tn.lval ); 824 printf( "+" ); 825 #ifndef FLEXNAMES 826 printf( "%.8s)", p->in.name ); 827 #else 828 printf( "%s)", p->in.name ); 829 #endif 830 return(1); 831 } 832 } 833 */ 834 835 genscall( p, cookie ) register NODE *p; { 836 /* structure valued call */ 837 return( gencall( p, cookie ) ); 838 } 839 840 /* tbl */ 841 int gc_numbytes; 842 /* tbl */ 843 844 gencall( p, cookie ) register NODE *p; { 845 /* generate the call given by p */ 846 register NODE *p1, *ptemp; 847 register temp, temp1; 848 register m; 849 850 if( p->in.right ) temp = argsize( p->in.right ); 851 else temp = 0; 852 853 if( p->in.op == STCALL || p->in.op == UNARY STCALL ){ 854 /* set aside room for structure return */ 855 856 if( p->stn.stsize > temp ) temp1 = p->stn.stsize; 857 else temp1 = temp; 858 } 859 860 if( temp > maxargs ) maxargs = temp; 861 SETOFF(temp1,4); 862 863 if( p->in.right ){ /* make temp node, put offset in, and generate args */ 864 ptemp = talloc(); 865 ptemp->in.op = OREG; 866 ptemp->tn.lval = -1; 867 ptemp->tn.rval = SP; 868 #ifndef FLEXNAMES 869 ptemp->in.name[0] = '\0'; 870 #else 871 ptemp->in.name = ""; 872 #endif 873 ptemp->in.rall = NOPREF; 874 ptemp->in.su = 0; 875 genargs( p->in.right, ptemp ); 876 ptemp->in.op = FREE; 877 } 878 879 p1 = p->in.left; 880 if( p1->in.op != ICON ){ 881 if( p1->in.op != REG ){ 882 if( p1->in.op != OREG || R2TEST(p1->tn.rval) ){ 883 if( p1->in.op != NAME ){ 884 order( p1, INAREG ); 885 } 886 } 887 } 888 } 889 890 /* 891 if( p1->in.op == REG && p->tn.rval == R5 ){ 892 cerror( "call register overwrite" ); 893 } 894 */ 895 /* tbl 896 setup gc_numbytes so reference to ZC works */ 897 898 gc_numbytes = temp&(0x3ff); 899 /* tbl */ 900 901 p->in.op = UNARY CALL; 902 m = match( p, INTAREG|INTBREG ); 903 904 /* compensate for deficiency in 'ret' instruction ... wah,kre */ 905 /* (plus in assignment to gc_numbytes above, for neatness only) */ 906 if (temp >= 1024) 907 printf(" addl2 $%d,sp\n", (temp&(~0x3ff))); 908 909 /* tbl 910 switch( temp ) { 911 case 0: 912 break; 913 case 2: 914 printf( " tst (sp)+\n" ); 915 break; 916 case 4: 917 printf( " cmp (sp)+,(sp)+\n" ); 918 break; 919 default: 920 printf( " add $%d,sp\n", temp); 921 } 922 tbl */ 923 return(m != MDONE); 924 } 925 926 /* tbl */ 927 char * 928 ccbranches[] = { 929 " jeql L%d\n", 930 " jneq L%d\n", 931 " jleq L%d\n", 932 " jlss L%d\n", 933 " jgeq L%d\n", 934 " jgtr L%d\n", 935 " jlequ L%d\n", 936 " jlssu L%d\n", 937 " jgequ L%d\n", 938 " jgtru L%d\n", 939 }; 940 /* tbl */ 941 942 cbgen( o, lab, mode ) { /* printf conditional and unconditional branches */ 943 944 /* tbl */ 945 if( o == 0 ) printf( " jbr L%d\n", lab ); 946 /* tbl */ 947 else { 948 if( o > UGT ) cerror( "bad conditional branch: %s", opst[o] ); 949 printf( ccbranches[o-EQ], lab ); 950 } 951 } 952 953 nextcook( p, cookie ) NODE *p; { 954 /* we have failed to match p with cookie; try another */ 955 if( cookie == FORREW ) return( 0 ); /* hopeless! */ 956 if( !(cookie&(INTAREG|INTBREG)) ) return( INTAREG|INTBREG ); 957 if( !(cookie&INTEMP) && asgop(p->in.op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG ); 958 return( FORREW ); 959 } 960 961 lastchance( p, cook ) NODE *p; { 962 /* forget it! */ 963 return(0); 964 } 965 966 optim2( p ) register NODE *p; { 967 /* do local tree transformations and optimizations */ 968 969 register NODE *r; 970 971 switch( p->in.op ) { 972 973 case AND: 974 /* commute L and R to eliminate compliments and constants */ 975 if( (p->in.left->in.op==ICON&&p->in.left->in.name[0]==0) || p->in.left->in.op==COMPL ) { 976 r = p->in.left; 977 p->in.left = p->in.right; 978 p->in.right = r; 979 } 980 case ASG AND: 981 /* change meaning of AND to ~R&L - bic on pdp11 */ 982 r = p->in.right; 983 if( r->in.op==ICON && r->in.name[0]==0 ) { /* compliment constant */ 984 r->tn.lval = ~r->tn.lval; 985 } 986 else if( r->in.op==COMPL ) { /* ~~A => A */ 987 r->in.op = FREE; 988 p->in.right = r->in.left; 989 } 990 else { /* insert complement node */ 991 p->in.right = talloc(); 992 p->in.right->in.op = COMPL; 993 p->in.right->in.rall = NOPREF; 994 p->in.right->in.type = r->in.type; 995 p->in.right->in.left = r; 996 p->in.right->in.right = NULL; 997 } 998 break; 999 1000 } 1001 } 1002 1003 NODE * addroreg(l) 1004 /* OREG was built in clocal() 1005 * for an auto or formal parameter 1006 * now its address is being taken 1007 * local code must unwind it 1008 * back to PLUS/MINUS REG ICON 1009 * according to local conventions 1010 */ 1011 { 1012 cerror("address of OREG taken"); 1013 } 1014 1015 1016 1017 # ifndef ONEPASS 1018 main( argc, argv ) char *argv[]; { 1019 return( mainp2( argc, argv ) ); 1020 } 1021 # endif 1022 1023 1024 /* added by jwf */ 1025 struct functbl { 1026 int fop; 1027 TWORD ftype; 1028 char *func; 1029 } opfunc[] = { 1030 DIV, TANY, "udiv", 1031 MOD, TANY, "urem", 1032 ASG DIV, TANY, "udiv", 1033 ASG MOD, TANY, "urem", 1034 0, 0, 0 }; 1035 1036 hardops(p) register NODE *p; { 1037 /* change hard to do operators into function calls. */ 1038 register NODE *q; 1039 register struct functbl *f; 1040 register o; 1041 register TWORD t; 1042 1043 o = p->in.op; 1044 t = p->in.type; 1045 if( t!=UNSIGNED && t!=ULONG ) return; 1046 1047 for( f=opfunc; f->fop; f++ ) { 1048 if( o==f->fop ) goto convert; 1049 } 1050 return; 1051 1052 /* need to rewrite tree for ASG OP */ 1053 /* must change ASG OP to a simple OP */ 1054 convert: 1055 if( asgop( o ) ) { 1056 q = talloc(); 1057 switch( p->in.op ) { 1058 case ASG DIV: 1059 q->in.op = DIV; 1060 break; 1061 case ASG MOD: 1062 q->in.op = MOD; 1063 break; 1064 } 1065 q->in.rall = NOPREF; 1066 q->in.type = p->in.type; 1067 q->in.left = tcopy(p->in.left); 1068 q->in.right = p->in.right; 1069 p->in.op = ASSIGN; 1070 p->in.right = q; 1071 zappost(q->in.left); /* remove post-INCR(DECR) from new node */ 1072 fixpre(q->in.left); /* change pre-INCR(DECR) to +/- */ 1073 p = q; 1074 1075 } 1076 1077 /* build comma op for args to function */ 1078 q = talloc(); 1079 q->in.op = CM; 1080 q->in.rall = NOPREF; 1081 q->in.type = INT; 1082 q->in.left = p->in.left; 1083 q->in.right = p->in.right; 1084 p->in.op = CALL; 1085 p->in.right = q; 1086 1087 /* put function name in left node of call */ 1088 p->in.left = q = talloc(); 1089 q->in.op = ICON; 1090 q->in.rall = NOPREF; 1091 q->in.type = INCREF( FTN + p->in.type ); 1092 #ifndef FLEXNAMES 1093 strcpy( q->in.name, f->func ); 1094 #else 1095 q->in.name = f->func; 1096 #endif 1097 q->tn.lval = 0; 1098 q->tn.rval = 0; 1099 1100 return; 1101 1102 } 1103 1104 zappost(p) NODE *p; { 1105 /* look for ++ and -- operators and remove them */ 1106 1107 register o, ty; 1108 register NODE *q; 1109 o = p->in.op; 1110 ty = optype( o ); 1111 1112 switch( o ){ 1113 1114 case INCR: 1115 case DECR: 1116 q = p->in.left; 1117 p->in.right->in.op = FREE; /* zap constant */ 1118 ncopy( p, q ); 1119 q->in.op = FREE; 1120 return; 1121 1122 } 1123 1124 if( ty == BITYPE ) zappost( p->in.right ); 1125 if( ty != LTYPE ) zappost( p->in.left ); 1126 } 1127 1128 fixpre(p) NODE *p; { 1129 1130 register o, ty; 1131 o = p->in.op; 1132 ty = optype( o ); 1133 1134 switch( o ){ 1135 1136 case ASG PLUS: 1137 p->in.op = PLUS; 1138 break; 1139 case ASG MINUS: 1140 p->in.op = MINUS; 1141 break; 1142 } 1143 1144 if( ty == BITYPE ) fixpre( p->in.right ); 1145 if( ty != LTYPE ) fixpre( p->in.left ); 1146 } 1147 1148 myreader(p) register NODE *p; { 1149 walkf( p, hardops ); /* convert ops to function calls */ 1150 canon( p ); /* expands r-vals for fileds */ 1151 walkf( p, optim2 ); 1152 /* jwf toff = 0; /* stack offset swindle */ 1153 } 1154 1155 1156