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