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