Esempio n. 1
0
File: types.c Progetto: xtao/c
int
canrepresent(CTy *l, CTy *r)
{
	if(!isitype(l) || !isitype(r))
		panic("internal error");
	return getmaxval(l) <= getmaxval(r) && getminval(l) >= getminval(r);
}
Esempio n. 2
0
File: emit.c Progetto: a8m/c
static void
incdec(Node *n)
{
	if(!isitype(n->type) && !isptr(n->type))
		panic("unimplemented incdec");
	addr(n->Incdec.operand);
	pushq("rax");
	load(n->type);
	if(isptr(n->type)) {
		if(n->Incdec.op == TOKINC)
			outi("add $%d, %%rax\n", n->type->Ptr.subty->size);
		else
			outi("add $%d, %%rax\n", -n->type->Ptr.subty->size);
	} else {
		if(n->Incdec.op == TOKINC)
			outi("inc %%rax\n");
		else
			outi("dec %%rax\n");
	}
	outi("movq %%rax, %%rcx\n");
	popq("rax");
	store(n->type);
	outi("movq %%rcx, %%rax\n");
	if(n->Incdec.post == 1) {
		if(n->Incdec.op == TOKINC)
			outi("dec %%rax\n");
		else
			outi("inc %%rax\n");
	}
}
Esempio n. 3
0
File: emit.c Progetto: a8m/c
static void
assign(Node *n)
{
	Node *l, *r;
	int op;

	op = n->Assign.op;
	l = n->Assign.l;
	r = n->Assign.r;
	if(op == '=') {
		expr(r);
		pushq("rax");
		addr(l);
		popq("rcx");
		if(!isptr(l->type) && !isitype(l->type) && !isstruct(l->type))
			errorf("unimplemented assign\n");
		store(l->type);
		outi("movq %%rcx, %%rax\n");
		return;
	}
	addr(l);
	pushq("rax");
	load(l->type);
	pushq("rax");
	expr(r);
	outi("movq %%rax, %%rcx\n");
	popq("rax");
	/* XXX this type is not correct for comparison ops works anyway, but should be changed*/
	obinop(op, n->type);
	outi("movq %%rax, %%rcx\n");
	popq("rax");
	store(l->type);
	outi("movq %%rcx, %%rax\n");
}
Esempio n. 4
0
File: emit.c Progetto: a8m/c
static void
load(CTy *t)
{
	if(isitype(t) || isptr(t)) {
		switch(t->size) {
		case 8:
			outi("movq (%%rax), %%rax\n");
			break;
		case 4:
			outi("movslq (%%rax), %%rax\n");
			break;
		case 2:
			outi("movswq (%%rax), %%rax\n");
			break;
		case 1:
			outi("movsbq (%%rax), %%rax\n");
			break;
		default:
			panic("internal error\n");
		}
		return;
	}
	if(isstruct(t)) {
		return;
	}
	if(isarray(t)) {
		return;
	}
	if(isfunc(t)) {
		return;
	}
	errorf("unimplemented load %d\n", t->t);
}
Esempio n. 5
0
File: emit.c Progetto: a8m/c
static void
call(Node *n)
{
	int i, nargs, nintargs, cleanup;
	Vec  *args;
	Node *arg;

	args = n->Call.args;
	i = nargs = args->len;
	/* Push args in reverse order */
	while(i-- != 0) {
		arg = vecget(args, i);
		if(!isitype(arg->type) && !isptr(arg->type) && !isarray(arg->type) && !isfunc(arg->type))
			errorposf(&arg->pos, "unimplemented arg type\n");
		expr(arg);
		pushq("rax");
	}
	nintargs = nargs;
	if(nintargs > 6)
		nintargs = 6;
	for(i = 0; i < nintargs; i++)
		popq(intargregs[i]);
	expr(n->Call.funclike);
	outi("call *%%rax\n");
	cleanup = 8 * (nargs - nintargs);
	if(cleanup) {
		outi("add $%d, %%rsp\n", cleanup);
		stackoffset -= cleanup;
	}
}
Esempio n. 6
0
File: emit.c Progetto: a8m/c
void
emitsym(Sym *sym)
{
	out("# emit sym %s\n", sym->name);
	switch(sym->k){
	case SYMGLOBAL:
		if(sym->Global.sclass == SCEXTERN)
			break;
		if(isfunc(sym->type)) {
			func(sym->init, sym->Global.label, sym->Global.sclass == SCGLOBAL);
			break;
		}
		penddata(sym->Global.label, sym->type, sym->init, sym->Global.sclass == SCGLOBAL);
		break;
	case SYMLOCAL:
		if(sym->init) {
			expr(sym->init);
			pushq("rax");
			outi("leaq %d(%%rbp), %%rax\n", sym->Local.slot->offset);
			popq("rcx");
			if(!isptr(sym->type) && !isitype(sym->type) && !isstruct(sym->type))
				errorf("unimplemented init\n");
			store(sym->type);
		}
		break;
	case SYMENUM:
	case SYMTYPE:
		panic("internal error");
	}
	out("\n");
}
Esempio n. 7
0
File: emit.c Progetto: a8m/c
static void
data(Data *d)
{
	InitMember *initmemb;
	int   i, offset;
	char *l;
	
	if(!d->init) {
		out(".comm %s, %d, %d\n", d->label, d->type->size, d->type->align);
		return;
	}
	if(d->isglobal)
		out(".globl %s\n", d->label);
	out("%s:\n", d->label);
	
	if(ischararray(d->type))
	if(d->init->t == NSTR) {
		out(".string %s\n", d->init->Str.v);
		return;
	}
	
	if(ischarptr(d->type))
	if(d->init->t == NSTR) {
		l = newlabel();
		out(".quad %s\n", l);
		out("%s:\n", l);
		out(".string %s\n", d->init->Str.v);
		return;
	}
	if(isitype(d->type) || isptr(d->type)) {
		itypedata(d->init);
		return;
	}
	if(isarray(d->type) || isstruct(d->type)) {
		if(d->init->t != NINIT)
			errorposf(&d->init->pos, "array/struct expects a '{' style initializer");
		offset = 0;
		for(i = 0; i < d->init->Init.inits->len ; i++) {
			initmemb = vecget(d->init->Init.inits, i);
			if(initmemb->offset != offset)
				out(".fill %d, 1, 0\n", initmemb->offset - offset);
			itypedata(initmemb->n);
			offset = initmemb->offset + initmemb->n->type->size;
		}
		if(offset < d->type->size)
			out(".fill %d, 1, 0\n", d->type->size - offset);
		return;
	}
	panic("internal error");
}
Esempio n. 8
0
File: emit.c Progetto: a8m/c
static void
cast(Node *n)
{
	CTy *from;
	CTy *to;
	
	expr(n->Cast.operand);
	from = n->Cast.operand->type;
	to = n->type;
	if(isptr(from) && isptr(to))
		return;
	if(isptr(to) && isitype(from))
		return;
	if(isptr(from) && isitype(to))
		return;
	if(isitype(from) && isitype(to))
		return;
	if(isfunc(from) && isptr(to))
		return;
	if(isarray(from) && isptr(to))
		return;
	errorf("unimplemented cast %d %d\n", from->t, to->t);
}
Esempio n. 9
0
File: parse.c Progetto: xtao/c
static Node *
ipromote(Node *n)
{
	if(!isitype(n->type))
		errorposf(&n->pos, "internal error - ipromote expects itype got %d", n->type->t);
	switch(n->type->Prim.type) {
	case PRIMCHAR:
	case PRIMSHORT:
		if(n->type->Prim.issigned)
			return mkcast(&n->pos, n, cint);
		else
			return mkcast(&n->pos, n, cuint);
	}
	return n;
}
Esempio n. 10
0
File: emit.c Progetto: a8m/c
static void
ereturn(Node *r)
{
	CTy *ty;
	
	if(r->Return.expr) {
		ty = r->Return.expr->type;
		if(!isitype(ty) && !isptr(ty))
			errorposf(&r->pos, "unimplemented return type");
		expr(r->Return.expr);
	}
	/* No need to cleanup with leave */
	outi("leave\n");
	outi("ret\n");
}
Esempio n. 11
0
File: emit.c Progetto: a8m/c
static void
func(Node *f, char *label, int isglobal)
{
	Vec *v;
	Sym *sym;
	int  i;
	
	calcslotoffsets(f);
	out("\n");
	out(".text\n");
	out("# function %s\n", f->Func.name);
	if(isglobal)
		out(".globl %s\n", label);
	out("%s:\n", label);
	pushq("rbp");
	outi("movq %%rsp, %%rbp\n");
	if(f->type->Func.isvararg) {
		stackoffset += 176;
		outi("sub $176, %%rsp\n");
		outi("movq %%rdi, (%%rsp)\n");
		outi("movq %%rsi, 8(%%rsp)\n");
		outi("movq %%rdx, 16(%%rsp)\n");
		outi("movq %%rcx, 24(%%rsp)\n");
		outi("movq %%r8, 32(%%rsp)\n");
		outi("movq %%r9, 40(%%rsp)\n");
	}
	if(f->Func.localsz) {
		outi("sub $%d, %%rsp\n", f->Func.localsz);
		stackoffset += f->Func.localsz;
	}
	v = f->Func.params;
	for(i = 0; i < v->len; i++) {
		sym = vecget(v, i);
		if(!isitype(sym->type) && !isptr(sym->type) && !isarray(sym->type))
			errorposf(&f->pos, "unimplemented arg type");
		if(i < 6) {
			outi("movq %%%s, %d(%%rbp)\n", intargregs[i], sym->Local.slot->offset);
		} else {
			outi("movq %d(%%rbp), %%rcx\n", 16 + 8 * (i - 6));
			outi("leaq %d(%%rbp), %%rax\n", sym->Local.slot->offset);
			store(sym->type);
		}
	}
	block(f->Func.body);
	outi("leave\n");
	outi("ret\n");
}
Esempio n. 12
0
File: emit.c Progetto: a8m/c
static void
itypedata(Node *prim)
{
	Const *c;

	if(!isitype(prim->type) && !isptr(prim->type))
		panic("internal error %d");
	c = foldexpr(prim);
	if(!c)
		errorposf(&prim->pos, "not a constant expression");
	if(c->p) {
		switch(prim->type->size) {
		case 8:
			out(".quad %s + %d\n", c->p, c->v);
			return;
		case 4:
			out(".long %s + %d\n", c->p, c->v);
			return;
		case 2:
			out(".short %s + %d\n", c->p, c->v);
			return;
		case 1:
			out(".byte %s + %d\n", c->p, c->v);
			return;
		default:
			panic("unimplemented");
		}
	}
	switch(prim->type->size) {
	case 8:
		out(".quad %d\n", c->v);
		return;
	case 4:
		out(".long %d\n", c->v);
		return;
	case 2:
		out(".short %d\n", c->v);
		return;
	case 1:
		out(".byte %d\n", c->v);
		return;
	default:
		panic("unimplemented");
	}
	panic("internal error");
}
Esempio n. 13
0
File: emit.c Progetto: a8m/c
static void
cond(Node *n)
{
	char *lfalse, *lend;

	if(!isitype(n->type) && !isptr(n->type))
		panic("unimplemented emit cond");
	expr(n->Cond.cond);
	lfalse = newlabel();
	lend = newlabel();
	outi("test %%rax, %%rax\n");
	outi("jz %s\n", lfalse);
	expr(n->Cond.iftrue);
	outi("jmp %s\n", lend);
	out("%s:\n", lfalse);
	expr(n->Cond.iffalse);
	out("%s:\n", lend);
}
Esempio n. 14
0
File: emit.c Progetto: a8m/c
static void
store(CTy *t)
{
	if(isitype(t) || isptr(t)) {
		switch(t->size) {
		case 8:
			outi("movq %%rcx, (%%rax)\n");
			break;
		case 4:
			outi("movl %%ecx, (%%rax)\n");
			break;
		case 2:
			outi("movw %%cx, (%%rax)\n");
			break;
		case 1:
			outi("movb %%cl, (%%rax)\n");
			break;
		default:
			panic("internal error\n");
		}
		return;
	}
	if(isstruct(t)) {
		pushq("rdi");
		pushq("rsi");
		pushq("rcx");
		outi("movq %%rcx, %%rsi\n");
		outi("movq %%rax, %%rdi\n");
		outi("movq $%d, %%rcx\n", t->size);
		outi("rep movsb\n");
		popq("rcx");
		popq("rsi");
		popq("rdi");
		return;
	}
	errorf("unimplemented store\n");
}
Esempio n. 15
0
File: emit.c Progetto: a8m/c
static void
obinop(int op, CTy *t)
{
	char *lset;
	char *lafter;
	char *opc;
	
	if(!isitype(t) && !isptr(t))
		panic("unimplemented binary operator type\n");
	switch(op) {
	case '+':
		outi("addq %%rcx, %%rax\n");
		break;
	case '-':
		outi("subq %%rcx, %%rax\n");
		break;
	case '*':
		outi("imul %%rcx, %%rax\n");
		break;
	case '/':
		outi("cqto\n");
		outi("idiv %%rcx\n");
		break;
	case '%':
		outi("cqto\n");
		outi("idiv %%rcx\n");
		outi("mov %%rdx, %%rax\n");
		break;
	case '|':
		outi("or %%rcx, %%rax\n");
		break;
	case '&':
		outi("and %%rcx, %%rax\n");
		break;
	case '^':
		outi("xor %%rcx, %%rax\n");
		break;
	case TOKSHR:
		outi("sar %%cl, %%rax\n");
		break;
	case TOKSHL:
		outi("sal %%cl, %%rax\n");
		break;
	case TOKEQL:
	case TOKNEQ:
	case TOKGEQ:
	case TOKLEQ:
	case '>':
	case '<':
		lset = newlabel();
		lafter = newlabel();
		switch(op) {
		case TOKEQL:
			opc = "jz";
			break;
		case TOKNEQ:
			opc = "jnz";
			break;
		case '<':
			opc = "jl";
			break;
		case '>':
			opc = "jg";
			break;
		case TOKGEQ:
			opc = "jge";
			break;
		case TOKLEQ:
			opc = "jle";
			break;
		}
		outi("cmp %%rcx, %%rax\n");
		outi("%s %s\n", opc, lset);
		outi("movq $0, %%rax\n");
		outi("jmp %s\n", lafter);
		out("%s:\n", lset);
		outi("movq $1, %%rax\n");
		out("%s:\n", lafter);
		break;
	default:
		errorf("unimplemented binop %d\n", op);
	}
}
Esempio n. 16
0
File: types.c Progetto: xtao/c
int
isarithtype(CTy *t)
{
	return isftype(t) || isitype(t);
}