|
|
1.1 root 1: /* C compiler: symbolic code generator */
2:
3: #include "c.h"
4:
5: static int maxoffset; /* maximum value of offset */
6: static int offset; /* current frame offset */
7: static Node *tail;
8:
9: dclproto(static Node gen,(Node));
10: dclproto(static int gen1,(Node, int, int));
11: dclproto(static int regoffset,(int, int));
12: dclproto(static unsigned regloc,(Symbol));
13: dclproto(static void address,(Symbol, Symbol, int));
14: dclproto(static void blockbeg,(Env *));
15: dclproto(static void blockend,(Env *));
16: dclproto(static void defaddress,(Symbol));
17: dclproto(static void defconst,(int, Value));
18: dclproto(static void defstring,(int, char *));
19: dclproto(static void defsymbol,(Symbol));
20: dclproto(static void emit,(Node));
21: dclproto(static void export,(Symbol));
22: dclproto(static void function,(Symbol, Symbol [], Symbol [], int));
23: dclproto(static void global,(Symbol));
24: dclproto(static void import,(Symbol));
25: dclproto(static void local,(Symbol));
26: dclproto(static void progbeg,(int, char **));
27: dclproto(static void progend,(void));
28: dclproto(static void segment,(int));
29: dclproto(static void space,(int));
30: dclproto(static void stabend,(Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *));
31: dclproto(static void stabline,(Coordinate *));
32: dclproto(static void sym,(char *, Symbol, char *));
33: dclproto(static void symname,(Symbol));
34:
35: static Interface symbolic = {
36: "symbolic",
37: 1, 1, 0, /* char */
38: 2, 2, 0, /* short */
39: 4, 4, 0, /* int */
40: 4, 4, 1, /* float */
41: 8, 4, 1, /* double */
42: 4, 4, 0, /* T * */
43: 0, 4, 0, /* struct */
44: 1, /* left_to_right */
45: 0, /* little_endian */
46: 1, /* jump_on_return */
47: 0, /* mulops_are_calls */
48: 0, /* compl_band */
49: 0, /* no_argb */
50: 0, /* no_dag */
51: address,
52: blockbeg,
53: blockend,
54: defaddress,
55: defconst,
56: defstring,
57: defsymbol,
58: emit,
59: export,
60: function,
61: gen,
62: global,
63: import,
64: local,
65: progbeg,
66: progend,
67: segment,
68: space,
69: 0, /* stabblock */
70: stabend,
71: 0, /* stabfend */
72: 0, /* stabinit */
73: stabline,
74: 0, /* stabsym */
75: 0, /* stabtype */
76: };
77: Interface *interfaces[] = { &symbolic, 0 };
78:
79: /* address - initialize q for addressing expression p+n */
80: static void address(q, p, n) Symbol q, p; int n; {
81: q->x.name = stringf("%s%s%d", p->x.name, n > 0 ? "+" : "", n);
82: }
83:
84: /* blockbeg - begin a compound statement */
85: static void blockbeg(e) Env *e; {
86: *e = offset;
87: }
88:
89: /* blockend - end a compound statement */
90: static void blockend(e) Env *e; {
91: if (offset > maxoffset)
92: maxoffset = offset;
93: offset = *e;
94: }
95:
96: /* defaddress - initialize an address */
97: static void defaddress(p) Symbol p; {
98: print("defaddress %s\n", p->x.name);
99: }
100:
101: /* defconst - define a constant */
102: static void defconst(ty, v) Value v; {
103: print("defconst ");
104: switch (ty) {
105: case C: print("char %d\n", v.uc); break;
106: case S: print("short %d\n", v.ss); break;
107: case I: print("int %d\n", v.i ); break;
108: case U: print("unsigned 0x%x\n", v.u ); break;
109: case P: print("void* 0x%x\n", v.p ); break;
110: case F: {
111: char buf[MAXLINE];
112: sprintf(buf, "float %.8e\n", v.f); /* fix */
113: outs(buf);
114: break;
115: }
116: case D: {
117: char buf[MAXLINE];
118: sprintf(buf, "double %.18e\n", v.d); /* fix */
119: outs(buf);
120: break;
121: }
122: default: assert(0);
123: }
124: }
125:
126: /* defstring - emit a string constant */
127: static void defstring(len, s) char *s; {
128: int n;
129:
130: print("defstring \"");
131: for (n = 0; len-- > 0; s++) {
132: if (n >= 72) {
133: print("\n");
134: n = 0;
135: }
136: if (*s == '"' || *s == '\\') {
137: print("\\%c", *s);
138: n += 2;
139: } else if (*s >= ' ' && *s < 0177) {
140: *bp++ = *s;
141: n += 1;
142: } else {
143: print("\\%d%d%d", (*s>>6)&3, (*s>>3)&7, *s&7);
144: n += 4;
145: }
146: }
147: print("\"\n");
148: }
149:
150: /* defsymbol - define a symbol: initialize p->x */
151: static void defsymbol(p) Symbol p; {
152: p->x.name = p->name;
153: if (glevel > 2 && p->scope >= LOCAL && p->type && isfunc(p->type))
154: sym("extern", p, "\n");
155: }
156:
157: /* emit - emit the dags on list p */
158: static void emit(p) Node p; {
159: for (; p; p = p->x.next)
160: if (p->op == LABEL+V) {
161: assert(p->syms[0]);
162: print("%s:\n", p->syms[0]->x.name);
163: } else {
164: int i;
165: assert(p->link == 0 || p->x.lev == 0);
166: print("node%c%d %s count=%d", p->x.lev == 0 ? '\'' : '#', p->x.id,
167: opname(p->op), p->count);
168: for (i = 0; i < MAXKIDS && p->kids[i]; i++)
169: print(" #%d", p->kids[i]->x.id);
170: for (i = 0; i < MAXSYMS && p->syms[i]; i++) {
171: if (p->syms[i]->x.name)
172: print(" %s", p->syms[i]->x.name);
173: if (p->syms[i]->name != p->syms[i]->x.name)
174: print(" (%s)", p->syms[i]->name);
175: }
176: print("\n");
177: }
178: }
179:
180: /* export - announce p as exported */
181: static void export(p) Symbol p; {
182: print("export %s\n", p->x.name);
183: }
184:
185: /* function - generate code for a function */
186: static void function(f, caller, callee, ncalls) Symbol f, caller[], callee[]; {
187: int i;
188:
189: sym("function", f, ncalls ? (char *)0 : "\n");
190: if (ncalls)
191: print(" ncalls=%d\n", ncalls);
192: offset = 0;
193: for (i = 0; caller[i] && callee[i]; i++) {
194: offset = roundup(offset, caller[i]->type->align);
195: caller[i]->x.name = caller[i]->name;
196: callee[i]->x.name = callee[i]->name;
197: caller[i]->x.offset = callee[i]->x.offset = offset;
198: sym("caller's parameter", caller[i], "\n");
199: sym("callee's parameter", callee[i], "\n");
200: offset += caller[i]->type->size;
201: }
202: maxoffset = offset = 0;
203: gencode(caller, callee);
204: print("maxoffset=%d\n", maxoffset);
205: emitcode();
206: print("end %s\n", f->x.name);
207: }
208:
209: /* gen - generate code for the dags on list p */
210: static Node gen(p) Node p; {
211: int n;
212: Node nodelist;
213:
214: tail = &nodelist;
215: for (n = 0; p; p = p->link) {
216: switch (generic(p->op)) { /* check for valid nodelist */
217: case CALL:
218: assert(!IR->no_dag || p->count == 0);
219: break;
220: case ARG:
221: case ASGN: case JUMP: case LABEL: case RET:
222: case EQ: case GE: case GT: case LE: case LT: case NE:
223: assert(p->count == 0);
224: break;
225: case INDIR:
226: assert(!IR->no_dag && p->count > 0);
227: break;
228: default:
229: assert(0);
230: }
231: n = gen1(p, 0, n);
232: }
233: *tail = 0;
234: return nodelist;
235: }
236:
237: /* gen1 - generate code for *p */
238: static int gen1(p, lev, n) Node p; {
239: if (p && p->x.id == 0) {
240: p->x.lev = lev;
241: p->x.id = ++n;
242: n = gen1(p->kids[0], lev + 1, n);
243: n = gen1(p->kids[1], lev + 1, n);
244: *tail = p;
245: tail = &p->x.next;
246: }
247: return n;
248: }
249:
250: /* global - announce a global */
251: static void global(p) Symbol p; {
252: sym("global", p, "\n");
253: }
254:
255: /* import - import a symbol */
256: static void import(p) Symbol p; {
257: print("import %s\n", p->x.name);
258: }
259:
260: /* local - local variable */
261: static void local(p) Symbol p; {
262: offset = roundup(offset, p->type->align);
263: p->x.name = p->name;
264: p->x.offset = offset;
265: sym("local", p, "\n");
266: offset += p->type->size;
267: }
268:
269: /* progbeg - beginning of program */
270: static void progbeg(argc, argv) char *argv[]; {
271: print("progbeg argv=");
272: while (argc--)
273: print("%s ", *argv++);
274: print("\n");
275: }
276:
277: /* progend - end of program */
278: static void progend() {
279: print("progend\n");
280: }
281:
282: /* regloc - return "id" for p's register */
283: static unsigned regloc(p) Symbol p; {
284: assert(p && p->sclass == REGISTER);
285: return 0;
286: }
287:
288: /* regoffset - return stack offset of cell that saves reg */
289: static int regoffset(regset, regnum) {
290: return -1;
291: }
292:
293: /* segment - switch to segment s */
294: static void segment(s) {
295: print("segment %s\n", &"text\0bss\0.data\0lit\0.sym\0."[5*s-5]);
296: }
297:
298: /* space - initialize n bytes of space */
299: static void space(n) {
300: print("space %d\n", n);
301: }
302:
303: /* sym - print symbol table entry for p, followed by str */
304: static void sym(kind, p, str) char *kind, *str; Symbol p; {
305: assert(kind);
306: if (glevel > 2) {
307: print("%s ", kind);
308: symname(p);
309: } else
310: print("%s %s", kind, p->name);
311: if (p->name != p->x.name)
312: print(" (%s)", p->x.name);
313: print(" type=%t class=%k scope=", p->type, p->sclass);
314: switch (p->scope) {
315: case CONSTANTS: print("CONSTANTS"); break;
316: case LABELS: print("LABELS"); break;
317: case GLOBAL: print("GLOBAL"); break;
318: case PARAM: print("PARAM"); break;
319: case LOCAL: print("LOCAL"); break;
320: default:
321: if (p->scope > LOCAL)
322: print("LOCAL+%d", p->scope - LOCAL);
323: else
324: print("%d", p->scope);
325: }
326: if (p->scope >= PARAM && p->sclass != STATIC)
327: print(" offset=%d ref=%d", p->x.offset, (int)(1000*p->ref));
328: if (glevel > 2) {
329: print(" up=");
330: symname(p->up);
331: }
332: if (str)
333: print(str);
334: }
335:
336: /* symname - print prefix, p's name, declaration source coordinate, suffix */
337: static void symname(p) Symbol p; {
338: if (p)
339: print("%s@%w.%d", p->name, &p->src, p->src.x);
340: else
341: print("0");
342: }
343:
344: /* stabend - finalize stab output */
345: static void stabend(cp, p, cpp, sp, stab) Coordinate *cp, **cpp; Symbol p, *sp, *stab; {
346: int i;
347:
348: symname(p);
349: print("\n");
350: for (i = 0; cpp[i] && sp[i]; i++) {
351: print("%w.%d: ", cpp[i], cpp[i]->x);
352: symname(sp[i]);
353: print("\n");
354: }
355: }
356:
357: /* stabline - emit line number information for source coordinate *cp */
358: static void stabline(cp) Coordinate *cp; {
359: if (cp->file)
360: print("%s:", cp->file);
361: print("%d.%d:\n", cp->y, cp->x);
362: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.