OpenCores
URL https://opencores.org/ocsvn/eco32/eco32/trunk

Subversion Repositories eco32

[/] [eco32/] [trunk/] [lcc/] [src/] [bytecode.c] - Rev 33

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.