|
|
1.1 root 1: /*
2: * n2/cc2.c
3: * Main driving routine for the code assembly phase of the C compiler.
4: * It reads the intermediate file and calls
5: * off to the appropriate routines to get things done.
6: */
7:
8: #ifdef vax
9: #include "INC$LIB:cc2.h"
10: #else
11: #include "cc2.h"
12: #endif
13:
14: /* Verbosity. Parallel to ccscan.c. */
15: #ifdef COHERENT
16: #define ERRMSG "cc:"
17: #else
18: #if INTEL
19: #define ERRMSG "***"
20: #else
21: #if OMF286
22: #define ERRMSG "MWC286:"
23: #else
24: #define ERRMSG "MWC86:"
25: #endif
26: #endif
27: #endif
28:
29: #if !OVERLAID
30: FILE *ifp; /* Input file */
31: FILE *ofp; /* Output file */
32: char file[NFNAME]; /* File name */
33: char module[NMNAME]; /* Module name */
34: int line; /* Line number */
35: char id[NCSYMB]; /* Name buffer */
36: VARIANT variant; /* Variant template */
37: int dotseg; /* Current segment # */
38: #endif
39:
40: int changes; /* Change flag */
41: ADDRESS dot; /* Current location */
42: SYM *hash2[NSHASH]; /* Symbol table */
43: INS ins; /* Head of instruction list */
44: int nlabdel; /* # of labels deleted */
45: int ndead; /* # of dead instructions deleted */
46: int nbrbr; /* # of branches to branches */
47: int nexbr; /* # of extra branches */
48: int ncbrbr; /* # of conditional branches to branches */
49: int nbrnext; /* # of branches to next instruction */
50: int nxjump; /* # of cross jumps */
51: int ncomseq; /* # of common sequences */
52: int nsimplify; /* # of instructions simplified */
53: int nuseless; /* # of instructions deleted */
54:
55: #if !TINY
56: int vflag; /* Verbosity */
57: int xflag; /* More verbosity */
58: #endif
59:
60: /*
61: * Segment table.
62: */
63: SEG seg[NSEG];
64:
65: #if !OVERLAID
66: /*
67: * Mainline.
68: * Interpret options and
69: * open files.
70: */
71: main(argc, argv)
72: char *argv[];
73: {
74: #ifdef vax
75: int ofd;
76: #endif
77:
78: passname = "cc2";
79: if (argc < 4)
80: usage();
81: getvariant(argv[1]);
82: #if GEMDOS
83: {
84: extern long gemdos();
85: extern char *lmalloc();
86: free(lmalloc((gemdos(0x48,-1L)-4096) & ~1023L));
87: }
88: #endif
89: if ((ifp=fopen(argv[2], SRMODE)) == NULL) {
90: fprintf(stderr, "%s: cannot open.\n", argv[2]);
91: exit(BAD);
92: }
93: if (isvariant(VASM)) {
94: if ((ofp=fopen(argv[3], SWMODE)) == NULL)
95: nocreate(argv[3]);
96: } else {
97: if (argc < 5)
98: usage();
99: if ((ofp=fopen(argv[4], SWMODE)) == NULL)
100: nocreate(argv[4]);
101: }
102: #if !TINY
103: if (argc > 5)
104: vflag = atoi(argv[5]);
105: if (argc > 6)
106: xflag = atoi(argv[6]);
107: #endif
108: labgen = 20000;
109: dotseg = -1;
110: outinit();
111: work2();
112: outdone();
113: if (notvariant(VASM)) {
114: fclose(ifp);
115: fclose(ofp);
116: if ((ifp=fopen(argv[4], SRMODE)) == NULL)
117: cfatal("%s: cannot reopen", argv[4]);
118: #ifdef vax
119: #if VAXFMT
120: if ((ofd=creat(argv[3], 0666, "rfm=var")) < 0
121: || (ofp=fdopen(ofd, SWMODE)) == NULL)
122: #else
123: if ((ofp=fopen(argv[3], SWMODE)) == NULL)
124: #endif
125: #else
126: if ((ofp=fopen(argv[3], SWMODE)) == NULL)
127: #endif
128: nocreate(argv[3]);
129: copycode();
130: }
131: if (isvariant(VSTAT))
132: showstats();
133: if (nerr != 0)
134: exit(BAD);
135: exit(OK);
136: }
137:
138: /*
139: * Print usage message.
140: */
141: usage()
142: {
143: fprintf(stderr, "Usage: cc2 variant in out [temp]\n");
144: exit(BAD);
145: }
146:
147: /*
148: * Complain that a file cannot be
149: * created.
150: */
151: nocreate(fn)
152: char *fn;
153: {
154: fprintf(stderr, "%s: cannot create.\n", fn);
155: exit(BAD);
156: }
157: #else
158: /*
159: * Driving routine for the
160: * overlaid version of the optimizer and
161: * code assembly phase. The files have all been
162: * opened by the command line scanner in the
163: * root segment. Set up a fatal error context and
164: * do the work. Return exit status.
165: */
166: cc2a()
167: {
168: #if MONOLITHIC
169: register int i;
170: #endif
171: passname = "cc2a";
172: if (setjmp(death) != 0) {
173: freesym2();
174: return (ABORT);
175: }
176: labgen = 20000;
177: dotseg = -1;
178: #if MONOLITHIC
179: dot = 0;
180: nlabdel = 0;
181: ndead = 0;
182: nbrbr = 0;
183: nexbr = 0;
184: ncbrbr = 0;
185: nbrnext = 0;
186: nxjump = 0;
187: ncomseq = 0;
188: nsimplify = 0;
189: nuseless = 0;
190: for (i=0; i<NSEG; ++i)
191: seg[i].s_dot = 0;
192: gendbgt(-1);
193: #endif
194: outinit();
195: work2();
196: outdone();
197: if (isvariant(VSTAT))
198: showstats();
199: if (isvariant(VASM))
200: freesym2();
201: if (nerr != 0)
202: return (BAD);
203: return (OK);
204: }
205:
206: /*
207: * Second part. Copy the code back. This is
208: * only done if aflag==0. The root segment will have moved
209: * all of the files around. The same fatal error game is
210: * played.
211: */
212: cc2b()
213: {
214: passname = "cc2b";
215: if (setjmp(death) != 0) {
216: freesym2();
217: return (ABORT);
218: }
219: copycode();
220: freesym2();
221: if (nerr != 0)
222: return (BAD);
223: return (OK);
224: }
225: #endif
226:
227: /*
228: * Print statistics.
229: */
230: showstats()
231: {
232: printstat(nlabdel, "label# deleted");
233: printstat(ndead, "dead instruction# deleted");
234: printstat(nbrbr, "jump# to a jump");
235: printstat(ncbrbr, "conditional jump# over a jump");
236: printstat(nbrnext, "jump# to next instruction");
237: printstat(nexbr, "extra jump#");
238: printstat(nxjump, "cross jump#");
239: printstat(ncomseq, "common sequence#");
240: printstat(nsimplify, "instruction# simplified");
241: printstat(nuseless, "instruction# deleted");
242: }
243:
244: /*
245: * Print a statistic message.
246: */
247: printstat(n, s)
248: register int n;
249: register char *s;
250: {
251: register int c;
252:
253: if (n != 0) {
254: #if OVERLAID
255: printf ("%s ", ERRMSG);
256: #endif
257: printf("%d ", n);
258: while ((c = *s++) != 0) {
259: if (c == '#') {
260: if (n != 1)
261: putchar('s');
262: } else
263: putchar(c);
264: }
265: putchar('\n');
266: }
267: }
268:
269: /*
270: * Read through the temporary file,
271: * processing things until you run into a
272: * function prolog operation. Functions
273: * get read in, optimized and written back
274: * out.
275: */
276: work2()
277: {
278: register int op;
279: sizeof_t size;
280: register INS *ip;
281: register SYM *sp;
282:
283: for (;;) {
284: switch (op = bget()) {
285:
286: case LINE:
287: line = iget();
288: break;
289:
290: case DLABEL:
291: gendbgt(0);
292: break;
293:
294: case FNAME:
295: sget(file, NFNAME);
296: break;
297:
298: case MNAME:
299: sget(module, NMNAME);
300: if (isvariant(VASM)) {
301: bput(op);
302: sput(module);
303: }
304: break;
305:
306: case GLABEL:
307: case SLABEL:
308: sget(id, NCSYMB);
309: sp = glookup(id, 1);
310: sp->s_seg = dotseg;
311: sp->s_value = dot;
312: if (op == GLABEL) {
313: sp->s_flag |= S_GBL;
314: }
315: if (isvariant(VASM)) {
316: bput(op);
317: sput(id);
318: }
319: break;
320:
321: case COMM:
322: sget(id, NCSYMB);
323: size = zget();
324: sp = glookup(id, 0);
325: if ((sp->s_flag&S_DEF) == 0) {
326: sp->s_seg = SBSS;
327: sp->s_flag |= S_GBL;
328: if (size > sp->s_value)
329: sp->s_value = size;
330: }
331: if (isvariant(VASM)) {
332: bput(op);
333: sput(id);
334: zput(size);
335: }
336: break;
337:
338: #ifdef KLUDGE
339: case SGUESS:
340: {
341: int seg;
342: sget(id, NCSYMB);
343: seg = bget();
344: sp = glookup(id, 0);
345: if ((sp->s_flag&S_DEF) == 0)
346: sp->s_seg = seg;
347: break;
348: }
349:
350: #endif
351:
352: case LLABEL:
353: sp = llookup(iget(), 1);
354: sp->s_seg = dotseg;
355: sp->s_value = dot;
356: sp->s_flag |= S_NFL;
357: if (isvariant(VASM)) {
358: bput(op);
359: iput((ival_t)sp->s_labno);
360: }
361: break;
362:
363: case BLOCK:
364: genblock(zget());
365: break;
366:
367: case ENTER:
368: genseg(bget());
369: break;
370:
371: case PROLOG:
372: #if !TINY
373: #define vcheck(v,s) if (vflag>v) check(s)
374: #else
375: #define vcheck(v,s) /* if (vflag>v) check(s) */
376: #endif
377: getfunc();
378: fixdbgt();
379: shuffle();
380: vcheck(0, "Befor optim");
381: do {
382: changes = 0;
383: labels();
384: vcheck(8, "After labels");
385: fixbr();
386: vcheck(8, "After fixbr()");
387: if (isvariant(VPEEP)) {
388: peephole();
389: vcheck(8, "After peephole");
390: }
391: if (notvariant(VNOOPT)) {
392: xjumps();
393: vcheck(8, "After xjumps");
394: comseq();
395: vcheck(8, "After comseq");
396: }
397: deadcode();
398: vcheck(2, "Before while (changes)");
399: } while (changes);
400: genprolog();
401: genfunc();
402: genepilog();
403: break;
404:
405: case ALIGN:
406: genalign(bget());
407: break;
408:
409: case CODE:
410: unbget(CODE);
411: ip = getins();
412: genins(ip);
413: free((char *) ip);
414: break;
415:
416: case FINISH:
417: genseg(-1);
418: if (isvariant(VASM))
419: bput(op);
420: return;
421:
422: case EOF:
423: cfatal("unexpected EOF");
424:
425: default:
426: cbotch("bad temporary file opcode %d", op);
427: }
428: }
429: }
430:
431: #if !TINY
432: /*
433: * Compiler debugging printout.
434: */
435: check(where)
436: char *where;
437: {
438: register INS *ip;
439:
440: printf("Check %s:\n", where);
441: for (ip = ins.i_fp; ip != &ins; ip = ip->i_fp) {
442: iprint(ip);
443: }
444: printf("\n");
445: }
446:
447: iprint(ip)
448: register INS *ip;
449: {
450: dprint(ip);
451: #if RUNNING_LARGE
452: printf("\t%08lx: %08lx %08lx: ", ip, ip->i_bp, ip->i_fp);
453: #else
454: printf("\t%04x: %04x %04x: ", ip, ip->i_bp, ip->i_fp);
455: #endif
456: switch (ip->i_type) {
457: case ENTER:
458: printf("enter %d", ip->i_seg);
459: break;
460: case EPILOG:
461: printf("epilog");
462: break;
463: case PROLOG:
464: printf("prolog");
465: break;
466: case BLOCK:
467: printf("block %ld", (long)ip->i_len);
468: break;
469: case ALIGN:
470: printf("align %d", ip->i_align);
471: break;
472: case LLABEL:
473: printf("label L%d", ip->i_labno);
474: break;
475: case JUMP:
476: printf("jump %d L%d", ip->i_rel, ip->i_labno);
477: break;
478: case LLLINK:
479: printf("llink L%d", ip->i_labno);
480: break;
481: case CODE:
482: printf("code %d(%d)", ip->i_op, ip->i_naddr);
483: break;
484: default:
485: printf("?? %d", ip->i_type);
486: break;
487: }
488: printf("\n");
489: }
490: #endif
491:
492: /* end of n2/cc2.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.