URL
https://opencores.org/ocsvn/eco32/eco32/trunk
Subversion Repositories eco32
[/] [eco32/] [trunk/] [lcc/] [src/] [bytecode.c] - Rev 66
Go to most recent revision | Compare with Previous | Blame | View Log
#include "c.h" #define I(f) b_##f static char rcsid[] = "$Id: bytecode.c,v 1.1 2002/08/28 23:12:41 drh Exp $"; 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 { double d = v.d; unsigned *p = (unsigned *)&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; 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)); 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); } 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 (cp->y != prevline) print("line %d\n", prevline = 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, 1, /* float */ 8, 8, 1, /* double */ 8, 8, 1, /* long double */ 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) */ };
Go to most recent revision | Compare with Previous | Blame | View Log