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

Defined functions

acon defined in line 592; used 8 times
adrcon defined in line 438; never used
adrput defined in line 508; used 4 times
callreg defined in line 373; never used
cbgen defined in line 703; used 2 times
conput defined in line 442; used 2 times
eobl2 defined in line 14; never used
flshape defined in line 382; never used
gencall defined in line 613; used 1 times
genscall defined in line 608; never used
hardops defined in line 770; used 1 times
hopcode defined in line 43; never used
insput defined in line 458; never used
lastchance defined in line 746; never used
lineid defined in line 9; never used
main defined in line 922; never used
myreader defined in line 893; never used
nextcook defined in line 738; never used
optim2 defined in line 856; used 1 times
popargs defined in line 635; used 1 times
rewfld defined in line 369; never used
rmove defined in line 327; never used
setregs defined in line 340; never used
shltype defined in line 377; used 2 times
shtemp defined in line 388; never used
shumul defined in line 423; used 6 times
special defined in line 900; never used
spsz defined in line 394; used 2 times
szty defined in line 355; used 3 times
upput defined in line 462; never used
where defined in line 5; never used
zzzcode defined in line 83; never used

Defined variables

brcase defined in line 79; used 5 times
ccbranches defined in line 655; used 4 times
ioptab defined in line 28; used 1 times
  • in line 48
lbranches defined in line 683; used 1 times
opfunc defined in line 755; used 1 times
respref defined in line 332; never used
revrel declared in line 700; defined in line 698; used 1 times
rnames defined in line 59; used 9 times
rstatus defined in line 69; used 1 times
toff defined in line 81; used 7 times

Defined struct's

functbl defined in line 751; used 2 times
  • in line 774(2)
hoptab defined in line 28; used 2 times
  • in line 46(2)

Defined macros

BITMASK defined in line 4; used 4 times
Last modified: 1982-06-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1408
Valid CSS Valid XHTML 1.0 Strict