📄 gexpr68.c
字号:
gen_codes(op_move, BESZ_DWORD, make_immed(ap3->offset->v.i &0xffffffff),
push);
#if sizeof(ULLONG_TYPE) == 4
gen_codes(op_move, BESZ_DWORD, make_immed(ap3->offset->v.i < 0 ? -
1: 0), push);
#else
gen_codes(op_move, BESZ_DWORD, make_immed(ap3->offset->v.i >> 32),
push);
#endif
gen_codes(op_move, BESZ_DWORD, makeareg(7), push);
ss = 12;
}
else
{
gen_codes(op_pea, BESZ_DWORD, ap, 0);
ss = 4;
}
}
if (size == 6)
call_library2("__LQFU", ss);
else
call_library2("__LQFS", ss);
if (pushed)
{
gen_codef(op_fmove, 10, makefreg(0), ap2);
gen_codef(op_fmove, 10, pop, makefreg(0));
}
freeop(ap);
ap->mode = am_doublereg;
ap->length = size;
}
else
{
if (ap->mode == am_areg)
{
ap2 = temp_data();
gen_codes(op_move, BESZ_DWORD, ap, ap2);
freeop(ap);
ap->preg = ap2->preg;
ap->mode = ap2->mode;
}
ap2 = temp_float();
gen_codef(op_fmove, ap->length, ap, ap2);
freeop(ap);
}
ap->mode = am_freg;
ap->preg = ap2->preg;
ap->tempflag = 1;
ap->length = 10;
return ;
}
//-------------------------------------------------------------------------
AMODE *floatstore(ENODE *e1, AMODE *ap, AMODE *ap1, int novalue, int size)
{
if (!ap1)
ap1 = gen_expr(e1, FALSE, TRUE, BESZ_DWORD);
if (e1 && isbit(e1))
{
do_extend(ap, BESZ_DWORD, F_DREG | F_VOL);
bit_store(ap, ap1, e1, novalue);
freeop(ap1);
}
else if (ap->mode != am_freg || ap1->mode != am_freg || ap1->preg != ap
->preg)
if (size == 6 || size == - 6)
{
gen_codef(op_fmove, 10, ap, push);
if (size == 6)
call_library2("__LFQU", 16);
else
call_library2("__LFQS", 16);
freeop(ap1);
ap->mode = am_doublereg;
ap->length = size;
}
else
{
gen_codef(op_fmove, size, ap, ap1);
freeop(ap);
ap = ap1;
}
if (novalue)
freeop(ap);
return ap;
}
//-------------------------------------------------------------------------
void doshift(int op, AMODE *ap2, AMODE *ap1, int div, int size)
{
AMODE *apr = copy_addr(ap1), *ap3;
if (div)
{
// ap2 always a const if we get in here
freeop(ap2);
switch (size)
{
case BESZ_BYTE:
case - BESZ_BYTE: gen_codes(op_btst, BESZ_BYTE, make_immed(7), ap1);
gen_code(op_beq, make_label(nextlabel), 0);
case 2:
case - 2: do_extend(ap1, BESZ_DWORD, F_DREG | F_VOL);
gen_codes(op_and, BESZ_DWORD, make_immed(0x8000), ap1);
gen_code(op_beq, make_label(nextlabel), 0);
freeop(ap1);
break;
case BESZ_DWORD:
case - BESZ_DWORD: default:
if (ap2->mode == am_immed && ap2->offset->v.i == 1 && ap1->mode
== am_dreg)
{
gen_codes(op_asr, BESZ_DWORD, ap2, ap1);
gen_code(op_bpl, make_label(nextlabel), 0);
gen_code(op_bcc, make_label(nextlabel), 0);
gen_codes(op_add, BESZ_DWORD, make_immed(1), ap1);
gen_label(nextlabel++);
return ;
}
else
{
if (ap1->mode == am_dreg)
{
gen_codes(op_tst, BESZ_DWORD, ap1, 0);
gen_code(op_bpl, make_label(nextlabel), 0);
}
else
{
do_extend(ap1, BESZ_DWORD, F_DREG | F_VOL);
gen_codes(op_and, BESZ_DWORD, make_immed(0x80000000), ap1);
gen_code(op_beq, make_label(nextlabel), 0);
freeop(ap1);
}
break;
}
}
ap3 = copy_addr(ap2);
ap3->offset = makeintnode(en_icon, ((1 << ap2->offset->v.i) - 1));
ap3->length = ap2->length;
gen_code(op_add, ap3, ap1);
gen_label(nextlabel++);
}
{
do_extend(apr, size, F_DREG | F_VOL);
if (ap2->mode == am_immed)
{
int temp = ap2->offset->v.i;
while (temp > 8)
{
temp = temp - 8;
gen_codes(op, size, make_immed(8), apr);
}
if (temp != 0)
gen_codes(op, size, make_immed(temp), apr);
}
else
{
do_extend(ap2, size, F_DREG);
gen_codes(op, size, ap2, apr);
freeop(ap2);
}
ap2->mode = am_dreg;
ap2->preg = apr->preg;
}
}
//-------------------------------------------------------------------------
AMODE *do6shift(int op, ENODE *node, int div, int size)
{
AMODE *ecx = makedreg(2), *ap1 = 0, *ap2, *ap3;
LLONG_TYPE t;
ap2 = gen_expr(node->v.p[1], FALSE, FALSE, BESZ_DWORD);
if (div)
{
// if we get in here ap2 is a const ...
ap1 = gen_expr(node->v.p[0], FALSE, FALSE, size);
do_extend(ap1, size, F_DOUBLEREG);
gen_codes(op_btst, BESZ_DWORD, make_immed(31), makedreg(0));
gen_1branch(op_beq, make_label(nextlabel));
{
AMODE *ap3 = copy_addr(ap2);
AMODE *ap4 = copy_addr(ap2);
t = (1 << ap2->offset->v.i) - 1;
#if sizeof(ULLONG_TYPE) == 4
ap3->offset = makeintnode(en_icon, t < 0 ? - 1: 0);
#else
ap3->offset = makeintnode(en_icon, t >> 32);
#endif
ap4->offset = makeintnode(en_icon, t);
ap3->length = ap2->length;
ap4->length = ap2->length;
gen_codes(op_add, BESZ_DWORD, ap3, makedreg(0));
gen_codes(op_add, BESZ_DWORD, apBESZ_DWORD, makedreg(1));
gen_code(op_bcc, make_label(nextlabel), 0);
gen_codes(op_add, BESZ_DWORD, make_immed(1), makedreg(0));
gen_label(nextlabel++);
}
gen_label(nextlabel++);
}
{
int xchg = - 1;
int pushed = FALSE;
if (dregs[2] && ap2->mode != am_dreg && ap2->preg != 2)
{
pushed = TRUE;
gen_push(2, am_dreg, 0);
}
if (ap2->mode == am_doublereg)
gen_push(1, am_dreg, 0);
else
{
if (ap2->length == 6 || ap2->length == - 6)
{
if (ap2->offset)
ap2->offset = makenode(en_add, ap2->offset, makeintnode
(en_icon, 4));
else
ap2->offset = makeintnode(en_icon, 4);
if (ap2->mode == am_ind)
ap2->mode = am_indx;
ap2->length = BESZ_DWORD;
}
else
do_extend(ap2, BESZ_DWORD, F_ALL);
gen_codes(op_move, BESZ_DWORD, ap2, push);
}
freeop(ap2);
if (!ap1)
ap1 = gen_expr(node->v.p[0], FALSE, FALSE, size);
if (ap1->mode == am_doublereg)
{
gen_push(1, am_dreg, 0);
gen_push(0, am_dreg, 0);
}
else if (ap1->mode == am_immed)
{
gen_codes(op_move, BESZ_DWORD, make_immed(ap1->offset->v.i), push);
#if sizeof(LLONG_TYPE) == 4
gen_codes(op_move, BESZ_DWORD, make_immed(ap1->offset->v.i < 0 ? - 1: 0)
, push);
#else
gen_codes(op_move, BESZ_DWORD, make_immed(ap1->offset->v.i >> 32), push);
#endif
}
else
{
ap2 = copy_addr(ap1);
if (ap2->offset)
ap2->offset = makenode(en_add, ap2->offset, makeintnode(en_icon,
4));
else
ap2->offset = makeintnode(en_icon, 4);
if (ap2->mode == am_ind)
ap2->mode = am_indx;
gen_codes(op_move, BESZ_DWORD, ap2, push);
gen_codes(op_move, BESZ_DWORD, ap1, push);
}
freeop(ap1);
if (op == op_lsr)
call_library2("__LXSHR", 12);
else if (op == op_asr)
call_library2("__LXSAR", 12);
else
call_library2("__LXSHL", 12);
if (pushed)
gen_pop(2, am_dreg, 0);
dregs[0]++;
dregs[1]++;
}
ap1 = xalloc(sizeof(AMODE));
ap1->mode = am_doublereg;
ap1->length = 6;
return ap1;
}
//-------------------------------------------------------------------------
void bit_store(AMODE *ap1, AMODE *ap2, ENODE *node, int novalue)
{
if (prm_68020 && !prm_coldfire)
{
AMODE *ap3;
if (ap1->mode != am_dreg)
do_extend(ap1, BESZ_DWORD, F_DREG | F_VOL);
gen_code3(op_bfins, 0, ap1, ap2, makebf(node, ap2, ap1->length));
ap1->mode = ap3->mode;
ap1->preg = ap3->preg;
ap1->tempflag = ap3->tempflag;
}
else if (ap1->mode == am_immed)
{
int vb;
AMODE *ap3;
if (prm_coldfire)
do_extend(ap2, BESZ_DWORD, F_DREG | F_VOL);
ap3 = make_immed(ap1->offset->v.i &mod_mask(node->bits));
// if (node->bits == 1) {
// if (!ap1->offset->v.i)
// gen_codes(op_bclr,BESZ_DWORD,make_immed(node->startbit),ap2);
// } else
if (mod_mask(node->bits) != ap3->offset->v.i)
gen_codes(op_andi, ap2->length, make_immed(~(mod_mask(node->bits)
<< node->startbit)), ap2);
// if ((vb = single_bit(ap1->offset->v.i)) != -1) {
// gen_codes(op_bset,BESZ_DWORD,make_immed(vb+node->startbit),ap2);
// }else
if (ap3->offset->v.i)
{
ap3->offset->v.i <<= node->startbit;
gen_codes(op_or, ap2->length, ap3, ap2);
}
ap1->mode = ap2->mode;
ap1->preg = ap2->preg;
ap1->tempflag = ap2->tempflag;
}
else
{
do_extend(ap1, ap2->length, F_DREG | F_VOL);
gen_codes(op_andi, BESZ_DWORD, make_immed(mod_mask(node->bits)), ap1);
if (!novalue)
gen_codes(op_move, BESZ_DWORD, ap1, push);
if (node->startbit)
doshift(op_asl, make_immed(node->startbit), ap1, FALSE, ap1->length)
;
gen_codes(op_andi, ap2->length, make_immed(~(mod_mask(node->bits) <<
node->startbit)), ap2);
gen_codes(op_or, ap2->length, ap1, ap2);
if (!novalue)
gen_codes(op_move, BESZ_DWORD, pop, ap1);
}
}
//-------------------------------------------------------------------------
AMODE *bit_load(AMODE *ap, ENODE *node, int size)
{
if (prm_68020 && !prm_coldfire)
{
AMODE *ap1 = temp_data();
ap1->tempflag = TRUE;
if (ap1->mode == am_immed)
gen_codes(op_move, BESZ_DWORD, ap1, ap);
else
gen_code3(op_bfextu, 0, ap, makebf(node, ap, size), ap1);
return ap1;
}
else
{
do_extend(ap, ap->length, F_DREG | F_VOL);
if (node->startbit)
doshift(op_asr, make_immed(node->startbit), ap, FALSE, ap->length);
gen_codes(op_andi, ap->length, make_immed(mod_mask(node->bits)), ap);
return ap;
}
}
//-------------------------------------------------------------------------
void loaddoublereg(AMODE *ap)
{
if (ap->mode == am_immed)
{
temp_doubledregs();
gen_codes(op_move, BESZ_DWORD, make_immed(ap->offset->v.i &0xffffffff), makedreg
(1));
#if sizeof(ULLONG_TYPE) == 4
gen_codes(op_move, BESZ_DWORD, make_immed(ap->offset->v.i < 0 ? - 1: 0),
makedreg(0));
#else
gen_codes(op_move, BESZ_DWORD, make_immed(ap->offset->v.i >> 32), makedreg(0)
);
#endif
}
else
{
AMODE *ap2;
ap = direct_data(ap);
temp_doubledregs();
gen_codes(op_move, BESZ_DWORD, ap, makedreg(0));
ap2 = copy_addr(ap);
if (ap2->offset)
ap2->offset = makenode(en_add, ap2->offset, makeintnode(en_icon, 4))
;
else
ap2->offset = makeintnode(en_icon, 4);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -