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

Defined functions

aobeg defined in line 241; never used
aocode defined in line 245; never used
aoend defined in line 249; never used
bccode defined in line 228; never used
bfcode defined in line 156; never used
branch defined in line 19; used 4 times
bycode defined in line 264; never used
defalign defined in line 33; never used
deflab defined in line 77; used 4 times
defnam defined in line 253; used 1 times
efcode defined in line 95; never used
ejobcode defined in line 236; never used
fldal defined in line 332; never used
fldty defined in line 337; never used
genswitch defined in line 391; never used
getlab defined in line 84; used 12 times
locctr defined in line 39; used 1 times
main defined in line 381; never used
makeheap defined in line 456; used 3 times
select defined in line 467; used 1 times
toreg defined in line 366; used 2 times
walkheap defined in line 476; used 3 times
where defined in line 341; never used
zecode defined in line 323; never used

Defined variables

NULLNAME defined in line 14; used 7 times
crslab defined in line 82; used 1 times
  • in line 86
ent_mask defined in line 90; used 3 times
fdefflag defined in line 13; used 4 times
ftlab1 defined in line 154; used 2 times
ftlab2 defined in line 154; used 2 times
gdebug defined in line 12; used 24 times
heapsw defined in line 389; used 6 times
labelno defined in line 15; used 20 times
lastloc defined in line 28; used 4 times
log2tab defined in line 30; used 1 times
  • in line 36
proflg defined in line 10; used 1 times
reg_use defined in line 93; used 7 times
sccsid defined in line 2; never used
strftn defined in line 11; used 4 times
toreg_strs defined in line 351; used 1 times

Defined struct's

type_move defined in line 351; used 2 times
  • in line 370(2)

Defined macros

LOG2SZ defined in line 31; used 1 times
  • in line 36
putstr defined in line 17; used 19 times
Last modified: 1985-08-25
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1875
Valid CSS Valid XHTML 1.0 Strict