|
|
1.1 root 1: /*
2: * Copyright (c) 1980 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char sccsid[] = "@(#)fend.c 5.4 (Berkeley) 1/12/87";
9: #endif not lint
10:
11: #include "whoami.h"
12: #include "0.h"
13: #include "tree.h"
14: #include "opcode.h"
15: #include "objfmt.h"
16: #include "align.h"
17: #include "tmps.h"
18:
19: /*
20: * this array keeps the pxp counters associated with
21: * functions and procedures, so that they can be output
22: * when their bodies are encountered
23: */
24: int bodycnts[ DSPLYSZ ];
25:
26: #ifdef PC
27: # include "pc.h"
28: # include <pcc.h>
29: #endif PC
30:
31: #ifdef OBJ
32: int cntpatch;
33: int nfppatch;
34: #endif OBJ
35:
36: #include "tree_ty.h"
37:
38: struct nl *Fp;
39: int pnumcnt;
40: /*
41: * Funcend is called to
42: * finish a block by generating
43: * the code for the statements.
44: * It then looks for unresolved declarations
45: * of labels, procedures and functions,
46: * and cleans up the name list.
47: * For the program, it checks the
48: * semantics of the program
49: * statement (yuchh).
50: */
51: funcend(fp, bundle, endline)
52: struct nl *fp;
53: struct tnode *bundle;
54: int endline;
55: {
56: register struct nl *p;
57: register int i, b;
58: int inp, out;
59: struct tnode *blk;
60: bool chkref;
61: struct nl *iop;
62: char *cp;
63: extern int cntstat;
64: # ifdef PC
65: struct entry_exit_cookie eecookie;
66: # endif PC
67: # ifndef PC
68: int var;
69: # endif PC
70:
71: cntstat = 0;
72: /*
73: * yyoutline();
74: */
75: if (program != NIL)
76: line = program->value[3];
77: blk = bundle->stmnt_blck.stmnt_list;
78: if (fp == NIL) {
79: cbn--;
80: # ifdef PTREE
81: nesting--;
82: # endif PTREE
83: return;
84: }
85: #ifdef OBJ
86: /*
87: * Patch the branch to the entry point of the function.
88: * Assure alignment of O_BEG structure.
89: */
90: if (((int)lc & 02) == 0)
91: word(0);
92: patch4((PTR_DCL) fp->value[NL_ENTLOC]);
93: /*
94: * Put out the block entrance code and the block name.
95: * HDRSZE is the number of bytes of info in the static
96: * BEG data area exclusive of the proc name. It is
97: * currently defined as:
98: /* struct hdr {
99: /* long framesze; /* number of bytes of local vars */
100: /* long nargs; /* number of bytes of arguments */
101: /* bool tests; /* TRUE => perform runtime tests */
102: /* short offset; /* offset of procedure in source file */
103: /* char name[1]; /* name of active procedure */
104: /* };
105: */
106: # define HDRSZE (2 * sizeof(long) + sizeof(short) + sizeof(bool))
107: var = put(2, ((lenstr(fp->symbol,0) + HDRSZE) << 8)
108: | (cbn == 1 && opt('p') == 0 ? O_NODUMP: O_BEG), (long)0);
109: /*
110: * output the number of bytes of arguments
111: * this is only checked on formal calls.
112: */
113: (void) put(2, O_CASE4, cbn == 1 ? (long)0 : (long)(fp->value[NL_OFFS]-DPOFF2));
114: /*
115: * Output the runtime test mode for the routine
116: */
117: (void) put(2, sizeof(bool) == 2 ? O_CASE2 : O_CASE4, opt('t') ? TRUE : FALSE);
118: /*
119: * Output line number and routine name
120: */
121: (void) put(2, O_CASE2, bundle->stmnt_blck.line_no);
122: putstr(fp->symbol, 0);
123: #endif OBJ
124: #ifdef PC
125: /*
126: * put out the procedure entry code
127: */
128: eecookie.nlp = fp;
129: if ( fp -> class == PROG ) {
130: /*
131: * If there is a label declaration in the main routine
132: * then there may be a non-local goto to it that does
133: * not appear in this module. We have to assume that
134: * such a reference may occur and generate code to
135: * prepare for it.
136: */
137: if ( parts[ cbn ] & LPRT ) {
138: parts[ cbn ] |= ( NONLOCALVAR | NONLOCALGOTO );
139: }
140: codeformain();
141: ftnno = fp -> value[NL_ENTLOC];
142: prog_prologue(&eecookie);
143: stabline(bundle->stmnt_blck.line_no);
144: stabfunc(fp, "program", bundle->stmnt_blck.line_no , (long) 0 );
145: } else {
146: ftnno = fp -> value[NL_ENTLOC];
147: fp_prologue(&eecookie);
148: stabline(bundle->stmnt_blck.line_no);
149: stabfunc(fp, fp->symbol, bundle->stmnt_blck.line_no,
150: (long)(cbn - 1));
151: for ( p = fp -> chain ; p != NIL ; p = p -> chain ) {
152: stabparam( p , p -> value[ NL_OFFS ] , (int) lwidth(p->type));
153: }
154: if ( fp -> class == FUNC ) {
155: /*
156: * stab the function variable
157: */
158: p = fp -> ptr[ NL_FVAR ];
159: stablvar( p , p -> value[ NL_OFFS ] , (int) lwidth( p -> type));
160: }
161: /*
162: * stab local variables
163: * rummage down hash chain links.
164: */
165: for ( i = 0 ; i <= 077 ; i++ ) {
166: for ( p = disptab[ i ] ; p != NIL ; p = p->nl_next) {
167: if ( ( p -> nl_block & 037 ) != cbn ) {
168: break;
169: }
170: /*
171: * stab locals (not parameters)
172: */
173: if ( p -> symbol != NIL ) {
174: if ( p -> class == VAR && p -> value[ NL_OFFS ] < 0 ) {
175: stablvar( p , p -> value[ NL_OFFS ] ,
176: (int) lwidth( p -> type ) );
177: } else if ( p -> class == CONST ) {
178: stabconst( p );
179: }
180: }
181: }
182: }
183: }
184: stablbrac( cbn );
185: /*
186: * ask second pass to allocate known locals
187: */
188: putlbracket(ftnno, &sizes[cbn]);
189: fp_entrycode(&eecookie);
190: #endif PC
191: if ( monflg ) {
192: if ( fp -> value[ NL_CNTR ] != 0 ) {
193: inccnt( fp -> value [ NL_CNTR ] );
194: }
195: inccnt( bodycnts[ fp -> nl_block & 037 ] );
196: }
197: if (fp->class == PROG) {
198: /*
199: * The glorious buffers option.
200: * 0 = don't buffer output
201: * 1 = line buffer output
202: * 2 = 512 byte buffer output
203: */
204: # ifdef OBJ
205: if (opt('b') != 1)
206: (void) put(1, O_BUFF | opt('b') << 8);
207: # endif OBJ
208: # ifdef PC
209: if ( opt( 'b' ) != 1 ) {
210: putleaf( PCC_ICON , 0 , 0
211: , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_BUFF" );
212: putleaf( PCC_ICON , opt( 'b' ) , 0 , PCCT_INT , (char *) 0 );
213: putop( PCC_CALL , PCCT_INT );
214: putdot( filename , line );
215: }
216: # endif PC
217: inp = 0;
218: out = 0;
219: for (p = fp->chain; p != NIL; p = p->chain) {
220: if (pstrcmp(p->symbol, input->symbol) == 0) {
221: inp++;
222: continue;
223: }
224: if (pstrcmp(p->symbol, output->symbol) == 0) {
225: out++;
226: continue;
227: }
228: iop = lookup1(p->symbol);
229: if (iop == NIL || bn != cbn) {
230: error("File %s listed in program statement but not declared", p->symbol);
231: continue;
232: }
233: if (iop->class != VAR) {
234: error("File %s listed in program statement but declared as a %s", p->symbol, classes[iop->class]);
235: continue;
236: }
237: if (iop->type == NIL)
238: continue;
239: if (iop->type->class != FILET) {
240: error("File %s listed in program statement but defined as %s",
241: p->symbol, nameof(iop->type));
242: continue;
243: }
244: # ifdef OBJ
245: (void) put(2, O_CON24, text(iop->type) ? 0 : width(iop->type->type));
246: i = lenstr(p->symbol,0);
247: (void) put(2, O_CON24, i);
248: (void) put(2, O_LVCON, i);
249: putstr(p->symbol, 0);
250: (void) put(2, O_LV | bn<<8+INDX, (int)iop->value[NL_OFFS]);
251: (void) put(1, O_DEFNAME);
252: # endif OBJ
253: # ifdef PC
254: putleaf( PCC_ICON , 0 , 0
255: , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
256: , "_DEFNAME" );
257: putLV( p -> symbol , bn , iop -> value[NL_OFFS] ,
258: iop -> extra_flags , p2type( iop ) );
259: putCONG( p -> symbol , strlen( p -> symbol )
260: , LREQ );
261: putop( PCC_CM , PCCT_INT );
262: putleaf( PCC_ICON , strlen( p -> symbol )
263: , 0 , PCCT_INT , (char *) 0 );
264: putop( PCC_CM , PCCT_INT );
265: putleaf( PCC_ICON
266: , text(iop->type) ? 0 : width(iop->type->type)
267: , 0 , PCCT_INT , (char *) 0 );
268: putop( PCC_CM , PCCT_INT );
269: putop( PCC_CALL , PCCT_INT );
270: putdot( filename , line );
271: # endif PC
272: }
273: }
274: /*
275: * Process the prog/proc/func body
276: */
277: noreach = FALSE;
278: line = bundle->stmnt_blck.line_no;
279: statlist(blk);
280: # ifdef PTREE
281: {
282: pPointer Body = tCopy( blk );
283:
284: pDEF( PorFHeader[ nesting -- ] ).PorFBody = Body;
285: }
286: # endif PTREE
287: # ifdef OBJ
288: if (cbn== 1 && monflg != FALSE) {
289: patchfil((PTR_DCL) (cntpatch - 2), (long)cnts, 2);
290: patchfil((PTR_DCL) (nfppatch - 2), (long)pfcnt, 2);
291: }
292: # endif OBJ
293: # ifdef PC
294: if ( fp -> class == PROG && monflg ) {
295: putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
296: , "_PMFLUSH" );
297: putleaf( PCC_ICON , cnts , 0 , PCCT_INT , (char *) 0 );
298: putleaf( PCC_ICON , pfcnt , 0 , PCCT_INT , (char *) 0 );
299: putop( PCC_CM , PCCT_INT );
300: putLV( PCPCOUNT , 0 , 0 , NGLOBAL , PCCT_INT );
301: putop( PCC_CM , PCCT_INT );
302: putop( PCC_CALL , PCCT_INT );
303: putdot( filename , line );
304: }
305: # endif PC
306: /*
307: * Clean up the symbol table displays and check for unresolves
308: */
309: line = endline;
310: if (fp->class == PROG && inp == 0 && (input->nl_flags & (NUSED|NMOD)) != 0) {
311: recovered();
312: error("Input is used but not defined in the program statement");
313: }
314: if (fp->class == PROG && out == 0 && (output->nl_flags & (NUSED|NMOD)) != 0) {
315: recovered();
316: error("Output is used but not defined in the program statement");
317: }
318: b = cbn;
319: Fp = fp;
320: chkref = (syneflg == errcnt[cbn] && opt('w') == 0)?TRUE:FALSE;
321: for (i = 0; i <= 077; i++) {
322: for (p = disptab[i]; p != NIL && (p->nl_block & 037) == b; p = p->nl_next) {
323: /*
324: * Check for variables defined
325: * but not referenced
326: */
327: if (chkref && p->symbol != NIL)
328: switch (p->class) {
329: case FIELD:
330: /*
331: * If the corresponding record is
332: * unused, we shouldn't complain about
333: * the fields.
334: */
335: default:
336: if ((p->nl_flags & (NUSED|NMOD)) == 0) {
337: warning();
338: nerror("%s %s is neither used nor set", classes[p->class], p->symbol);
339: break;
340: }
341: /*
342: * If a var parameter is either
343: * modified or used that is enough.
344: */
345: if (p->class == REF)
346: continue;
347: # ifdef OBJ
348: if ((p->nl_flags & NUSED) == 0) {
349: warning();
350: nerror("%s %s is never used", classes[p->class], p->symbol);
351: break;
352: }
353: # endif OBJ
354: # ifdef PC
355: if (((p->nl_flags & NUSED) == 0) && ((p->extra_flags & NEXTERN) == 0)) {
356: warning();
357: nerror("%s %s is never used", classes[p->class], p->symbol);
358: break;
359: }
360: # endif PC
361: if ((p->nl_flags & NMOD) == 0) {
362: warning();
363: nerror("%s %s is used but never set", classes[p->class], p->symbol);
364: break;
365: }
366: case LABEL:
367: case FVAR:
368: case BADUSE:
369: break;
370: }
371: switch (p->class) {
372: case BADUSE:
373: cp = "s";
374: /* This used to say ud_next
375: that is not a member of nl so
376: i changed it to nl_next,
377: which may be wrong */
378: if (p->chain->nl_next == NIL)
379: cp++;
380: eholdnl();
381: if (p->value[NL_KINDS] & ISUNDEF)
382: nerror("%s undefined on line%s", p->symbol, cp);
383: else
384: nerror("%s improperly used on line%s", p->symbol, cp);
385: pnumcnt = 10;
386: pnums((struct udinfo *) p->chain);
387: pchr('\n');
388: break;
389:
390: case FUNC:
391: case PROC:
392: # ifdef OBJ
393: if ((p->nl_flags & NFORWD))
394: nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
395: # endif OBJ
396: # ifdef PC
397: if ((p->nl_flags & NFORWD) && ((p->extra_flags & NEXTERN) == 0))
398: nerror("Unresolved forward declaration of %s %s", classes[p->class], p->symbol);
399: # endif PC
400: break;
401:
402: case LABEL:
403: if (p->nl_flags & NFORWD)
404: nerror("label %s was declared but not defined", p->symbol);
405: break;
406: case FVAR:
407: if ((p->nl_flags & NMOD) == 0)
408: nerror("No assignment to the function variable");
409: break;
410: }
411: }
412: /*
413: * Pop this symbol
414: * table slot
415: */
416: disptab[i] = p;
417: }
418:
419: # ifdef OBJ
420: (void) put(1, O_END);
421: # endif OBJ
422: # ifdef PC
423: fp_exitcode(&eecookie);
424: stabrbrac(cbn);
425: putrbracket(ftnno);
426: fp_epilogue(&eecookie);
427: if (fp -> class != PROG) {
428: fp_formalentry(&eecookie);
429: }
430: /*
431: * declare pcp counters, if any
432: */
433: if ( monflg && fp -> class == PROG ) {
434: putprintf( " .data" , 0 );
435: aligndot(PCCT_INT);
436: putprintf( " .comm " , 1 );
437: putprintf( PCPCOUNT , 1 );
438: putprintf( ",%d" , 0 , ( cnts + 1 ) * sizeof (long) );
439: putprintf( " .text" , 0 );
440: }
441: # endif PC
442: #ifdef DEBUG
443: dumpnl(fp->ptr[2], (int) fp->symbol);
444: #endif
445:
446: #ifdef OBJ
447: /*
448: * save the namelist for the debugger pdx
449: */
450:
451: savenl(fp->ptr[2], (int) fp->symbol);
452: #endif
453:
454: /*
455: * Restore the
456: * (virtual) name list
457: * position
458: */
459: nlfree(fp->ptr[2]);
460: /*
461: * Proc/func has been
462: * resolved
463: */
464: fp->nl_flags &= ~NFORWD;
465: /*
466: * Patch the beg
467: * of the proc/func to
468: * the proper variable size
469: */
470: if (Fp == NIL)
471: elineon();
472: # ifdef OBJ
473: patchfil((PTR_DCL) var,
474: roundup(-sizes[cbn].om_max, (long) A_STACK), 2);
475: # endif OBJ
476: cbn--;
477: if (inpflist(fp->symbol)) {
478: opop('l');
479: }
480: }
481:
482: #ifdef PC
483: /*
484: * construct the long name of a function based on it's static nesting.
485: * into a caller-supplied buffer (that should be about BUFSIZ big).
486: */
487: sextname( buffer , name , level )
488: char buffer[];
489: char *name;
490: int level;
491: {
492: char *starthere;
493: int i;
494:
495: starthere = &buffer[0];
496: for ( i = 1 ; i < level ; i++ ) {
497: sprintf( starthere , EXTFORMAT , enclosing[ i ] );
498: starthere += strlen( enclosing[ i ] ) + 1;
499: }
500: sprintf( starthere , EXTFORMAT , name );
501: starthere += strlen( name ) + 1;
502: if ( starthere >= &buffer[ BUFSIZ ] ) {
503: panic( "sextname" );
504: }
505: }
506:
507: /*
508: * code for main()
509: */
510: #ifdef vax
511:
512: codeformain()
513: {
514: putprintf(" .text" , 0 );
515: putprintf(" .align 1" , 0 );
516: putprintf(" .globl _main" , 0 );
517: putprintf("_main:" , 0 );
518: putprintf(" .word 0" , 0 );
519: if ( opt ( 't' ) ) {
520: putprintf(" pushl $1" , 0 );
521: } else {
522: putprintf(" pushl $0" , 0 );
523: }
524: putprintf(" calls $1,_PCSTART" , 0 );
525: putprintf(" movl 4(ap),__argc" , 0 );
526: putprintf(" movl 8(ap),__argv" , 0 );
527: putprintf(" calls $0,_program" , 0 );
528: putprintf(" pushl $0" , 0 );
529: putprintf(" calls $1,_PCEXIT" , 0 );
530: }
531: #endif vax
532:
533: #ifdef tahoe
534: codeformain()
535: {
536: putprintf(" .text" , 0 );
537: putprintf(" .align 1" , 0 );
538: putprintf(" .globl _main" , 0 );
539: putprintf("_main:" , 0 );
540: putprintf(" .word 0" , 0 );
541: if ( opt ( 't' ) ) {
542: putprintf(" pushl $1" , 0 );
543: } else {
544: putprintf(" pushl $0" , 0 );
545: }
546: putprintf(" callf $8,_PCSTART" , 0 );
547: putprintf(" movl 4(fp),__argc" , 0 );
548: putprintf(" movl 8(fp),__argv" , 0 );
549: putprintf(" callf $4,_program" , 0 );
550: putprintf(" pushl $0" , 0 );
551: putprintf(" callf $8,_PCEXIT" , 0 );
552: }
553: #endif tahoe
554:
555: /*
556: * prologue for the program.
557: * different because it
558: * doesn't have formal entry point
559: */
560: #if defined(vax) || defined(tahoe)
561: prog_prologue(eecookiep)
562: struct entry_exit_cookie *eecookiep;
563: {
564: putprintf(" .text" , 0 );
565: putprintf(" .align 1" , 0 );
566: putprintf(" .globl _program" , 0 );
567: putprintf("_program:" , 0 );
568: /*
569: * register save mask
570: */
571: eecookiep -> savlabel = (int) getlab();
572: putprintf(" .word %s%d", 0, (int) SAVE_MASK_LABEL , eecookiep -> savlabel );
573: }
574:
575: fp_prologue(eecookiep)
576: struct entry_exit_cookie *eecookiep;
577: {
578:
579: sextname( eecookiep -> extname, eecookiep -> nlp -> symbol , cbn - 1 );
580: putprintf( " .text" , 0 );
581: putprintf( " .align 1" , 0 );
582: putprintf( " .globl %s%s", 0, (int) FORMALPREFIX, (int) eecookiep -> extname );
583: putprintf( " .globl %s" , 0 , (int) eecookiep -> extname );
584: putprintf( "%s:" , 0 , (int) eecookiep -> extname );
585: /*
586: * register save mask
587: */
588: eecookiep -> savlabel = (int) getlab();
589: putprintf(" .word %s%d", 0, (int) SAVE_MASK_LABEL , eecookiep -> savlabel );
590: }
591: #endif vax || tahoe
592:
593: /*
594: * code before any user code.
595: * or code that is machine dependent.
596: */
597: #ifdef vax
598: fp_entrycode(eecookiep)
599: struct entry_exit_cookie *eecookiep;
600: {
601: int ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
602: int proflabel = (int) getlab();
603: int setjmp0 = (int) getlab();
604:
605: /*
606: * top of code; destination of jump from formal entry code.
607: */
608: eecookiep -> toplabel = (int) getlab();
609: (void) putlab( (char *) eecookiep -> toplabel );
610: putprintf(" subl2 $%s%d,sp" , 0 , (int) FRAME_SIZE_LABEL, ftnno );
611: if ( profflag ) {
612: /*
613: * call mcount for profiling
614: */
615: putprintf( " moval " , 1 );
616: putprintf( PREFIXFORMAT , 1 , (int) LABELPREFIX , proflabel );
617: putprintf( ",r0" , 0 );
618: putprintf( " jsb mcount" , 0 );
619: putprintf( " .data" , 0 );
620: putprintf( " .align 2" , 0 );
621: (void) putlab( (char *) proflabel );
622: putprintf( " .long 0" , 0 );
623: putprintf( " .text" , 0 );
624: }
625: /*
626: * if there are nested procedures that access our variables
627: * we must save the display.
628: */
629: if ( parts[ cbn ] & NONLOCALVAR ) {
630: /*
631: * save old display
632: */
633: putprintf( " movq %s+%d,%d(%s)" , 0
634: , (int) DISPLAYNAME , cbn * sizeof(struct dispsave)
635: , DSAVEOFFSET , (int) P2FPNAME );
636: /*
637: * set up new display by saving AP and FP in appropriate
638: * slot in display structure.
639: */
640: putprintf( " movq %s,%s+%d" , 0
641: , (int) P2APNAME , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) );
642: }
643: /*
644: * set underflow checking if runtime tests
645: */
646: if ( opt( 't' ) ) {
647: putprintf( " bispsw $0xe0" , 0 );
648: }
649: /*
650: * zero local variables if checking is on
651: * by calling blkclr( bytes of locals , starting local address );
652: */
653: if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
654: putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
655: , "_blkclr" );
656: putLV((char *) 0 , cbn , (int) sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR );
657: putleaf( PCC_ICON , (int) (( -sizes[ cbn ].om_max ) - DPOFF1)
658: , 0 , PCCT_INT ,(char *) 0 );
659: putop( PCC_CM , PCCT_INT );
660: putop( PCC_CALL , PCCT_INT );
661: putdot( filename , line );
662: }
663: /*
664: * set up goto vector if non-local goto to this frame
665: */
666: if ( parts[ cbn ] & NONLOCALGOTO ) {
667: putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
668: , "_setjmp" );
669: putLV( (char *) 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
670: putop( PCC_CALL , PCCT_INT );
671: putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 );
672: putop( PCC_NE , PCCT_INT );
673: putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , (char *) 0 );
674: putop( PCC_CBRANCH , PCCT_INT );
675: putdot( filename , line );
676: /*
677: * on non-local goto, setjmp returns with address to
678: * be branched to.
679: */
680: putprintf( " jmp (r0)" , 0 );
681: (void) putlab((char *) setjmp0);
682: }
683: }
684: #endif vax
685:
686: #ifdef tahoe
687: fp_entrycode(eecookiep)
688: struct entry_exit_cookie *eecookiep;
689: {
690: int ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
691: int proflabel = (int) getlab();
692: int setjmp0 = (int) getlab();
693:
694: /*
695: * top of code; destination of jump from formal entry code.
696: */
697: eecookiep -> toplabel = (int) getlab();
698: (void) putlab( (char *) eecookiep -> toplabel );
699: putprintf(" subl3 $%s%d,fp,sp" , 0 , (int) FRAME_SIZE_LABEL, ftnno );
700: if ( profflag ) {
701: /*
702: * call mcount for profiling
703: */
704: putprintf( " pushal " , 1 );
705: putprintf( PREFIXFORMAT , 0 , (int) LABELPREFIX , proflabel );
706: putprintf( " callf $8,mcount" , 0 );
707: putprintf( " .data" , 0 );
708: putprintf( " .align 2" , 0 );
709: (void) putlab( (char *) proflabel );
710: putprintf( " .long 0" , 0 );
711: putprintf( " .text" , 0 );
712: }
713: /*
714: * if there are nested procedures that access our variables
715: * we must save the display.
716: */
717: if ( parts[ cbn ] & NONLOCALVAR ) {
718: /*
719: * save old display
720: */
721: putprintf( " movl %s+%d,%d(%s)" , 0
722: , (int) DISPLAYNAME , cbn * sizeof(struct dispsave)
723: , DSAVEOFFSET , (int) P2FPNAME );
724: /*
725: * set up new display by saving FP in appropriate
726: * slot in display structure.
727: */
728: putprintf( " movl %s,%s+%d" , 0
729: , (int) P2FPNAME , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) );
730: }
731: /*
732: * set underflow checking if runtime tests
733: */
734: if ( opt( 't' ) ) {
735: putprintf( " bicpsw $0x20" , 0 );
736: }
737: /*
738: * zero local variables if checking is on
739: * by calling blkclr( bytes of locals , starting local address );
740: */
741: if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
742: putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
743: , "_blkclr" );
744: putLV((char *) 0 , cbn , (int) sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR );
745: putleaf( PCC_ICON , (int) (( -sizes[ cbn ].om_max ) - DPOFF1)
746: , 0 , PCCT_INT ,(char *) 0 );
747: putop( PCC_CM , PCCT_INT );
748: putop( PCC_CALL , PCCT_INT );
749: putdot( filename , line );
750: }
751: /*
752: * set up goto vector if non-local goto to this frame
753: */
754: if ( parts[ cbn ] & NONLOCALGOTO ) {
755: putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
756: , "_setjmp" );
757: putLV( (char *) 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
758: putop( PCC_CALL , PCCT_INT );
759: putleaf( PCC_ICON , 0 , 0 , PCCT_INT , (char *) 0 );
760: putop( PCC_NE , PCCT_INT );
761: putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , (char *) 0 );
762: putop( PCC_CBRANCH , PCCT_INT );
763: putdot( filename , line );
764: /*
765: * on non-local goto, setjmp returns with address to
766: * be branched to.
767: */
768: putprintf( " jmp (r0)" , 0 );
769: (void) putlab((char *) setjmp0);
770: }
771: }
772: #endif tahoe
773:
774: #if defined(vax) || defined(tahoe)
775: fp_exitcode(eecookiep)
776: struct entry_exit_cookie *eecookiep;
777: {
778: /*
779: * if there were file variables declared at this level
780: * call PCLOSE( ap ) to clean them up.
781: */
782: if ( dfiles[ cbn ] ) {
783: putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
784: , "_PCLOSE" );
785: putleaf( PCC_REG , 0 , P2AP , PCCM_ADDTYPE( PCCT_CHAR , PCCTM_PTR ) , (char *) 0 );
786: putop( PCC_CALL , PCCT_INT );
787: putdot( filename , line );
788: }
789: /*
790: * if this is a function,
791: * the function variable is the return value.
792: * if it's a scalar valued function, return scalar,
793: * else, return a pointer to the structure value.
794: */
795: if ( eecookiep-> nlp -> class == FUNC ) {
796: struct nl *fvar = eecookiep-> nlp -> ptr[ NL_FVAR ];
797: long fvartype = p2type( fvar -> type );
798: long label;
799: char labelname[ BUFSIZ ];
800:
801: switch ( classify( fvar -> type ) ) {
802: case TBOOL:
803: case TCHAR:
804: case TINT:
805: case TSCAL:
806: case TDOUBLE:
807: case TPTR:
808: putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
809: fvar -> value[ NL_OFFS ] ,
810: fvar -> extra_flags ,
811: (int) fvartype );
812: putop( PCC_FORCE , (int) fvartype );
813: break;
814: default:
815: label = (int) getlab();
816: sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label );
817: putprintf( " .data" , 0 );
818: aligndot(A_STRUCT);
819: putprintf( " .lcomm %s,%d" , 0 ,
820: (int) labelname , (int) lwidth( fvar -> type ) );
821: putprintf( " .text" , 0 );
822: putleaf( PCC_NAME , 0 , 0 , (int) fvartype , labelname );
823: putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
824: fvar -> value[ NL_OFFS ] ,
825: fvar -> extra_flags ,
826: (int) fvartype );
827: putstrop( PCC_STASG , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR) ,
828: (int) lwidth( fvar -> type ) ,
829: align( fvar -> type ) );
830: putdot( filename , line );
831: putleaf( PCC_ICON , 0 , 0 , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR), labelname );
832: putop( PCC_FORCE , (int) PCCM_ADDTYPE(fvartype, PCCTM_PTR) );
833: break;
834: }
835: putdot( filename , line );
836: }
837: /*
838: * if there are nested procedures we must save the display.
839: */
840: if ( parts[ cbn ] & NONLOCALVAR ) {
841: /*
842: * restore old display entry from save area
843: */
844: #ifdef vax
845: putprintf( " movq %d(%s),%s+%d" , 0
846: , DSAVEOFFSET , (int) P2FPNAME
847: , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) );
848: #endif
849: #ifdef tahoe
850: putprintf( " movl %d(%s),%s+%d" , 0
851: , DSAVEOFFSET , (int) P2FPNAME
852: , (int) DISPLAYNAME , cbn * sizeof(struct dispsave) );
853: #endif
854: }
855: }
856: #endif vax || tahoe
857:
858: #if defined(vax) || defined(tahoe)
859: fp_epilogue(eecookiep)
860: struct entry_exit_cookie *eecookiep;
861: {
862: stabline(line);
863: putprintf(" ret" , 0 );
864: /*
865: * set the register save mask.
866: */
867: putprintf(" .set %s%d,0x%x", 0,
868: (int) SAVE_MASK_LABEL, eecookiep -> savlabel, savmask());
869: }
870: #endif vax || tahoe
871:
872: #if defined(vax) || defined(tahoe)
873: fp_formalentry(eecookiep)
874: struct entry_exit_cookie *eecookiep;
875: {
876:
877: putprintf(" .align 1", 0);
878: putprintf("%s%s:" , 0 , (int) FORMALPREFIX , (int) eecookiep -> extname );
879: putprintf(" .word %s%d", 0, (int) SAVE_MASK_LABEL, eecookiep -> savlabel );
880: putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_FCALL" );
881: putRV((char *) 0 , cbn ,
882: eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) ,
883: NPARAM , PCCTM_PTR | PCCT_STRTY );
884: putRV((char *) 0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, PCCTM_PTR|PCCT_STRTY);
885: putop( PCC_CM , PCCT_INT );
886: putop( PCC_CALL , PCCT_INT );
887: putdot( filename , line );
888: putjbr( (long) eecookiep -> toplabel );
889: }
890: #endif vax || tahoe
891:
892: #ifdef mc68000
893:
894: codeformain()
895: {
896: putprintf(" .text", 0);
897: putprintf(" .globl _main", 0);
898: putprintf("_main:", 0);
899: putprintf(" link %s,#0", 0, P2FPNAME);
900: if (opt('t')) {
901: putprintf(" pea 1", 0);
902: } else {
903: putprintf(" pea 0", 0);
904: }
905: putprintf(" jbsr _PCSTART", 0);
906: putprintf(" addql #4,sp", 0);
907: putprintf(" movl %s@(8),__argc", 0, P2FPNAME);
908: putprintf(" movl %s@(12),__argv", 0, P2FPNAME);
909: putprintf(" jbsr _program", 0);
910: putprintf(" pea 0", 0);
911: putprintf(" jbsr _PCEXIT", 0);
912: }
913:
914: prog_prologue(eecookiep)
915: struct entry_exit_cookie *eecookiep;
916: {
917: int ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
918:
919: putprintf(" .text", 0);
920: putprintf(" .globl _program", 0);
921: putprintf("_program:", 0);
922: putprintf(" link %s,#0", 0, P2FPNAME);
923: putprintf(" addl #-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
924: /* touch new end of stack, to break more stack space */
925: putprintf(" tstb sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
926: putprintf(" moveml #%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
927: }
928:
929: fp_prologue(eecookiep)
930: struct entry_exit_cookie *eecookiep;
931: {
932: int ftnno = eecookiep -> nlp -> value[NL_ENTLOC];
933:
934: sextname(eecookiep -> extname, eecookiep -> nlp -> symbol, cbn - 1);
935: putprintf(" .text", 0);
936: putprintf(" .globl %s%s", 0, FORMALPREFIX, eecookiep -> extname);
937: putprintf(" .globl %s", 0, eecookiep -> extname);
938: putprintf("%s:", 0, eecookiep -> extname);
939: putprintf(" link %s,#0", 0, P2FPNAME);
940: putprintf(" addl #-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
941: /* touch new end of stack, to break more stack space */
942: putprintf(" tstb sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
943: putprintf(" moveml #%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
944: }
945:
946: fp_entrycode(eecookiep)
947: struct entry_exit_cookie *eecookiep;
948: {
949: char *proflabel = getlab();
950: char *setjmp0 = getlab();
951:
952: /*
953: * fill in the label cookie
954: */
955: eecookiep -> toplabel = getlab();
956: (void) putlab(eecookiep -> toplabel);
957: /*
958: * call mcount if we are profiling.
959: */
960: if ( profflag ) {
961: putprintf(" movl #%s%d,a0", 0, LABELPREFIX, proflabel);
962: putprintf(" jsr mcount", 0);
963: putprintf(" .data", 0);
964: putprintf(" .even", 0);
965: (void) putlab(proflabel);
966: putprintf(" .long 0", 0);
967: putprintf(" .text", 0);
968: }
969: /*
970: * if there are nested procedures that access our variables
971: * we must save the display
972: */
973: if (parts[cbn] & NONLOCALVAR) {
974: /*
975: * save the old display
976: */
977: putprintf(" movl %s+%d,%s@(%d)", 0,
978: DISPLAYNAME, cbn * sizeof(struct dispsave),
979: P2FPNAME, DSAVEOFFSET);
980: /*
981: * set up the new display by saving the framepointer
982: * in the display structure.
983: */
984: putprintf(" movl %s,%s+%d", 0,
985: P2FPNAME, DISPLAYNAME, cbn * sizeof(struct dispsave));
986: }
987: /*
988: * zero local variables if checking is on
989: * by calling blkclr( bytes of locals , starting local address );
990: */
991: if ( opt( 't' ) && ( -sizes[ cbn ].om_max ) > DPOFF1 ) {
992: putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
993: , "_blkclr" );
994: putLV( 0 , cbn , sizes[ cbn ].om_max , NLOCAL , PCCT_CHAR );
995: putleaf( PCC_ICON , ( -sizes[ cbn ].om_max ) - DPOFF1
996: , 0 , PCCT_INT , 0 );
997: putop( PCC_CM , PCCT_INT );
998: putop( PCC_CALL , PCCT_INT );
999: putdot( filename , line );
1000: }
1001: /*
1002: * set up goto vector if non-local goto to this frame
1003: */
1004: if ( parts[ cbn ] & NONLOCALGOTO ) {
1005: putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
1006: , "_setjmp" );
1007: putLV( 0 , cbn , GOTOENVOFFSET , NLOCAL , PCCTM_PTR|PCCT_STRTY );
1008: putop( PCC_CALL , PCCT_INT );
1009: putleaf( PCC_ICON , 0 , 0 , PCCT_INT , 0 );
1010: putop( PCC_NE , PCCT_INT );
1011: putleaf( PCC_ICON , setjmp0 , 0 , PCCT_INT , 0 );
1012: putop( PCC_CBRANCH , PCCT_INT );
1013: putdot( filename , line );
1014: /*
1015: * on non-local goto, setjmp returns with address to
1016: * be branched to.
1017: */
1018: putprintf(" movl d0,a0", 0);
1019: putprintf(" jmp a0@", 0);
1020: (void) putlab(setjmp0);
1021: }
1022: }
1023:
1024: fp_exitcode(eecookiep)
1025: struct entry_exit_cookie *eecookiep;
1026: {
1027: /*
1028: * if there were file variables declared at this level
1029: * call PCLOSE( ap ) to clean them up.
1030: */
1031: if ( dfiles[ cbn ] ) {
1032: putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR )
1033: , "_PCLOSE" );
1034: putleaf( PCC_REG , 0 , P2AP , PCCM_ADDTYPE( PCCT_CHAR , PCCTM_PTR ) , 0 );
1035: putop( PCC_CALL , PCCT_INT );
1036: putdot( filename , line );
1037: }
1038: /*
1039: * if this is a function,
1040: * the function variable is the return value.
1041: * if it's a scalar valued function, return scalar,
1042: * else, return a pointer to the structure value.
1043: */
1044: if ( eecookiep -> nlp -> class == FUNC ) {
1045: struct nl *fvar = eecookiep -> nlp -> ptr[ NL_FVAR ];
1046: long fvartype = p2type( fvar -> type );
1047: char *label;
1048: char labelname[ BUFSIZ ];
1049:
1050: switch ( classify( fvar -> type ) ) {
1051: case TBOOL:
1052: case TCHAR:
1053: case TINT:
1054: case TSCAL:
1055: case TDOUBLE:
1056: case TPTR:
1057: putRV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
1058: fvar -> value[ NL_OFFS ] ,
1059: fvar -> extra_flags ,
1060: fvartype );
1061: putop( PCC_FORCE , fvartype );
1062: break;
1063: default:
1064: label = getlab();
1065: sprintf( labelname , PREFIXFORMAT , LABELPREFIX , label );
1066: putprintf(" .lcomm %s,%d", 0,
1067: labelname, lwidth(fvar -> type));
1068: putleaf( PCC_NAME , 0 , 0 , fvartype , labelname );
1069: putLV( fvar -> symbol , ( fvar -> nl_block ) & 037 ,
1070: fvar -> value[ NL_OFFS ] ,
1071: fvar -> extra_flags ,
1072: fvartype );
1073: putstrop( PCC_STASG , PCCM_ADDTYPE(fvartype, PCCTM_PTR) ,
1074: lwidth( fvar -> type ) ,
1075: align( fvar -> type ) );
1076: putdot( filename , line );
1077: putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE(fvartype, PCCTM_PTR), labelname );
1078: putop( PCC_FORCE , PCCM_ADDTYPE(fvartype, PCCTM_PTR) );
1079: break;
1080: }
1081: putdot( filename , line );
1082: }
1083: /*
1084: * if we saved a display, we must restore it.
1085: */
1086: if ( parts[ cbn ] & NONLOCALVAR ) {
1087: /*
1088: * restore old display entry from save area
1089: */
1090: putprintf(" movl %s@(%d),%s+%d", 0,
1091: P2FPNAME, DSAVEOFFSET,
1092: DISPLAYNAME, cbn * sizeof(struct dispsave));
1093: }
1094: }
1095:
1096: fp_epilogue(eecookiep)
1097: struct entry_exit_cookie *eecookiep;
1098: {
1099: /*
1100: * all done by the second pass.
1101: */
1102: }
1103:
1104: fp_formalentry(eecookiep)
1105: struct entry_exit_cookie *eecookiep;
1106: {
1107: putprintf( "%s%s:" , 0 , FORMALPREFIX , eecookiep -> extname );
1108: putprintf(" link %s,#0", 0, P2FPNAME);
1109: putprintf(" addl #-%s%d,sp", 0, FRAME_SIZE_LABEL, ftnno);
1110: /* touch new end of stack, to break more stack space */
1111: putprintf(" tstb sp@(-%s%d)", 0, PAGE_BREAK_LABEL, ftnno);
1112: putprintf(" moveml #%s%d,sp@", 0, SAVE_MASK_LABEL, ftnno);
1113: putleaf( PCC_ICON , 0 , 0 , PCCM_ADDTYPE( PCCTM_FTN | PCCT_INT , PCCTM_PTR ) , "_FCALL" );
1114: putRV( 0 , cbn ,
1115: eecookiep -> nlp -> value[ NL_OFFS ] + sizeof( struct formalrtn * ) ,
1116: NPARAM , PCCTM_PTR | PCCT_STRTY );
1117: putRV(0, cbn, eecookiep -> nlp -> value[NL_OFFS], NPARAM, PCCTM_PTR|PCCT_STRTY);
1118: putop( PCC_CM , PCCT_INT );
1119: putop( PCC_CALL , PCCT_INT );
1120: putdot( filename , line );
1121: putjbr( eecookiep -> toplabel );
1122: }
1123: #endif mc68000
1124: #endif PC
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.