📄 iexpr.c
字号:
*
* The first argument of this and other routines is a target for
* assignmennt. If this is 0 and a target is needed a temp will be
* used; otherwise the target will be evaluated annd used.
*/
{
IMODE *ap1, *ap2, *ap3;
int lab0, lab1, lab2;
int natsize, siz1;
if (node == 0)
{
// DIAG("null node in gen_expr.");
return 0;
}
switch (node->nodetype)
{
case en_cl_reg:
ap1 = gen_expr( node->v.p[0], flags, size);
return ap1;
case en_cb:
siz1 = - ISZ_UCHAR;
goto castjoin;
case en_cub:
case en_cbool:
siz1 = ISZ_UCHAR;
goto castjoin;
case en_cw:
siz1 = - ISZ_USHORT;
goto castjoin;
case en_cuw:
siz1 = ISZ_USHORT;
goto castjoin;
case en_ci:
siz1 = - ISZ_UINT;
goto castjoin;
case en_cui:
siz1 = ISZ_UINT;
goto castjoin;
case en_cl:
siz1 = - ISZ_ULONG;
goto castjoin;
case en_cul:
siz1 = ISZ_ULONG;
goto castjoin;
case en_cll:
siz1 = - ISZ_ULONGLONG;
goto castjoin;
case en_cull:
siz1 = ISZ_ULONGLONG;
goto castjoin;
case en_cf:
siz1 = ISZ_FLOAT;
goto castjoin;
case en_cd:
siz1 = ISZ_DOUBLE;
goto castjoin;
case en_cld:
siz1 = ISZ_LDOUBLE;
goto castjoin;
case en_cfi:
siz1 = ISZ_IFLOAT;
goto castjoin;
case en_cri:
siz1 = ISZ_IDOUBLE;
goto castjoin;
case en_clri:
siz1 = ISZ_ILDOUBLE;
goto castjoin;
case en_cfc:
siz1 = ISZ_CFLOAT;
goto castjoin;
case en_crc:
siz1 = ISZ_CDOUBLE;
goto castjoin;
case en_clrc:
siz1 = ISZ_CLDOUBLE;
goto castjoin;
case en_cp:
siz1 = ISZ_UINT;
castjoin: ap1 = gen_expr( node->v.p[0], flags, natural_size(node
->v.p[0]));
#ifdef XXXXX
if (ap1->mode == i_immed) {
if (isintconst(ap1->offset->nodetype))
if (siz1 <= ISZ_ULONGLONG) {
ap1->offset->nodetype = en_llucon;
ap1->offset->v.i = CastToInt(siz1,ap1->offset->v.i);
} else {
ap1->offset->nodetype = en_llucon;
ap1->offset->v.i = CastToInt(siz1,ap1->offset->v.f);
}
else if (isfloatconst(ap1->offset->nodetype))
if (siz1 <= ISZ_ULONGLONG) {
ap1->offset->nodetype = en_lrcon;
ap1->offset->v.f = CastToFloat(siz1,ap1->offset->v.i);
} else {
ap1->offset->nodetype = en_lrcon;
ap1->offset->v.f = CastToFloat(siz1,ap1->offset->v.i);
}
}
#endif
if (ap1->size == siz1)
ap2 = ap1;
else
{
gen_icode(i_assn, ap2 = tempreg(siz1, 0), ap1, 0);
}
return ap2;
case en_structret:
if (!structret_imode) {
SYM *sp = makesym(sc_auto);
ENODE *en;
sp->tp = maketype(bt_int, stdintsize); // dummy so backend is happy
sp->name = "structret";
en = makenode(en_autocon, (void *)sp, 0);
ap1 = xalloc(sizeof(IMODE));
ap1->mode = i_direct;
ap1->size = ISZ_ADDR;
ap1->offset = en;
if ((currentfunc->pascaldefn || currentfunc->isstdcall) &&
currentfunc->tp->lst.head && currentfunc->tp->lst.head != (SYM*)
- 1)
sp->value.i = (currentfunc->tp->lst.head
->value.i + ((currentfunc->tp->lst.head->tp->size + stdintsize-1)
&-stdintsize));
else
if (declclass && !(currentfunc->value.classdata.cppflags
&PF_STATIC))
sp->value.i = stdretblocksize + stdintsize+(currentfunc
->farproc * stdintsize);
else
sp->value.i = stdretblocksize+(currentfunc->farproc
*stdintsize);
structret_imode = ap1;
}
return structret_imode;
case en_napccon:
case en_nacon:
case en_autocon:
case en_autoreg:
case en_absacon:
case en_nalabcon:
ap1 = make_imaddress(node, ISZ_ADDR);
return ap1; /* return reg */
case en_labcon:
ap1 = xalloc(sizeof(IMODE));
ap1->offset = node;
ap1->mode = i_direct;
ap1->size = size;
return ap1; /* return reg */
case en_imode:
ap2 = node->v.p[0];
return ap2; /* return reg */
case en_boolcon:
case en_ccon:
case en_cucon:
case en_icon:
case en_lcon:
case en_lucon:
case en_iucon:
case en_llcon:
case en_llucon:
ap1 = make_immed(node->v.i);
ap1->offset->nodetype = node->nodetype;
return ap1;
case en_fcon:
case en_rcon:
case en_lrcon:
case en_fimaginarycon:
case en_rimaginarycon:
case en_lrimaginarycon:
case en_fcomplexcon:
case en_rcomplexcon:
case en_lrcomplexcon:
ap1 = make_fimmed(node->v.f);
ap1->offset->nodetype = node->nodetype;
return ap1;
case en_bool_ref:
case en_b_ref:
case en_w_ref:
case en_ub_ref:
case en_uw_ref:
case en_l_ref:
case en_a_ref:
case en_ua_ref:
case en_i_ref:
case en_ui_ref:
case en_ptr_ref:
case en_ul_ref:
case en_floatref:
case en_doubleref:
case en_longdoubleref:
case en_ll_ref:
case en_ull_ref:
case en_fimaginaryref:
case en_rimaginaryref:
case en_lrimaginaryref:
case en_fcomplexref:
case en_rcomplexref:
case en_lrcomplexref:
ap1 = gen_deref(node, flags, size);
return ap1;
case en_regref:
ap1 = xalloc(sizeof(IMODE));
ap1->offset = node;
ap1->mode = i_direct;
ap1->size = ISZ_UINT;
return ap1;
case en_bits:
size = natural_size(node->v.p[0]);
ap1 = gen_expr( node->v.p[0], 0, size);
ap1 = make_bf(node, ap1, size);
return ap1;
case en_asuminus:
return gen_asunary(node, flags, size, i_neg);
case en_ascompl:
return gen_asunary(node, flags, size, i_not);
case en_uminus:
return gen_unary(node, flags, size, i_neg);
case en_compl:
return gen_unary(node, flags, size, i_not);
case en_add:
case en_addstruc:
return gen_binary(node, flags, size, i_add);
case en_addcast:
lab0 = nextlabel++;
ap1 = gen_expr( node, flags, size);
gen_icgoto(i_je, lab0, ap1, make_immed(0));
ap2 = gen_expr( node->v.p[1], 0, size);
gen_icode(i_add, ap3 = genasn(0, size), ap1, ap2);
gen_label(lab0);
return ap3;
case en_sub:
return gen_binary(node, flags, size, i_sub);
case en_and:
return gen_binary(node, flags, size, i_and);
case en_or:
return gen_binary(node, flags, size, i_or);
case en_xor:
return gen_binary(node, flags, size, i_eor);
case en_pmul:
return gen_pmul(node, flags, size);
case en_pdiv:
return gen_pdiv(node, flags, size);
case en_mul:
return gen_binary(node, flags, size, i_smul);
case en_umul:
return gen_binary(node, flags, size, i_umul);
case en_div:
return gen_binary(node, flags, size, i_sdiv);
case en_udiv:
return gen_binary(node, flags, size, i_udiv);
case en_mod:
return gen_binary(node, flags, size, i_smod);
case en_umod:
return gen_binary(node, flags, size, i_umod);
case en_alsh:
return gen_binary(node, flags, size, i_asl);
case en_arsh:
case en_arshd:
return gen_binary(node, flags, size, i_asr);
case en_lsh:
return gen_binary(node, flags, size, i_lsl);
case en_rsh:
return gen_binary(node, flags, size, i_lsr);
case en_asadd:
return gen_asbin(node, flags, size, i_asadd);
case en_assub:
return gen_asbin(node, flags, size, i_assub);
case en_asand:
return gen_asbin(node, flags, size, i_asand);
case en_asor:
return gen_asbin(node, flags, size, i_asor);
case en_asxor:
return gen_asbin(node, flags, size, i_aseor);
case en_aslsh:
return gen_asbin(node, flags, size, i_aslsl);
case en_asrsh:
return gen_asbin(node, flags, size, i_aslsr);
case en_asalsh:
return gen_asbin(node, flags, size, i_asasl);
case en_asarsh:
case en_asarshd:
return gen_asbin(node, flags, size, i_asasr);
case en_asmul:
return gen_asbin(node, flags, size, i_assmul);
case en_asumul:
return gen_asbin(node, flags, size, i_asumul);
case en_asdiv:
return gen_asbin(node, flags, size, i_assdiv);
case en_asudiv:
return gen_asbin(node, flags, size, i_asudiv);
case en_asmod:
return gen_asbin(node, flags, size, i_assmod);
case en_asumod:
return gen_asbin(node, flags, size, i_asumod);
case en_assign:
return gen_assign(node, flags, size, FALSE);
case en_refassign:
return gen_assign(node, flags | F_NOVALUE, size, TRUE);
case en_moveblock:
return gen_moveblock(node, flags, size);
case en_clearblock:
return gen_clearblock(node, flags, size);
case en_ainc:
return gen_aincdec(node, flags, size, i_add);
case en_adec:
return gen_aincdec(node, flags, size, i_sub);
case en_land:
case en_lor:
case en_eq:
case en_ne:
case en_lt:
case en_le:
case en_gt:
case en_ge:
case en_ult:
case en_ule:
case en_ugt:
case en_uge:
case en_not:
return gen_relat(node);
case en_cond:
return gen_hook(node, flags, size);
case en_void:
gen_void(node->v.p[0]);
return gen_expr( node->v.p[1], flags, size);
case en_arrayindex:
return gen_binary(node,flags,size,i_arrayindex);
case en_array:
return gen_binary(node,flags,size,i_array);
case en_dvoid:
ap1 = gen_expr( node->v.p[0], flags, size);
gen_expr( node->v.p[1], flags, size);
return ap1;
case en_voidnz:
lab0 = nextlabel++;
falsejp(node->v.p[0]->v.p[0], lab0);
gen_void(node->v.p[1]);
gen_label(lab0);
return gen_expr( node->v.p[0]->v.p[1], 0, ISZ_UINT); /* will typically
be part of a void tree, or top of tree */
case en_pfcall:
case en_pfcallb:
case en_pcallblock:
return gen_pfcall(node, flags, size);
case en_fcall:
case en_callblock:
case en_fcallb:
case en_sfcall:
case en_scallblock:
case en_sfcallb:
case en_intcall:
case en_trapcall:
case en_thiscall:
return gen_fcall(node, flags, size);
case en_repcons:
return gen_repcons(node);
case en_conslabel:
if (node->v.p[1]->v.sp->nullsym)
return 0;
node->v.p[1]->v.sp->value.classdata.conslabel = nextlabel;
gen_label(nextlabel++);
return gen_expr( node->v.p[0], flags, size);
case en_destlabel:
if (node->v.p[1]->v.sp->nullsym)
return 0;
node->v.p[1]->v.sp->value.classdata.destlabel = nextlabel;
gen_label(nextlabel++);
return gen_expr(node->v.p[0], flags, size);
default:
case en_movebyref:
/* explicitly uncoded */
DIAG("uncoded node in gen_expr.");
return 0;
}
}
//-------------------------------------------------------------------------
IMODE *gen_void(ENODE *node)
{
gen_expr( node, 0, natural_size(node));
// gen_code(op_void,0,0);
return 0;
}
//-------------------------------------------------------------------------
int natural_size(ENODE *node)
/*
* return the natural evaluation size of a node.
*/
{
int siz0, siz1;
if (node == 0)
return 0;
switch (node->nodetype)
{
case en_structret:
return ISZ_ADDR;
case en_asuminus:
case en_ascompl:
case en_bits:
case en_cl_reg:
return natural_size(node->v.p[0]);
;
case en_ccon:
case en_cucon:
return ISZ_UCHAR;
case en_lcon:
case en_icon:
return - ISZ_UINT;
case en_lucon:
case en_iucon:
return ISZ_UINT;
case en_rcon:
case en_doubleref:
return ISZ_DOUBLE;
case en_lrcon:
case en_longdoubleref:
return ISZ_LDOUBLE;
case en_floatref:
case en_fcon:
return ISZ_FLOAT;
case en_fimaginaryref:
case en_fimaginarycon:
case en_cfi:
return ISZ_IFLOAT;
case en_rimaginaryref:
case en_rimaginarycon:
case en_cri:
return ISZ_IDOUBLE;
case en_lrimaginaryref:
case en_lrimaginarycon:
case en_clri:
return ISZ_ILDOUBLE;
case en_fcomplexref:
case en_fcomplexcon:
case en_cfc:
return ISZ_CFLOAT;
case en_rcomplexref:
case en_rcomplexcon:
case en_crc:
return ISZ_CDOUBLE;
case en_lrcomplexref:
case en_lrcomplexcon:
case en_clrc:
return ISZ_CLDOUBLE;
case en_boolcon:
return ISZ_BOOL;
case en_llucon:
return ISZ_ULONGLONG;
case en_llcon:
return - ISZ_ULONGLONG;
case en_imode:
return ISZ_ADDR;
case en_cl:
case en_l_ref:
return - ISZ_ULONG;
case en_i_ref:
case en_ci:
return - ISZ_UINT ;
case en_a_ref:
return ISZ_ADDR;
case en_ptr_ref:
case en_trapcall:
case en_labcon:
case en_nacon:
case en_autocon:
case en_napccon:
case en_absacon:
case en_nalabcon:
return ISZ_ADDR;
case en_autoreg:
return ISZ_REG;
case en_fcall:
case en_callblock:
case en_fcallb:
case en_sfcall:
case en_scallblock:
case en_sfcallb:
case en_pfcall:
case en_pcallblock:
case en_pfcallb:
case en_intcall:
return natural_size(node->v.p[1]);
case en_tempref:
return ISZ_UINT;
case en_regref:
return ISZ_REG;
case en_ull_ref:
case en_cull:
return ISZ_ULONGLONG;
case en_ll_ref:
case en_cll:
return - ISZ_ULONGLONG;
case en_ul_ref:
case en_cul:
return ISZ_ULONG;
case en_ui_ref:
case en_cui:
return ISZ_UINT;
case en_ua_ref:
case en_cp:
return ISZ_ADDR;
case en_bool_ref:
case en_cbool:
return ISZ_BOOL;
case en_ub_ref:
case en_cub:
return ISZ_UCHAR;
case en_b_ref:
case en_cb:
return - ISZ_UCHAR;
case en_uw_ref:
case en_cuw:
return ISZ_USHORT;
case en_cw:
case en_w_ref:
return - ISZ_USHORT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -