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