📄 gexpr68.c
字号:
if (ap2->mode == am_ind)
ap2->mode = am_indx;
gen_codes(op_move, BESZ_DWORD, ap2, makedreg(1));
freeop(ap);
}
ap->mode = am_doublereg;
ap->length = 6;
}
//-------------------------------------------------------------------------
void do_extend(AMODE *ap, int osize, int flags)
/*
* if isize is not equal to osize then the operand ap will be
* loaded into a register (if not already) and if osize is
* greater than isize it will be extended to match.
*/
{
AMODE *ap2, *ap1;
int isize = ap->length;
if (osize == - 5)
osize = 5;
if (isize && isize != osize && isize != - osize && ap->mode != am_immed)
{
if (ap->mode == am_dreg && (!(flags &F_VOL) || ap->tempflag))
ap2 = ap;
else
{
if (!(flags &F_NOREUSE))
freeop(ap);
ap2 = temp_data();
}
if (chksize(isize, osize))
{
/* moving to a lower type */
if (isize > 6)
{
tofloat(ap, isize);
if (osize <= 6)
{
int pushed = FALSE;
ap2 = floatstore(0, ap, ap2, FALSE, osize);
ap->mode = ap2->mode;
ap->preg = ap2->preg;
ap->sreg = ap2->sreg;
ap->offset = ap2->offset;
ap->length = osize;
ap->tempflag = 1;
}
}
else
{
if (ap->mode != am_dreg || ap->preg != ap2->preg)
if (isize == 6 || isize == - 6)
if (ap->mode == am_doublereg)
{
if (ap2->preg != 1)
{
dregs[ap2->preg]--;
dregs[1]++;
}
ap2->mode = am_dreg;
ap2->preg = 1;
ap2->tempflag = 1;
}
else
gen_codes(op_move, BESZ_DWORD, ap, ap2);
else
gen_codes(op_move, isize, ap, ap2);
ap->mode = ap2->mode;
ap->preg = ap2->preg;
ap->length = osize;
ap->tempflag = ap2->tempflag;
}
}
else
{
/* moving up in type */
if (isize > 6)
{
tofloat(ap, isize);
freeop(ap2);
}
else if (isize == 6 || isize == - 6 || osize > 6)
{
tofloat(ap, isize);
ap->tempflag = 1;
}
else
{
int size6 = osize == 6 || osize == - 6;
if (osize == 6 || osize == - 6)
osize = BESZ_DWORD;
if (ap->mode == am_areg && (isize == BESZ_BYTE || isize == - BESZ_BYTE))
gen_codes(op_move, BESZ_DWORD, ap, ap2);
if (size6 && (isize == BESZ_DWORD || isize == - BESZ_DWORD))
gen_codes(op_move, isize, ap, ap2);
else if (isize < 0)
{
if (!equal_address(ap, ap2))
{
gen_codes(op_move, isize, ap, ap2);
freeop(ap);
}
if ((isize == BESZ_BYTE || isize == - BESZ_BYTE) && osize == - BESZ_DWORD &&
(prm_68020 || prm_coldfire))
gen_codes(op_extb, BESZ_DWORD, ap2, 0);
else
{
if (isize == BESZ_BYTE || isize == - BESZ_BYTE)
gen_codes(op_ext, 2, ap2, 0);
if (osize == - BESZ_DWORD || osize == BESZ_DWORD)
gen_codes(op_ext, BESZ_DWORD, ap2, 0);
}
}
else
{
if (equal_address(ap, ap2))
ap2 = temp_data();
gen_codes(op_moveq, 0, make_immed(0), ap2);
gen_codes(op_move, ap->length, ap, ap2);
freeop(ap);
}
if (size6)
{
freeop(ap2);
temp_doubledregs();
if (ap2->preg != 1)
gen_codes(op_move, BESZ_DWORD, ap2, makedreg(1));
gen_codes(op_moveq, BESZ_DWORD, make_immed(0), makedreg(0));
if (isize < 0)
{
int label = nextlabel++;
gen_codes(op_tst, BESZ_DWORD, makedreg(1), 0);
gen_1branch(op_bpl, make_label(label));
gen_codes(op_subq, BESZ_DWORD, make_immed(1), makedreg(0));
gen_label(label);
}
ap->mode = am_doublereg;
ap->length = 6;
osize = 6;
}
else
{
ap->mode = am_dreg;
ap->preg = ap2->preg;
ap->tempflag = ap2->tempflag;
ap->length = osize;
}
}
}
}
if (((flags &F_VOL) == 0) || ap->tempflag)
{
switch (ap->mode)
{
case am_doublereg:
if (flags &F_DOUBLEREG)
return ;
break;
case am_freg:
if (flags &F_FREG)
return ;
break;
case am_immed:
if (flags &F_IMMED)
return ;
/* mode ok */
break;
case am_areg:
if (flags &F_AREG)
return ;
break;
case am_dreg:
if (flags &F_DREG)
return ;
break;
case am_indx:
case am_ind:
case am_ainc:
case am_adec:
if (flags &F_REGI)
return ;
break;
case am_baseindxdata:
case am_baseindxaddr:
if (flags &F_REGIX)
return ;
break;
case am_adirect:
case am_direct:
if (flags &F_ABS)
return ;
case am_pcindx:
if (flags &(F_PCI | F_PCIX))
return ;
break;
}
}
if (flags &(F_FREG | F_DREG))
{
if (flags &F_DREG)
{
if (ap->mode != am_dreg || !ap->tempflag && (flags &F_VOL))
if (isize == osize || isize == - osize || ap->mode == am_immed)
{
if (osize < 7)
{
freeop(ap);
ap2 = temp_data();
ap2->length = osize;
gen_code(op_move, ap, ap2);
ap->mode = ap2->mode;
ap->preg = ap2->preg;
ap->tempflag = ap2->tempflag;
}
else
{
tofloat(ap, isize);
}
}
}
else if (ap->mode != am_freg)
{
tofloat(ap, isize);
}
else if (flags &F_VOL)
{
ap2 = temp_float();
ap2->length = osize;
gen_codes(op_fmove, osize, ap, ap2);
ap->mode = ap2->mode;
ap->preg = ap2->preg;
ap->tempflag = ap2->tempflag;
}
}
if ((flags &F_DOUBLEREG) && !(flags &(F_MEM | F_IMMED)) && ap->mode !=
am_doublereg)
loaddoublereg(ap);
if (flags &F_AREG)
{
if (isize == - BESZ_BYTE)
{
freeop(ap);
ap2 = temp_data();
gen_codes(op_move, BESZ_BYTE, ap, ap2);
gen_codes(op_ext, 2, ap2, 0);
ap->mode = ap2->mode;
ap->preg = ap2->preg;
ap->tempflag = 1;
isize = - 2;
}
if (isize == BESZ_BYTE)
{
freeop(ap);
ap2 = temp_data();
gen_codes(op_move, BESZ_BYTE, ap, ap2);
gen_codes(op_and, 2, make_immed(0xff), ap2);
ap->mode = ap2->mode;
ap->preg = ap2->preg;
ap->tempflag = 1;
isize = 2;
}
freeop(ap);
ap2 = temp_addr();
gen_codes(op_move, isize, ap, ap2);
ap->mode = am_areg;
ap->preg = ap2->preg;
ap->tempflag = 1;
}
if (osize != isize && osize == 5)
{
int lab = nextlabel++;
ap2 = temp_data();
gen_codes(op_moveq, BESZ_DWORD, make_immed(0), ap2);
gen_codes(op_cmp, BESZ_BYTE, make_immed(0), ap);
gen_code(op_beq, make_label(lab), 0);
gen_codes(op_moveq, BESZ_BYTE, make_immed(1), ap2);
gen_label(lab);
freeop(ap);
ap->mode = ap->mode;
ap->tempflag = ap2->tempflag;
ap->length = ap2->length;
ap->preg = ap2->preg;
}
ap->length = osize;
if (osize == 5)
ap->length = 5;
}
//-------------------------------------------------------------------------
int isshort(ENODE *node)
/*
* return true if the node passed can be generated as a short
* offset.
*/
{
return (isintconst(node->nodetype) || node->nodetype == en_absacon) &&
(node->v.i >= - 32768 && node->v.i <= 32767);
}
//-------------------------------------------------------------------------
int isbyte(ENODE *node)
/*
* return true if the node passed can be evaluated as a byte
* offset.
*/
{
return isintconst(node->nodetype) && ( - 128 <= node->v.i && node->v.i <=
127);
}
//-------------------------------------------------------------------------
int isamshort(AMODE *ap)
{
LLONG_TYPE v;
if (ap->offset->nodetype != en_icon)
return TRUE;
v = ap->offset->v.i;
return (v >= - 32768 && v < 32767);
}
//-------------------------------------------------------------------------
int isamshort2(AMODE *ap, AMODE *ap2)
{
LLONG_TYPE v;
if (ap->offset->nodetype != en_icon || ap2->offset->nodetype != en_icon)
return TRUE;
v = ap->offset->v.i + ap2->offset->v.i;
return (v >= - 32768 && v < 32767);
}
//-------------------------------------------------------------------------
int isambyte(AMODE *ap)
{
long v;
if (ap->offset->nodetype != en_icon)
return FALSE;
v = ap->offset->v.i;
return (v >= - 128 && v < 128);
}
//-------------------------------------------------------------------------
int isambyte2(AMODE *ap, AMODE *ap2)
{
long v;
if (ap->offset->nodetype != en_icon || ap2->offset->nodetype != en_icon)
return FALSE;
v = ap->offset->v.i + ap2->offset->v.i;
return (v >= - 128 && v < 128);
}
//-------------------------------------------------------------------------
static int depth(ENODE *node)
{
int a, b;
if (!node)
return 0;
switch (node->nodetype)
{
case en_structret:
return 0;
case en_cfi:
case en_cfc:
case en_cri:
case en_crc:
case en_clri:
case en_clrc:
case en_cll:
case en_cull:
case en_ci:
case en_cui:
case en_cl:
case en_cul:
case en_cp:
case en_cbool:
case en_cub:
case en_cb:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -