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