Code Search for Developers
 
 
  

pass2.c from Nxabega at Krugle


Show pass2.c syntax highlighted

#include "c.h"
#include "rcc.h"
#if WIN32
#include <fcntl.h>
#include <io.h>
#endif


Interface *IR = NULL;
int Aflag;		/* >= 0 if -A specified */
int Pflag;		/* != 0 if -P specified */
int glevel;		/* == [0-9] if -g[0-9] specified */
int xref;		/* != 0 for cross-reference data */
Symbol YYnull;		/* _YYnull  symbol if -n or -nvalidate specified */
Symbol YYcheck;		/* _YYcheck symbol if -nvalidate,check specified */

static int verbose = 1;
#define VERBOSE(n,arg) (verbose >= n ? (void)(arg):(void)0)
static int nuids;
static rcc_item_ty *items;
static void **itemmap;

static void *uid2type(int uid) {
	assert(uid >= 0 && uid < nuids);
	if (itemmap[uid] == NULL) {
		Type ty;
		rcc_type_ty type = (void *)items[uid];
		assert(items[uid]);
		assert(items[uid]->uid == uid);
		assert(items[uid]->kind == rcc_Type_enum);
		type = items[uid]->v.rcc_Type.type;
		assert(type);
		switch (type->kind) {
		case rcc_INT_enum:
			ty = btot(INT, type->size);
			assert(ty->align == type->align);
			break;
		case rcc_UNSIGNED_enum:
			ty = btot(UNSIGNED, type->size);
			assert(ty->align == type->align);
			break;
		case rcc_FLOAT_enum:
			ty = btot(FLOAT, type->size);
			assert(ty->align == type->align);
			break;
		case rcc_VOID_enum:
			ty = voidtype;
			break;
		case rcc_POINTER_enum:
			ty = ptr(uid2type(type->v.rcc_POINTER.type));
			break;
		case rcc_ARRAY_enum:
			ty = uid2type(type->v.rcc_ARRAY.type);
			assert(ty->size > 0);
			ty = array(ty, type->size/ty->size, 0);
			break;
		case rcc_CONST_enum:
			ty = qual(CONST, uid2type(type->v.rcc_CONST.type));
			break;
		case rcc_VOLATILE_enum:
			ty = qual(VOLATILE, uid2type(type->v.rcc_VOLATILE.type));
			break;
		case rcc_ENUM_enum: {
			int i, n = Seq_length(type->v.rcc_ENUM.ids);
			ty = newstruct(ENUM, string(type->v.rcc_ENUM.tag));
			ty->type = inttype;
			ty->size = ty->type->size;
			ty->align = ty->type->align;
			ty->u.sym->u.idlist = newarray(n + 1, sizeof *ty->u.sym->u.idlist, PERM);
			for (i = 0; i < n; i++) {
				rcc_enum__ty e = Seq_remlo(type->v.rcc_ENUM.ids);
				Symbol p = install(e->id, &identifiers, GLOBAL, PERM);
				p->type = ty;
				p->sclass = ENUM;
				p->u.value = e->value;
				ty->u.sym->u.idlist[i] = p;
				free(e);
			}
			ty->u.sym->u.idlist[i] = NULL;
			Seq_free(&type->v.rcc_ENUM.ids);
			break;
			}
		case rcc_STRUCT_enum: case rcc_UNION_enum: {
			int i, n;
			Field *tail;
			list_ty fields;
			if (type->kind == rcc_STRUCT_enum) {
				ty = newstruct(STRUCT, string(type->v.rcc_STRUCT.tag));
				fields = type->v.rcc_STRUCT.fields;
			} else {
				ty = newstruct(UNION, string(type->v.rcc_UNION.tag));
				fields = type->v.rcc_UNION.fields;
			}
			itemmap[uid] = ty;	/* recursive types */
			ty->size = type->size;
			ty->align = type->align;
			tail = &ty->u.sym->u.s.flist;
			n = Seq_length(fields);
			for (i = 0; i < n; i++) {
				rcc_field_ty field = Seq_remlo(fields);
				NEW0(*tail, PERM);
				(*tail)->name = (char *)field->id;
				(*tail)->type = uid2type(field->type);
				(*tail)->offset = field->offset;
				(*tail)->bitsize = field->bitsize;
				(*tail)->lsb = field->lsb;
				if (isconst((*tail)->type))
					ty->u.sym->u.s.cfields = 1;
				if (isvolatile((*tail)->type))
					ty->u.sym->u.s.vfields = 1;
				tail = &(*tail)->link;
				free(field);
			}
			Seq_free(&fields);
			break;
			}
		case rcc_FUNCTION_enum: {
			int n = Seq_length(type->v.rcc_FUNCTION.formals);
			if (n > 0) {
				int i;
				Type *proto = newarray(n + 1, sizeof *proto, PERM);
				for (i = 0; i < n; i++) {
					int *formal = Seq_remlo(type->v.rcc_FUNCTION.formals);
					proto[i] = uid2type(*formal);
					free(formal);
				}
				proto[i] = NULL;
				ty = func(uid2type(type->v.rcc_FUNCTION.type), proto, 0);
			} else
				ty = func(uid2type(type->v.rcc_FUNCTION.type), NULL, 1);
			Seq_free(&type->v.rcc_FUNCTION.formals);
			break;
			}
		default: assert(0);
		}
		if (itemmap[uid] == NULL) {
			itemmap[uid] = ty;
			free(type);
			free(items[uid]);
			items[uid] = NULL;
		} else
			assert(itemmap[uid] == ty);
	}
	return itemmap[uid];
}

