|
|
1.1 root 1: /*
2: * This is the mainline of the new,
3: * direct to bits code generator. It is mainly
4: * just a driving routine. The tree reader and
5: * the diagnostic routines are also in this
6: * file. Everything in here is machine independent.
7: */
8: #ifdef vax
9: #include "INC$LIB:cc1.h"
10: #else
11: #include "cc1.h"
12: #endif
13:
14: #if !OVERLAID
15: FILE *ifp; /* Input file */
16: FILE *ofp; /* Output file */
17: char file[NFNAME]; /* File name */
18: char module[NMNAME]; /* Module name */
19: int line; /* Line number */
20: char id[NCSYMB]; /* Temp. id buffer */
21: VARIANT variant; /* Variant template */
22: #if !TINY
23: int mflag; /* Debug modify routines */
24: int sflag; /* Debug select routines */
25: int oflag; /* Debug output routines */
26: #endif
27: #endif
28:
29: int qccmp(); /* Quicksort compare */
30: SYM *hash1[NSHASH]; /* Hash table */
31: int nnsw; /* Switch nesting level */
32: int nsw[NNSW]; /* Switch label */
33: CASES *cases; /* Case buffer */
34:
35: #if !OVERLAID
36: /*
37: * Mainline.
38: * Interpret options and
39: * open files.
40: */
41: main(argc, argv)
42: char *argv[];
43: {
44: passname = "cc1";
45: if (argc < 4)
46: usage();
47: getvariant(argv[1]);
48: #if GEMDOS
49: {
50: extern long gemdos();
51: extern char *lmalloc();
52: free(lmalloc((gemdos(0x48,-1L)-4096) & ~1023L));
53: }
54: #endif
55: if ((ifp=fopen(argv[2], SRMODE)) == NULL) {
56: fprintf(stderr, "%s: cannot open.\n", argv[2]);
57: exit(BAD);
58: }
59: if ((ofp=fopen(argv[3], SWMODE)) == NULL) {
60: fprintf(stderr, "%s: cannot create.\n", argv[3]);
61: exit(BAD);
62: }
63: #if !TINY
64: if (argc > 4)
65: mflag = atoi(argv[4]);
66: if (argc > 5)
67: sflag = atoi(argv[5]);
68: if (argc > 6)
69: oflag = atoi(argv[6]);
70: #endif
71: labgen = 10000;
72: oldseg = -1;
73: work1();
74: if (nerr != 0)
75: exit(BAD);
76: exit(OK);
77: }
78:
79: /*
80: * Print usage message.
81: */
82: usage()
83: {
84: #if !TINY
85: fprintf(stderr,
86: "Usage: cc1 variant in out [mlevel [slevel [olevel]]]\n");
87: #else
88: fprintf(stderr, "Usage: cc1 variant in out\n");
89: #endif
90: exit(BAD);
91: }
92: #else
93: /*
94: * Mainline for the overlaid version
95: * of the coder. The files are already open.
96: * Set up for fatal errors. Process the file
97: * and return status.
98: */
99: cc1()
100: {
101: passname = "cc1";
102: if (setjmp(death) != 0) {
103: freenode();
104: freepool();
105: freegsym();
106: return (ABORT);
107: }
108: labgen = 10000;
109: oldseg = -1;
110: #if MONOLITHIC
111: nnsw = 0;
112: #endif
113: work1();
114: freenode();
115: freepool();
116: freegsym();
117: if (nerr != 0)
118: return (BAD);
119: return (OK);
120: }
121: #endif
122:
123: /*
124: * Read temp. file.
125: * Do simple things right here.
126: * Read in trees and pass them over
127: * to the tree compilation code.
128: */
129: work1()
130: {
131: register int i;
132: register int op;
133: register TREE *tp;
134: register int d;
135: register int n;
136: register int tt;
137: register int ln;
138:
139: coderinit();
140: for (;;) {
141: op = bget();
142: switch (op) {
143:
144: case LINE:
145: line = iget();
146: /* bput(op); */
147: /* iput(line); */
148: break;
149:
150: case DLABEL:
151: bput(DLABEL);
152: tcpy(bget());
153: break;
154:
155: case MNAME:
156: sget(module, NMNAME);
157: bput(op);
158: sput(module);
159: break;
160:
161: case FNAME:
162: sget(file, NFNAME);
163: /* bput(op); */
164: /* sput(file); */
165: break;
166:
167: case GLABEL:
168: case SLABEL:
169: sget(id, NCSYMB);
170: bput(op);
171: sput(id);
172: break;
173:
174: case COMM:
175: bput(op);
176: sget(id, NCSYMB);
177: sput(id);
178: zput(zget());
179: break;
180:
181: case LLABEL:
182: bput(op);
183: iput(iget());
184: break;
185:
186: case BLOCK:
187: bput(op);
188: zput(zget());
189: break;
190:
191: case JUMP:
192: genubr(iget());
193: break;
194:
195: case ENTER:
196: newseg(bget());
197: break;
198:
199: case AUTOS:
200: doautos();
201: break;
202:
203: case PROLOG:
204: bput(PROLOG);
205: doprolog();
206: break;
207:
208: case ALIGN:
209: bput(ALIGN);
210: bput(bget());
211: break;
212:
213: case EPILOG:
214: doepilog();
215: bput(EPILOG);
216: break;
217:
218: case EEXPR:
219: tp = modify(treeget(), MEFFECT);
220: code(tp, MEFFECT, 0, 0);
221: break;
222:
223: case IBLOCK:
224: iblock(bget());
225: break;
226:
227: case IEXPR:
228: tp = treeget();
229: tt = tp->t_type;
230: tp = modify(tp->t_lp, MINIT);
231: iexpr(tp, tt);
232: break;
233:
234: case FEXPR:
235: case TEXPR:
236: ln = iget();
237: tp = modify(treeget(), MFLOW);
238: code(tp, MFLOW, op==TEXPR, ln);
239: break;
240:
241: case REXPR:
242: tp = modify(treeget(), MRETURN);
243: code(tp, MRETURN, 0, 0);
244: break;
245:
246: case SEXPR:
247: if (nnsw >= NNSW)
248: cfatal("switch overflow");
249: nsw[nnsw++] = n = newlab();
250: tp = modify(treeget(), MSWITCH);
251: code(tp, MSWITCH, 0, 0);
252: genubr(n);
253: break;
254:
255: case SBODY:
256: if (nnsw <= 0)
257: cbotch("switch underflow");
258: genlab(nsw[--nnsw]);
259: d = iget();
260: n = iget();
261: if (n != 0) {
262: cases = (CASES *)malloc(n*sizeof(CASES));
263: if (cases == NULL)
264: cfatal("too many cases");
265: for (i=0; i<n; ++i) {
266: cases[i].c_val = iget();
267: cases[i].c_lab = iget();
268: }
269: shellsort((char *)cases, n, sizeof(cases[0]), &qccmp);
270: }
271: genswitch(d, n);
272: if (n != 0)
273: free((char *)cases);
274: break;
275:
276: case FINISH:
277: bput(op);
278: return;
279:
280: case EOF:
281: cfatal("unexpected EOF");
282:
283: default:
284: cbotch("bad temporary file opcode %d", op);
285: }
286: }
287: }
288:
289: /*
290: * This routine is used by the library
291: * quicksort routine to compare two elements
292: * in the case constant buffer.
293: */
294: qccmp(a, b)
295: struct cases *a, *b;
296: {
297: return (a->c_val - b->c_val);
298: }
299:
300: /*
301: * Generate a local label.
302: */
303: genlab(n)
304: {
305: bput(LLABEL);
306: iput(n);
307: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.