⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pass2.c

📁 quakeIII源码这个不用我多说吧
💻 C
📖 第 1 页 / 共 2 页
字号:
#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++) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -