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