static Symbol uid2symbol(int uid) {
	assert(uid >= 0 && uid < nuids);
	if (itemmap[uid] == NULL) {
		Symbol p;
		rcc_symbol_ty symbol;
		assert(items[uid]);
		assert(items[uid]->uid == uid);
		assert(items[uid]->kind == rcc_Symbol_enum);
		symbol = items[uid]->v.rcc_Symbol.symbol;
		assert(symbol);
		NEW0(p, PERM);
		p->name = (char *)symbol->id;
		p->scope = symbol->scope;
		p->sclass = symbol->sclass;
		p->type = uid2type(symbol->type);
#define xx(f,n) p->f = symbol->flags>>n;
		xx(structarg,0)
		xx(addressed,1)
		xx(computed,2)
		xx(temporary,3)
		xx(generated,4)
#undef xx
		p->ref = symbol->ref/10000.0;
		assert(p->scope != CONSTANTS && p->scope != LABELS);
		if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN)
			(*IR->defsymbol)(p);
		itemmap[uid] = p;
		free(symbol);
		free(items[uid]);
		items[uid] = NULL;
	}
	return itemmap[uid];
}

#define xx(s) static void do##s(rcc_interface_ty);
xx(Export)
xx(Import)
xx(Global)
xx(Local)
xx(Address)
xx(Segment)
xx(Defaddress)
xx(Deflabel)
xx(Defconst)
xx(Defconstf)
xx(Defstring)
xx(Space)
xx(Function)
xx(Blockbeg)
xx(Blockend)
xx(Forest)
#undef xx
static void (*doX[])(rcc_interface_ty in) = {
#define xx(s) 0,
xx(Export)
xx(Import)
xx(Global)
xx(Local)
xx(Address)
xx(Segment)
xx(Defaddress)
xx(Deflabel)
xx(Defconst)
xx(Defconstf)
xx(Defstring)
xx(Space)
xx(Function)
xx(Blockbeg)
xx(Blockend)
xx(Forest)
	0
#undef xx
};

static void interface(rcc_interface_ty in) {
	assert(in);
	(*doX[in->kind])(in);
	free(in);
}

static void doExport(rcc_interface_ty in) {
	(*IR->export)(uid2symbol(in->v.rcc_Export.p));
}

static void doImport(rcc_interface_ty in) {
	Symbol p = uid2symbol(in->v.rcc_Export.p);

	(*IR->import)(p);
	p->defined = 1;
}

