* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / lcc / src / .svn / text-base / bytecode.c.svn-base
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);
15                 }
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]);
50                 }
51                 return;
52         }
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 );
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;
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);
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;
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);
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         }
191 static void gen01(Node p) {
192         if (p) {
193                 gen01(p->kids[0]);
194                 gen01(p->kids[1]);
195                 gen02(p);
196         }
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;
260         }
261         length = filelength( f );
262         sourceFile = malloc( length + 1 );
263         if ( sourceFile ) {
264                 fread( sourceFile, length, 1, f );
265                 sourceFile[length] = 0;
266         }
268         fclose( f );
269         sourceLine = 1;
270         sourcePtr = sourceFile;
273 static void PrintToSourceLine( int line ) {
274         int             c;
276         if ( !sourceFile ) {
277                 return;
278         }
279         while ( sourceLine <= line ) {
280                 int             i;
282                 for ( i = 0 ; sourcePtr[i] && sourcePtr[i] != '\n' ; i++ ) {
283                 }
284                 c = sourcePtr[i];
285                 if ( c == '\n' ) {
286                         sourcePtr[i] = 0;
287                 }
288                 print( ";%d:%s\n", sourceLine, sourcePtr );
289                 if ( c == 0 ) {
290                         sourcePtr += i; // end of file
291                 } else {
292                         sourcePtr += i+1;
293                 }
294                 sourceLine++;
295         }
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;
308                 }
309                 // load the new source file
310                 LoadSourceFile( cp->file );
311         }
312         if (cp->y != prevline) {
313                 print("line %d\n", prevline = cp->y);
314                 PrintToSourceLine( cp->y );
315         }
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) */