📄 genexp.c
字号:
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 + -