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