|
|
1.1 root 1: # include <stdio.h>
2: extern int Pflag, bbcnt;
3: # include "mfile1.h"
4:
5: int minrvar = 11;
6: int wloop_level = LL_BOT;
7: int floop_level = LL_BOT;
8: int maxboff;
9: int maxtemp;
10: codgen(p)
11: NODE *p;
12: { extern int bothdebug;
13: if(bothdebug)
14: tfree(p);
15: } /* so pcc2 stuff doesn't get loaded */
16: #if !defined(COMBINED)
17:
18: main( argc, argv ) char *argv[];
19: {
20: int r; char errbuf[BUFSIZ];
21:
22: setbuf(stderr, errbuf);
23: r = mainp1( argc, argv );
24: flushx();
25: return( r );
26: }
27:
28: beg_file()
29: {
30: /* called as the very first thing by the parser to do machine
31: * dependent stuff
32: */
33: regvar = minrvar;
34: dbfile(NULL);
35: }
36:
37: #else /* defined(COMBINED) */
38:
39: locctr(i)
40: int i;
41: {
42: static int last = PROG;
43:
44: if (i == last)
45: return;
46: else if (i == PROG)
47: printx(" .text\n");
48: else if (i == DATA)
49: printx(" .data\n");
50: else
51: cerror("funny location counter");
52: last = i;
53: }
54:
55: #endif
56:
57: NODE *
58: treecpy(p) /* first pass version of tcopy() */
59: register NODE *p;
60: {
61: /* make a fresh copy of p */
62: register NODE *q;
63:
64: q = talloc();
65: *q = *p;
66: switch (optype(q->in.op))
67: {
68: case BITYPE:
69: q->in.right = treecpy(p->in.right);
70: case UTYPE:
71: q->in.left = treecpy(p->in.left);
72: }
73: return (q);
74: }
75:
76: #if !defined(COMBINED)
77:
78: NODE *
79: clocal(p) NODE *p;
80: {
81: register NODE *l,*ll,*r;
82: if( p->in.op == STAR )
83: { /* if it looks like index mode put the */
84: /* offset on the right */
85: l = p->in.left;
86: if( l->in.op == PLUS )
87: {
88: ll = l->in.left;
89: if( ll->in.op != MUL && ll->in.op != UNARY AND )
90: {
91: if( (l->in.right)->in.op == MUL )
92: {
93: r = l->in.right;
94: l->in.right = l->in.left;
95: l->in.left = r;
96: }
97: }
98: }
99: }
100: #ifdef DASSOVCOL
101: if (!asgbinop(p->in.op) && p->in.op != ASSIGN)
102: return (p);
103: r = p->in.right;
104: if (optype(r->in.op) == LTYPE)
105: return (p);
106: l = r->in.left;
107: if (r->in.op == QUEST || (r->in.op == CONV && l->in.op == QUEST) ||
108: (r->in.op == CONV && l->in.op == CONV &&
109: l->in.left->in.op == QUEST))
110: /* distribute assigns over colons */
111: {
112: register NODE *pwork;
113: NODE *pcpy = treecpy(p), *pnew;
114: #ifndef NODBG
115: extern int xdebug, eprint();
116:
117: if (xdebug)
118: {
119: puts("Entering [op]=?: distribution");
120: eprint(p);
121: }
122: #endif
123: pnew = pcpy->in.right;
124: while (pnew->in.op != QUEST)
125: pnew = pnew->in.left;
126: /*
127: * pnew is top of new tree
128: */
129: if ((pwork = p)->in.right->in.op == QUEST)
130: {
131: tfree(pwork->in.right);
132: pwork->in.right = pnew->in.right->in.left;
133: pnew->in.right->in.left = pwork;
134: /* at this point, 1/2 distributed. Tree looks like:
135: * ASSIGN|ASGOP
136: * LVAL QUEST
137: * EXPR1 COLON
138: * ASSIGN|ASGOP EXPR3
139: * LVAL EXPR2
140: * pnew "holds" new tree from QUEST node
141: */
142: }
143: else
144: {
145: NODE *pholdtop = pwork;
146:
147: pwork = pwork->in.right;
148: while (pwork->in.left->in.op != QUEST)
149: pwork = pwork->in.left;
150: tfree(pwork->in.left);
151: pwork->in.left = pnew->in.right->in.left;
152: pnew->in.right->in.left = pholdtop;
153: /* at this point, 1/2 distributed. Tree looks like:
154: * ASSIGN|ASGOP
155: * LVAL ANY # OF CONVs
156: * QUEST
157: * EXPR1 COLON
158: * ASSIGN|ASGOP EXPR3
159: * LVAL ANY # OF CONVs
160: * EXPR2
161: * pnew "holds" new tree from QUEST node
162: */
163: }
164: if ((pwork = pcpy)->in.right->in.op == QUEST)
165: {
166: pwork->in.right = pnew->in.right->in.right;
167: pnew->in.right->in.right = pwork;
168: /*
169: * done with the easy case
170: */
171: }
172: else
173: {
174: NODE *pholdtop = pwork;
175:
176: pwork = pwork->in.right;
177: while (pwork->in.left->in.op != QUEST)
178: pwork = pwork->in.left;
179: pwork->in.left = pnew->in.right->in.right;
180: pnew->in.right->in.right = pholdtop;
181: /*
182: * done with the CONVs case
183: */
184: }
185: p = pnew;
186: #ifndef NODBG
187: if (xdebug)
188: {
189: puts("Leaving [op]=?: distribution");
190: eprint(p);
191: }
192: #endif
193: }
194: #endif
195: return(p);
196: }
197: #endif
198:
199: cisreg( t ) TWORD t;
200: { /* is an automatic variable of type t OK for a register variable */
201:
202: if( t==INT || t==UNSIGNED || ISPTR(t) || t==CHAR || t==UCHAR
203: || t==SHORT || t==USHORT || t==FLOAT
204: /* (sigh) || t==STRTY || t == UNIONTY*/ )
205: {
206: if( regvar >= 6 )
207: {
208: nextrvar = regvar--;
209: if( regvar < minrvar ) minrvar = regvar;
210: return(1);
211: }
212: }
213: return(0);
214: }
215:
216: opbigsz( op )
217: {
218: /* the size below which we do not shrink ops */
219: switch( op )
220: {
221:
222: default:
223: return( SZINT );
224:
225: case PLUS:
226: case MINUS:
227: case OR:
228: case AND:
229: case ER:
230: case COMPL:
231: case UNARY MINUS:
232: return( SZCHAR );
233:
234: }
235: }
236:
237: branch(n) /* branch to label n or return */
238: int n;
239: {
240: if (!reached) /* return <expr>; } comes here 2x */
241: return;
242: genubr(n);
243: }
244:
245: #if !defined(COMBINED)
246: /* direct switch beginning */
247: static int tablelabel;
248:
249: struct sw heapsw[SWITSZ]; /* heap for switches */
250:
251: /* test for whether to do a direct switch */
252: # ifndef DSWTEST
253: # define DSWTEST(r,n) (r>0 && r<=(3*n) && n>=4)
254: # endif
255: /* test for whether to do a heap switch */
256: # ifndef HEAPTEST
257: # define HEAPTEST( n ) (n>8)
258: # endif
259:
260: genswitch(p,n) register struct sw *p;
261: {
262: /* p points to an array of structures, each consisting
263: of a constant value and a label.
264: The first is >=0 if there is a default label;
265: its value is the label number
266: The entries p[1] to p[n] are the nontrivial cases
267: */
268: register i;
269: register CONSZ j, range;
270: register dlab, swlab;
271:
272: range = p[n].sval-p[1].sval;
273:
274: if( DSWTEST( range, n ) )
275: { /* implement a direct switch */
276:
277: swlab = getlab();
278: dlab = ((p->slab >= 0) ? p->slab : getlab());
279:
280: dswbegin( n, p[1].sval, range, swlab, dlab );
281:
282: for( i=1,j=p[1].sval; i<=n; j++)
283: {
284: if( j == p[i].sval )
285: {
286: dswcase( p[i].slab );
287: j = p[i++].sval;
288: }
289: else
290: {
291: dswcase( dlab );
292: }
293: }
294:
295: /* in case dswbegin changed location counters... */
296: locctr( PROG );
297:
298: if( p->slab >= 0 ) genubr( dlab );
299: else deflab( dlab );
300: return;
301: }
302:
303: if( HEAPTEST(n) )
304: { /* heap switch */
305:
306: heapsw[0].slab = dlab = (p->slab >= 0 ? p->slab : getlab());
307: makeheap(p, n, 1); /* build heap */
308: walkheap(1, n); /* produce code */
309:
310: if( p->slab >= 0 )
311: genubr( dlab );
312: else
313: deflab( dlab );
314: return;
315: }
316:
317: /* simple switch code */
318:
319: for( i=1; i<=n; ++i ) sswtest( p[i].sval, p[i].slab );
320: if( p->slab>=0 ) genubr( p->slab );
321:
322: }
323:
324: makeheap(p, m, n)
325: register struct sw *p;
326: {
327: register int q;
328:
329: q = select(m);
330: heapsw[n] = p[q];
331: if( q>1 ) makeheap(p, q-1, 2*n);
332: if( q<m ) makeheap(p+q, m-q, 2*n+1);
333: }
334:
335: select(m) {
336: register int l,i,k;
337:
338: for(i=1; ; i*=2)
339: if( (i-1) > m ) break;
340: l = ((k = i/2 - 1) + 1)/2;
341: return( l + (m-k < l ? m-k : l));
342: }
343:
344: walkheap(start, limit)
345: {
346: int label;
347:
348:
349: if( start > limit ) return;
350: sswtest( heapsw[start].sval, heapsw[start].slab );
351: if( (2*start) > limit ) {
352: genubr( heapsw[0].slab );
353: return;
354: }
355: if( (2*start+1) <= limit ) {
356: label = getlab();
357: hswelse( label );
358: } else
359: hswelse( heapsw[0].slab );
360: walkheap( 2*start, limit);
361: if( (2*start+1) <= limit ) {
362: deflab( label );
363: walkheap( 2*start+1, limit);
364: }
365: }
366:
367:
368: dswbegin( numb, first, range, labl, dlab )
369: CONSZ first, range;
370: int numb, labl, dlab;
371: {
372: printx(" casel r0,$%ld,$%ld\n", first, range );
373: printx("L%d:\n", labl );
374: tablelabel = labl;
375: }
376:
377: dswcase( l )
378: int l;
379: {
380: printx(" .word L%d-L%d\n", l, tablelabel );
381: }
382:
383: sswtest( val, lab )
384: CONSZ val;
385: int lab;
386: {
387: printx( " cmpl r0,$%ld\n jeql L%d\n", val, lab );
388: }
389:
390: hswelse( lab )
391: int lab;
392: {
393: printx(" jgtr L%d\n", lab );
394: }
395: #endif /* COMBINED */
396:
397: OFFSZ inoff; /* size of offset in structure */
398:
399: static inwd; /* current bit offset in word */
400: static long word; /* word being built from fields */
401:
402: zecode( n )
403: int n;
404: {
405: /* n integer words of zeros */
406: if (n <= 0) return;
407: printx( " .space %d\n", 4*n );
408: inoff += n*SZINT;
409: }
410:
411: vfdzero( n ){ /* define n bits of zeros in a vfd */
412:
413: /* this could be done more cleverly: the following is safe */
414:
415: sz_incode( (CONSZ)0, n );
416: }
417:
418: incode (p, sz)
419: NODE *p;
420: {
421: sz_incode(p->tn.lval, sz);
422: }
423:
424: sz_incode( val, sz )
425: CONSZ val;
426: {
427:
428: /* generate initialization code for assigning a constant c
429: to a field of width sz */
430: /* we assume that the proper alignment has been obtained */
431: /* inoff is updated to have the proper final value */
432:
433: if((sz+inwd) > SZLONG) cerror("incode: field > long");
434:
435: /* this code will have to be replaced if the size of a long on
436: /* the target machine differs from that on the host machine */
437:
438: # ifdef RTOLBYTES
439: word |= ((unsigned)(val<<(SZLONG-sz))) >> (SZLONG-sz-inwd);
440: # else
441: word |= ((unsigned)(val<<(SZLONG-sz))) >> inwd;
442: # endif
443: inwd += sz;
444: inoff += sz;
445:
446: /* if initialization can be carried out using shorts, do it */
447: # if (SZSHORT >= ALINIT)
448: if(inwd == SZSHORT )
449: {
450: # ifdef RTOLBYTES
451: genshort( (short) word );
452: # else
453: genshort( (short) (word>>(SZLONG-SZSHORT)) );
454: # endif
455: word = inwd = 0;
456: } else
457: # endif
458: if( inwd == SZLONG )
459: {
460: genlong( word );
461: word = inwd = 0;
462: }
463: }
464:
465: fincode( d, sz )
466: double d;
467: int sz;
468: {
469: /* output code to initialize space of size sz to the value d */
470: /* the proper alignment has been obtained */
471: /* on the target machine, write it out in hex! */
472:
473: #if defined(vax)
474: union { float f; double d; int i[2] } cheat;
475:
476: if (sz == SZDOUBLE)
477: {
478: cheat.d = d;
479: printx("\t.long\t0x%x,0x%x\t# %.20e\n", cheat.i[0], cheat.i[1],
480: cheat.d);
481: }
482: else
483: {
484: cheat.f = d;
485: printx("\t.long\t0x%x\t# %.20e\n", cheat.i[0], cheat.f);
486: }
487: #else
488: printx(" %s 0%c%.20e\n",
489: sz == SZDOUBLE ? ".double" : ".float",
490: sz == SZDOUBLE ? 'd' : 'f', d);
491: #endif
492: inoff += sz;
493:
494: }
495:
496: int ftlab1, ftlab2;
497: int proflag;
498:
499: int ent_mask[] = {
500: 0,0,0,0,0, 0xfc0, 0xf80, 0xf00, 0xe00, 0xc00, 0x800, 0};
501:
502: #if defined(COMBINED)
503: efcode(type)
504: int type;
505: #else
506: efcode()
507: #endif
508: {
509: /* code for the end of a function */
510: long spoff; /* offset from stack pointer */
511:
512: #if defined(COMBINED)
513: deflab(retlab);
514: repl_retval(type);
515: printx("\tret\n");
516: #else
517: genret( strftn, strftn, retlab );
518: #endif
519: printx( " .set L.R%d,0x%x\n", ftnno, ent_mask[minrvar] );
520:
521: #ifdef FORT
522: spoff = maxboff;
523: if( spoff >= BITOOR(AUTOINIT) ) spoff -= BITOOR(AUTOINIT);
524: spoff += maxtemp;
525: spoff /= SZCHAR;
526: printx( " .set L.F%d,%ld\n", ftnno, spoff / SZCHAR );
527: #else
528: spoff = maxboff;
529: if( spoff >= BITOOR(AUTOINIT) ) spoff -= BITOOR(AUTOINIT);
530: spoff += maxtemp;
531: spoff /= SZCHAR;
532: printx("\t.set\tL.SO%d,0x%x\n", ftnno, spoff);
533: #endif
534: regvar = minrvar = 11;
535: #ifdef GDEBUG
536: dbfunend(getlab());
537: #endif
538: }
539:
540: bfcode( a, n )
541: int a[], n;
542: {
543: /* code for the beginning of a function; a is an array of
544: indices in stab for the arguments; n is the number */
545: register i;
546:
547: /* routine prolog */
548:
549: printx( " .word L.R%d\n", ftnno);
550: printx("\tsubl2\t$L.SO%d,sp\n", ftnno);
551:
552: retlab = getlab();
553:
554: if( proflag )
555: { /* profile code */
556: i = getlab();
557: printx(" movab L%d,r0\n", i);
558: printx(" jsb mcount\n");
559: printx(" .data\n");
560: printx(" .align 2\n");
561: printx("L%d: .long 0\n", i);
562: printx(" .text\n");
563: }
564: if(Pflag) {
565: printx("\t.data\n\t.comm _proFptr,4\n\t.text\n");
566: printx("\ttstl locprof+4\n\tbneq L%da\n", ++bbcnt);
567: printx("\tmovl _proFptr,locprof+4\n\tmoval locprof,_proFptr\n");
568: printx("#entry %d\n", bbcnt);
569: printf("L%da:\tincl locprof+%d\n", bbcnt, 4*(bbcnt+3));
570: }
571: #ifdef GDEBUG
572: dbfunbeg(&stab[curftn]);
573: for (i = 0; i < n; ++i) {
574: extern TWORD argty[];
575: extern int argsoff[];
576: struct symtab q;
577: q = stab[a[i]];
578: q.sclass = PARAM;
579: q.stype = argty[i];
580: q.offset = argsoff[i];
581: dbfunarg(&q);
582: }
583: #endif
584: }
585:
586: defnam( psym )
587: register struct symtab *psym;
588: {
589: /* define the current location as the name psym->sname
590: * first give the debugging info for external definitions
591: */
592: /*if( psym->slevel == 0 ) /* make sure it's external */
593: /* ISFTN(psym->stype) ? prdef(psym,0) : prdef(psym,dsflag);
594: */
595:
596: if (psym->sclass == EXTDEF)
597: printx( " .globl %s\n", exname(psym->sname) );
598: printx("%s:\n", exname(psym->sname));
599: }
600:
601: commdec(id) /* generate a .comm from stab index id */
602: int id;
603: {
604: #if !defined(COMBINED)
605: register struct symtab *psym;
606: OFFSZ n;
607:
608: psym = &stab[id];
609: psym->sflags |= SBSS;
610: n = tsize(psym->stype, psym->dimoff, psym->sizoff) / SZCHAR;
611: if (psym->sclass == STATIC)
612: if (psym->slevel)
613: printx(" .lcomm L%d,%ld\n", psym->offset, n);
614: else
615: printx(" .lcomm %s,%ld\n", exname(psym->sname), n);
616: else if (psym->sclass == EXTERN)
617: printx(" .comm %s,%ld\n", exname(psym->sname), n);
618:
619: else
620: cerror("Non-static/external in common");
621: #endif
622: }
623:
624: myfcon(p)
625: NODE *p;
626: {
627: union { double d; int i[2]; } u;
628:
629: u.d = p->fpn.dval;
630: if (u.i[1] == 0) /* no significant lo bits, shorten */
631: {
632: p->fn.type = FLOAT;
633: p->fn.csiz = FLOAT;
634: }
635: }
636:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.