📄 iexpr.c
字号:
case en_cd:
return ISZ_DOUBLE;
case en_cld:
return ISZ_LDOUBLE;
case en_cf:
return ISZ_ULONGLONG;
case en_not:
case en_compl:
case en_uminus:
case en_assign:
case en_refassign:
case en_lassign:
case en_ainc:
case en_adec:
case en_moveblock:
case en_stackblock:
case en_movebyref:
case en_clearblock:
return natural_size(node->v.p[0]);
case en_add:
case en_sub:
case en_addstruc:
case en_umul:
case en_udiv:
case en_umod:
case en_pmul:
case en_arrayindex:
case en_mul:
case en_div:
case en_pdiv:
case en_mod:
case en_and:
case en_or:
case en_xor:
case en_asalsh:
case en_asarsh:
case en_alsh:
case en_arsh:
case en_lsh:
case en_rsh:
case en_eq:
case en_ne:
case en_lt:
case en_le:
case en_gt:
case en_ge:
case en_ugt:
case en_uge:
case en_ult:
case en_ule:
case en_land:
case en_lor:
case en_asadd:
case en_assub:
case en_asmul:
case en_asdiv:
case en_asmod:
case en_asand:
case en_asumod:
case en_asudiv:
case en_asumul:
case en_asor:
case en_aslsh:
case en_asxor:
case en_asrsh:
case en_asarshd:
case en_arshd:
siz0 = natural_size(node->v.p[0]);
siz1 = natural_size(node->v.p[1]);
if (chksize(siz1, siz0))
return siz1;
else
return siz0;
case en_array:
return ISZ_ADDR ;
case en_void:
case en_cond:
case en_repcons:
return natural_size(node->v.p[1]);
case en_voidnz:
return natural_size(node->v.p[1]);
case en_conslabel:
case en_destlabel:
case en_addcast:
return natural_size(node->v.p[0]);
default:
DIAG("natural size error.");
break;
}
return 0;
}
//-------------------------------------------------------------------------
void gen_compare(ENODE *node, int btype, int label)
/*
* generate code to do a comparison of the two operands of
* node.
*/
{
IMODE *ap1, *ap2;
int size;
size = natural_size(node);
ap1 = gen_expr( node->v.p[0], 0, size);
ap2 = gen_expr( node->v.p[1], 0, size);
gen_icgoto(btype, label, ap1, ap2);
}
//-------------------------------------------------------------------------
IMODE *gen_set(ENODE *node, int btype, int aa)
{
IMODE *ap1, *ap2, *ap3;
int size;
ap1 = gen_expr( node->v.p[0], 0, size);
ap2 = gen_expr( node->v.p[1], 0, size);
ap3 = tempreg(ISZ_UINT, 0);
gen_icode(btype, ap3, ap2, ap1);
return ap3;
}
//-------------------------------------------------------------------------
IMODE *defcond(ENODE *node)
{
IMODE *ap1, *ap2, *ap3;
int size;
ap1 = gen_expr( node->v.p[0], 0, size);
ap2 = make_immed(0);
ap3 = tempreg(ISZ_UINT, 0);
gen_icode(i_setne, ap3, ap2, ap1);
return ap3;
}
//-------------------------------------------------------------------------
static IMODE *truerelat(ENODE *node)
{
IMODE *ap1;
if (node == 0)
return 0;
switch (node->nodetype)
{
case en_eq:
ap1 = gen_set(node, i_sete, 0);
break;
case en_ne:
ap1 = gen_set(node, i_setne, 0);
break;
case en_lt:
ap1 = gen_set(node, i_setl, 0);
break;
case en_le:
ap1 = gen_set(node, i_setle, 0);
break;
case en_gt:
ap1 = gen_set(node, i_setg, 0);
break;
case en_ge:
ap1 = gen_set(node, i_setge, 0);
break;
case en_ult:
ap1 = gen_set(node, i_setc, 0);
break;
case en_ule:
ap1 = gen_set(node, i_setbe, 0);
break;
case en_ugt:
ap1 = gen_set(node, i_seta, 0);
break;
case en_uge:
ap1 = gen_set(node, i_setnc, 0);
break;
case en_not:
ap1 = defcond(node);
break;
default:
DIAG("True-relat error");
break;
}
ap1->size = ISZ_UCHAR;
return ap1;
}
//-------------------------------------------------------------------------
static int complex_relat(ENODE *node)
{
if (!node)
return 0;
switch (node->nodetype)
{
case en_cl_reg:
return complex_relat(node->v.p[0]);
case en_ull_ref:
case en_ll_ref:
case en_cull:
case en_cll:
case en_llcon:
case en_llucon:
return 1;
case en_bits:
case en_a_ref:
case en_ua_ref:
case en_i_ref:
case en_ui_ref:
case en_l_ref:
case en_cl:
case en_ul_ref:
case en_cul:
case en_ci:
case en_cui:
case en_cp:
case en_ub_ref:
case en_cub:
case en_bool_ref:
case en_cbool:
case en_b_ref:
case en_cb:
case en_uw_ref:
case en_cuw:
case en_cw:
case en_w_ref:
case en_cd:
case en_cld:
case en_cf:
case en_cfc:
case en_crc:
case en_clrc:
case en_cfi:
case en_cri:
case en_clri:
case en_uminus:
case en_ainc:
case en_adec:
case en_moveblock:
case en_stackblock:
case en_movebyref:
case en_clearblock:
return complex_relat(node->v.p[0]);
case en_icon:
case en_lcon:
case en_lucon:
case en_iucon:
case en_boolcon:
case en_ccon:
case en_cucon:
case en_rcon:
case en_doubleref:
case en_lrcon:
case en_longdoubleref:
case en_fcon:
case en_floatref:
case en_fimaginaryref:
case en_rimaginaryref:
case en_lrimaginaryref:
case en_fcomplexref:
case en_rcomplexref:
case en_lrcomplexref:
case en_fimaginarycon:
case en_rimaginarycon:
case en_lrimaginarycon:
case en_fcomplexcon:
case en_rcomplexcon:
case en_lrcomplexcon:
case en_absacon:
case en_trapcall:
case en_labcon:
case en_nacon:
case en_autocon:
case en_autoreg:
case en_napccon:
case en_nalabcon:
case en_tempref:
case en_regref:
return 0;
case en_eq:
case en_ne:
case en_lt:
case en_le:
case en_gt:
case en_ge:
case en_ugt:
case en_uge:
case en_ult:
case en_ule:
case en_land:
case en_lor:
case en_not:
case en_compl:
return 1;
case en_div:
case en_udiv:
case en_pdiv:
case en_mod:
case en_umod:
case en_assign:
case en_refassign:
case en_lassign:
case en_asuminus:
case en_ascompl:
case en_add:
case en_sub:
case en_addstruc:
case en_addcast:
case en_umul:
case en_pmul:
case en_arrayindex:
case en_mul:
case en_and:
case en_or:
case en_xor:
case en_asalsh:
case en_asarsh:
case en_alsh:
case en_arsh:
case en_arshd:
case en_asarshd:
case en_lsh:
case en_rsh:
case en_asadd:
case en_assub:
case en_asmul:
case en_asdiv:
case en_asmod:
case en_asand:
case en_asumod:
case en_asudiv:
case en_asumul:
case en_asor:
case en_aslsh:
case en_asxor:
case en_asrsh:
case en_repcons:
case en_array:
return complex_relat(node->v.p[0]) || complex_relat(node->v.p[1]);
case en_void:
case en_cond:
case en_voidnz:
return complex_relat(node->v.p[1]);
case en_conslabel:
case en_destlabel:
return complex_relat(node->v.p[0]);
case en_sfcall:
case en_sfcallb:
case en_scallblock:
case en_pfcall:
case en_pfcallb:
case en_thiscall:
case en_fcall:
case en_intcall:
case en_callblock:
case en_fcallb:
case en_pcallblock:
return 0;
default:
DIAG("error in complex_relat routine.");
return 1;
}
}
//-------------------------------------------------------------------------
IMODE *gen_relat(ENODE *node)
{
long lab1, lab2;
IMODE *ap1;
int size = natural_size(node);
if (node->nodetype != en_land && node->nodetype != en_lor && !complex_relat
(node->v.p[0]) && !complex_relat(node->v.p[1]))
{
ap1 = truerelat(node);
}
else
{
ap1 = tempreg(ISZ_UINT, 0);
lab1 = nextlabel++, lab2 = nextlabel++;
truejp(node, lab1);
gen_iiconst(ap1,0);
gen_igoto(lab2);
gen_label(lab1);
gen_iiconst(ap1,1);
gen_label(lab2);
}
return ap1;
}
//-------------------------------------------------------------------------
void truejp(ENODE *node, int label)
/*
* generate a jump to label if the node passed evaluates to
* a true condition.
*/
{
IMODE *ap1;
int siz1;
int lab0;
if (node == 0)
return ;
switch (node->nodetype)
{
case en_eq:
gen_compare(node, i_je, label);
break;
case en_ne:
gen_compare(node, i_jne, label);
break;
case en_lt:
gen_compare(node, i_jl, label);
break;
case en_le:
gen_compare(node, i_jle, label);
break;
case en_gt:
gen_compare(node, i_jg, label);
break;
case en_ge:
gen_compare(node, i_jge, label);
break;
case en_ult:
gen_compare(node, i_jc, label);
break;
case en_ule:
gen_compare(node, i_jbe, label);
break;
case en_ugt:
gen_compare(node, i_ja, label);
break;
case en_uge:
gen_compare(node, i_jnc, label);
break;
case en_land:
lab0 = nextlabel++;
falsejp(node->v.p[0], lab0);
truejp(node->v.p[1], label);
gen_label(lab0);
break;
case en_lor:
truejp(node->v.p[0], label);
truejp(node->v.p[1], label);
break;
case en_not:
falsejp(node->v.p[0], label);
break;
default:
siz1 = natural_size(node);
ap1 = gen_expr( node, 0, siz1);
gen_icgoto(i_jne, label, ap1, make_immed(0));
break;
}
}
//-------------------------------------------------------------------------
void falsejp(ENODE *node, int label)
/*
* generate code to execute a jump to label if the expression
* passed is false.
*/
{
IMODE *ap;
int siz1;
int lab0;
if (node == 0)
return ;
switch (node->nodetype)
{
case en_eq:
gen_compare(node, i_jne, label);
break;
case en_ne:
gen_compare(node, i_je, label);
break;
case en_lt:
gen_compare(node, i_jge, label);
break;
case en_le:
gen_compare(node, i_jg, label);
break;
case en_gt:
gen_compare(node, i_jle, label);
break;
case en_ge:
gen_compare(node, i_jl, label);
break;
case en_ult:
gen_compare(node, i_jnc, label);
break;
case en_ule:
gen_compare(node, i_ja, label);
break;
case en_ugt:
gen_compare(node, i_jbe, label);
break;
case en_uge:
gen_compare(node, i_jc, label);
break;
case en_land:
falsejp(node->v.p[0], label);
falsejp(node->v.p[1], label);
break;
case en_lor:
lab0 = nextlabel++;
truejp(node->v.p[0], lab0);
falsejp(node->v.p[1], label);
gen_label(lab0);
break;
case en_not:
truejp(node->v.p[0], label);
break;
default:
siz1 = natural_size(node);
ap = gen_expr( node, 0, siz1);
gen_icgoto(i_je, label, ap, make_immed(0));
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -