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

Defined functions

aobeg defined in line 206; never used
aocode defined in line 210; never used
aoend defined in line 214; never used
bccode defined in line 194; never used
bfcode defined in line 129; never used
branch defined in line 15; used 3 times
bycode defined in line 229; never used
defalign defined in line 26; used 1 times
deflab defined in line 66; used 7 times
defnam defined in line 218; used 1 times
efcode defined in line 78; never used
ejobcode defined in line 201; never used
fldal defined in line 305; never used
fldty defined in line 310; never used
genswitch defined in line 330; never used
getlab defined in line 73; used 9 times
locctr defined in line 32; used 3 times
main defined in line 320; never used
makeheap defined in line 415; used 3 times
select defined in line 426; used 1 times
walkheap defined in line 435; used 3 times
where defined in line 314; never used
zecode defined in line 288; never used

Defined variables

NULLNAME defined in line 10; used 1 times
crslab defined in line 71; used 1 times
  • in line 75
fdefflag defined in line 9; used 2 times
gdebug defined in line 8; used 1 times
heapsw defined in line 328; used 6 times
labelno defined in line 11; used 2 times
lastloc defined in line 24; used 4 times
proflg defined in line 6; used 1 times
strftn defined in line 7; used 4 times

Defined macros

putstr defined in line 13; used 10 times
Last modified: 1991-07-29
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3327
Valid CSS Valid XHTML 1.0 Strict