static void doGlobal(rcc_interface_ty in) {
	Symbol p = uid2symbol(in->v.rcc_Global.p);

	p->u.seg = in->v.rcc_Global.seg;
	(*IR->global)(p);
	p->defined = 1;
}

static void doLocal(rcc_interface_ty in) {
	int uid = in->v.rcc_Local.uid;

	assert(uid >= 0 && uid < nuids);
	assert(items[uid] == NULL);
	items[uid] = rcc_Symbol(uid, in->v.rcc_Local.p);
	if (in->v.rcc_Local.p->scope >= LOCAL)
		addlocal(uid2symbol(uid));
}

static void doAddress(rcc_interface_ty in) {
	int uid = in->v.rcc_Address.uid;
	Symbol p = uid2symbol(in->v.rcc_Address.p);

	assert(uid >= 0 && uid < nuids);
	assert(items[uid] == NULL);
	items[uid] = rcc_Symbol(uid, in->v.rcc_Address.q);
	if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN)
		(*IR->address)(uid2symbol(uid), p, in->v.rcc_Address.n);
	else {
		Code cp = code(Address);
		cp->u.addr.sym = uid2symbol(uid);
		cp->u.addr.base = p;
		cp->u.addr.offset = in->v.rcc_Address.n;
	}
}

static void doSegment(rcc_interface_ty in) {
	(*IR->segment)(in->v.rcc_Segment.seg);
}

static void doDefaddress(rcc_interface_ty in) {
	(*IR->defaddress)(uid2symbol(in->v.rcc_Defaddress.p));
}

static void doDeflabel(rcc_interface_ty in) {
	(*IR->defaddress)(findlabel(in->v.rcc_Deflabel.label));
}

static void doDefconst(rcc_interface_ty in) {
	Value v;

	v.i = in->v.rcc_Defconst.value;
	(*IR->defconst)(in->v.rcc_Defconst.suffix, in->v.rcc_Defconst.size, v);
}

static void doDefconstf(rcc_interface_ty in) {
	Value v;
	unsigned *p = (unsigned *)&v.d;

	p[swap]   = in->v.rcc_Defconstf.value->msb;
	p[1-swap] = in->v.rcc_Defconstf.value->lsb;
	(*IR->defconst)(F, in->v.rcc_Defconstf.size, v);
	free(in->v.rcc_Defconstf.value);
}

static void doDefstring(rcc_interface_ty in) {
	(*IR->defstring)(in->v.rcc_Defstring.s.len, (char *)in->v.rcc_Defstring.s.str);
	free((char *)in->v.rcc_Defstring.s.str);
}

static void doSpace(rcc_interface_ty in) {
	(*IR->space)(in->v.rcc_Space.n);
}

static void doFunction(rcc_interface_ty in) {
	int i, n;
	Symbol *caller, *callee;

	/*
	 Initialize:
	  define the function symbol,
	  initialize callee and caller arrays.
	*/
	cfunc = uid2symbol(in->v.rcc_Function.f);
	labels = table(NULL, LABELS);
	enterscope();
	n = Seq_length(in->v.rcc_Function.caller);
	caller = newarray(n + 1, sizeof *caller, FUNC);
	for (i = 0; i < n; i++) {
		int *uid = Seq_remlo(in->v.rcc_Function.caller);
		caller[i] = uid2symbol(*uid);
		free(uid);
	}
	caller[i] = NULL;
	Seq_free(&in->v.rcc_Function.caller);
	callee = newarray(n + 1, sizeof *callee, FUNC);
	for (i = 0; i < n; i++) {
		int *uid = Seq_remlo(in->v.rcc_Function.callee);
		callee[i] = uid2symbol(*uid);
		free(uid);
	}
	callee[i] = NULL;
	Seq_free(&in->v.rcc_Function.callee);
	cfunc->u.f.callee = callee;
	cfunc->defined = 1;
	/*
	 Initialize the code list,
	  traverse the interfaces inside the function;
	  each call appends code list entries.
	*/
	codelist = &codehead;
	codelist->next = NULL;
	n = Seq_length(in->v.rcc_Function.codelist);
	for (i = 0; i < n; i++)
		interface(Seq_remlo(in->v.rcc_Function.codelist));
	Seq_free(&in->v.rcc_Function.codelist);
	/*
	 Call the back end,
	 Wrap-up.
	*/
	exitscope();
	(*IR->function)(cfunc, caller, callee, in->v.rcc_Function.ncalls);
	cfunc = NULL;
	labels = NULL;
}

