📄 gexpr68.c
字号:
case en_cuw:
case en_cw:
case en_cd:
case en_cld:
case en_cf:
case en_bits:
case en_ll_ref:
case en_ull_ref:
case en_l_ref:
case en_ul_ref:
case en_a_ref:
case en_ua_ref:
case en_i_ref:
case en_ui_ref:
case en_ub_ref:
case en_bool_ref:
case en_b_ref:
case en_uw_ref:
case en_w_ref:
case en_longdoubleref:
case en_doubleref:
case en_floatref:
case en_fimaginaryref:
case en_rimaginaryref:
case en_lrimaginaryref:
case en_fcomplexref:
case en_rcomplexref:
case en_lrcomplexref:
return 1+depth(node->v.p[0]);
case en_uminus:
case en_moveblock:
case en_stackblock:
case en_movebyref:
case en_clearblock:
return 1+depth(node->v.p[0]);
case en_fimaginarycon:
case en_rimaginarycon:
case en_lrimaginarycon:
case en_fcomplexcon:
case en_rcomplexcon:
case en_lrcomplexcon:
case en_llcon:
case en_llucon:
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_lrcon:
case en_fcon:
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 1;
case en_not:
case en_compl:
case en_substack:
return 1+depth(node->v.p[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_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_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_ainc:
case en_adec:
a = depth(node->v.p[0]);
b = depth(node->v.p[1]);
if (a > b)
return 1+a;
return 1+b;
case en_array:
a = depth(node->v.p[0]);
b = depth(node->v.p[1])-1;
if (a > b)
return 1+a;
return 1+b;
case en_void:
case en_cond:
case en_voidnz:
case en_dvoid:
return 1+depth(node->v.p[1]);
case en_sfcall:
case en_sfcallb:
case en_scallblock:
case en_pfcall:
case en_pfcallb:
case en_fcall:
case en_intcall:
case en_callblock:
case en_fcallb:
case en_pcallblock:
case en_thiscall:
return 1;
case en_cl_reg:
case en_conslabel:
case en_destlabel:
case en_addcast:
return depth(node->v.p[0]);
default:
DIAG("error in depth routine.");
return 1;
}
}
//-------------------------------------------------------------------------
void noids(AMODE *ap)
{
switch (ap->mode)
{
case am_baseindxaddr:
case am_baseindxdata:
case am_pcindxdata:
case am_pcindxaddr:
case am_iiprepca:
case am_iipostpca:
case am_iiprepcd:
case am_iipostpcd:
case am_iiprea:
case am_iipred:
case am_iiposta:
case am_iipostd:
do_extend(ap, ap->length, F_DREG | F_VOL);
break;
}
}
//-------------------------------------------------------------------------
AMODE *direct_data(AMODE *ap)
{
AMODE *ap3;
int oldlen = ap->length;
switch (ap->mode)
{
case am_ainc:
case am_adec:
case am_ind:
ap->mode = am_indx;
ap->offset = makeintnode(en_icon, 0);
return ap;
case am_adirect:
case am_direct:
case am_immed:
case am_indx:
case am_pcindx:
return ap;
case am_pc:
ap->mode = am_indx;
ap->offset = makeintnode(en_icon, 0);
return ap;
default:
freeop(ap);
ap3 = temp_addr();
ap->length = BESZ_DWORD;
gen_code(op_lea, ap, ap3);
ap3->mode = am_indx;
ap3->offset = makeintnode(en_icon, 0);
ap3->length = oldlen;
freeop(ap);
return ap3;
}
}
//-------------------------------------------------------------------------
AMODE *doindex(ENODE *node, enum e_node type)
{
AMODE *ap, *ap2, *ap3;
ENODE node2;
int scale;
switch (node->nodetype)
{
case en_icon:
ap = gen_expr(node, FALSE, TRUE, BESZ_DWORD);
break;
case en_lsh:
if ((prm_68020 && (scale = node->v.p[1]->v.i) < 4 && scale) &&
(!prm_coldfire || (scale < 3)))
{
ap = gen_expr(node->v.p[0], FALSE, TRUE, BESZ_DWORD);
if (node->v.p[0]->nodetype == en_bits)
ap = bit_load(ap, node->v.p[0], BESZ_DWORD);
if (ap->mode != am_immed)
do_extend(ap, BESZ_DWORD, F_DREG);
if (ap->mode == am_immed)
{
while (--scale)
ap->offset->v.i <<= 1;
}
else
{
do_extend(ap, BESZ_DWORD, F_DREG);
if (ap->mode == am_dreg)
ap->mode = am_baseindxdata;
else
ap->mode = am_baseindxaddr;
ap->sreg = ap->preg;
ap->preg = - 1;
ap->scale = scale;
ap->offset = makeintnode(en_icon, 0);
}
break;
}
default:
node2.v.p[0] = node;
node2.nodetype = type;
ap = gen_deref(&node2, BESZ_DWORD);
switch (ap->mode)
{
case am_ainc:
case am_adec:
ap2 = temp_addr();
gen_lea(ap->length, ap, ap2);
freeop(ap);
ap = ap2;
case am_baseindxdata:
case am_baseindxaddr:
if (ap->sreg >= 0 && ap->preg >= 0)
{
freeop(ap);
ap3 = temp_addr();
gen_lea(BESZ_DWORD, ap, ap3);
ap3->mode = am_ind;
ap = ap3;
}
}
break;
}
return ap;
}
//-------------------------------------------------------------------------
AMODE *gen_index(ENODE *node)
/*
* generate code to evaluate an index node (^+) and return
* the addressing mode of the result. This routine takes no
* flags since it always returns either am_ind or am_indx.
*/
{
AMODE *ap1, *ap2, *ap3, *ap;
ENODE node2;
int a = depth(node->v.p[1]) - depth(node->v.p[0]);
int nsize;
if (a <= 2)
{
ap1 = doindex(node->v.p[0], node->nodetype);
// nsize = natural_size(node->v.p[1]) ;
// if (nsize == 6 || nsize == -6)
// aprtocx(ap1) ;
ap2 = doindex(node->v.p[1], node->nodetype);
}
else
{
ap2 = doindex(node->v.p[1], node->nodetype);
// nsize = natural_size(node->v.p[0]) ;
// if (nsize == 6 || nsize == -6)
// aprtocx(ap2) ;
ap1 = doindex(node->v.p[0], node->nodetype);
}
tryagain: switch (ap1->mode)
{
case am_areg:
switch (ap2->mode)
{
case am_areg:
ap1->sreg = ap2->preg;
ap1->mode = am_baseindxaddr;
ap1->offset = makeintnode(en_icon, 0);
ap1->scale = 0;
return ap1;
case am_dreg:
ap1->sreg = ap2->preg;
ap1->mode = am_baseindxdata;
ap1->offset = makeintnode(en_icon, 0);
ap1->scale = 0;
return ap1;
case am_adirect:
if ((!prm_largedata && (prm_datarel || !prm_smalldata)) ||
prm_68020)
{
ap1->mode = am_indx;
ap1->offset = ap2->offset;
return ap1;
}
ap = temp_addr();
gen_lea(0, ap2, ap);
ap1->mode = am_baseindxaddr;
ap1->offset = makeintnode(en_icon, 0);
ap1->scale = 0;
ap1->sreg = ap->preg;
return ap1;
case am_immed:
if ((!prm_largedata && (prm_datarel || !prm_smalldata)) ||
prm_68020)
{
ap1->mode = am_indx;
ap1->offset = ap2->offset;
return ap1;
}
ap = temp_data();
gen_codes(op_move, BESZ_DWORD, ap2, ap);
ap1->mode = am_baseindxdata;
ap1->offset = makeintnode(en_icon, 0);
ap1->scale = 0;
ap1->sreg = ap->preg;
return ap1;
case am_indx:
if (prm_68020 || isambyte(ap2))
{
ap1->mode = am_baseindxaddr;
ap1->offset = ap2->offset;
ap1->scale = 0;
ap1->sreg = ap2->preg;
return ap1;
}
freeop(ap2);
ap = temp_addr();
gen_lea(0, ap2, ap);
ap->mode = am_baseindxaddr;
ap->sreg = ap1->preg;
ap->scale = 0;
ap->offset = makeintnode(en_icon, 0);
return ap;
case am_ind:
ap1->mode = am_baseindxaddr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -