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