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

📄 genexp.c

📁 用C++编写的一个编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
	if(topush == ECX)
		gen_code(op_mov, 4, ecx, right);

	if(op == op_idiv)
		gen_code(op_cdg, 4, NULL, NULL);
	else if(op == op_div)
		gen_code(op_xor, 4, edx, edx);

	gen_code (op, 4, div, NULL);

	if(regs[topush])
		pop_reg(topush);

	if(mod)
		gen_code(op_xchg, 4, edx, eax);

	if(left->base_reg != EAX)
	{
		gen_code(op_xchg, 4, eax, left);
		tmp = regs[EAX];
		regs[EAX] = regs[left->base_reg];
		regs[left->base_reg] = tmp;
	}
	
	freeregs(right);
	release();
	return left;
}
AddrMode *gen_ptr(struct _expnode *exp)
{
	AddrMode *mv = gen_exp(exp, F_MEM, exp->datatype->size);
	AddrMode *res;
	if(mv->mode == am_direct)
	{
		mv->mode = am_imme;
		res = mv;
	}
	else if(mv->mode == am_relative
		|| mv->mode == am_scale)
	{
		res= temp_data();
		gen_code(op_lea, 4, res, mv);
		freeregs(mv);
	}
	else 
		debug("[gen_ptr] error");
	return res;
}
AddrMode *gen_val(struct _expnode *exp)
{
	AddrMode *mv = gen_exp(exp, F_ALL, 4);
	AddrMode *res;
	if(mv->mode == am_dreg)
	{
		mv->mode = am_relative;
		res = mv;
	}
	else if(mv->mode == am_relative
		|| mv->mode == am_scale)
	{
		res= temp_data();
		gen_code(op_mov, 4, res, mv);
		res->mode = am_relative;
		freeregs(mv);
	}
	else 
		debug("[gen_ptr] error");
	return res;
}
AddrMode *gen_unary(int op, struct _expnode *opd)
{
	AddrMode *mv = gen_exp(opd, F_DREG, 4);
	gen_code(op, 4, mv, NULL);
	return mv;
}
void gen_compare(int op, 
	struct _expnode *opd1,
	struct _expnode *opd2, 
	int labelno)
{
	AddrMode *left, *right;
	mark();
	left=gen_exp(opd1, F_DREG, 4);
	right=gen_exp(opd2, F_ALL, 4);
	gen_code(op_cmp, 4, left, right);
	freeregs(left);
	freeregs(right);
	release();
	gen_code(op, 4, newLabel(labelno), NULL);
	return ;
}
void truejp(struct _expnode *exp, int label)
/*
*      generate a jump to label if the node passed evaluates to
*      a true condition.
*/
{
	AddrMode *res;
	int             lab0;

	switch( exp->exptype )
	{
	case exp_eq:
		gen_compare(op_jz,exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_ueq:
		gen_compare(op_jnz, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_les:
		gen_compare(op_jl, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_leq:
		gen_compare(op_jle, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_gtr:
		gen_compare(op_jg, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_geq:
		gen_compare(op_jge, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_ules:
		gen_compare(op_jb, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_uleq:
		gen_compare(op_jbe, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_ugtr:
		gen_compare(op_ja, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_ugeq:
		gen_compare(op_jae, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_land:
		lab0 = newlabelno++;
		falsejp(exp->val.opd[0],lab0);
		truejp(exp->val.opd[1],label);
		gen_label(lab0);
		break;
	case exp_lor:
		truejp(exp->val.opd[0],label);
		truejp(exp->val.opd[1],label);
		break;
	case exp_lnot:
		falsejp(exp->val.opd[1],label);
		break;
	default:
		if (exp->exptype == exp_const) {
			if (exp->val.f != 0) 
				gen_code(op_jmp, 4, newLabel(label),0);
		}
		else 
		{
			int size = exp->datatype->size;
			res = gen_exp(exp, F_ALL, size);
			gen_code(op_cmp, size, res, newImme(NULL, 0));
			freeregs(res);
			gen_code(op_jnz, 4, newLabel(label), NULL);
		}
		break;
	}
}

void falsejp(struct _expnode *exp, int label)
/*
*      generate code to execute a jump to label if the expression
*      passed is false.
*/
{   
	int             lab0;
	AddrMode *res;
	if( exp == NULL )
	return;
	switch( exp->exptype )
	{
	case exp_eq:
		gen_compare(op_jnz,exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_ueq:
		gen_compare(op_jz, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_les:
		gen_compare(op_jge, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_leq:
		gen_compare(op_jg, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_gtr:
		gen_compare(op_jle, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_geq:
		gen_compare(op_jl, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_ules:
		gen_compare(op_jae, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_uleq:
		gen_compare(op_ja, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_ugtr:
		gen_compare(op_jbe, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_ugeq:
		gen_compare(op_jb, exp->val.opd[0], exp->val.opd[1], label);
		break;
	case exp_land:
		falsejp(exp->val.opd[0],label);
		falsejp(exp->val.opd[1],label);
		break;
	case exp_lor:
		lab0 = newlabelno++;
		truejp(exp->val.opd[0],lab0);
		falsejp(exp->val.opd[1],label);
		gen_label(lab0);
		break;
	case exp_lnot:
		truejp(exp->val.opd[1],label);
		break;
	default:
		if (exp->exptype == exp_const) {
			if (exp->val.f == 0) 
				gen_code(op_jmp, 4, newLabel(label),0);
		}
		else 
		{
			int size = exp->datatype->size;
			res = gen_exp(exp,F_ALL, size);
			gen_code(op_cmp, size, res, newImme(NULL, 0));
			freeregs(res);
			gen_code(op_jz, 4, newLabel(label), NULL);
		}
		break;
	}
}
AddrMode *gen_shift(int op, struct _expnode *opd1, struct _expnode *opd2)
{
	AddrMode *left, *right;
	AddrMode *eax = newDreg(EAX), *ecx = newDreg(ECX);

	if(is_unsigned(opd1->datatype->basic_type))
		op++;//use shl, shr

	left = gen_exp(opd1, F_DREG, opd1->datatype->size);
	mark();
	right = gen_exp(opd2, F_ALL, opd1->datatype->size);

	
	if (right ->mode == am_imme)
	{
		gen_code(op, 4, left, right);
	}
	else if(left->base_reg == ECX) 
	{
		if (right->mode == am_dreg) {
			gen_code(op_xchg, 4, left, right);
			gen_code2(op, 4, right, 1, ecx);
			gen_code(op_xchg, 4, left, right);
		}
		else {
			if (regs[0])
				push_reg(EAX);
			gen_code(op_xchg, 4, eax,ecx);
			gen_code(op_mov, 4, ecx, right);
			gen_code2(op, 4, eax, 1, ecx);
			gen_code(op_xchg, 4, eax,ecx);
			if (regs[0])
				pop_reg(EAX);
		}
	}
	else if (right->mode == am_dreg) {
		if (right->base_reg!= ECX)
			gen_code(op_xchg, 4, right,ecx);
		gen_code2(op, 4, left, 1, ecx);
		if (right->base_reg != ECX)
			gen_code(op_xchg, 4, right,ecx);
	}
	else {
		if (regs[1])
			push_reg(ECX);
		gen_code(op_mov, 4, ecx, right);
		gen_code2(op, 4, left, 1, ecx);
		if (regs[1])
			pop_reg(ECX);
	}
	freeregs(right);
	release();
	return left;
}
AddrMode *gen_index(struct _expnode *exp)
{
	struct _expnode *base = exp->val.opd[0], *offset=exp->val.opd[1];
	AddrMode *left, *right, *tmp;
	AddrMode *basereg, *indexreg;
	left = gen_exp(base, F_ALL|F_ADDR, 4);
//	mark();
	right = gen_exp(offset, F_ALL, 4);

	if(exp->exptype == exp_ptomem)
	{
		tmp = temp_data();
		gen_code(op_mov, 4, tmp, left);
		tmp->mode = am_relative;
		freeregs(left);
		left = tmp;
	}

	if(right->mode == am_imme)
	{
		left->offset+=right->offset;
		return left;
	}

	if(left->mode == am_direct)
	{
		freeregs(right);
		left->mode = am_imme;
		basereg = temp_data();
		gen_code (op_mov, 4, basereg, right);
		gen_code (op_add, 4, basereg, left);
		basereg->mode = am_relative;
		return basereg;
	}
	else if(left->mode == am_relative)
	{
		if(right->mode == am_dreg)
		{
			left->mode = am_scale;
			left->scale = 1;
			left->index_reg = right->base_reg;
		}
		else 
		{
			freeregs(right);

			indexreg = temp_data();
			if(right->mode !=am_dreg || indexreg->base_reg != right->base_reg)
				gen_code (op_mov, 4, indexreg, right);
			left->mode = am_scale;
			left->index_reg = indexreg->base_reg;
		}
	}
	else if(left->mode == am_scale)
	{
		freeregs(right);
		indexreg = newDreg(left->index_reg);
		gen_code(op_add, 4, indexreg, right);
	}
	else 
	{
		debug("not memory addresss!\n");
	}
	if(is_real(exp->datatype->basic_type))
		left->size = exp->datatype->size;
//	release();
	return left;
}
AddrMode *gen_indecr(int kind, struct _expnode *opd)//kind <0 means opd is on the left
{
	AddrMode *res;
	int size = opd->datatype->size;
	AddrMode *mv;
	if(kind>0)
	{
		 mv = gen_exp(opd, F_MEM, size); 
		if(kind == exp_incr)
			gen_code(op_inc, size, mv, NULL);
		else 
			gen_code(op_dec, size, mv, NULL);
		res = mv;
	}
	else 
	{
		kind = -kind;
		res = temp_data();
		mark();
		mv = gen_exp(opd, F_MEM, size);
		if(size<4)
			gen_code2(op_movsx, 4, res, size, mv);
		else 
			gen_code(op_mov, 4, res, mv);

		if(kind == exp_incr)
			gen_code(op_inc, size, mv, NULL);
		else 
			gen_code(op_dec, size, mv, NULL);
		freeregs(mv);
		release();
	}
	return res;
}
AddrMode *gen_trinary(struct _expnode *exp)
{
	AddrMode *res=temp_data(), *left, *right;
	int size = exp->datatype->size;
	int falselabel= newlabelno++, exitlabel=newlabelno++;
	ExpNode *judge=exp->val.opd[0];
	ExpNode *opd1=exp->val.opd[1]->val.opd[0];
	ExpNode *opd2=exp->val.opd[1]->val.opd[1];
	
	mark();
	falsejp(judge, falselabel);
	left = gen_exp(opd1, F_ALL, size);
	gen_code(op_mov, size, res, left);
	gen_code(op_jmp, 4, newLabel(exitlabel), NULL);
	gen_label(falselabel);
	right = gen_exp(opd2, F_ALL, size);
	gen_code(op_mov, size, res, right);
	gen_label(exitlabel);

	release();
	return res;
}

⌨️ 快捷键说明

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