|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)code.c 1.1 86/02/03 SMI"; ! 3: #endif ! 4: ! 5: ! 6: # include "cpass1.h" ! 7: # include <sys/types.h> ! 8: ! 9: # include <a.out.h> ! 10: # include <stab.h> ! 11: ! 12: #ifndef VAX ! 13: extern char *rnames[]; ! 14: #endif ! 15: ! 16: #ifndef ONEPASS ! 17: int usedregs; ! 18: int usedfpregs; ! 19: #endif !ONEPASS ! 20: ! 21: int proflg = 0; /* are we generating profiling code? */ ! 22: int strftn = 0; /* is the current function one which returns a value */ ! 23: int fltfun = 0; /* is function float or double? */ ! 24: int optimize = 0; /* is optimization enabled? If so, no SLINEs for you */ ! 25: #ifdef STACKPROBE ! 26: int noprobe= 1; /* are we not generating 68000 stack probes? */ ! 27: #endif ! 28: int gdebug; ! 29: int fdefflag; /* are we within a function definition ? */ ! 30: char NULLNAME[8]; ! 31: int labelno; ! 32: ! 33: branch( n ) ! 34: { ! 35: /* output a branch to label n */ ! 36: /* exception is an ordinary function branching to retlab: then, return */ ! 37: if( n == retlab && !strftn ){ ! 38: #ifdef VAX ! 39: printf( " ret\n" ); ! 40: #else ! 41: printf( " jra LE%d\n", ftnno ); ! 42: #endif ! 43: } ! 44: else ! 45: #ifdef VAX ! 46: printf( " jbr L%d\n", n ); ! 47: #else ! 48: printf(" jra L%d\n", n ); ! 49: #endif ! 50: } ! 51: ! 52: int lastloc = { -1 }; ! 53: ! 54: #ifdef VAX ! 55: short log2tab[] = {0, 0, 1, 2, 2, 3, 3, 3, 3}; ! 56: #define LOG2SZ 9 ! 57: #endif ! 58: ! 59: defalign(n) ! 60: { ! 61: /* cause the alignment to become a multiple of n */ ! 62: #ifdef VAX ! 63: n /= SZCHAR; ! 64: if( lastloc != PROG && n > 1 ) printf( " .align %d\n", n >= 0 && n < LOG2SZ ? log2tab[n] : 0 ); ! 65: #else ! 66: if ( lastloc != PROG && n > 1 ) printf(" .even\n"); ! 67: #endif ! 68: } ! 69: ! 70: locctr( l ) ! 71: { ! 72: register temp; ! 73: /* l is PROG, ADATA, DATA, STRNG, ISTRNG, or STAB */ ! 74: ! 75: if( l == lastloc ) return(l); ! 76: temp = lastloc; ! 77: lastloc = l; ! 78: switch( l ){ ! 79: ! 80: case PROG: ! 81: printf( " .text\n" ); ! 82: psline(lineno); ! 83: break; ! 84: ! 85: case DATA: ! 86: case ADATA: ! 87: if (temp != DATA && temp != ADATA) ! 88: printf( " .data\n" ); ! 89: break; ! 90: ! 91: /* The following levels of .data statements will be problems if ! 92: there is ever any relocation required. */ ! 93: case STRNG: ! 94: #ifdef VAX ! 95: printf( " .data 1\n" ); ! 96: #else ! 97: printf( " .data1\n" ); ! 98: #endif ! 99: break; ! 100: ! 101: case ISTRNG: ! 102: #ifdef VAX ! 103: printf( " .data 2\n" ); ! 104: #else ! 105: printf( " .data2\n" ); ! 106: #endif ! 107: break; ! 108: ! 109: case STAB: ! 110: printf( " .stab\n" ); ! 111: break; ! 112: ! 113: default: ! 114: cerror( "illegal location counter" ); ! 115: } ! 116: ! 117: return( temp ); ! 118: } ! 119: ! 120: deflab( n ) ! 121: { ! 122: /* output something to define the current position as label n */ ! 123: printf( "L%d:\n", n ); ! 124: } ! 125: ! 126: int crslab = 10; ! 127: ! 128: getlab() ! 129: { ! 130: /* return a number usable for a label */ ! 131: return( ++crslab ); ! 132: } ! 133: ! 134: ! 135: #ifdef VAX ! 136: int ent_mask[] = { ! 137: 0,0,0,0,0, 0xfc0, 0xf80, 0xf00, 0xe00, 0xc00, 0x800, 0}; ! 138: ! 139: int reg_use = 11; ! 140: #else ! 141: extern int regsused; ! 142: #endif ! 143: ! 144: efcode() ! 145: { ! 146: /* code for the end of a function */ ! 147: ! 148: #ifdef VAX ! 149: if( strftn ){ /* copy output (in R2) to caller */ ! 150: register NODE *l, *r; ! 151: register struct symtab *p; ! 152: register TWORD t; ! 153: register int j; ! 154: int i; ! 155: ! 156: p = STP(curftn); ! 157: t = p->stype; ! 158: t = DECREF(t); ! 159: ! 160: deflab( retlab ); ! 161: ! 162: i = getlab(); /* label for return area */ ! 163: #ifndef LCOMM ! 164: printf(" .data\n" ); ! 165: printf(" .align 2\n" ); ! 166: printf("L%d: .space %d\n", i, tsize(t, p->dimoff, p->sizoff)/SZCHAR ); ! 167: printf(" .text\n" ); ! 168: #else ! 169: { int sz = tsize(t, p->dimoff, p->sizoff) / SZCHAR; ! 170: if (sz % sizeof (int)) ! 171: sz += sizeof (int) - (sz % sizeof (int)); ! 172: printf(" .lcomm L%d,%d\n", i, sz); ! 173: } ! 174: #endif ! 175: psline(lineno); ! 176: printf(" movab L%d,r1\n", i); ! 177: ! 178: reached = 1; ! 179: l = block( REG, NIL, NIL, PTR|t, p->dimoff, p->sizoff ); ! 180: l->tn.rval = 1; /* R1 */ ! 181: l->tn.lval = 0; /* no offset */ ! 182: r = block( REG, NIL, NIL, PTR|t, p->dimoff, p->sizoff ); ! 183: r->tn.rval = 0; /* R0 */ ! 184: r->tn.lval = 0; ! 185: l = buildtree( UNARY MUL, l, NIL ); ! 186: r = buildtree( UNARY MUL, r, NIL ); ! 187: l = buildtree( ASSIGN, l, r ); ! 188: l->in.op = FREE; ! 189: ecomp( l->in.left ); ! 190: printf( " movab L%d,r0\n", i ); ! 191: /* turn off strftn flag, so return sequence will be generated */ ! 192: strftn = 0; ! 193: } ! 194: branch( retlab ); ! 195: #ifndef VMS ! 196: printf( " .set L%d,0x%x\n", ftnno, ent_mask[reg_use] ); ! 197: #else ! 198: printf( " .set L%d,%d # Hex = 0x%x\n", ftnno, 0x3c| ent_mask[reg_use], ent_mask[reg_use] ); ! 199: /* KLS kludge, under VMS if you use regs 2-5, you must save them. */ ! 200: #endif ! 201: reg_use = 11; ! 202: p2bend(); ! 203: fdefflag = 0; ! 204: #else ! 205: /* 68k code */ ! 206: /* NOTE: We still have to add FTN and stab support here */ ! 207: if( strftn ){ /* copy output (in r0) to caller */ ! 208: register struct symtab *p; ! 209: register int stlab; ! 210: register int count; ! 211: int size; ! 212: ! 213: p = STP(curftn); ! 214: ! 215: deflab( retlab ); ! 216: ! 217: stlab = getlab(); ! 218: printf( " movl d0,a0\n" ); ! 219: printf( " movl #L%d,a1\n", stlab ); ! 220: size = tsize( DECREF(p->stype), p->dimoff, p->sizoff ) / SZCHAR; ! 221: printf( " .bss\nL%d: .=.+%d\n .text\n", ! 222: stlab, size ); ! 223: if (size <= 20) { ! 224: count = size/2; ! 225: while( size ){ /* simple load/store loop */ ! 226: count = (size > 2) ? 4 : 2; ! 227: printf(" mov%c a0@+,a1@+\n", ! 228: count==2 ? 'w' : 'l'); ! 229: size -= count; ! 230: } ! 231: } else { ! 232: int residue; ! 233: ! 234: count = size / sizeof(long); ! 235: residue = size % sizeof(long); ! 236: if (count > 0x7fff) { ! 237: printf(" movl #%d,d0\n", count-1); ! 238: printf("1: movl a0@+,a1@+\n"); ! 239: printf(" dbra d0,1b\n"); ! 240: printf(" subql #1,d0\n"); ! 241: printf(" jcc 1b\n"); ! 242: } else { ! 243: printf(" movw #%d,d0\n", count-1); ! 244: printf("1: movl a0@+,a1@+\n"); ! 245: printf(" dbra d0,1b\n"); ! 246: } ! 247: switch(residue) { ! 248: case 1: ! 249: printf(" movb a0@+,a1@+\n"); ! 250: break; ! 251: case 2: ! 252: printf(" movw a0@+,a1@+\n"); ! 253: break; ! 254: case 3: ! 255: printf(" movw a0@+,a1@+\n"); ! 256: printf(" movb a0@+,a1@+\n"); ! 257: break; ! 258: default: ! 259: break; ! 260: } ! 261: } ! 262: printf( " movl #L%d,d0\n", stlab ); ! 263: /* turn off strftn flag, so return sequence will be generated */ ! 264: strftn = 0; ! 265: } ! 266: /* branch( retlab ); */ ! 267: p2bend(); ! 268: fdefflag = 0; ! 269: #endif ! 270: } ! 271: ! 272: int ftlab1, ftlab2; ! 273: ! 274: bfcode( a, n ) int a[]; ! 275: { ! 276: /* code for the beginning of a function; a is an array of ! 277: indices in stab for the arguments; n is the number */ ! 278: register i; ! 279: register temp; ! 280: register struct symtab *p; ! 281: int off; ! 282: char *toreg(); ! 283: ! 284: locctr( PROG ); ! 285: p = STP(curftn); ! 286: if (p == NULL) return; ! 287: temp = p->stype; ! 288: temp = DECREF(temp); ! 289: #ifdef VAX ! 290: printf( " .align 1\n"); ! 291: #else ! 292: /* magic cookie for c2 */ ! 293: /* uses old (pre-TERROR) type format */ ! 294: printf( "|#PROC# %#o\n", (temp&BTMASK) | ((temp&~BTMASK)>>2) ); ! 295: #endif ! 296: defnam( p ); ! 297: strftn = (temp==STRTY) || (temp==UNIONTY); ! 298: fltfun = (temp==FLOAT) || (temp==DOUBLE); ! 299: ! 300: retlab = getlab(); ! 301: ! 302: /* routine prolog */ ! 303: ! 304: #ifdef VAX ! 305: printf( " .word L%d\n", ftnno); ! 306: #else !VAX ! 307: printf(" link a6,#0\n"); ! 308: printf(" addl #-LF%d,sp\n", ftnno); ! 309: #ifdef STACKPROBE ! 310: if (noprobe!=1){ ! 311: printf(" tstb sp@(-LP%d)\n",ftnno); ! 312: } ! 313: #endif ! 314: printf(" moveml #LS%d,sp@\n",ftnno); ! 315: if (use68881) { ! 316: /* ! 317: * save floating registers used for variables ! 318: */ ! 319: if (use68020) { ! 320: printf(" fmovem #LSS%d,a6@(-LFF%d:l)\n", ! 321: ftnno, ftnno); ! 322: } else { ! 323: /* 68881 without 68020; unlikely combination */ ! 324: printf(" movl #-LFF%d,a0\n", ftnno); ! 325: printf(" fmovem #LSS%d,a6@(0,a0:l)\n", ftnno); ! 326: } ! 327: } ! 328: #endif !VAX ! 329: ! 330: #ifdef VAX ! 331: ftlab1 = getlab(); ! 332: ftlab2 = getlab(); ! 333: printf( " jbr L%d\n", ftlab1); ! 334: printf( "L%d:\n", ftlab2); ! 335: #endif ! 336: if( proflg ) { /* profile code */ ! 337: i = getlab(); ! 338: #ifdef VAX ! 339: printf(" movab L%d,r0\n", i); ! 340: printf(" jsb mcount\n"); ! 341: printf(" .data\n"); ! 342: printf(" .align 2\n"); ! 343: printf("L%d: .long 0\n", i); ! 344: printf(" .text\n"); ! 345: #else ! 346: printf(" movl #L%d,a0\n",i); ! 347: printf(" jsr mcount\n"); ! 348: printf(" .bss\n .even\n"); ! 349: printf("L%d: .skip 4\n .text\n",i); ! 350: #endif ! 351: psline(lineno); ! 352: } ! 353: ! 354: off = ARGINIT; ! 355: ! 356: for( i=0; i<n; ++i ){ ! 357: #ifndef VAX ! 358: char type; ! 359: #endif ! 360: ! 361: p = STP(a[i]); ! 362: if( p->sclass == REGISTER ){ ! 363: temp = p->offset; /* save register number */ ! 364: p->sclass = PARAM; /* forget that it is a register */ ! 365: p->offset = NOOFFSET; ! 366: oalloc( p, &off ); ! 367: #ifdef VAX ! 368: /*tbl*/ printf( " %s %d(ap),r%d\n", ! 369: toreg(p->stype), p->offset/SZCHAR, temp ); ! 370: #else ! 371: printf( " %s a6@(%d),%s\n", ! 372: toreg(p->stype), p->offset/SZCHAR, ! 373: rnames[temp]); ! 374: markused(temp); ! 375: #endif ! 376: p->offset = temp; /* remember register number */ ! 377: p->sclass = REGISTER; /* remember that it is a register */ ! 378: } ! 379: /* The 68k doesn't have this code. I'll try it for a while */ ! 380: #ifdef VAX ! 381: else if( p->stype == STRTY || p->stype == UNIONTY ) { ! 382: p->offset = NOOFFSET; ! 383: if( oalloc( p, &off ) ) cerror( "bad argument" ); ! 384: SETOFF( off, ALSTACK ); ! 385: } ! 386: #endif ! 387: else { ! 388: if( oalloc( p, &off ) ) cerror( "bad argument" ); ! 389: } ! 390: ! 391: } ! 392: if (gdebug) { ! 393: #ifdef STABDOT ! 394: pstabdot(N_SLINE, lineno); ! 395: #else ! 396: pstab(NULLNAME, N_SLINE); ! 397: printf("0,%d,LL%d\n", lineno, labelno); ! 398: printf("LL%d:\n", labelno++); ! 399: #endif ! 400: } ! 401: fdefflag = 1; ! 402: } ! 403: ! 404: bccode() ! 405: { /* called just before the first executable statment */ ! 406: /* by now, the automatics and register variables are allocated */ ! 407: SETOFF( autooff, SZINT ); ! 408: /* set aside store area offset */ ! 409: p2bbeg( autooff, regvar ); ! 410: #ifdef VAX ! 411: reg_use = (reg_use > regvar ? regvar : reg_use); ! 412: #endif ! 413: } ! 414: ! 415: ejobcode( flag ) ! 416: { ! 417: /* called just before final exit */ ! 418: /* flag is 1 if errors, 0 if none */ ! 419: } ! 420: ! 421: aobeg() ! 422: { ! 423: /* called before removing automatics from stab */ ! 424: } ! 425: ! 426: aocode(p) struct symtab *p; ! 427: { ! 428: /* called when automatic p removed from stab */ ! 429: } ! 430: ! 431: aoend() ! 432: { ! 433: /* called after removing all automatics from stab */ ! 434: } ! 435: ! 436: defnam( p ) register struct symtab *p; ! 437: { ! 438: /* define the current location as the name p->sname */ ! 439: ! 440: if( p->sclass == EXTDEF ){ ! 441: printf( " .globl %s\n", exname( p->sname ) ); ! 442: } ! 443: if( p->sclass == STATIC && p->slevel>1 ) deflab( p->offset ); ! 444: else printf( "%s:\n", exname( p->sname ) ); ! 445: ! 446: } ! 447: ! 448: bycode( t, i ) ! 449: { ! 450: #ifdef ASSTRINGS ! 451: static int lastoctal = 0; ! 452: #endif ! 453: ! 454: /* put byte i+1 in a string */ ! 455: ! 456: #ifdef ASSTRINGS ! 457: ! 458: i &= 077; ! 459: if ( t < 0 ){ ! 460: if ( i != 0 ) printf( "\"\n" ); ! 461: } else { ! 462: if ( i == 0 ) printf("\t.ascii\t\""); ! 463: if ( t == '\\' || t == '"'){ ! 464: lastoctal = 0; ! 465: printf("\\%c", t); ! 466: } ! 467: /* ! 468: * We escape the colon in strings so that ! 469: * c2 will, in its infinite wisdom, interpret ! 470: * the characters preceding the colon as a label. ! 471: * If we didn't escape the colon, c2 would ! 472: * throw away any trailing blanks or tabs after ! 473: * the colon, but reconstruct a assembly ! 474: * language semantically correct program. ! 475: * C2 hasn't been taught about strings. ! 476: */ ! 477: else if ( t == ':' || t < 040 || t >= 0177 || t == '|' || t == ';' ){ ! 478: lastoctal++; ! 479: printf("\\%o",t); ! 480: } ! 481: else if ( lastoctal && '0' <= t && t <= '9' ){ ! 482: lastoctal = 0; ! 483: printf("\"\n\t.ascii\t\"%c", t ); ! 484: } ! 485: else ! 486: { ! 487: lastoctal = 0; ! 488: putchar(t); ! 489: } ! 490: if ( i == 077 ) printf("\"\n"); ! 491: } ! 492: #else ! 493: ! 494: i &= 07; ! 495: if( t < 0 ){ /* end of the string */ ! 496: if( i != 0 ) printf( "\n" ); ! 497: } ! 498: ! 499: else { /* stash byte t into string */ ! 500: if( i == 0 ) printf( " .byte " ); ! 501: else printf( "," ); ! 502: #ifdef VAX ! 503: printf( "0x%x", t ); ! 504: #else ! 505: printf( "0x%x", t ); ! 506: #endif ! 507: if( i == 07 ) printf( "\n" ); ! 508: } ! 509: #endif ! 510: } ! 511: ! 512: zecode( n ) ! 513: { ! 514: /* n integer words of zeros */ ! 515: OFFSZ temp; ! 516: #ifndef VAX ! 517: register i; ! 518: #endif ! 519: ! 520: if( n <= 0 ) return; ! 521: #ifdef VAX ! 522: printf( " .space %d\n", (SZINT/SZCHAR)*n ); ! 523: #else ! 524: printf( " .skip %d\n", (SZINT/SZCHAR)*n ); ! 525: #endif ! 526: temp = n; ! 527: inoff += temp*SZINT; ! 528: } ! 529: ! 530: fldal( t ) unsigned t; ! 531: { /* return the alignment of field of type t */ ! 532: uerror( "illegal field type" ); ! 533: return( ALINT ); ! 534: } ! 535: ! 536: fldty( p ) struct symtab *p; ! 537: { /* fix up type of field p */ ! 538: ; ! 539: } ! 540: ! 541: ! 542: where(c) ! 543: { /* print location of error */ ! 544: /* c is either 'u', 'c', or 'w' */ ! 545: /* GCOS version */ ! 546: fprintf( stderr, "%s, line %d: ", ftitle, lineno ); ! 547: } ! 548: ! 549: ! 550: /* tbl - toreg() returns a pointer to a char string ! 551: which is the correct "register move" for the passed type ! 552: */ ! 553: struct type_move ! 554: {TWORD fromtype; char tostrng[8];} toreg_strs[] = ! 555: { ! 556: #ifdef VAX ! 557: CHAR, "cvtbl", ! 558: SHORT, "cvtwl", ! 559: INT, "movl", ! 560: LONG, "movl", ! 561: FLOAT, "movf", ! 562: DOUBLE, "movd", ! 563: UCHAR, "movzbl", ! 564: USHORT, "movzwl", ! 565: UNSIGNED, "movl", ! 566: ULONG, "movl", ! 567: #else ! 568: CHAR, "movb", ! 569: UCHAR, "movb", ! 570: SHORT, "movw", ! 571: USHORT, "movw", ! 572: #endif ! 573: -1, "" ! 574: }; ! 575: ! 576: char ! 577: *toreg(type) ! 578: TWORD type; ! 579: { ! 580: struct type_move *p; ! 581: ! 582: for ( p=toreg_strs; p->fromtype > 0; p++) ! 583: if (p->fromtype == type) ! 584: return(p->tostrng); ! 585: ! 586: /* type not found, must be a pointer type */ ! 587: if (use68881 && type == FLOAT) { ! 588: return("fmoves"); ! 589: } ! 590: if (use68881 && type == DOUBLE) { ! 591: return("fmoved"); ! 592: } ! 593: return("movl"); ! 594: } ! 595: /* tbl */ ! 596: ! 597: ! 598: main( argc, argv ) char *argv[]; ! 599: { ! 600: int v; ! 601: #ifdef BUFSTDERR ! 602: char errbuf[BUFSIZ]; ! 603: setbuf(stderr, errbuf); ! 604: #endif ! 605: /* ffloat_(); /* HACK -- avoid sky board even if present */ ! 606: v = mainp1( argc, argv ); ! 607: floatnote(); ! 608: exit( v ); ! 609: } ! 610: ! 611: struct sw heapsw[SWITSZ]; /* heap for switches */ ! 612: ! 613: genswitch(p,n) register struct sw *p; ! 614: { ! 615: /* p points to an array of structures, each consisting ! 616: of a constant value and a label. ! 617: The first is >=0 if there is a default label; ! 618: its value is the label number ! 619: The entries p[1] to p[n] are the nontrivial cases ! 620: */ ! 621: register i; ! 622: register CONSZ j, range; ! 623: register dlab, swlab; ! 624: ! 625: range = p[n].sval-p[1].sval; ! 626: ! 627: if( range>0 && range <= 3*n && n>=4 ){ /* implement a direct switch */ ! 628: ! 629: dlab = p->slab >= 0 ? p->slab : getlab(); ! 630: #ifdef VAX ! 631: swlab = getlab(); ! 632: ! 633: /* already in r0 */ ! 634: printf(" casel r0,$%ld,$%ld\n", p[1].sval, range); ! 635: printf("L%d:\n", swlab); ! 636: for( i=1,j=p[1].sval; i<=n; j++) { ! 637: printf(" .word L%d-L%d\n", (j == p[i].sval ? ((j=p[i++].sval), p[i-1].slab) : dlab), ! 638: swlab); ! 639: } ! 640: ! 641: if( p->slab >= 0 ) branch( dlab ); ! 642: else printf("L%d:\n", dlab); ! 643: #else ! 644: if( p[1].sval ){ ! 645: printf( " subl #" ); ! 646: printf( CONFMT, p[1].sval ); ! 647: printf( ",d0\n" ); ! 648: } ! 649: ! 650: /* note that this is a cl; it thus checks ! 651: for numbers below range as well as out of range. ! 652: */ ! 653: printf( " cmpl #%ld,d0\n", range ); ! 654: printf( " jhi L%d\n", dlab ); ! 655: ! 656: if (use68020) { ! 657: printf( " movw pc@(6,d0:w:2),d0\n" ); ! 658: } else { ! 659: printf( " addw d0,d0\n" ); ! 660: printf( " movw pc@(6,d0:w),d0\n" ); ! 661: } ! 662: printf( " jmp pc@(2,d0:w)\n" ); ! 663: ! 664: /* output table */ ! 665: ! 666: /* printf( "L%d = \n", swlab=getlab() ); */ ! 667: printf( "L%d: \n", swlab=getlab() ); ! 668: for( i=1,j=p[1].sval; i<=n; ++j ) ! 669: printf( " .word L%d-L%d\n", ( j == p[i].sval ) ? ! 670: p[i++].slab : dlab, swlab ); ! 671: if( p->slab< 0 ) deflab( dlab ); ! 672: #endif ! 673: return; ! 674: ! 675: } ! 676: ! 677: if( n>8 ) { /* heap switch */ ! 678: #ifdef VAX ! 679: heapsw[0].slab = dlab = p->slab >= 0 ? p->slab : getlab(); ! 680: makeheap(p, n, 1); /* build heap */ ! 681: ! 682: walkheap(1, n); /* produce code */ ! 683: ! 684: if( p->slab >= 0 ) ! 685: branch( dlab ); ! 686: else ! 687: printf("L%d:\n", dlab); ! 688: return; ! 689: #else ! 690: /* drop comparison loop, then switch table, then comparison table */ ! 691: int tbllab, llab; ! 692: int biggest, smallest, range; ! 693: char sizechar; ! 694: char *sizeword; ! 695: int unsgned = 1; ! 696: tbllab = getlab(); ! 697: dlab = p->slab>=0 ? p->slab : getlab(); ! 698: biggest = p[n].sval; ! 699: smallest = p[1].sval; ! 700: range = biggest-smallest; ! 701: if (biggest<=0377 && smallest>=0){ ! 702: sizechar = 'b';sizeword = ".byte"; ! 703: smallest = 0; ! 704: }else if ( range<=0377 && range > 0 ){ ! 705: sizechar = 'b';sizeword = ".byte"; ! 706: }else if (biggest<=0177777 && smallest>=0){ ! 707: sizechar = 'w';sizeword = ".word"; ! 708: smallest = 0; ! 709: }else if ( range<=0177777 && range > 0 ){ ! 710: sizechar = 'w';sizeword = ".word"; ! 711: }else{ ! 712: sizechar = 'l';sizeword = ".long"; smallest = 0; unsgned = 0; ! 713: } ! 714: ! 715: if( smallest ){ ! 716: printf( " %sl #%d,d0\n", smallest<0?"add":"sub", ! 717: abs(smallest) ); ! 718: printf( " cmpl #%d,d0\n", range ); ! 719: printf( " jhi L%d\n", dlab ); ! 720: } else if (sizechar != 'l' ){ ! 721: printf( " cmpl #%d,d0\n", biggest ); ! 722: printf( " jhi L%d\n", dlab ); ! 723: } ! 724: printf( " lea L%d,a0\n mov%s #%d,d1\n", ! 725: tbllab, (n<=128)?"eq":"w",n-1); ! 726: llab = getlab(); ! 727: printf( "L%d: cmp%c a0@+,d0\n db%s d1,L%d\n", ! 728: llab, sizechar, unsgned?"cc":"ge", llab); ! 729: printf( " jne L%d\n", dlab ); ! 730: if (use68020) { ! 731: printf( " movw pc@(6,d1:w:2),d0\n" ); ! 732: } else { ! 733: printf( " addw d1,d1\n" ); ! 734: printf( " movw pc@(6,d1:w),d0\n" ); ! 735: } ! 736: printf( " jmp pc@(2,d0:w)\n" ); ! 737: /* put out statement list forwards, comparison table backwards*/ ! 738: printf( "L%d: \n", swlab=getlab() ); ! 739: for( i=1; i<=n; i++ ) ! 740: printf( " .word L%d-L%d\n", p[i].slab, swlab ); ! 741: printf( "L%d: \n", tbllab ); ! 742: for( i=n; i>=1; i-- ) ! 743: printf( " %s %d\n", sizeword, p[i].sval-smallest ); ! 744: if (sizechar == 'b') ! 745: printf(" .even\n"); ! 746: if( p->slab< 0 ) deflab( dlab ); ! 747: return; ! 748: #endif ! 749: } ! 750: ! 751: /* debugging code */ ! 752: ! 753: /* out for the moment ! 754: if( n >= 4 ) werror( "inefficient switch: %d, %d", n, (int) (range/n) ); ! 755: */ ! 756: ! 757: /* simple switch code */ ! 758: ! 759: for( i=1; i<=n; ++i ){ ! 760: /* already in r0 */ ! 761: ! 762: #ifdef VAX ! 763: printf( " cmpl r0,$" ); ! 764: #else ! 765: printf( " cmpl #" ); ! 766: #endif ! 767: printf( CONFMT, p[i].sval ); ! 768: #ifdef VAX ! 769: printf( "\n jeql L%d\n", p[i].slab ); ! 770: #else ! 771: printf( ",d0\n jeq L%d\n", p[i].slab ); ! 772: #endif ! 773: } ! 774: ! 775: if( p->slab>=0 ) branch( p->slab ); ! 776: } ! 777: ! 778: #ifdef VAX ! 779: ! 780: makeheap(p, m, n) ! 781: register struct sw *p; ! 782: { ! 783: register int q; ! 784: ! 785: q = select(m); ! 786: heapsw[n] = p[q]; ! 787: if( q>1 ) makeheap(p, q-1, 2*n); ! 788: if( q<m ) makeheap(p+q, m-q, 2*n+1); ! 789: } ! 790: ! 791: select(m) ! 792: { ! 793: register int l,i,k; ! 794: ! 795: for(i=1; ; i*=2) ! 796: if( (i-1) > m ) break; ! 797: l = ((k = i/2 - 1) + 1)/2; ! 798: return( l + (m-k < l ? m-k : l)); ! 799: } ! 800: ! 801: walkheap(start, limit) ! 802: { ! 803: int label; ! 804: ! 805: ! 806: if( start > limit ) return; ! 807: #ifdef VAX ! 808: printf( " cmpl r0,$" ); ! 809: #else ! 810: printf( " cmpl #" ); ! 811: #endif ! 812: printf( CONFMT, heapsw[start].sval ); ! 813: #ifdef VAX ! 814: printf( "\n jeql L%d\n", heapsw[start].slab ); ! 815: #else ! 816: printf( ",d0\n beq L%d\n", heapsw[start].slab ); ! 817: #endif ! 818: if( (2*start) > limit ) { ! 819: #ifdef VAX ! 820: printf(" jbr L%d\n", heapsw[0].slab); ! 821: #else ! 822: printf(" bra L%d\n", heapsw[0].slab); ! 823: #endif ! 824: return; ! 825: } ! 826: if( (2*start+1) <= limit ) { ! 827: label = getlab(); ! 828: #ifdef VAX ! 829: printf(" jgtr L%d\n", label); ! 830: #else ! 831: printf(" bgt L%d\n", label); ! 832: #endif ! 833: } else ! 834: #ifdef VAX ! 835: printf(" jgtr L%d\n", heapsw[0].slab); ! 836: #else ! 837: printf(" bgt L%d\n", heapsw[0].slab); ! 838: #endif ! 839: walkheap( 2*start, limit); ! 840: if( (2*start+1) <= limit ) { ! 841: printf("L%d:\n", label); ! 842: walkheap( 2*start+1, limit); ! 843: } ! 844: } ! 845: #endif VAX heap code
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.