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