* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / lcc / src / bytecode.c
blob871056a05f19eebac093d862987e5c71489c8b09
1 #include "c.h"
2 #define I(f) b_##f
5 static void I(segment)(int n) {
6 static int cseg;
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);
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);
22 static void I(defaddress)(Symbol p) {
23 print("address %s\n", p->x.name);
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]);
51 return;
53 assert(0);
56 static void I(defstring)(int len, char *str) {
57 char *s;
59 for (s = str; s < str + len; s++)
60 print("byte 1 %d\n", (*s)&0377);
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;
73 temp.f = p->u.c.v.d;
74 p->x.name = stringf("%U", temp.ui );
76 break;// JDC: added this
77 default: assert(0);
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;
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;
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;
149 assert(0);
152 static void I(emit)(Node p) {
153 for (; p; p = p->link)
154 dumptree(p);
157 static void I(export)(Symbol p) {
158 print("export %s\n", p->x.name);
161 static void I(function)(Symbol f, Symbol caller[], Symbol callee[], int ncalls) {
162 int i;
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;
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);
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;
191 static void gen01(Node p) {
192 if (p) {
193 gen01(p->kids[0]);
194 gen01(p->kids[1]);
195 gen02(p);
199 static Node I(gen)(Node p) {
200 Node q;
202 assert(p);
203 for (q = p; q; q = q->link)
204 gen01(q);
205 return p;
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);
213 static void I(import)(Symbol p) {
214 print("import %s\n", p->x.name);
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;
224 static void I(progbeg)(int argc, char *argv[]) {}
226 static void I(progend)(void) {}
228 static void I(space)(int n) {
229 print("skip %d\n", n);
232 //========================================================
234 // JDC: hacked up to get interleaved source lines in asm code
235 static char *sourceFile;
236 static char *sourcePtr;
237 static int sourceLine;
239 static int filelength( FILE *f ) {
240 int pos;
241 int end;
243 pos = ftell (f);
244 fseek (f, 0, SEEK_END);
245 end = ftell (f);
246 fseek (f, pos, SEEK_SET);
248 return end;
251 static void LoadSourceFile( const char *filename ) {
252 FILE *f;
253 int length;
255 f = fopen( filename, "r" );
256 if ( !f ) {
257 print( ";couldn't open %s\n", filename );
258 sourceFile = NULL;
259 return;
261 length = filelength( f );
262 sourceFile = malloc( length + 1 );
263 if ( sourceFile ) {
264 fread( sourceFile, length, 1, f );
265 sourceFile[length] = 0;
268 fclose( f );
269 sourceLine = 1;
270 sourcePtr = sourceFile;
273 static void PrintToSourceLine( int line ) {
274 int c;
276 if ( !sourceFile ) {
277 return;
279 while ( sourceLine <= line ) {
280 int i;
282 for ( i = 0 ; sourcePtr[i] && sourcePtr[i] != '\n' ; i++ ) {
284 c = sourcePtr[i];
285 if ( c == '\n' ) {
286 sourcePtr[i] = 0;
288 print( ";%d:%s\n", sourceLine, sourcePtr );
289 if ( c == 0 ) {
290 sourcePtr += i; // end of file
291 } else {
292 sourcePtr += i+1;
294 sourceLine++;
298 static void I(stabline)(Coordinate *cp) {
299 static char *prevfile;
300 static int prevline;
302 if (cp->file && (prevfile == NULL || strcmp(prevfile, cp->file) != 0)) {
303 print("file \"%s\"\n", prevfile = cp->file);
304 prevline = 0;
305 if ( sourceFile ) {
306 free( sourceFile );
307 sourceFile = NULL;
309 // load the new source file
310 LoadSourceFile( cp->file );
312 if (cp->y != prevline) {
313 print("line %d\n", prevline = cp->y);
314 PrintToSourceLine( cp->y );
318 //========================================================
320 #define b_blockbeg blockbeg
321 #define b_blockend blockend
323 Interface bytecodeIR = {
324 {1, 1, 0}, /* char */
325 {2, 2, 0}, /* short */
326 {4, 4, 0}, /* int */
327 {4, 4, 0}, /* long */
328 {4, 4, 0}, /* long long */
329 {4, 4, 0}, /* float */ // JDC: use inline floats
330 {4, 4, 0}, /* double */ // JDC: don't ever emit 8 byte double code
331 {4, 4, 0}, /* long double */ // JDC: don't ever emit 8 byte double code
332 {4, 4, 0}, /* T* */
333 {0, 4, 0}, /* struct */
334 0, /* little_endian */
335 0, /* mulops_calls */
336 0, /* wants_callb */
337 0, /* wants_argb */
338 1, /* left_to_right */
339 0, /* wants_dag */
340 0, /* unsigned_char */
341 I(address),
342 I(blockbeg),
343 I(blockend),
344 I(defaddress),
345 I(defconst),
346 I(defstring),
347 I(defsymbol),
348 I(emit),
349 I(export),
350 I(function),
351 I(gen),
352 I(global),
353 I(import),
354 I(local),
355 I(progbeg),
356 I(progend),
357 I(segment),
358 I(space),
359 0, /* I(stabblock) */
360 0, /* I(stabend) */
361 0, /* I(stabfend) */
362 0, /* I(stabinit) */
363 I(stabline),
364 0, /* I(stabsym) */
365 0, /* I(stabtype) */