# 2.11BSD#431 - /usr/src/lib/pcc/code.c

##### Functions

    aobeg             X
    aocode            X
    aoend             X
    bccode            X
    bfcode            X
    branch            X
    bycode            X
    defalign          X
    deflab            X
    defnam            X
    efcode            X
    ejobcode          X
    fldal             X
    fldty             X
    genswitch         X
    getlab            X
    locctr            X
    main              X
    makeheap          X
    select            X
    walkheap          X
    where             X
    zecode            X

##### Variables

    NULLNAME          X
    crslab            X
    fdefflag          X
    gdebug            X
    heapsw            X
    labelno           X
    lastloc           X
    proflg            X
    strftn            X

##### Macros

    putstr            X

       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

- in line 124, 390, 412

bycode defined in line 229; never used
defalign defined in line 26; used 1 times

- in line 366

deflab defined in line 66; used 7 times

- in line 91, 224, 367, 377
- in /usr/src/lib/pcc/local2.c line 116-120(2), 759

defnam defined in line 218; used 1 times

- in line 139

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

- in line 93, 144-149(2), 345-346(2), 384, 448
- in /usr/src/lib/pcc/local2.c line 115, 751

locctr defined in line 32; used 3 times

- in line 137, 365, 375

main defined in line 320; never used
makeheap defined in line 415; used 3 times

- in line 385, 422-423(2)

select defined in line 426; used 1 times

- in line 420

walkheap defined in line 435; used 3 times

- in line 387, 452-455(2)

where defined in line 314; never used
zecode defined in line 288; never used

#### Defined variables

NULLNAME defined in line 10; used 1 times

- in line 186

crslab defined in line 71; used 1 times

- in line 75

fdefflag defined in line 9; used 2 times

- in line 126, 191

gdebug defined in line 8; used 1 times

- in line 182

heapsw defined in line 328; used 6 times

- in line 384, 421, 441-444(3), 451

labelno defined in line 11; used 2 times

- in line 187-188(2)

lastloc defined in line 24; used 4 times

- in line 29, 36-38(3)

proflg defined in line 6; used 1 times

- in line 148

strftn defined in line 7; used 4 times

- in line 18, 81, 122, 142

#### Defined macros

putstr defined in line 13; used 10 times

- in line 19, 42, 48, 95-97(2), 240-242(2), 270, 280, 407

Last modified: 1991-07-29 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1431 |