1: # include "mfile2"
   2: /* a lot of the machine dependent parts of the second pass */
   3: 
   4: # define BITMASK(n) ((1L<<n)-1)
   5: 
   6: lineid( l, fn ) char *fn; {
   7:     /* identify line l and file fn */
   8:     printf( "/	line %d, file %s\n", l, fn );
   9:     }
  10: 
  11: eobl2(){
  12:     OFFSZ spoff;    /* offset from stack pointer */
  13: 
  14:     spoff = maxoff;
  15:     if( spoff >= AUTOINIT ) spoff -= AUTOINIT;
  16:     spoff /= SZCHAR;
  17:     SETOFF(spoff,2);
  18:     printf( "	.F%d = %Ld.\n", ftnno, spoff );
  19:     if( fltused ) {
  20:         fltused = 0;
  21:         printf( "	.globl	fltused\n" );
  22:         }
  23:     }
  24: 
  25: struct hoptab { int opmask; char * opstring; } ioptab[]= {
  26: 
  27:     ASG PLUS, "add",
  28:     ASG MINUS, "sub",
  29:     ASG OR, "bis",
  30:     ASG AND,    "bic",
  31:     ASG ER, "xor",
  32:     ASG MUL, "mul",
  33:     ASG DIV, "div",
  34:     ASG MOD, "div",
  35:     ASG LS, "asl",
  36:     ASG RS, "asr",
  37: 
  38:     -1, ""    };
  39: 
  40: hopcode( f, o ){
  41:     /* output the appropriate string from the above table */
  42: 
  43:     register struct hoptab *q;
  44: 
  45:     for( q = ioptab;  q->opmask>=0; ++q ){
  46:         if( q->opmask == o ){
  47:             printf( "%s", q->opstring );
  48:             if( f == 'F' ) printf( "f" );
  49:             return;
  50:             }
  51:         }
  52:     cerror( "no hoptab for %s", opst[o] );
  53:     }
  54: 
  55: char *
  56: rnames[]= {  /* keyed to register number tokens */
  57: 
  58:     "r0", "r1",
  59:     "r2", "r3", "r4",
  60:     "r5", "sp", "pc",
  61: 
  62:     "fr0", "fr1", "fr2", "fr3",
  63:     "fr4", "fr5",   /* not accumulators - used for temps */
  64:     };
  65: 
  66: int rstatus[] = {
  67:     SAREG|STAREG, SAREG|STAREG,
  68:     SAREG|STAREG, SAREG|STAREG, SAREG|STAREG,   /* use as scratch if not reg var */
  69:     SAREG, SAREG, SAREG,
  70: 
  71:     SBREG|STBREG, SBREG|STBREG, SBREG|STBREG, SBREG|STBREG,
  72:     SBREG, SBREG,
  73:     };
  74: 
  75: NODE *brnode;
  76: int brcase;
  77: 
  78: int toff = 0; /* number of stack locations used for args */
  79: 
  80: zzzcode( p, c ) NODE *p; {
  81:     register m;
  82:     switch( c ){
  83: 
  84:     case 'B':   /* output b if type is byte */
  85:         if( p->type == CHAR || p->type == UCHAR ) printf( "b" );
  86:         return;
  87: 
  88:     case 'N':  /* logical ops, turned into 0-1 */
  89:         /* use register given by register 1 */
  90:         cbgen( 0, m=getlab(), 'I' );
  91:         deflab( p->label );
  92:         printf( "	clr	%s\n", rnames[getlr( p, '1' )->rval] );
  93:         if( p->type == LONG || p->type == ULONG )
  94:             printf( "	clr	%s\n", rnames[getlr( p, '1' )->rval + 1] );
  95:         deflab( m );
  96:         return;
  97: 
  98:     case 'I':
  99:     case 'F':
 100:         cbgen( p->op, p->label, c );
 101:         return;
 102: 
 103:     case 'A':
 104:     case 'C':
 105:         /* logical operators for longs
 106: 		   defer comparisons until branch occurs */
 107: 
 108:         brnode = tcopy( p );
 109:         brcase = c;
 110:         return;
 111: 
 112:     case 'H':  /* fix up unsigned shifts */
 113:         {   register NODE *q;
 114:             register r, l;
 115:             TWORD t;
 116: 
 117:             if( p->op == ASG LS ) return;
 118:             if( p->op != ASG RS ) cerror( "ZH bad" );
 119:             if( p->left->op != REG ) cerror( "SH left bad" );
 120: 
 121:             r = p->left->rval;
 122:             t = p->left->type;
 123:             l = (t==LONG || t == ULONG );
 124: 
 125:             if( t != UNSIGNED && t != UCHAR && t != ULONG ) return;  /* signed is ok */
 126: 
 127:             /* there are three cases:  right side is a constant,
 128: 				and has the shift value; right side is
 129: 				a temporary reg, and has the - shift value,
 130: 				and right side is something else: A1 has the
 131: 				- shift value then */
 132: 
 133:             /* in the case where the value is known (rhs a constant),
 134: 				the mask is just computed and put out... */
 135: 
 136:             if( p->right->op == ICON ){
 137:                 int s;
 138:                 s = p->right->lval;
 139:                 if( l ){
 140:                     if( s >= 16 ){
 141:                         printf( "	clr	r%d\n", r );
 142:                         s -= 16;
 143:                         ++r;
 144:                         }
 145:                     }
 146:                 if( s >= 16 ) printf( "	clr	r%d\n", r );
 147:                 else {
 148:                     m = 0100000;
 149:                     m >>= s;  /* sign extends... */
 150:                     m <<= 1;
 151:                     printf( "	bic	$%o,r%d\n", m, r );
 152:                     }
 153:                 return;
 154:                 }
 155: 
 156:             /* general case */
 157: 
 158:             if( istnode( p->right ) ) q = p->right;
 159:             else q = getlr( p, '1' );  /* where -shift is stored */
 160: 
 161:             /* first, we store the shifted value on the stack */
 162:             printf( "	mov	r%d,-(sp)\n", r );
 163:             if( l ) printf( "	mov	r%d,-(sp)\n", r+1 );
 164: 
 165:             /* now, make a mask */
 166: 
 167:             printf( "	mov	$100000,r%d\n", r );
 168:             if( l ) printf( "	clr	r%d\n", r+1 );
 169: 
 170:             /* shift (arithmetically ) */
 171:             if( l ) expand( q, RNOP, "	ashc	AR" );
 172:             else expand( q, RNOP, "	ash	AR" );
 173:             printf( ",r%d\n", r );
 174: 
 175:             if( l ) printf( "	ashc	$1,r%d\n", r );
 176:             else printf( "	asl	r%d\n", r );
 177: 
 178:             /* now, we have a mask: use it to clear sp, and reload */
 179: 
 180:             if( l ){
 181:                 printf( "\tbic\tr%d,(sp)\n\tmov\t(sp)+,r%d\n", r+1, r+1 );
 182:                 }
 183:             printf( "\tbic\tr%d,(sp)\n\tmov\t(sp)+,r%d\n", r, r );
 184:             /* whew! */
 185:             return;
 186:             }
 187: 
 188:     case 'V':
 189:         /* sign extend or not -- register is one less than the
 190: 		   left descendent */
 191: 
 192:         m = p->left->rval - 1;
 193: 
 194:         if( ISUNSIGNED(p->type) ){
 195:             printf( "	clr	r%d\n", m );
 196:             }
 197:         else {
 198:             printf( "	sxt	r%d\n", m );
 199:             }
 200:         return;
 201: 
 202:         /* stack management macros */
 203:     case '-':
 204:         if( toff ++ ) printf( "-" );
 205:         printf( "(sp)" );
 206:         return;
 207: 
 208:     case '4':
 209:         if( toff == 0 ) ++toff;  /* can't push doubles that way */
 210:         printf( "-(sp)" );
 211:         toff += 4;
 212:         return;
 213: 
 214:     case '~':
 215:         /* complimented CR */
 216:         p->right->lval = ~p->right->lval;
 217:         conput( getlr( p, 'R' ) );
 218:         p->right->lval = ~p->right->lval;
 219:         return;
 220: 
 221:     case 'M':
 222:         /* negated CR */
 223:         p->right->lval = -p->right->lval;
 224:         conput( getlr( p, 'R' ) );
 225:         p->right->lval = -p->right->lval;
 226:         return;
 227: 
 228:     case 'L':  /* INIT for long constants */
 229:         {
 230:             unsigned hi, lo;
 231:             lo = p->left->lval & BITMASK(SZINT);
 232:             hi = ( p->left->lval >> SZINT ) & BITMASK(SZINT);
 233:             printf( "	%o; %o\n", hi, lo );
 234:             return;
 235:         }
 236: 
 237:     case 'T':
 238:         /* Truncate longs for type conversions:
 239: 		    LONG|ULONG -> CHAR|UCHAR|INT|UNSIGNED
 240: 		   increment offset to second word */
 241: 
 242:         m = p->type;
 243:         p = p->left;
 244:         switch( p->op ){
 245:         case NAME:
 246:         case OREG:
 247:             p->lval += SZINT/SZCHAR;
 248:             return;
 249:         case REG:
 250:             rfree( p->rval, p->type );
 251:             p->rval += 1;
 252:             p->type = m;
 253:             rbusy( p->rval, p->type );
 254:             return;
 255:         default:
 256:             cerror( "Illegal ZT type conversion" );
 257:             return;
 258: 
 259:             }
 260: 
 261:     case 'U':
 262:         /* same as AL for exp under U* */
 263:         if( p->left->op == UNARY MUL ) {
 264:             adrput( getlr( p->left, 'L' ) );
 265:             return;
 266:             }
 267:         cerror( "Illegal ZU" );
 268:         /* NO RETURN */
 269: 
 270:     case 'W':   /* structure size */
 271:         if( p->op == STASG )
 272:             printf( "%d", p->stsize);
 273:         else    cerror( "Not a structure" );
 274:         return;
 275: 
 276:     case 'S':  /* structure assignment */
 277:         {
 278:             register NODE *l, *r;
 279:             register size, count;
 280: 
 281:             if( p->op == STASG ){
 282:                 l = p->left;
 283:                 r = p->right;
 284:                 }
 285:             else if( p->op == STARG ){  /* store an arg onto the stack */
 286:                 r = p->left;
 287:                 }
 288:             else cerror( "STASG bad" );
 289: 
 290:             if( r->op == ICON ) r->op = NAME;
 291:             else if( r->op == REG ) r->op = OREG;
 292:             else if( r->op != OREG ) cerror( "STASG-r" );
 293: 
 294:             size = p->stsize;
 295:             count = size / 2;
 296: 
 297:             r->lval += size;
 298:             if( p->op == STASG ) l->lval += size;
 299: 
 300:             while( count-- ){ /* simple load/store loop */
 301:                 r->lval -= 2;
 302:                 expand( r, FOREFF, "	mov	AR," );
 303:                 if( p->op == STASG ){
 304:                     l->lval -= 2;
 305:                     expand( l, FOREFF, "AR\n" );
 306:                     }
 307:                 else {
 308:                     printf( "-(sp)\n" );
 309:                     }
 310: 
 311:                 }
 312: 
 313:             if( r->op == NAME ) r->op = ICON;
 314:             else if( r->op == OREG ) r->op = REG;
 315: 
 316:             }
 317:         break;
 318: 
 319:     default:
 320:         cerror( "illegal zzzcode" );
 321:         }
 322:     }
 323: 
 324: rmove( rt, rs, t ) TWORD t; {
 325:     printf( "	%s	%s,%s\n", (t==FLOAT||t==DOUBLE)?"movf":"mov", rnames[rs], rnames[rt] );
 326:     }
 327: 
 328: struct respref
 329: respref[] = {
 330:     INTAREG|INTBREG,    INTAREG|INTBREG,
 331:     INAREG|INBREG,  INAREG|INBREG|SOREG|STARREG|SNAME|STARNM|SCON,
 332:     INTEMP, INTEMP,
 333:     FORARG, FORARG,
 334:     INTAREG,    SOREG|SNAME,
 335:     0,  0 };
 336: 
 337: setregs(){ /* set up temporary registers */
 338:     register i;
 339: 
 340:     /* use any unused variable registers as scratch registers */
 341:     fregs = maxtreg>=MINRVAR ? maxtreg + 1 : MINRVAR;
 342:     if( xdebug ){
 343:         /* -x changes number of free regs to 2, -xx to 3, etc. */
 344:         if( (xdebug+1) < fregs ) fregs = xdebug+1;
 345:         }
 346:     /* NOTE: for pdp11 fregs <= 4 for float regs */
 347:     if( fregs > 4 ) fregs = 4;
 348:     for( i=MINRVAR; i<=MAXRVAR; i++ )
 349:         rstatus[i] = i<fregs ? SAREG|STAREG : SAREG;
 350:     }
 351: 
 352: szty(t) TWORD t; { /* size, in words, needed to hold thing of type t */
 353:     /* really is the number of registers to hold type t */
 354:     switch( t ) {
 355: 
 356:     case LONG:
 357:     case ULONG:
 358:         return( SZLONG/SZINT );
 359: 
 360:     default:
 361:         return(1);
 362: 
 363:         }
 364:     }
 365: 
 366: rewfld( p ) NODE *p; {
 367:     return(1);
 368:     }
 369: 
 370: callreg(p) NODE *p; {
 371:     return( (p->type==DOUBLE||p->type==FLOAT) ? FR0 : R0 );
 372:     }
 373: 
 374: shltype( o, p ) NODE *p; {
 375:     if( o == NAME|| o==REG || o == ICON || o == OREG ) return( 1 );
 376:     return( o==UNARY MUL && shumul(p->left) );
 377:     }
 378: 
 379: flshape( p ) register NODE *p; {
 380:     register o = p->op;
 381:     if( o==NAME || o==REG || o==ICON || o==OREG ) return( 1 );
 382:     return( o==UNARY MUL && shumul(p->left)==STARNM );
 383:     }
 384: 
 385: shtemp( p ) register NODE *p; {
 386:     if( p->op == UNARY MUL ) p = p->left;
 387:     if( p->op == REG || p->op == OREG ) return( !istreg( p->rval ) );
 388:     return( p->op == NAME || p->op == ICON );
 389:     }
 390: 
 391: spsz( t, v ) TWORD t; CONSZ v; {
 392: 
 393:     /* is v the size to increment something of type t */
 394: 
 395:     if( !ISPTR(t) ) return( 0 );
 396:     t = DECREF(t);
 397: 
 398:     if( ISPTR(t) ) return( v == 2 );
 399: 
 400:     switch( t ){
 401: 
 402:     case UCHAR:
 403:     case CHAR:
 404:         return( v == 1 );
 405: 
 406:     case INT:
 407:     case UNSIGNED:
 408:         return( v == 2 );
 409: 
 410:     case FLOAT:
 411:         return( v == 4 );
 412: 
 413:     case DOUBLE:
 414:         return( v == 8 );
 415:         }
 416: 
 417:     return( 0 );
 418:     }
 419: 
 420: shumul( p ) register NODE *p; {
 421:     register o;
 422: 
 423:     o = p->op;
 424:     if( o == NAME || o == OREG || o == ICON ) return( STARNM );
 425: 
 426:     if( ( o == INCR || o == ASG MINUS ) &&
 427:         ( p->left->op == REG && p->right->op == ICON ) &&
 428:         p->right->name[0] == '\0' &&
 429:         spsz( p->left->type, p->right->lval ) )
 430:         return( STARREG );
 431: 
 432:     return( 0 );
 433:     }
 434: 
 435: adrcon( val ) CONSZ val; {
 436:     printf( CONFMT, val );
 437:     }
 438: 
 439: conput( p ) register NODE *p; {
 440:     switch( p->op ){
 441: 
 442:     case ICON:
 443:         acon( p );
 444:         return;
 445: 
 446:     case REG:
 447:         printf( "%s", rnames[p->rval] );
 448:         return;
 449: 
 450:     default:
 451:         cerror( "illegal conput" );
 452:         }
 453:     }
 454: 
 455: insput( p ) NODE *p; {
 456:     cerror( "insput" );
 457:     }
 458: 
 459: upput( p ) NODE *p; {
 460:     /* output the address of the second word in the
 461: 	   pair pointed to by p (for LONGs)*/
 462:     CONSZ save;
 463: 
 464:     if( p->op == FLD ){
 465:         p = p->left;
 466:         }
 467: 
 468:     save = p->lval;
 469:     switch( p->op ){
 470: 
 471:     case NAME:
 472:         p->lval += SZINT/SZCHAR;
 473:         acon( p );
 474:         break;
 475: 
 476:     case ICON:
 477:         /* addressable value of the constant */
 478:         p->lval &= BITMASK(SZINT);
 479:         printf( "$" );
 480:         acon( p );
 481:         break;
 482: 
 483:     case REG:
 484:         printf( "%s", rnames[p->rval+1] );
 485:         break;
 486: 
 487:     case OREG:
 488:         p->lval += SZINT/SZCHAR;
 489:         if( p->rval == R5 ){  /* in the argument region */
 490:             if( p->name[0] != '\0' ) werror( "bad arg temp" );
 491:             }
 492:         if( p->lval != 0 || p->name[0] != '\0' ) acon( p );
 493:         printf( "(%s)", rnames[p->rval] );
 494:         break;
 495: 
 496:     default:
 497:         cerror( "illegal upper address" );
 498:         break;
 499: 
 500:         }
 501:     p->lval = save;
 502: 
 503:     }
 504: 
 505: adrput( p ) register NODE *p; {
 506:     /* output an address, with offsets, from p */
 507: 
 508:     if( p->op == FLD ){
 509:         p = p->left;
 510:         }
 511:     switch( p->op ){
 512: 
 513:     case NAME:
 514:         acon( p );
 515:         return;
 516: 
 517:     case ICON:
 518:         /* addressable value of the constant */
 519:         if( szty( p->type ) == 2 ) {
 520:             /* print the high order value */
 521:             CONSZ save;
 522:             save = p->lval;
 523:             p->lval = ( p->lval >> SZINT ) & BITMASK(SZINT);
 524:             printf( "$" );
 525:             acon( p );
 526:             p->lval = save;
 527:             return;
 528:             }
 529:         printf( "$" );
 530:         acon( p );
 531:         return;
 532: 
 533:     case REG:
 534:         printf( "%s", rnames[p->rval] );
 535:         return;
 536: 
 537:     case OREG:
 538:         if( p->rval == R5 ){  /* in the argument region */
 539:             if( p->name[0] != '\0' ) werror( "bad arg temp" );
 540:             printf( CONFMT, p->lval );
 541:             printf( ".(r5)" );
 542:             return;
 543:             }
 544:         if( p->lval != 0 || p->name[0] != '\0' ) acon( p );
 545:         printf( "(%s)", rnames[p->rval] );
 546:         return;
 547: 
 548:     case UNARY MUL:
 549:         /* STARNM or STARREG found */
 550:         if( tshape(p, STARNM) ) {
 551:             printf( "*" );
 552:             adrput( p->left);
 553:             }
 554:         else {  /* STARREG - really auto inc or dec */
 555:             /* turn into OREG so replacement node will
 556: 			   reflect the value of the expression */
 557:             register i;
 558:             register NODE *q, *l;
 559: 
 560:             l = p->left;
 561:             q = l->left;
 562:             p->op = OREG;
 563:             p->rall = q->rall;
 564:             p->lval = q->lval;
 565:             p->rval = q->rval;
 566:             for( i=0; i<NCHNAM; i++ )
 567:                 p->name[i] = q->name[i];
 568:             if( l->op == INCR ) {
 569:                 adrput( p );
 570:                 printf( "+" );
 571:                 p->lval -= l->right->lval;
 572:                 }
 573:             else {  /* l->op == ASG MINUS */
 574:                 printf( "-" );
 575:                 adrput( p );
 576:                 }
 577:             tfree( l );
 578:         }
 579:         return;
 580: 
 581:     default:
 582:         cerror( "illegal address" );
 583:         return;
 584: 
 585:         }
 586: 
 587:     }
 588: 
 589: acon( p ) register NODE *p; { /* print out a constant */
 590: 
 591:     if( p->name[0] == '\0' ){   /* constant only */
 592:         printf( CONFMT, p->lval);
 593:         printf( "." );
 594:         }
 595:     else if( p->lval == 0 ) {   /* name only */
 596:         printf( "%.8s", p->name );
 597:         }
 598:     else {              /* name + offset */
 599:         printf( "%.8s+", p->name );
 600:         printf( CONFMT, p->lval );
 601:         printf( "." );
 602:         }
 603:     }
 604: 
 605: genscall( p, cookie ) register NODE *p; {
 606:     /* structure valued call */
 607:     return( gencall( p, cookie ) );
 608:     }
 609: 
 610: gencall( p, cookie ) register NODE *p; {
 611:     /* generate the call given by p */
 612:     register temp;
 613:     register m;
 614: 
 615:     if( p->right ) temp = argsize( p->right );
 616:     else temp = 0;
 617: 
 618:     if( p->right ){ /* generate args */
 619:         genargs( p->right );
 620:         }
 621: 
 622:     if( !shltype( p->left->op, p->left ) ) {
 623:         order( p->left, INAREG|SOREG );
 624:         }
 625: 
 626:     p->op = UNARY CALL;
 627:     m = match( p, INTAREG|INTBREG );
 628:     popargs( temp );
 629:     return(m != MDONE);
 630:     }
 631: 
 632: popargs( size ) register size; {
 633:     /* pop arguments from stack */
 634: 
 635:     toff -= size/2;
 636:     if( toff == 0 && size >= 2 ) size -= 2;
 637:     switch( size ) {
 638:     case 0:
 639:         break;
 640:     case 2:
 641:         printf( "	tst	(sp)+\n" );
 642:         break;
 643:     case 4:
 644:         printf( "	cmp	(sp)+,(sp)+\n" );
 645:         break;
 646:     default:
 647:         printf( "	add	$%d.,sp\n", size);
 648:         }
 649:     }
 650: 
 651: char *
 652: ccbranches[] = {
 653:     "	jeq	L%d\n",
 654:     "	jne	L%d\n",
 655:     "	jle	L%d\n",
 656:     "	jlt	L%d\n",
 657:     "	jge	L%d\n",
 658:     "	jgt	L%d\n",
 659:     "	jlos	L%d\n",
 660:     "	jlo	L%d\n",
 661:     "	jhis	L%d\n",
 662:     "	jhi	L%d\n",
 663:     };
 664: 
 665: /*	long branch table
 666: 
 667:    This table, when indexed by a logical operator,
 668:    selects a set of three logical conditions required
 669:    to generate long comparisons and branches.  A zero
 670:    entry indicates that no branch is required.
 671:    E.G.:  The <= operator would generate:
 672: 	cmp	AL,AR
 673: 	jlt	lable	/ 1st entry LT -> lable
 674: 	jgt	1f	/ 2nd entry GT -> 1f
 675: 	cmp	UL,UR
 676: 	jlos	lable	/ 3rd entry ULE -> lable
 677:    1:
 678:  */
 679: 
 680: int lbranches[][3] = {
 681:     /*EQ*/  0,  NE, EQ,
 682:     /*NE*/  NE, 0,  NE,
 683:     /*LE*/  LT, GT, ULE,
 684:     /*LT*/  LT, GT, ULT,
 685:     /*GE*/  GT, LT, UGE,
 686:     /*GT*/  GT, LT, UGT,
 687:     /*ULE*/ ULT,    UGT,    ULE,
 688:     /*ULT*/ ULT,    UGT,    ULT,
 689:     /*UGE*/ UGT,    ULT,    UGE,
 690:     /*UGT*/ UGT,    ULT,    UGT,
 691:     };
 692: 
 693: /* logical relations when compared in reverse order (cmp R,L) */
 694: extern short revrel[] ;
 695: 
 696: cbgen( o, lab, mode ) { /*   printf conditional and unconditional branches */
 697:     register *plb;
 698:     int lab1f;
 699: 
 700:     if( o == 0 ) printf( "	jbr	L%d\n", lab );
 701:     else    if( o > UGT ) cerror( "bad conditional branch: %s", opst[o] );
 702:     else {
 703:         switch( brcase ) {
 704: 
 705:         case 'A':
 706:         case 'C':
 707:             plb = lbranches[ o-EQ ];
 708:             lab1f = getlab();
 709:             expand( brnode, FORCC, brcase=='C' ? "\tcmp\tAL,AR\n" : "\ttst\tAR\n" );
 710:             if( *plb != 0 )
 711:                 printf( ccbranches[*plb-EQ], lab);
 712:             if( *++plb != 0 )
 713:                 printf( ccbranches[*plb-EQ], lab1f);
 714:             expand( brnode, FORCC, brcase=='C' ? "\tcmp\tUL,UR\n" : "\ttst\tUR\n" );
 715:             printf( ccbranches[*++plb-EQ], lab);
 716:             deflab( lab1f );
 717:             reclaim( brnode, RNULL, 0 );
 718:             break;
 719: 
 720:         default:
 721:             if( mode=='F' ) o = revrel[ o-EQ ];
 722:             printf( ccbranches[o-EQ], lab );
 723:             break;
 724:             }
 725: 
 726:         brcase = 0;
 727:         brnode = 0;
 728:         }
 729:     }
 730: 
 731: nextcook( p, cookie ) NODE *p; {
 732:     /* we have failed to match p with cookie; try another */
 733:     if( cookie == FORREW ) return( 0 );  /* hopeless! */
 734:     if( !(cookie&(INTAREG|INTBREG)) ) return( INTAREG|INTBREG );
 735:     if( !(cookie&INTEMP) && asgop(p->op) ) return( INTEMP|INAREG|INTAREG|INTBREG|INBREG );
 736:     return( FORREW );
 737:     }
 738: 
 739: lastchance( p, cook ) NODE *p; {
 740:     /* forget it! */
 741:     return(0);
 742:     }
 743: 
 744: struct functbl {
 745:     int fop;
 746:     TWORD ftype;
 747:     char *func;
 748:     } opfunc[] = {
 749:     MUL,        LONG,   "lmul",
 750:     DIV,        LONG,   "ldiv",
 751:     MOD,        LONG,   "lrem",
 752:     ASG MUL,    LONG,   "almul",
 753:     ASG DIV,    LONG,   "aldiv",
 754:     ASG MOD,    LONG,   "alrem",
 755:     MUL,        ULONG,  "lmul",
 756:     DIV,        ULONG,  "uldiv",
 757:     MOD,        ULONG,  "ulrem",
 758:     ASG MUL,    ULONG,  "almul",
 759:     ASG DIV,    ULONG,  "auldiv",
 760:     ASG MOD,    ULONG,  "aulrem",
 761:     0,  0,  0 };
 762: 
 763: hardops(p)  register NODE *p; {
 764:     /* change hard to do operators into function calls.
 765: 	   for pdp11 do long * / %	*/
 766:     register NODE *q;
 767:     register struct functbl *f;
 768:     register o;
 769:     register TWORD t;
 770: 
 771:     o = p->op;
 772:     t = p->type;
 773:     if( t!=LONG && t!=ULONG ) return;
 774: 
 775:     for( f=opfunc; f->fop; f++ ) {
 776:         if( o==f->fop && t==f->ftype ) goto convert;
 777:         }
 778:     return;
 779: 
 780:     /* need address of left node for ASG OP */
 781:     /* WARNING - this won't work for long in a REG */
 782:     convert:
 783:     if( asgop( o ) ) {
 784:         switch( p->left->op ) {
 785: 
 786:         case UNARY MUL: /* convert to address */
 787:             p->left->op = FREE;
 788:             p->left = p->left->left;
 789:             break;
 790: 
 791:         case NAME:  /* convert to ICON pointer */
 792:             p->left->op = ICON;
 793:             p->left->type = INCREF( p->left->type );
 794:             break;
 795: 
 796:         case OREG:  /* convert OREG to address */
 797:             p->left->op = REG;
 798:             p->left->type = INCREF( p->left->type );
 799:             if( p->left->lval != 0 ) {
 800:                 q = talloc();
 801:                 q->op = PLUS;
 802:                 q->rall = NOPREF;
 803:                 q->type = p->left->type;
 804:                 q->left = p->left;
 805:                 q->right = talloc();
 806: 
 807:                 q->right->op = ICON;
 808:                 q->right->rall = NOPREF;
 809:                 q->right->type = INT;
 810:                 q->right->name[0] = '\0';
 811:                 q->right->lval = p->left->lval;
 812:                 q->right->rval = 0;
 813: 
 814:                 p->left->lval = 0;
 815:                 p->left = q;
 816:                 }
 817:             break;
 818: 
 819:         default:
 820:             cerror( "Bad address for hard ops" );
 821:             /* NO RETURN */
 822: 
 823:             }
 824:         }
 825: 
 826:     /* build comma op for args to function */
 827:     q = talloc();
 828:     q->op = CM;
 829:     q->rall = NOPREF;
 830:     q->type = INT;
 831:     q->left = p->left;
 832:     q->right = p->right;
 833:     p->op = CALL;
 834:     p->right = q;
 835: 
 836:     /* put function name in left node of call */
 837:     p->left = q = talloc();
 838:     q->op = ICON;
 839:     q->rall = NOPREF;
 840:     q->type = INCREF( FTN + p->type );
 841:     strcpy( q->name, f->func );
 842:     q->lval = 0;
 843:     q->rval = 0;
 844: 
 845:     return;
 846: 
 847:     }
 848: 
 849: optim2( p ) register NODE *p; {
 850:     /* do local tree transformations and optimizations */
 851: 
 852:     register NODE *r;
 853: 
 854:     switch( p->op ) {
 855: 
 856:     case AND:
 857:         /* commute L and R to eliminate compliments and constants */
 858:         if( p->left->op==ICON || p->left->op==COMPL ) {
 859:             r = p->left;
 860:             p->left = p->right;
 861:             p->right = r;
 862:             }
 863:     case ASG AND:
 864:         /* change meaning of AND to ~R&L - bic on pdp11 */
 865:         r = p->right;
 866:         if( r->op==ICON ) { /* compliment constant */
 867:             r->lval = ~r->lval;
 868:             }
 869:         else if( r->op==COMPL ) { /* ~~A => A */
 870:             r->op = FREE;
 871:             p->right = r->left;
 872:             }
 873:         else { /* insert complement node */
 874:             p->right = talloc();
 875:             p->right->op = COMPL;
 876:             p->right->rall = NOPREF;
 877:             p->right->type = r->type;
 878:             p->right->left = r;
 879:             p->right->right = NULL;
 880:             }
 881:         break;
 882: 
 883:         }
 884:     }
 885: 
 886: myreader(p) register NODE *p; {
 887:     walkf( p, hardops );    /* convert ops to function calls */
 888:     canon( p );     /* expands r-vals for fileds */
 889:     walkf( p, optim2 );
 890:     toff = 0;  /* stack offset swindle */
 891:     }
 892: 
 893: special( p, shape ) register NODE *p; {
 894:     /* special shape matching routine */
 895: 
 896:     switch( shape ) {
 897: 
 898:     case SCCON:
 899:         if( p->op == ICON && p->name[0]=='\0' && p->lval>= -128 && p->lval <=127 ) return( 1 );
 900:         break;
 901: 
 902:     case SICON:
 903:         if( p->op == ICON && p->name[0]=='\0' && p->lval>= 0 && p->lval <=32767 ) return( 1 );
 904:         break;
 905: 
 906:     default:
 907:         cerror( "bad special shape" );
 908: 
 909:         }
 910: 
 911:     return( 0 );
 912:     }
 913: 
 914: # ifndef ONEPASS
 915: main( argc, argv ) char *argv[]; {
 916:     return( mainp2( argc, argv ) );
 917:     }
 918: # endif

