1 #include "c.h"
2 #define I(f) b_##f
3
4
I(segment)5 static void I(segment)(int n) {
6 static int cseg;
7
8 if (cseg != n)
9 switch (cseg = n) {
10 case CODE: print("code\n"); return;
11 case DATA: print("data\n"); return;
12 case BSS: print("bss\n"); return;
13 case LIT: print("lit\n"); return;
14 default: assert(0);
15 }
16 }
17
I(address)18 static void I(address)(Symbol q, Symbol p, long n) {
19 q->x.name = stringf("%s%s%D", p->x.name, n > 0 ? "+" : "", n);
20 }
21
I(defaddress)22 static void I(defaddress)(Symbol p) {
23 print("address %s\n", p->x.name);
24 }
25
I(defconst)26 static void I(defconst)(int suffix, int size, Value v) {
27 switch (suffix) {
28 case I:
29 if (size > sizeof (int))
30 print("byte %d %D\n", size, v.i);
31 else
32 print("byte %d %d\n", size, v.i);
33 return;
34 case U:
35 if (size > sizeof (unsigned))
36 print("byte %d %U\n", size, v.u);
37 else
38 print("byte %d %u\n", size, v.u);
39 return;
40 case P: print("byte %d %U\n", size, (unsigned long)v.p); return;
41 case F:
42 if (size == 4) {
43 floatint_t fi;
44 fi.f = v.d;
45 print("byte 4 %u\n", fi.ui);
46 } else {
47 unsigned *p = (unsigned *)&v.d;
48 print("byte 4 %u\n", p[swap]);
49 print("byte 4 %u\n", p[1 - swap]);
50 }
51 return;
52 }
53 assert(0);
54 }
55
I(defstring)56 static void I(defstring)(int len, char *str) {
57 char *s;
58
59 for (s = str; s < str + len; s++)
60 print("byte 1 %d\n", (*s)&0377);
61 }
62
I(defsymbol)63 static void I(defsymbol)(Symbol p) {
64 if (p->scope == CONSTANTS)
65 switch (optype(ttob(p->type))) {
66 case I: p->x.name = stringf("%D", p->u.c.v.i); break;
67 case U: p->x.name = stringf("%U", p->u.c.v.u); break;
68 case P: p->x.name = stringf("%U", p->u.c.v.p); break;
69 case F:
70 { // JDC: added this to get inline floats
71 floatint_t temp;
72
73 temp.f = p->u.c.v.d;
74 p->x.name = stringf("%U", temp.ui );
75 }
76 break;// JDC: added this
77 default: assert(0);
78 }
79 else if (p->scope >= LOCAL && p->sclass == STATIC)
80 p->x.name = stringf("$%d", genlabel(1));
81 else if (p->scope == LABELS || p->generated)
82 p->x.name = stringf("$%s", p->name);
83 else
84 p->x.name = p->name;
85 }
86
dumptree(Node p)87 static void dumptree(Node p) {
88 switch (specific(p->op)) {
89 case ASGN+B:
90 assert(p->kids[0]);
91 assert(p->kids[1]);
92 assert(p->syms[0]);
93 dumptree(p->kids[0]);
94 dumptree(p->kids[1]);
95 print("%s %d\n", opname(p->op), p->syms[0]->u.c.v.u);
96 return;
97 case RET+V:
98 assert(!p->kids[0]);
99 assert(!p->kids[1]);
100 print("%s\n", opname(p->op));
101 return;
102 }
103 switch (generic(p->op)) {
104 case CNST: case ADDRG: case ADDRF: case ADDRL: case LABEL:
105 assert(!p->kids[0]);
106 assert(!p->kids[1]);
107 assert(p->syms[0] && p->syms[0]->x.name);
108 print("%s %s\n", opname(p->op), p->syms[0]->x.name);
109 return;
110 case CVF: case CVI: case CVP: case CVU:
111 assert(p->kids[0]);
112 assert(!p->kids[1]);
113 assert(p->syms[0]);
114 dumptree(p->kids[0]);
115 print("%s %d\n", opname(p->op), p->syms[0]->u.c.v.i);
116 return;
117 case ARG: case BCOM: case NEG: case INDIR: case JUMP: case RET:
118 assert(p->kids[0]);
119 assert(!p->kids[1]);
120 dumptree(p->kids[0]);
121 print("%s\n", opname(p->op));
122 return;
123 case CALL:
124 assert(p->kids[0]);
125 assert(!p->kids[1]);
126 assert(optype(p->op) != B);
127 dumptree(p->kids[0]);
128 print("%s\n", opname(p->op));
129 if ( !p->count ) { printf("pop\n"); }; // JDC
130 return;
131 case ASGN: case BOR: case BAND: case BXOR: case RSH: case LSH:
132 case ADD: case SUB: case DIV: case MUL: case MOD:
133 assert(p->kids[0]);
134 assert(p->kids[1]);
135 dumptree(p->kids[0]);
136 dumptree(p->kids[1]);
137 print("%s\n", opname(p->op));
138 return;
139 case EQ: case NE: case GT: case GE: case LE: case LT:
140 assert(p->kids[0]);
141 assert(p->kids[1]);
142 assert(p->syms[0]);
143 assert(p->syms[0]->x.name);
144 dumptree(p->kids[0]);
145 dumptree(p->kids[1]);
146 print("%s %s\n", opname(p->op), p->syms[0]->x.name);
147 return;
148 }
149 assert(0);
150 }
151
I(emit)152 static void I(emit)(Node p) {
153 for (; p; p = p->link)
154 dumptree(p);
155 }
156
I(export)157 static void I(export)(Symbol p) {
158 print("export %s\n", p->x.name);
159 }
160
I(function)161 static void I(function)(Symbol f, Symbol caller[], Symbol callee[], int ncalls) {
162 int i;
163
164 (*IR->segment)(CODE);
165 offset = 0;
166 for (i = 0; caller[i] && callee[i]; i++) {
167 offset = roundup(offset, caller[i]->type->align);
168 caller[i]->x.name = callee[i]->x.name = stringf("%d", offset);
169 caller[i]->x.offset = callee[i]->x.offset = offset;
170 offset += caller[i]->type->size;
171 }
172 maxargoffset = maxoffset = argoffset = offset = 0;
173 gencode(caller, callee);
174 print("proc %s %d %d\n", f->x.name, maxoffset, maxargoffset);
175 emitcode();
176 print("endproc %s %d %d\n", f->x.name, maxoffset, maxargoffset);
177
178 }
179
gen02(Node p)180 static void gen02(Node p) {
181 assert(p);
182 if (generic(p->op) == ARG) {
183 assert(p->syms[0]);
184 argoffset += (p->syms[0]->u.c.v.i < 4 ? 4 : p->syms[0]->u.c.v.i);
185 } else if (generic(p->op) == CALL) {
186 maxargoffset = (argoffset > maxargoffset ? argoffset : maxargoffset);
187 argoffset = 0;
188 }
189 }
190
gen01(Node p)191 static void gen01(Node p) {
192 if (p) {
193 gen01(p->kids[0]);
194 gen01(p->kids[1]);
195 gen02(p);
196 }
197 }
198
I(gen)199 static Node I(gen)(Node p) {
200 Node q;
201
202 assert(p);
203 for (q = p; q; q = q->link)
204 gen01(q);
205 return p;
206 }
207
I(global)208 static void I(global)(Symbol p) {
209 print("align %d\n", p->type->align > 4 ? 4 : p->type->align);
210 print("LABELV %s\n", p->x.name);
211 }
212
I(import)213 static void I(import)(Symbol p) {
214 print("import %s\n", p->x.name);
215 }
216
I(local)217 static void I(local)(Symbol p) {
218 offset = roundup(offset, p->type->align);
219 p->x.name = stringf("%d", offset);
220 p->x.offset = offset;
221 offset += p->type->size;
222 }
223
I(progbeg)224 static void I(progbeg)(int argc, char *argv[]) {}
225
I(progend)226 static void I(progend)(void) {}
227
I(space)228 static void I(space)(int n) {
229 print("skip %d\n", n);
230 }
231
232 //========================================================
233
234 // JDC: hacked up to get interleaved source lines in asm code
235 static char *sourceFile;
236 static char *sourcePtr;
237 static int sourceLine;
238
filelength(FILE * f)239 static int filelength( FILE *f ) {
240 int pos;
241 int end;
242
243 pos = ftell (f);
244 fseek (f, 0, SEEK_END);
245 end = ftell (f);
246 fseek (f, pos, SEEK_SET);
247
248 return end;
249 }
250
LoadSourceFile(const char * filename)251 static void LoadSourceFile( const char *filename ) {
252 FILE *f;
253 int length;
254
255 f = fopen( filename, "r" );
256 if ( !f ) {
257 print( ";couldn't open %s\n", filename );
258 sourceFile = NULL;
259 return;
260 }
261 length = filelength( f );
262 sourceFile = malloc( length + 1 );
263 if ( sourceFile ) {
264 size_t size;
265 size = fread( sourceFile, length, 1, f );
266 sourceFile[length] = 0;
267 }
268
269 fclose( f );
270 sourceLine = 1;
271 sourcePtr = sourceFile;
272 }
273
PrintToSourceLine(int line)274 static void PrintToSourceLine( int line ) {
275 int c;
276
277 if ( !sourceFile ) {
278 return;
279 }
280 while ( sourceLine <= line ) {
281 int i;
282
283 for ( i = 0 ; sourcePtr[i] && sourcePtr[i] != '\n' ; i++ ) {
284 }
285 c = sourcePtr[i];
286 if ( c == '\n' ) {
287 sourcePtr[i] = 0;
288 }
289 print( ";%d:%s\n", sourceLine, sourcePtr );
290 if ( c == 0 ) {
291 sourcePtr += i; // end of file
292 } else {
293 sourcePtr += i+1;
294 }
295 sourceLine++;
296 }
297 }
298
I(stabline)299 static void I(stabline)(Coordinate *cp) {
300 static char *prevfile;
301 static int prevline;
302
303 if (cp->file && (prevfile == NULL || strcmp(prevfile, cp->file) != 0)) {
304 print("file \"%s\"\n", prevfile = cp->file);
305 prevline = 0;
306 if ( sourceFile ) {
307 free( sourceFile );
308 sourceFile = NULL;
309 }
310 // load the new source file
311 LoadSourceFile( cp->file );
312 }
313 if (cp->y != prevline) {
314 print("line %d\n", prevline = cp->y);
315 PrintToSourceLine( cp->y );
316 }
317 }
318
319 //========================================================
320
321 #define b_blockbeg blockbeg
322 #define b_blockend blockend
323
324 Interface bytecodeIR = {
325 {1, 1, 0}, /* char */
326 {2, 2, 0}, /* short */
327 {4, 4, 0}, /* int */
328 {4, 4, 0}, /* long */
329 {4, 4, 0}, /* long long */
330 {4, 4, 0}, /* float */ // JDC: use inline floats
331 {4, 4, 0}, /* double */ // JDC: don't ever emit 8 byte double code
332 {4, 4, 0}, /* long double */ // JDC: don't ever emit 8 byte double code
333 {4, 4, 0}, /* T* */
334 {0, 4, 0}, /* struct */
335 0, /* little_endian */
336 0, /* mulops_calls */
337 0, /* wants_callb */
338 0, /* wants_argb */
339 1, /* left_to_right */
340 0, /* wants_dag */
341 0, /* unsigned_char */
342 I(address),
343 I(blockbeg),
344 I(blockend),
345 I(defaddress),
346 I(defconst),
347 I(defstring),
348 I(defsymbol),
349 I(emit),
350 I(export),
351 I(function),
352 I(gen),
353 I(global),
354 I(import),
355 I(local),
356 I(progbeg),
357 I(progend),
358 I(segment),
359 I(space),
360 0, /* I(stabblock) */
361 0, /* I(stabend) */
362 0, /* I(stabfend) */
363 0, /* I(stabinit) */
364 I(stabline),
365 0, /* I(stabsym) */
366 0, /* I(stabtype) */
367 };
368