static struct block {
	Code begin;
	struct block *prev;
} *blockstack = NULL;

static void doBlockbeg(rcc_interface_ty in) {
	struct block *b;
	Code cp = code(Blockbeg);

	enterscope();
	cp->u.block.level = level;
	cp->u.block.locals = newarray(1, sizeof *cp->u.block.locals, FUNC);
	cp->u.block.locals[0] = NULL;
	cp->u.block.identifiers = NULL;
	cp->u.block.types = NULL;
	NEW(b, FUNC);
	b->begin = cp;
	b->prev = blockstack;
	blockstack = b;
}

static void doBlockend(rcc_interface_ty in) {
	assert(blockstack);
	code(Blockend)->u.begin = blockstack->begin;
	blockstack = blockstack->prev;
	exitscope();
}

static Node visit(rcc_node_ty node) {
	int op;
	Node left = NULL, right = NULL, p = NULL;
	Symbol sym = NULL;

	switch (node->kind) {
#define T(x) rcc_##x##_enum
	case T(CSE): {
		Symbol q = uid2symbol(node->v.rcc_CSE.uid);
		assert(q->temporary);
		q->u.t.cse = p = visit(node->v.rcc_CSE.node);
		break;
		}
	case T(CNST): {
		Value v;
		v.i = node->v.rcc_CNST.value;
		sym = constant(btot(node->suffix, node->size), v);
		op = CNST;
		break;
		}
	case T(CNSTF): {
		Value v;
		unsigned *p = (unsigned *)&v.d;
		p[swap]   = node->v.rcc_CNSTF.value->msb;
		p[1-swap] = node->v.rcc_CNSTF.value->lsb;
		sym = constant(btot(node->suffix, node->size), v);
		free(node->v.rcc_CNSTF.value);
		op = CNST;
		break;
		}
	case T(ARG):
		p = newnode(ARG + node->suffix + sizeop(node->size),
			visit(node->v.rcc_ARG.left), NULL,
			intconst(node->v.rcc_ARG.len));
		p->syms[1] = intconst(node->v.rcc_ARG.align);
		break;
	case T(ASGN):
		p = newnode(ASGN + node->suffix + sizeop(node->size),
			visit(node->v.rcc_ASGN.left), visit(node->v.rcc_ASGN.right),
			intconst(node->v.rcc_ASGN.len));
		p->syms[1] = intconst(node->v.rcc_ASGN.align);
		break;
	case T(CVT):
		op = node->v.rcc_CVT.op;
		left = visit(node->v.rcc_CVT.left);
		sym = intconst(node->v.rcc_CVT.fromsize);
		break;
	case T(CALL):
		op = CALL;
		left = visit(node->v.rcc_CALL.left);
		NEW0(sym, FUNC);
		sym->type = uid2type(node->v.rcc_CALL.type);
		break;
	case T(CALLB):
		op = CALL;
		left  = visit(node->v.rcc_CALLB.left);
		right = visit(node->v.rcc_CALLB.right);
		NEW0(sym, FUNC);
		sym->type = uid2type(node->v.rcc_CALLB.type);
		break;
	case T(RET):
		op = RET;
		break;
	case T(ADDRG):
		op = ADDRG;
		sym = uid2symbol(node->v.rcc_ADDRG.uid);
		break;
	case T(ADDRL):
		op = ADDRL;
		sym = uid2symbol(node->v.rcc_ADDRG.uid);
		break;
	case T(ADDRF):
		op = ADDRF;
		sym = uid2symbol(node->v.rcc_ADDRG.uid);
		break;
	case T(Unary):
		op = node->v.rcc_Unary.op;
		left = visit(node->v.rcc_Unary.left);
		break;
	case T(Binary):
		op = node->v.rcc_Binary.op;
		left  = visit(node->v.rcc_Binary.left);
		right = visit(node->v.rcc_Binary.right);
		break;
	case T(Compare):
		op = node->v.rcc_Compare.op;
		left  = visit(node->v.rcc_Compare.left);
		right = visit(node->v.rcc_Compare.right);
		sym = findlabel(node->v.rcc_Compare.label);
		break;
	case T(LABEL):
		op = LABEL;
		sym = findlabel(node->v.rcc_LABEL.label);
		break;
	case T(BRANCH):
		op = JUMP;
		left = newnode(ADDRG+P+sizeop(voidptype->size), NULL, NULL, findlabel(node->v.rcc_BRANCH.label));
		break;
#undef T
	default: assert(0);
	}
	if (p == NULL)
		p = newnode(op + node->suffix + sizeop(node->size), left, right, sym);
	free(node);
	return p;
}

