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