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