|
|
1.1 ! root 1: # include "mfile1" ! 2: # include <sys/types.h> ! 3: # include <a.out.h> ! 4: # include <stab.h> ! 5: ! 6: int proflg = 0; /* are we generating profiling code? */ ! 7: int strftn = 0; /* is the current function one which returns a value */ ! 8: int gdebug; ! 9: int fdefflag; /* are we within a function definition ? */ ! 10: #ifndef STABDOT ! 11: char NULLNAME[8]; ! 12: #endif ! 13: int labelno; ! 14: ! 15: branch( n ){ ! 16: /* output a branch to label n */ ! 17: /* exception is an ordinary function branching to retlab: then, return */ ! 18: if( n == retlab && !strftn ){ ! 19: register TWORD t; ! 20: register r; ! 21: /* set number of regs in assem comment field */ ! 22: /* so optimizers can do a better job */ ! 23: r = 0; ! 24: if( retstat & RETVAL ){ /* the function rets a val somewhere */ ! 25: t = (&stab[curftn])->stype; ! 26: t = DECREF(t); ! 27: r++; /* it is at least one */ ! 28: if(t == DOUBLE) ! 29: r++; /* it takes two */ ! 30: } else /* the fn does not ret a val */ ! 31: r = 2; ! 32: printf( " ret#%d\n", r ); ! 33: } ! 34: else printf( " jbr L%d\n", n ); ! 35: } ! 36: ! 37: int lastloc = { -1 }; ! 38: ! 39: short log2tab[] = {0, 0, 1, 2, 2, 3, 3, 3, 3}; ! 40: #define LOG2SZ 9 ! 41: ! 42: defalign(n) { ! 43: /* cause the alignment to become a multiple of n */ ! 44: n /= SZCHAR; ! 45: if( lastloc != PROG && n > 1 ) printf( " .align %d\n", n >= 0 && n < LOG2SZ ? log2tab[n] : 0 ); ! 46: } ! 47: ! 48: locctr( l ){ ! 49: register temp; ! 50: /* l is PROG, ADATA, DATA, STRNG, ISTRNG, or STAB */ ! 51: ! 52: if( l == lastloc ) return(l); ! 53: temp = lastloc; ! 54: lastloc = l; ! 55: switch( l ){ ! 56: ! 57: case PROG: ! 58: printf( " .text\n" ); ! 59: psline(); ! 60: break; ! 61: ! 62: case DATA: ! 63: case ADATA: ! 64: printf( " .data\n" ); ! 65: break; ! 66: ! 67: case STRNG: ! 68: printf( " .data 1\n" ); ! 69: break; ! 70: ! 71: case ISTRNG: ! 72: printf( " .data 2\n" ); ! 73: break; ! 74: ! 75: case STAB: ! 76: printf( " .stab\n" ); ! 77: break; ! 78: ! 79: default: ! 80: cerror( "illegal location counter" ); ! 81: } ! 82: ! 83: return( temp ); ! 84: } ! 85: ! 86: deflab( n ){ ! 87: /* output something to define the current position as label n */ ! 88: printf( "L%d:\n", n ); ! 89: } ! 90: ! 91: int crslab = 10; ! 92: ! 93: getlab(){ ! 94: /* return a number usable for a label */ ! 95: return( ++crslab ); ! 96: } ! 97: ! 98: ! 99: efcode(){ ! 100: /* code for the end of a function */ ! 101: ! 102: if( strftn ){ /* copy output (in R2) to caller */ ! 103: register NODE *l, *r; ! 104: register struct symtab *p; ! 105: register TWORD t; ! 106: register int i; ! 107: ! 108: p = &stab[curftn]; ! 109: t = p->stype; ! 110: t = DECREF(t); ! 111: ! 112: deflab( retlab ); ! 113: ! 114: i = getlab(); /* label for return area */ ! 115: #ifndef LCOMM ! 116: printf(" .data\n" ); ! 117: printf(" .align 2\n" ); ! 118: printf("L%d: .space %d\n", i, tsize(t, p->dimoff, p->sizoff)/SZCHAR ); ! 119: printf(" .text\n" ); ! 120: #else ! 121: { int sz = tsize(t, p->dimoff, p->sizoff) / SZCHAR; ! 122: if (sz % (SZINT/SZCHAR)) ! 123: sz += (SZINT/SZCHAR) - (sz % (SZINT/SZCHAR)); ! 124: printf(" .lcomm L%d,%d\n", i, sz); ! 125: } ! 126: #endif ! 127: psline(); ! 128: printf(" movab L%d,r1\n", i); ! 129: ! 130: reached = 1; ! 131: l = block( REG, NIL, NIL, PTR|t, p->dimoff, p->sizoff ); ! 132: l->tn.rval = 1; /* R1 */ ! 133: l->tn.lval = 0; /* no offset */ ! 134: r = block( REG, NIL, NIL, PTR|t, p->dimoff, p->sizoff ); ! 135: r->tn.rval = 0; /* R0 */ ! 136: r->tn.lval = 0; ! 137: l = buildtree( UNARY MUL, l, NIL ); ! 138: r = buildtree( UNARY MUL, r, NIL ); ! 139: l = buildtree( ASSIGN, l, r ); ! 140: l->in.op = FREE; ! 141: ecomp( l->in.left ); ! 142: printf( " movab L%d,r0\n", i ); ! 143: /* turn off strftn flag, so return sequence will be generated */ ! 144: strftn = 0; ! 145: } ! 146: branch( retlab ); ! 147: p2bend(); ! 148: fdefflag = 0; ! 149: } ! 150: ! 151: int ftlab1, ftlab2; ! 152: ! 153: bfcode( a, n ) int a[]; { ! 154: /* code for the beginning of a function; a is an array of ! 155: indices in stab for the arguments; n is the number */ ! 156: register i; ! 157: register temp; ! 158: register struct symtab *p; ! 159: int off; ! 160: #ifdef REG_CHAR ! 161: char *toreg(); ! 162: #endif ! 163: char *rname(); ! 164: ! 165: locctr( PROG ); ! 166: p = &stab[curftn]; ! 167: printf( " .align 1\n"); ! 168: defnam( p ); ! 169: temp = p->stype; ! 170: temp = DECREF(temp); ! 171: strftn = (temp==STRTY) || (temp==UNIONTY); ! 172: ! 173: retlab = getlab(); ! 174: ! 175: /* routine prolog */ ! 176: ! 177: printf( " .word L%d\n", ftnno); ! 178: if (gdebug) { ! 179: #ifdef STABDOT ! 180: pstabdot(N_SLINE, lineno); ! 181: #else ! 182: pstab(NULLNAME, N_SLINE); ! 183: printf("0,%d,LL%d\n", lineno, labelno); ! 184: printf("LL%d:\n", labelno++); ! 185: #endif ! 186: } ! 187: ftlab1 = getlab(); ! 188: ftlab2 = getlab(); ! 189: printf( " jbr L%d\n", ftlab1); ! 190: printf( "L%d:\n", ftlab2); ! 191: if( proflg ) { /* profile code */ ! 192: i = getlab(); ! 193: printf(" pushl $L%d\n", i); ! 194: printf(" callf $8,mcount\n"); ! 195: printf(" .data\n"); ! 196: printf(" .align 2\n"); ! 197: printf("L%d: .long 0\n", i); ! 198: printf(" .text\n"); ! 199: psline(); ! 200: } ! 201: ! 202: off = ARGINIT; ! 203: ! 204: for( i=0; i<n; ++i ){ ! 205: p = &stab[a[i]]; ! 206: if( p->sclass == REGISTER ){ ! 207: temp = p->offset; /* save register number */ ! 208: p->sclass = PARAM; /* forget that it is a register */ ! 209: p->offset = NOOFFSET; ! 210: oalloc( p, &off ); ! 211: #ifdef REG_CHAR ! 212: printf( " %s", toreg(p->stype)) ); ! 213: #else ! 214: printf(" movl"); ! 215: #endif ! 216: printf( " %d(fp),%s\n", p->offset/SZCHAR, rname(temp) ); ! 217: p->offset = temp; /* remember register number */ ! 218: p->sclass = REGISTER; /* remember that it is a register */ ! 219: #ifdef REG_CHAR ! 220: temp = p->stype; ! 221: if( temp==CHAR || temp==SHORT ) ! 222: p->stype = INT; ! 223: else if( temp==UCHAR || temp==USHORT ) ! 224: p->stype = UNSIGNED; ! 225: #endif ! 226: } ! 227: else if( p->stype == STRTY || p->stype == UNIONTY ) { ! 228: p->offset = NOOFFSET; ! 229: if( oalloc( p, &off ) ) cerror( "bad argument" ); ! 230: SETOFF( off, ALSTACK ); ! 231: } ! 232: else { ! 233: if( oalloc( p, &off ) ) cerror( "bad argument" ); ! 234: } ! 235: ! 236: } ! 237: fdefflag = 1; ! 238: } ! 239: ! 240: bccode(){ /* called just before the first executable statment */ ! 241: /* by now, the automatics and register variables are allocated */ ! 242: SETOFF( autooff, SZINT ); ! 243: /* set aside store area offset */ ! 244: p2bbeg( autooff, regvar ); ! 245: } ! 246: ! 247: ejobcode( flag ){ ! 248: /* called just before final exit */ ! 249: /* flag is 1 if errors, 0 if none */ ! 250: } ! 251: ! 252: aobeg(){ ! 253: /* called before removing automatics from stab */ ! 254: } ! 255: ! 256: aocode(p) struct symtab *p; { ! 257: /* called when automatic p removed from stab */ ! 258: } ! 259: ! 260: aoend(){ ! 261: /* called after removing all automatics from stab */ ! 262: } ! 263: ! 264: defnam( p ) register struct symtab *p; { ! 265: /* define the current location as the name p->sname */ ! 266: ! 267: if( p->sclass == EXTDEF ){ ! 268: printf( " .globl %s\n", exname( p->sname ) ); ! 269: } ! 270: if( p->sclass == STATIC && p->slevel>1 ) deflab( p->offset ); ! 271: else printf( "%s:\n", exname( p->sname ) ); ! 272: ! 273: } ! 274: ! 275: bycode( t, i ){ ! 276: #ifdef ASSTRINGS ! 277: static int lastoctal = 0; ! 278: #endif ! 279: ! 280: /* put byte i+1 in a string */ ! 281: ! 282: #ifdef ASSTRINGS ! 283: ! 284: i &= 077; ! 285: if ( t < 0 ){ ! 286: if ( i != 0 ) printf( "\"\n" ); ! 287: } else { ! 288: if ( i == 0 ) printf("\t.ascii\t\""); ! 289: if ( t == '\\' || t == '"'){ ! 290: lastoctal = 0; ! 291: printf("\\%c", t); ! 292: } ! 293: else if ( t < 040 || t >= 0177 ){ ! 294: lastoctal++; ! 295: printf("\\%o",t); ! 296: } ! 297: else if ( lastoctal && '0' <= t && t <= '9' ){ ! 298: lastoctal = 0; ! 299: printf("\"\n\t.ascii\t\"%c", t ); ! 300: } ! 301: else ! 302: { ! 303: lastoctal = 0; ! 304: putchar(t); ! 305: } ! 306: if ( i == 077 ) printf("\"\n"); ! 307: } ! 308: #else ! 309: ! 310: i &= 07; ! 311: if( t < 0 ){ /* end of the string */ ! 312: if( i != 0 ) printf( "\n" ); ! 313: } ! 314: ! 315: else { /* stash byte t into string */ ! 316: if( i == 0 ) printf( " .byte " ); ! 317: else printf( "," ); ! 318: printf( "0x%x", t ); ! 319: if( i == 07 ) printf( "\n" ); ! 320: } ! 321: #endif ! 322: } ! 323: ! 324: zecode( n ){ ! 325: /* n integer words of zeros */ ! 326: OFFSZ temp; ! 327: if( n <= 0 ) return; ! 328: printf( " .space %d\n", (SZINT/SZCHAR)*n ); ! 329: temp = n; ! 330: inoff += temp*SZINT; ! 331: } ! 332: ! 333: fldal( t ) unsigned t; { /* return the alignment of field of type t */ ! 334: uerror( "illegal field type" ); ! 335: return( ALINT ); ! 336: } ! 337: ! 338: fldty( p ) struct symtab *p; { /* fix up type of field p */ ! 339: ; ! 340: } ! 341: ! 342: where(c){ /* print location of error */ ! 343: /* c is either 'u', 'c', or 'w' */ ! 344: /* GCOS version */ ! 345: fprintf( stderr, "%s, line %d: ", ftitle, lineno ); ! 346: } ! 347: ! 348: ! 349: #ifdef REG_CHAR ! 350: /* tbl - toreg() returns a pointer to a char string ! 351: which is the correct "register move" for the passed type ! 352: */ ! 353: struct type_move {TWORD fromtype; char tostrng[8];} toreg_strs[] = ! 354: { ! 355: CHAR, "cvtbl", ! 356: SHORT, "cvtwl", ! 357: UCHAR, "movzbl", ! 358: USHORT, "movzwl", ! 359: 0, "movl" ! 360: }; ! 361: ! 362: char ! 363: *toreg(type) ! 364: TWORD type; ! 365: { ! 366: struct type_move *p; ! 367: ! 368: for ( p=toreg_strs; p->fromtype != 0; p++) ! 369: if (p->fromtype == type) return(p->tostrng); ! 370: ! 371: /* type not found, must be a word type */ ! 372: return(p->tostrng); ! 373: } ! 374: /* tbl */ ! 375: #endif ! 376: ! 377: ! 378: main( argc, argv ) char *argv[]; { ! 379: #ifdef BUFSTDERR ! 380: char errbuf[BUFSIZ]; ! 381: setbuf(stderr, errbuf); ! 382: #endif ! 383: return(mainp1( argc, argv )); ! 384: } ! 385: ! 386: struct sw heapsw[SWITSZ]; /* heap for switches */ ! 387: ! 388: genswitch(p,n) register struct sw *p;{ ! 389: /* p points to an array of structures, each consisting ! 390: of a constant value and a label. ! 391: The first is >=0 if there is a default label; ! 392: its value is the label number ! 393: The entries p[1] to p[n] are the nontrivial cases ! 394: */ ! 395: register i; ! 396: register CONSZ j; ! 397: register CONSZ unsigned range; ! 398: register dlab, swlab; ! 399: ! 400: range = p[n].sval-p[1].sval; ! 401: ! 402: if( range <= 3*n && n>=4 ){ /* implement a direct switch */ ! 403: ! 404: swlab = getlab(); ! 405: dlab = p->slab >= 0 ? p->slab : getlab(); ! 406: ! 407: /* already in r0 */ ! 408: printf( " casel r0,$" ); ! 409: printf( CONFMT, p[1].sval ); ! 410: printf(",$"); ! 411: printf( CONFMT, range); ! 412: printf("\n .align 1\nL%d:\n", swlab); ! 413: for( i=1,j=p[1].sval; i<=n; j++) { ! 414: printf(" .word L%d-L%d\n", (j == p[i].sval ? ((j=p[i++].sval), p[i-1].slab) : dlab), ! 415: swlab); ! 416: } ! 417: ! 418: if( p->slab >= 0 ) branch( dlab ); ! 419: else printf("L%d:\n", dlab); ! 420: return; ! 421: ! 422: } ! 423: ! 424: if( n>8 ) { /* heap switch */ ! 425: ! 426: heapsw[0].slab = dlab = p->slab >= 0 ? p->slab : getlab(); ! 427: makeheap(p, n, 1); /* build heap */ ! 428: ! 429: walkheap(1, n); /* produce code */ ! 430: ! 431: if( p->slab >= 0 ) ! 432: branch( dlab ); ! 433: else ! 434: printf("L%d:\n", dlab); ! 435: return; ! 436: } ! 437: ! 438: /* debugging code */ ! 439: ! 440: /* out for the moment ! 441: if( n >= 4 ) werror( "inefficient switch: %d, %d", n, (int) (range/n) ); ! 442: */ ! 443: ! 444: /* simple switch code */ ! 445: ! 446: for( i=1; i<=n; ++i ){ ! 447: /* already in r0 */ ! 448: ! 449: printf( " cmpl r0,$" ); ! 450: printf( CONFMT, p[i].sval ); ! 451: printf( "\n jeql L%d\n", p[i].slab ); ! 452: } ! 453: ! 454: if( p->slab>=0 ) branch( p->slab ); ! 455: } ! 456: ! 457: makeheap(p, m, n) ! 458: register struct sw *p; ! 459: { ! 460: register int q; ! 461: ! 462: q = select(m); ! 463: heapsw[n] = p[q]; ! 464: if( q>1 ) makeheap(p, q-1, 2*n); ! 465: if( q<m ) makeheap(p+q, m-q, 2*n+1); ! 466: } ! 467: ! 468: select(m) { ! 469: register int l,i,k; ! 470: ! 471: for(i=1; ; i*=2) ! 472: if( (i-1) > m ) break; ! 473: l = ((k = i/2 - 1) + 1)/2; ! 474: return( l + (m-k < l ? m-k : l)); ! 475: } ! 476: ! 477: walkheap(start, limit) ! 478: { ! 479: int label; ! 480: ! 481: ! 482: if( start > limit ) return; ! 483: printf( " cmpl r0,$" ); ! 484: printf( CONFMT, heapsw[start].sval); ! 485: printf("\n jeql L%d\n", heapsw[start].slab); ! 486: if( (2*start) > limit ) { ! 487: printf(" jbr L%d\n", heapsw[0].slab); ! 488: return; ! 489: } ! 490: if( (2*start+1) <= limit ) { ! 491: label = getlab(); ! 492: printf(" jgtr L%d\n", label); ! 493: } else ! 494: printf(" jgtr L%d\n", heapsw[0].slab); ! 495: walkheap( 2*start, limit); ! 496: if( (2*start+1) <= limit ) { ! 497: printf("L%d:\n", label); ! 498: walkheap( 2*start+1, limit); ! 499: } ! 500: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.