aboutsummaryrefslogtreecommitdiffstats
path: root/lcc/src/bytecode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lcc/src/bytecode.c')
-rwxr-xr-xlcc/src/bytecode.c730
1 files changed, 365 insertions, 365 deletions
diff --git a/lcc/src/bytecode.c b/lcc/src/bytecode.c
index f32a04f..8b8a6b6 100755
--- a/lcc/src/bytecode.c
+++ b/lcc/src/bytecode.c
@@ -1,365 +1,365 @@
-#include "c.h"
-#define I(f) b_##f
-
-
-static void I(segment)(int n) {
- static int cseg;
-
- if (cseg != n)
- switch (cseg = n) {
- case CODE: print("code\n"); return;
- case DATA: print("data\n"); return;
- case BSS: print("bss\n"); return;
- case LIT: print("lit\n"); return;
- default: assert(0);
- }
-}
-
-static void I(address)(Symbol q, Symbol p, long n) {
- q->x.name = stringf("%s%s%D", p->x.name, n > 0 ? "+" : "", n);
-}
-
-static void I(defaddress)(Symbol p) {
- print("address %s\n", p->x.name);
-}
-
-static void I(defconst)(int suffix, int size, Value v) {
- switch (suffix) {
- case I:
- if (size > sizeof (int))
- print("byte %d %D\n", size, v.i);
- else
- print("byte %d %d\n", size, v.i);
- return;
- case U:
- if (size > sizeof (unsigned))
- print("byte %d %U\n", size, v.u);
- else
- print("byte %d %u\n", size, v.u);
- return;
- case P: print("byte %d %U\n", size, (unsigned long)v.p); return;
- case F:
- if (size == 4) {
- float f = v.d;
- print("byte 4 %u\n", *(unsigned *)&f);
- } else {
- unsigned *p = (unsigned *)&v.d;
- print("byte 4 %u\n", p[swap]);
- print("byte 4 %u\n", p[1 - swap]);
- }
- return;
- }
- assert(0);
-}
-
-static void I(defstring)(int len, char *str) {
- char *s;
-
- for (s = str; s < str + len; s++)
- print("byte 1 %d\n", (*s)&0377);
-}
-
-static void I(defsymbol)(Symbol p) {
- if (p->scope == CONSTANTS)
- switch (optype(ttob(p->type))) {
- case I: p->x.name = stringf("%D", p->u.c.v.i); break;
- case U: p->x.name = stringf("%U", p->u.c.v.u); break;
- case P: p->x.name = stringf("%U", p->u.c.v.p); break;
- case F:
- { // JDC: added this to get inline floats
- unsigned temp;
-
- *(float *)&temp = p->u.c.v.d;
- p->x.name = stringf("%U", temp );
- }
- break;// JDC: added this
- default: assert(0);
- }
- else if (p->scope >= LOCAL && p->sclass == STATIC)
- p->x.name = stringf("$%d", genlabel(1));
- else if (p->scope == LABELS || p->generated)
- p->x.name = stringf("$%s", p->name);
- else
- p->x.name = p->name;
-}
-
-static void dumptree(Node p) {
- switch (specific(p->op)) {
- case ASGN+B:
- assert(p->kids[0]);
- assert(p->kids[1]);
- assert(p->syms[0]);
- dumptree(p->kids[0]);
- dumptree(p->kids[1]);
- print("%s %d\n", opname(p->op), p->syms[0]->u.c.v.u);
- return;
- case RET+V:
- assert(!p->kids[0]);
- assert(!p->kids[1]);
- print("%s\n", opname(p->op));
- return;
- }
- switch (generic(p->op)) {
- case CNST: case ADDRG: case ADDRF: case ADDRL: case LABEL:
- assert(!p->kids[0]);
- assert(!p->kids[1]);
- assert(p->syms[0] && p->syms[0]->x.name);
- print("%s %s\n", opname(p->op), p->syms[0]->x.name);
- return;
- case CVF: case CVI: case CVP: case CVU:
- assert(p->kids[0]);
- assert(!p->kids[1]);
- assert(p->syms[0]);
- dumptree(p->kids[0]);
- print("%s %d\n", opname(p->op), p->syms[0]->u.c.v.i);
- return;
- case ARG: case BCOM: case NEG: case INDIR: case JUMP: case RET:
- assert(p->kids[0]);
- assert(!p->kids[1]);
- dumptree(p->kids[0]);
- print("%s\n", opname(p->op));
- return;
- case CALL:
- assert(p->kids[0]);
- assert(!p->kids[1]);
- assert(optype(p->op) != B);
- dumptree(p->kids[0]);
- print("%s\n", opname(p->op));
- if ( !p->count ) { printf("pop\n"); }; // JDC
- return;
- case ASGN: case BOR: case BAND: case BXOR: case RSH: case LSH:
- case ADD: case SUB: case DIV: case MUL: case MOD:
- assert(p->kids[0]);
- assert(p->kids[1]);
- dumptree(p->kids[0]);
- dumptree(p->kids[1]);
- print("%s\n", opname(p->op));
- return;
- case EQ: case NE: case GT: case GE: case LE: case LT:
- assert(p->kids[0]);
- assert(p->kids[1]);
- assert(p->syms[0]);
- assert(p->syms[0]->x.name);
- dumptree(p->kids[0]);
- dumptree(p->kids[1]);
- print("%s %s\n", opname(p->op), p->syms[0]->x.name);
- return;
- }
- assert(0);
-}
-
-static void I(emit)(Node p) {
- for (; p; p = p->link)
- dumptree(p);
-}
-
-static void I(export)(Symbol p) {
- print("export %s\n", p->x.name);
-}
-
-static void I(function)(Symbol f, Symbol caller[], Symbol callee[], int ncalls) {
- int i;
-
- (*IR->segment)(CODE);
- offset = 0;
- for (i = 0; caller[i] && callee[i]; i++) {
- offset = roundup(offset, caller[i]->type->align);
- caller[i]->x.name = callee[i]->x.name = stringf("%d", offset);
- caller[i]->x.offset = callee[i]->x.offset = offset;
- offset += caller[i]->type->size;
- }
- maxargoffset = maxoffset = argoffset = offset = 0;
- gencode(caller, callee);
- print("proc %s %d %d\n", f->x.name, maxoffset, maxargoffset);
- emitcode();
- print("endproc %s %d %d\n", f->x.name, maxoffset, maxargoffset);
-
-}
-
-static void gen02(Node p) {
- assert(p);
- if (generic(p->op) == ARG) {
- assert(p->syms[0]);
- argoffset += (p->syms[0]->u.c.v.i < 4 ? 4 : p->syms[0]->u.c.v.i);
- } else if (generic(p->op) == CALL) {
- maxargoffset = (argoffset > maxargoffset ? argoffset : maxargoffset);
- argoffset = 0;
- }
-}
-
-static void gen01(Node p) {
- if (p) {
- gen01(p->kids[0]);
- gen01(p->kids[1]);
- gen02(p);
- }
-}
-
-static Node I(gen)(Node p) {
- Node q;
-
- assert(p);
- for (q = p; q; q = q->link)
- gen01(q);
- return p;
-}
-
-static void I(global)(Symbol p) {
- print("align %d\n", p->type->align > 4 ? 4 : p->type->align);
- print("LABELV %s\n", p->x.name);
-}
-
-static void I(import)(Symbol p) {
- print("import %s\n", p->x.name);
-}
-
-static void I(local)(Symbol p) {
- offset = roundup(offset, p->type->align);
- p->x.name = stringf("%d", offset);
- p->x.offset = offset;
- offset += p->type->size;
-}
-
-static void I(progbeg)(int argc, char *argv[]) {}
-
-static void I(progend)(void) {}
-
-static void I(space)(int n) {
- print("skip %d\n", n);
-}
-
-//========================================================
-
-// JDC: hacked up to get interleaved source lines in asm code
-static char *sourceFile;
-static char *sourcePtr;
-static int sourceLine;
-
-static int filelength( FILE *f ) {
- int pos;
- int end;
-
- pos = ftell (f);
- fseek (f, 0, SEEK_END);
- end = ftell (f);
- fseek (f, pos, SEEK_SET);
-
- return end;
-}
-
-static void LoadSourceFile( const char *filename ) {
- FILE *f;
- int length;
-
- f = fopen( filename, "r" );
- if ( !f ) {
- print( ";couldn't open %s\n", filename );
- sourceFile = NULL;
- return;
- }
- length = filelength( f );
- sourceFile = malloc( length + 1 );
- if ( sourceFile ) {
- fread( sourceFile, length, 1, f );
- sourceFile[length] = 0;
- }
-
- fclose( f );
- sourceLine = 1;
- sourcePtr = sourceFile;
-}
-
-static void PrintToSourceLine( int line ) {
- int c;
-
- if ( !sourceFile ) {
- return;
- }
- while ( sourceLine <= line ) {
- int i;
-
- for ( i = 0 ; sourcePtr[i] && sourcePtr[i] != '\n' ; i++ ) {
- }
- c = sourcePtr[i];
- if ( c == '\n' ) {
- sourcePtr[i] = 0;
- }
- print( ";%d:%s\n", sourceLine, sourcePtr );
- if ( c == 0 ) {
- sourcePtr += i; // end of file
- } else {
- sourcePtr += i+1;
- }
- sourceLine++;
- }
-}
-
-static void I(stabline)(Coordinate *cp) {
- static char *prevfile;
- static int prevline;
-
- if (cp->file && (prevfile == NULL || strcmp(prevfile, cp->file) != 0)) {
- print("file \"%s\"\n", prevfile = cp->file);
- prevline = 0;
- if ( sourceFile ) {
- free( sourceFile );
- sourceFile = NULL;
- }
- // load the new source file
- LoadSourceFile( cp->file );
- }
- if (cp->y != prevline) {
- print("line %d\n", prevline = cp->y);
- PrintToSourceLine( cp->y );
- }
-}
-
-//========================================================
-
-#define b_blockbeg blockbeg
-#define b_blockend blockend
-
-Interface bytecodeIR = {
- 1, 1, 0, /* char */
- 2, 2, 0, /* short */
- 4, 4, 0, /* int */
- 4, 4, 0, /* long */
- 4, 4, 0, /* long long */
- 4, 4, 0, /* float */ // JDC: use inline floats
- 4, 4, 0, /* double */ // JDC: don't ever emit 8 byte double code
- 4, 4, 0, /* long double */ // JDC: don't ever emit 8 byte double code
- 4, 4, 0, /* T* */
- 0, 4, 0, /* struct */
- 0, /* little_endian */
- 0, /* mulops_calls */
- 0, /* wants_callb */
- 0, /* wants_argb */
- 1, /* left_to_right */
- 0, /* wants_dag */
- 0, /* unsigned_char */
- I(address),
- I(blockbeg),
- I(blockend),
- I(defaddress),
- I(defconst),
- I(defstring),
- I(defsymbol),
- I(emit),
- I(export),
- I(function),
- I(gen),
- I(global),
- I(import),
- I(local),
- I(progbeg),
- I(progend),
- I(segment),
- I(space),
- 0, /* I(stabblock) */
- 0, /* I(stabend) */
- 0, /* I(stabfend) */
- 0, /* I(stabinit) */
- I(stabline),
- 0, /* I(stabsym) */
- 0, /* I(stabtype) */
-};
+#include "c.h"
+#define I(f) b_##f
+
+
+static void I(segment)(int n) {
+ static int cseg;
+
+ if (cseg != n)
+ switch (cseg = n) {
+ case CODE: print("code\n"); return;
+ case DATA: print("data\n"); return;
+ case BSS: print("bss\n"); return;
+ case LIT: print("lit\n"); return;
+ default: assert(0);
+ }
+}
+
+static void I(address)(Symbol q, Symbol p, long n) {
+ q->x.name = stringf("%s%s%D", p->x.name, n > 0 ? "+" : "", n);
+}
+
+static void I(defaddress)(Symbol p) {
+ print("address %s\n", p->x.name);
+}
+
+static void I(defconst)(int suffix, int size, Value v) {
+ switch (suffix) {
+ case I:
+ if (size > sizeof (int))
+ print("byte %d %D\n", size, v.i);
+ else
+ print("byte %d %d\n", size, v.i);
+ return;
+ case U:
+ if (size > sizeof (unsigned))
+ print("byte %d %U\n", size, v.u);
+ else
+ print("byte %d %u\n", size, v.u);
+ return;
+ case P: print("byte %d %U\n", size, (unsigned long)v.p); return;
+ case F:
+ if (size == 4) {
+ float f = v.d;
+ print("byte 4 %u\n", *(unsigned *)&f);
+ } else {
+ unsigned *p = (unsigned *)&v.d;
+ print("byte 4 %u\n", p[swap]);
+ print("byte 4 %u\n", p[1 - swap]);
+ }
+ return;
+ }
+ assert(0);
+}
+
+static void I(defstring)(int len, char *str) {
+ char *s;
+
+ for (s = str; s < str + len; s++)
+ print("byte 1 %d\n", (*s)&0377);
+}
+
+static void I(defsymbol)(Symbol p) {
+ if (p->scope == CONSTANTS)
+ switch (optype(ttob(p->type))) {
+ case I: p->x.name = stringf("%D", p->u.c.v.i); break;
+ case U: p->x.name = stringf("%U", p->u.c.v.u); break;
+ case P: p->x.name = stringf("%U", p->u.c.v.p); break;
+ case F:
+ { // JDC: added this to get inline floats
+ unsigned temp;
+
+ *(float *)&temp = p->u.c.v.d;
+ p->x.name = stringf("%U", temp );
+ }
+ break;// JDC: added this
+ default: assert(0);
+ }
+ else if (p->scope >= LOCAL && p->sclass == STATIC)
+ p->x.name = stringf("$%d", genlabel(1));
+ else if (p->scope == LABELS || p->generated)
+ p->x.name = stringf("$%s", p->name);
+ else
+ p->x.name = p->name;
+}
+
+static void dumptree(Node p) {
+ switch (specific(p->op)) {
+ case ASGN+B:
+ assert(p->kids[0]);
+ assert(p->kids[1]);
+ assert(p->syms[0]);
+ dumptree(p->kids[0]);
+ dumptree(p->kids[1]);
+ print("%s %d\n", opname(p->op), p->syms[0]->u.c.v.u);
+ return;
+ case RET+V:
+ assert(!p->kids[0]);
+ assert(!p->kids[1]);
+ print("%s\n", opname(p->op));
+ return;
+ }
+ switch (generic(p->op)) {
+ case CNST: case ADDRG: case ADDRF: case ADDRL: case LABEL:
+ assert(!p->kids[0]);
+ assert(!p->kids[1]);
+ assert(p->syms[0] && p->syms[0]->x.name);
+ print("%s %s\n", opname(p->op), p->syms[0]->x.name);
+ return;
+ case CVF: case CVI: case CVP: case CVU:
+ assert(p->kids[0]);
+ assert(!p->kids[1]);
+ assert(p->syms[0]);
+ dumptree(p->kids[0]);
+ print("%s %d\n", opname(p->op), p->syms[0]->u.c.v.i);
+ return;
+ case ARG: case BCOM: case NEG: case INDIR: case JUMP: case RET:
+ assert(p->kids[0]);
+ assert(!p->kids[1]);
+ dumptree(p->kids[0]);
+ print("%s\n", opname(p->op));
+ return;
+ case CALL:
+ assert(p->kids[0]);
+ assert(!p->kids[1]);
+ assert(optype(p->op) != B);
+ dumptree(p->kids[0]);
+ print("%s\n", opname(p->op));
+ if ( !p->count ) { printf("pop\n"); }; // JDC
+ return;
+ case ASGN: case BOR: case BAND: case BXOR: case RSH: case LSH:
+ case ADD: case SUB: case DIV: case MUL: case MOD:
+ assert(p->kids[0]);
+ assert(p->kids[1]);
+ dumptree(p->kids[0]);
+ dumptree(p->kids[1]);
+ print("%s\n", opname(p->op));
+ return;
+ case EQ: case NE: case GT: case GE: case LE: case LT:
+ assert(p->kids[0]);
+ assert(p->kids[1]);
+ assert(p->syms[0]);
+ assert(p->syms[0]->x.name);
+ dumptree(p->kids[0]);
+ dumptree(p->kids[1]);
+ print("%s %s\n", opname(p->op), p->syms[0]->x.name);
+ return;
+ }
+ assert(0);
+}
+
+static void I(emit)(Node p) {
+ for (; p; p = p->link)
+ dumptree(p);
+}
+
+static void I(export)(Symbol p) {
+ print("export %s\n", p->x.name);
+}
+
+static void I(function)(Symbol f, Symbol caller[], Symbol callee[], int ncalls) {
+ int i;
+
+ (*IR->segment)(CODE);
+ offset = 0;
+ for (i = 0; caller[i] && callee[i]; i++) {
+ offset = roundup(offset, caller[i]->type->align);
+ caller[i]->x.name = callee[i]->x.name = stringf("%d", offset);
+ caller[i]->x.offset = callee[i]->x.offset = offset;
+ offset += caller[i]->type->size;
+ }
+ maxargoffset = maxoffset = argoffset = offset = 0;
+ gencode(caller, callee);
+ print("proc %s %d %d\n", f->x.name, maxoffset, maxargoffset);
+ emitcode();
+ print("endproc %s %d %d\n", f->x.name, maxoffset, maxargoffset);
+
+}
+
+static void gen02(Node p) {
+ assert(p);
+ if (generic(p->op) == ARG) {
+ assert(p->syms[0]);
+ argoffset += (p->syms[0]->u.c.v.i < 4 ? 4 : p->syms[0]->u.c.v.i);
+ } else if (generic(p->op) == CALL) {
+ maxargoffset = (argoffset > maxargoffset ? argoffset : maxargoffset);
+ argoffset = 0;
+ }
+}
+
+static void gen01(Node p) {
+ if (p) {
+ gen01(p->kids[0]);
+ gen01(p->kids[1]);
+ gen02(p);
+ }
+}
+
+static Node I(gen)(Node p) {
+ Node q;
+
+ assert(p);
+ for (q = p; q; q = q->link)
+ gen01(q);
+ return p;
+}
+
+static void I(global)(Symbol p) {
+ print("align %d\n", p->type->align > 4 ? 4 : p->type->align);
+ print("LABELV %s\n", p->x.name);
+}
+
+static void I(import)(Symbol p) {
+ print("import %s\n", p->x.name);
+}
+
+static void I(local)(Symbol p) {
+ offset = roundup(offset, p->type->align);
+ p->x.name = stringf("%d", offset);
+ p->x.offset = offset;
+ offset += p->type->size;
+}
+
+static void I(progbeg)(int argc, char *argv[]) {}
+
+static void I(progend)(void) {}
+
+static void I(space)(int n) {
+ print("skip %d\n", n);
+}
+
+//========================================================
+
+// JDC: hacked up to get interleaved source lines in asm code
+static char *sourceFile;
+static char *sourcePtr;
+static int sourceLine;
+
+static int filelength( FILE *f ) {
+ int pos;
+ int end;
+
+ pos = ftell (f);
+ fseek (f, 0, SEEK_END);
+ end = ftell (f);
+ fseek (f, pos, SEEK_SET);
+
+ return end;
+}
+
+static void LoadSourceFile( const char *filename ) {
+ FILE *f;
+ int length;
+
+ f = fopen( filename, "r" );
+ if ( !f ) {
+ print( ";couldn't open %s\n", filename );
+ sourceFile = NULL;
+ return;
+ }
+ length = filelength( f );
+ sourceFile = malloc( length + 1 );
+ if ( sourceFile ) {
+ fread( sourceFile, length, 1, f );
+ sourceFile[length] = 0;
+ }
+
+ fclose( f );
+ sourceLine = 1;
+ sourcePtr = sourceFile;
+}
+
+static void PrintToSourceLine( int line ) {
+ int c;
+
+ if ( !sourceFile ) {
+ return;
+ }
+ while ( sourceLine <= line ) {
+ int i;
+
+ for ( i = 0 ; sourcePtr[i] && sourcePtr[i] != '\n' ; i++ ) {
+ }
+ c = sourcePtr[i];
+ if ( c == '\n' ) {
+ sourcePtr[i] = 0;
+ }
+ print( ";%d:%s\n", sourceLine, sourcePtr );
+ if ( c == 0 ) {
+ sourcePtr += i; // end of file
+ } else {
+ sourcePtr += i+1;
+ }
+ sourceLine++;
+ }
+}
+
+static void I(stabline)(Coordinate *cp) {
+ static char *prevfile;
+ static int prevline;
+
+ if (cp->file && (prevfile == NULL || strcmp(prevfile, cp->file) != 0)) {
+ print("file \"%s\"\n", prevfile = cp->file);
+ prevline = 0;
+ if ( sourceFile ) {
+ free( sourceFile );
+ sourceFile = NULL;
+ }
+ // load the new source file
+ LoadSourceFile( cp->file );
+ }
+ if (cp->y != prevline) {
+ print("line %d\n", prevline = cp->y);
+ PrintToSourceLine( cp->y );
+ }
+}
+
+//========================================================
+
+#define b_blockbeg blockbeg
+#define b_blockend blockend
+
+Interface bytecodeIR = {
+ 1, 1, 0, /* char */
+ 2, 2, 0, /* short */
+ 4, 4, 0, /* int */
+ 4, 4, 0, /* long */
+ 4, 4, 0, /* long long */
+ 4, 4, 0, /* float */ // JDC: use inline floats
+ 4, 4, 0, /* double */ // JDC: don't ever emit 8 byte double code
+ 4, 4, 0, /* long double */ // JDC: don't ever emit 8 byte double code
+ 4, 4, 0, /* T* */
+ 0, 4, 0, /* struct */
+ 0, /* little_endian */
+ 0, /* mulops_calls */
+ 0, /* wants_callb */
+ 0, /* wants_argb */
+ 1, /* left_to_right */
+ 0, /* wants_dag */
+ 0, /* unsigned_char */
+ I(address),
+ I(blockbeg),
+ I(blockend),
+ I(defaddress),
+ I(defconst),
+ I(defstring),
+ I(defsymbol),
+ I(emit),
+ I(export),
+ I(function),
+ I(gen),
+ I(global),
+ I(import),
+ I(local),
+ I(progbeg),
+ I(progend),
+ I(segment),
+ I(space),
+ 0, /* I(stabblock) */
+ 0, /* I(stabend) */
+ 0, /* I(stabfend) */
+ 0, /* I(stabinit) */
+ I(stabline),
+ 0, /* I(stabsym) */
+ 0, /* I(stabtype) */
+};