static void doForest(rcc_interface_ty in) {
	Node *tail = &code(Gen)->u.forest;
	int i, n = Seq_length(in->v.rcc_Forest.nodes);

	for (i = 0; i < n; i++) {
		*tail = visit(Seq_remlo(in->v.rcc_Forest.nodes));
		assert(*tail);
		tail = &(*tail)->link;
	}
	*tail = NULL;
	Seq_free(&in->v.rcc_Forest.nodes);
}

int main(int argc, char *argv[]) {
	int i, version;
	float stamp = (assert(strstr(rcsid, ",v")), strtod(strstr(rcsid, ",v")+2, NULL))
;
	char *infile = NULL, *outfile = NULL;
	rcc_program_ty pickle;

	for (i = 1; i < argc; i++)
		if (*argv[i] != '-' || strcmp(argv[i], "-") == 0) {
			if (infile == NULL)
				infile = argv[i];
			else if (outfile == NULL)
				outfile = argv[i];
		}
	if (infile != NULL && strcmp(infile, "-") != 0
	&& freopen(infile, "rb", stdin) == NULL) {
		fprint(stderr, "%s: can't read `%s'\n", argv[0], infile);
		exit(EXIT_FAILURE);
	}
#if WIN32
	else
		_setmode(_fileno(stdin), _O_BINARY);
#endif
	if (outfile != NULL && strcmp(outfile, "-") != 0
	&& freopen(outfile, "w", stdout) == NULL) {
		fprint(stderr, "%s: can't write `%s'\n", argv[0], outfile);
		exit(EXIT_FAILURE);
	}
	version = read_int(stdin);
	assert(version/100 == (int)stamp);
	pickle = rcc_read_program(stdin);
	argc = pickle->argc;
	argv = newarray(argc + 1, sizeof *argv, PERM);
	{
		for (i = 0; i < argc; i++) {
			string_ty *arg = Seq_remlo(pickle->argv);
			argv[i] = (char *)arg->str;
			free(arg);
		}
		argv[i] = NULL;
		assert(i == argc);
		Seq_free(&pickle->argv);
	}
	for (i = argc - 1; i > 0; i--)
		if (strncmp(argv[i], "-target=", 8) == 0)
			break;
	if (i > 0) {
		int j;
		for (j = 0; bindings[j].name && bindings[j].ir; j++)
			if (strcmp(&argv[i][8], bindings[j].name) == 0) {
				IR = bindings[j].ir;
				break;
			}
	}
	if (!IR) {
		fprint(stderr, "%s: unknown target", argv[0]);
		if (i > 0)
			fprint(stderr, " `%s'", &argv[i][8]);
		fprint(stderr, "; must specify one of\n");
		for (i = 0; bindings[i].name; i++)
			fprint(stderr, "\t-target=%s\n", bindings[i].name);
		exit(EXIT_FAILURE);
	}
	IR->wants_dag = 0;	/* pickle's hold trees */
	init(argc, argv);
	genlabel(pickle->nlabels);
	level = GLOBAL;
	{
		int i, count;
		nuids = pickle->nuids;
		items = newarray(nuids, sizeof *items, PERM);
		itemmap = newarray(nuids, sizeof *items, PERM);
		for (i = 0; i < nuids; i++) {
			itemmap[i] = NULL;
			items[i] = NULL;
		}
		(*IR->progbeg)(argc, argv);
		count = Seq_length(pickle->items);
		for (i = 0; i < count; i++) {
			rcc_item_ty item = Seq_remlo(pickle->items);
			int uid = item->uid;
			assert(uid >= 0 && uid < nuids);
			assert(items[uid] == NULL);
			items[uid] = item;
		}
		Seq_free(&pickle->items);
#define xx(s) assert(rcc_##s##_enum < sizeof doX/sizeof doX[0] && doX[rcc_##s##_enum]==0); \
	      doX[rcc_##s##_enum] = do##s;
	      xx(Export)
	      xx(Import)
	      xx(Global)
	      xx(Local)
	      xx(Address)
	      xx(Segment)
	      xx(Defaddress)
	      xx(Deflabel)
	      xx(Defconst)
	      xx(Defconstf)
	      xx(Defstring)
	      xx(Space)
	      xx(Function)
	      xx(Blockbeg)
	      xx(Blockend)
	      xx(Forest)
#undef xx
		count = Seq_length(pickle->interfaces);
		for (i = 0; i < count; i++)
			interface(Seq_remlo(pickle->interfaces));
		Seq_free(&pickle->interfaces);
		free(pickle);
		(*IR->progend)();
	}
	deallocate(PERM);
	return errcnt > 0;
}

/* main_init - process program arguments */
void main_init(int argc, char *argv[]) {
	int i;
	static int inited;

	if (inited)
		return;
	inited = 1;
	for (i = 1; i < argc; i++)
		if (strcmp(argv[i], "-g") == 0 || strcmp(argv[i], "-g2") == 0)
			glevel = 2;
		else if (strcmp(argv[i], "-w") == 0)
			wflag++;
		else if (strcmp(argv[i], "-v") == 0) {
			fprint(stderr, "%s %s\n", argv[0], rcsid);
			verbose++;
		} else if (strncmp(argv[i], "-errout=", 8) == 0) {
			FILE *f = fopen(argv[i]+8, "w");
			if (f == NULL) {
				fprint(stderr, "%s: can't write errors to `%s'\n", argv[0], argv[i]+8);
				exit(EXIT_FAILURE);
			}
			fclose(f);
			f = freopen(argv[i]+8, "w", stderr);
			assert(f);
		} else if (strncmp(argv[i], "-e", 2) == 0) {
			int x;
			if ((x = strtol(&argv[i][2], NULL, 0)) > 0)
				errlimit = x;
		}
}

void init(int argc, char *argv[]) {
	{extern void main_init(int, char *[]); main_init(argc, argv);}
	{extern void prof_init(int, char *[]); prof_init(argc, argv);}
	{extern void trace_init(int, char *[]); trace_init(argc, argv);}
	{extern void type_init(int, char *[]); type_init(argc, argv);}
	{extern void x86linux_init(int, char *[]); x86linux_init(argc, argv);}
}




See more files for this project here

Nxabega

Nxabega is a First Person Shooter (FPS) based upon the open sourced Quake 3 engine and game code. The final intention is to provide a rich single player game.

Project homepage: http://sourceforge.net/projects/nxabega
Programming language(s): C,C++
License: other

  2html.c
  alloc.c
  alpha.md
  asdl.c
  bind.c
  bytecode.c
  c.h
  config.h
  dag.c
  dagcheck.md
  decl.c
  enode.c
  error.c
  event.c
  expr.c
  gen.c
  init.c
  inits.c
  input.c
  lex.c
  list.c
  main.c
  mips.md
  null.c
  output.c
  pass2.c
  prof.c
  profio.c
  rcc.asdl
  run.sh
  simp.c
  sparc.md
  stab.c
  stab.h
  stmt.c
  string.c
  sym.c
  symbolic.c
  token.h
  trace.c
  tree.c
  types.c
  x86.md
  x86linux.md