|
|
1.1 root 1: /*
2: * This file contains the main
3: * driving routine for the code assembly
4: * phase of the C compiler.
5: * It reads the intermediate file and calls
6: * off to the appropriate routines to get things
7: * done.
8: */
9: #ifdef vax
10: #include "INC$LIB:cc2.h"
11: #else
12: #include "cc2.h"
13: #endif
14:
15: /* Verbosity. Parallel to ccscan.c. */
16: #ifdef COHERENT
17: #define ERRMSG "cc:"
18: #else
19: #if INTEL
20: #define ERRMSG "***"
21: #else
22: #if OMF286
23: #define ERRMSG "MWC286:"
24: #else
25: #define ERRMSG "MWC86:"
26: #endif
27: #endif
28: #endif
29:
30: #if !OVERLAID
31: FILE *ifp; /* Input file */
32: FILE *ofp; /* Output file */
33: char file[NFNAME]; /* File name */
34: char module[NMNAME]; /* Module name */
35: int line; /* Line number */
36: char id[NCSYMB]; /* Name buffer */
37: VARIANT variant; /* Variant template */
38: int dotseg; /* Current segment # */
39: #endif
40:
41: int changes; /* Change flag */
42: ADDRESS dot; /* Current location */
43: SYM *hash2[NSHASH]; /* Symbol table */
44: INS ins; /* Head of instruction list */
45: int nlabdel; /* # of labels deleted */
46: int ndead; /* # of dead instructions deleted */
47: int nbrbr; /* # of branches to branches */
48: int nexbr; /* # of extra branches */
49: int ncbrbr; /* # of conditional branches to branches */
50: int nbrnext; /* # of branches to next instruction */
51: int nxjump; /* # of cross jumps */
52: int ncomseq; /* # of common sequences */
53: int nsimplify; /* # of instructions simplified */
54: int nuseless; /* # of instructions deleted */
55:
56: #if !TINY
57: int vflag; /* Verbosity */
58: int xflag; /* More verbosity */
59: #endif
60:
61: /*
62: * Segment table.
63: */
64: SEG seg[NSEG];
65:
66: #if !OVERLAID
67: /*
68: * Mainline.
69: * Interpret options and
70: * open files.
71: */
72: main(argc, argv)
73: char *argv[];
74: {
75: #ifdef vax
76: int ofd;
77: #endif
78:
79: passname = "cc2";
80: if (argc < 4)
81: usage();
82: getvariant(argv[1]);
83: #if GEMDOS
84: {
85: extern long gemdos();
86: extern char *lmalloc();
87: free(lmalloc((gemdos(0x48,-1L)-4096) & ~1023L));
88: }
89: #endif
90: if ((ifp=fopen(argv[2], SRMODE)) == NULL) {
91: fprintf(stderr, "%s: cannot open.\n", argv[2]);
92: exit(BAD);
93: }
94: if (isvariant(VASM)) {
95: if ((ofp=fopen(argv[3], SWMODE)) == NULL)
96: nocreate(argv[3]);
97: } else {
98: if (argc < 5)
99: usage();
100: if ((ofp=fopen(argv[4], SWMODE)) == NULL)
101: nocreate(argv[4]);
102: }
103: #if !TINY
104: if (argc > 5)
105: vflag = atoi(argv[5]);
106: if (argc > 6)
107: xflag = atoi(argv[6]);
108: #endif
109: labgen = 20000;
110: dotseg = -1;
111: outinit();
112: work2();
113: outdone();
114: if (notvariant(VASM)) {
115: fclose(ifp);
116: fclose(ofp);
117: if ((ifp=fopen(argv[4], SRMODE)) == NULL)
118: cfatal("%s: cannot reopen", argv[4]);
119: #ifdef vax
120: #if VAXFMT
121: if ((ofd=creat(argv[3], 0666, "rfm=var")) < 0
122: || (ofp=fdopen(ofd, SWMODE)) == NULL)
123: #else
124: if ((ofp=fopen(argv[3], SWMODE)) == NULL)
125: #endif
126: #else
127: if ((ofp=fopen(argv[3], SWMODE)) == NULL)
128: #endif
129: nocreate(argv[3]);
130: copycode();
131: }
132: if (isvariant(VSTAT))
133: showstats();
134: if (nerr != 0)
135: exit(BAD);
136: exit(OK);
137: }
138:
139: /*
140: * Print usage message.
141: */
142: usage()
143: {
144: fprintf(stderr, "Usage: cc2 variant in out [temp]\n");
145: exit(BAD);
146: }
147:
148: /*
149: * Complain that a file cannot be
150: * created.
151: */
152: nocreate(fn)
153: char *fn;
154: {
155: fprintf(stderr, "%s: cannot create.\n", fn);
156: exit(BAD);
157: }
158: #else
159: /*
160: * Driving routine for the
161: * overlaid version of the optimizer and
162: * code assembly phase. The files have all been
163: * opened by the command line scanner in the
164: * root segment. Set up a fatal error context and
165: * do the work. Return exit status.
166: */
167: cc2a()
168: {
169: #if MONOLITHIC
170: register int i;
171: #endif
172: passname = "cc2a";
173: if (setjmp(death) != 0) {
174: freesym2();
175: return (ABORT);
176: }
177: labgen = 20000;
178: dotseg = -1;
179: #if MONOLITHIC
180: dot = 0;
181: nlabdel = 0;
182: ndead = 0;
183: nbrbr = 0;
184: nexbr = 0;
185: ncbrbr = 0;
186: nbrnext = 0;
187: nxjump = 0;
188: ncomseq = 0;
189: nsimplify = 0;
190: nuseless = 0;
191: for (i=0; i<NSEG; ++i)
192: seg[i].s_dot = 0;
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(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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.