Defined functions

acon defined in line 589; used 8 times
adrcon defined in line 435; used 1 times
adrput defined in line 505; used 6 times
callreg defined in line 370; used 1 times
cbgen defined in line 696; used 11 times
conput defined in line 439; used 3 times
eobl2 defined in line 11; used 3 times
flshape defined in line 379; used 1 times
gencall defined in line 610; used 3 times
genscall defined in line 605; used 1 times
hardops defined in line 763; used 1 times
hopcode defined in line 40; used 1 times
insput defined in line 455; used 1 times
lastchance defined in line 739; used 1 times
lineid defined in line 6; used 3 times
main defined in line 915; never used
myreader defined in line 886; used 1 times
nextcook defined in line 731; used 1 times
optim2 defined in line 849; used 1 times
popargs defined in line 632; used 1 times
rewfld defined in line 366; used 1 times
rmove defined in line 324; used 1 times
setregs defined in line 337; used 3 times
shltype defined in line 374; used 4 times
shtemp defined in line 385; used 1 times
shumul defined in line 420; used 7 times
special defined in line 893; used 1 times
spsz defined in line 391; used 2 times
szty defined in line 352; used 16 times
upput defined in line 459; used 1 times
zzzcode defined in line 80; used 1 times

Defined variables

brcase defined in line 76; used 5 times
brnode defined in line 75; used 5 times
ccbranches defined in line 652; used 4 times
ioptab defined in line 25; used 1 times
  • in line 45
lbranches defined in line 680; used 1 times
opfunc defined in line 748; used 1 times
respref defined in line 329; never used
rnames defined in line 56; used 20 times
rstatus defined in line 66; used 4 times
toff defined in line 78; used 7 times

Defined struct's

functbl defined in line 744; used 2 times
  • in line 767(2)
hoptab defined in line 25; used 2 times
  • in line 43(2)

Defined macros

BITMASK defined in line 4; used 4 times

Usage of this include

local2.c used 1 times
Last modified: 1979-01-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2147
Valid CSS Valid XHTML 1.0 Strict