1: # include <stdio.h> 2: # include <signal.h> 3: 4: # include "mfile1" 5: 6: int proflag; 7: int strftn = 0; /* is the current function one which returns a value */ 8: FILE *tmpfile; 9: FILE *outfile = stdout; 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( " jmp cret\n" ); 16: } 17: else printf( " jbr L%d\n", n ); 18: } 19: 20: int lastloc = PROG; 21: 22: defalign(n) { 23: /* cause the alignment to become a multiple of n */ 24: n /= SZCHAR; 25: if( lastloc != PROG && n > 1 ) printf( " .even\n" ); 26: } 27: 28: locctr( l ){ 29: register temp; 30: /* l is PROG, ADATA, DATA, STRNG, ISTRNG, or STAB */ 31: 32: if( l == lastloc ) return(l); 33: temp = lastloc; 34: lastloc = l; 35: switch( l ){ 36: 37: case PROG: 38: outfile = stdout; 39: printf( " .text\n" ); 40: break; 41: 42: case DATA: 43: case ADATA: 44: outfile = stdout; 45: if( temp != DATA && temp != ADATA ) 46: printf( " .data\n" ); 47: break; 48: 49: case STRNG: 50: case ISTRNG: 51: outfile = tmpfile; 52: break; 53: 54: case STAB: 55: cerror( "locctr: STAB unused" ); 56: break; 57: 58: default: 59: cerror( "illegal location counter" ); 60: } 61: 62: return( temp ); 63: } 64: 65: deflab( n ){ 66: /* output something to define the current position as label n */ 67: fprintf( outfile, "L%d:\n", n ); 68: } 69: 70: int crslab = 10; 71: 72: getlab(){ 73: /* return a number usable for a label */ 74: return( ++crslab ); 75: } 76: 77: efcode(){ 78: /* code for the end of a function */ 79: 80: if( strftn ){ /* copy output (in r0) to caller */ 81: register struct symtab *p; 82: register int stlab; 83: register int count; 84: int size; 85: 86: p = &stab[curftn]; 87: 88: deflab( retlab ); 89: 90: stlab = getlab(); 91: printf( " mov $L%d,r1\n", stlab ); 92: size = tsize( DECREF(p->stype), p->dimoff, p->sizoff ) / SZCHAR; 93: count = size/2; 94: while( count-- ) { 95: printf( " mov (r0)+,(r1)+\n" ); 96: } 97: printf( " mov $L%d,r0\n", stlab ); 98: printf( " .bss\nL%d: .=.+%d.\n .text\n", stlab, size ); 99: /* turn off strftn flag, so return sequence will be generated */ 100: strftn = 0; 101: } 102: branch( retlab ); 103: p2bend(); 104: } 105: 106: bfcode( a, n ) int a[]; { 107: /* code for the beginning of a function; a is an array of 108: indices in stab for the arguments; n is the number */ 109: register i; 110: register temp; 111: register struct symtab *p; 112: int off; 113: 114: locctr( PROG ); 115: p = &stab[curftn]; 116: defnam( p ); 117: temp = p->stype; 118: temp = DECREF(temp); 119: strftn = (temp==STRTY) || (temp==UNIONTY); 120: 121: retlab = getlab(); 122: if( proflag ){ 123: int plab; 124: plab = getlab(); 125: printf( " mov $L%d,r0\n", plab ); 126: printf( " jsr pc,mcount\n" ); 127: printf( " .bss\nL%d: .=.+2\n .text\n", plab ); 128: } 129: 130: /* routine prolog */ 131: 132: printf( " jsr r5,csv\n" ); 133: /* adjust stack for autos */ 134: printf( " sub $.F%d,sp\n", ftnno ); 135: 136: off = ARGINIT; 137: 138: for( i=0; i<n; ++i ){ 139: p = &stab[a[i]]; 140: if( p->sclass == REGISTER ){ 141: temp = p->offset; /* save register number */ 142: p->sclass = PARAM; /* forget that it is a register */ 143: p->offset = NOOFFSET; 144: oalloc( p, &off ); 145: printf( " mov %d.(r5),r%d\n", p->offset/SZCHAR, temp ); 146: p->offset = temp; /* remember register number */ 147: p->sclass = REGISTER; /* remember that it is a register */ 148: } 149: else { 150: if( oalloc( p, &off ) ) cerror( "bad argument" ); 151: } 152: 153: } 154: } 155: 156: bccode(){ /* called just before the first executable statment */ 157: /* by now, the automatics and register variables are allocated */ 158: SETOFF( autooff, SZINT ); 159: /* set aside store area offset */ 160: p2bbeg( autooff, regvar ); 161: } 162: 163: ejobcode( flag ){ 164: /* called just before final exit */ 165: /* flag is 1 if errors, 0 if none */ 166: } 167: 168: aobeg(){ 169: /* called before removing automatics from stab */ 170: } 171: 172: aocode(p) struct symtab *p; { 173: /* called when automatic p removed from stab */ 174: } 175: 176: aoend(){ 177: /* called after removing all automatics from stab */ 178: } 179: 180: defnam( p ) register struct symtab *p; { 181: /* define the current location as the name p->sname */ 182: 183: if( p->sclass == EXTDEF ){ 184: printf( " .globl %s\n", exname( p->sname ) ); 185: } 186: if( p->sclass == STATIC && p->slevel>1 ) deflab( p->offset ); 187: else printf( "%s:\n", exname( p->sname ) ); 188: 189: } 190: 191: bycode( t, i ){ 192: /* put byte i+1 in a string */ 193: 194: i &= 07; 195: if( t < 0 ){ /* end of the string */ 196: if( i != 0 ) fprintf( outfile, "\n" ); 197: } 198: 199: else { /* stash byte t into string */ 200: if( i == 0 ) fprintf( outfile, " .byte " ); 201: else fprintf( outfile, "," ); 202: fprintf( outfile, "%o", t ); 203: if( i == 07 ) fprintf( outfile, "\n" ); 204: } 205: } 206: 207: zecode( n ){ 208: /* n integer words of zeros */ 209: OFFSZ temp; 210: register i; 211: 212: if( n <= 0 ) return; 213: printf( " " ); 214: for( i=1; i<n; i++ ) { 215: if( i%8 == 0 ) 216: printf( "\n " ); 217: printf( "0; " ); 218: } 219: printf( "0\n" ); 220: temp = n; 221: inoff += temp*SZINT; 222: } 223: 224: fldal( t ) unsigned t; { /* return the alignment of field of type t */ 225: uerror( "illegal field type" ); 226: return( ALINT ); 227: } 228: 229: fldty( p ) struct symtab *p; { /* fix up type of field p */ 230: ; 231: } 232: 233: where(c){ /* print location of error */ 234: /* c is either 'u', 'c', or 'w' */ 235: fprintf( stderr, "%s, line %d: ", ftitle, lineno ); 236: } 237: 238: char *tmpname = "/tmp/pcXXXXXX"; 239: 240: main( argc, argv ) char *argv[]; { 241: int dexit(); 242: register int c; 243: register int i; 244: int r; 245: 246: for( i=1; i<argc; ++i ) 247: if( argv[i][0] == '-' && argv[i][1] == 'X' && argv[i][2] == 'p' ) { 248: proflag = 1; 249: } 250: 251: mktemp(tmpname); 252: if(signal( SIGHUP, SIG_IGN) != SIG_IGN) signal(SIGHUP, dexit); 253: if(signal( SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, dexit); 254: if(signal( SIGTERM, SIG_IGN) != SIG_IGN) signal(SIGTERM, dexit); 255: tmpfile = fopen( tmpname, "w" ); 256: 257: r = mainp1( argc, argv ); 258: 259: tmpfile = freopen( tmpname, "r", tmpfile ); 260: if( tmpfile != NULL ) 261: while((c=getc(tmpfile)) != EOF ) 262: putchar(c); 263: else cerror( "Lost temp file" ); 264: unlink(tmpname); 265: return( r ); 266: } 267: 268: dexit( v ) { 269: unlink(tmpname); 270: exit(1); 271: } 272: 273: genswitch(p,n) register struct sw *p;{ 274: /* p points to an array of structures, each consisting 275: of a constant value and a label. 276: The first is >=0 if there is a default label; 277: its value is the label number 278: The entries p[1] to p[n] are the nontrivial cases 279: */ 280: register i; 281: register CONSZ j, range; 282: register dlab, swlab; 283: 284: range = p[n].sval-p[1].sval; 285: 286: if( range>0 && range <= 3*n && n>=4 ){ /* implement a direct switch */ 287: 288: dlab = p->slab >= 0 ? p->slab : getlab(); 289: 290: if( p[1].sval ){ 291: printf( " sub $" ); 292: printf( CONFMT, p[1].sval ); 293: printf( ".,r0\n" ); 294: } 295: 296: /* note that this is a cl; it thus checks 297: for numbers below range as well as out of range. 298: */ 299: printf( " cmp r0,$%ld.\n", range ); 300: printf( " jhi L%d\n", dlab ); 301: 302: printf( " asl r0\n" ); 303: printf( " jmp *L%d(r0)\n", swlab = getlab() ); 304: 305: /* output table */ 306: 307: locctr( ADATA ); 308: defalign( ALPOINT ); 309: deflab( swlab ); 310: 311: for( i=1,j=p[1].sval; i<=n; ++j ){ 312: 313: printf( " L%d\n", ( j == p[i].sval ) ? 314: p[i++].slab : dlab ); 315: } 316: 317: locctr( PROG ); 318: 319: if( p->slab< 0 ) deflab( dlab ); 320: return; 321: 322: } 323: 324: /* debugging code */ 325: 326: /* out for the moment 327: if( n >= 4 ) werror( "inefficient switch: %d, %d", n, (int) (range/n) ); 328: */ 329: 330: /* simple switch code */ 331: 332: for( i=1; i<=n; ++i ){ 333: /* already in r0 */ 334: 335: printf( " cmp r0,$" ); 336: printf( CONFMT, p[i].sval ); 337: printf( ".\n jeq L%d\n", p[i].slab ); 338: } 339: 340: if( p->slab>=0 ) branch( p->slab ); 341: }