📄 gexpr386.c
字号:
DIAG("complexstore: double fregs");
return apr ;
}
ap2 = copy_addr(apr);
switch(apr->length)
{
case BESZ_CFLOAT:
offs = 4;
siz = BESZ_FLOAT;
break;
case BESZ_CDOUBLE:
offs = 8;
siz = BESZ_DOUBLE;
break;
case BESZ_CLDOUBLE:
offs = 10;
siz = BESZ_LDOUBLE;
break;
}
ap2->offset = makenode(en_add,ap2->offset,makeintnode(en_icon,offs));
gen_codefs(op_fstp,siz,apr,0);
gen_codefs(op_fstp,siz,ap2,0);
freeop(apr);
apr->mode = am_frfr;
apr->length = BESZ_CLDOUBLE;
return apr;
}
//-------------------------------------------------------------------------
AMODE *floatstore(ENODE *node, AMODE *apr, int novalue, int size)
{
if (isbit(node))
{
AMODE *ap1 = fstack();
do_extend(ap1, BESZ_DWORD , F_DREG | F_VOL);
bit_store(apr, ap1, node, novalue);
return ap1;
}
else if (size <= BESZ_DWORD )
{
int pushed = FALSE;
if (regs[0] && apr->preg != 0)
{
pushed = 1;
gen_push(EAX, am_dreg, 0);
}
do_ftol();
if (apr->mode != am_dreg || apr->preg != 0)
gen_codes(op_mov, size, apr, makedreg(EAX));
if (pushed)
gen_pop(EAX, am_dreg, 0);
if (novalue)
freeop(apr);
return apr;
}
else if (size <= BESZ_QWORD)
{
gen_codef(op_fistp, apr, 0);
if (novalue)
freeop(apr);
return apr;
}
else
{
if (novalue || apr->length == BESZ_LDOUBLE)
{
gen_codef(op_fstp, apr, 0);
return apr;
}
else
{
gen_codef(op_fst, apr, 0);
return makefreg(0);
}
}
}
//-------------------------------------------------------------------------
void complexload(AMODE *ap, int flag)
{
AMODE *ap2 ;
int offs = 0, siz = BESZ_BYTE;
if (ap->mode == am_frfr)
return;
if (ap->mode == am_fconst)
{
AMODE *ap1;
int siz1 = ap->length -13;
int o = prm_optmult ;
prm_optmult = FALSE;
if (siz1>BESZ_DOUBLE)
siz1++;
ap1 = make_label(queue_floatval(ap->offset->v.c.r, siz1));
queue_floatval(ap->offset->v.c.i, siz1);
ap->mode = am_direct;
ap->offset = ap1->offset;
prm_optmult = o ;
}
ap2 = copy_addr(ap);
switch(ap->length)
{
case BESZ_CFLOAT:
offs = 4;
siz = BESZ_FLOAT;
break;
case BESZ_CDOUBLE:
offs = 8;
siz = BESZ_DOUBLE;
break;
case BESZ_CLDOUBLE:
offs = 10;
siz = BESZ_LDOUBLE;
break;
}
ap2->offset = makenode(en_add,ap2->offset,makeintnode(en_icon,offs));
gen_codefs(op_fld,siz,ap2,0);
gen_codefs(op_fld,siz,ap,0);
freeop(ap);
ap->mode = am_frfr;
ap->length = BESZ_CLDOUBLE;
}
//-------------------------------------------------------------------------
void floatload(AMODE *ap, int flag)
{
if (ap->mode == am_fconst)
{
switch (ap->preg)
{
case fczero:
gen_codef(op_fldz, 0, 0);
break;
case fcone:
gen_codef(op_fld1, 0, 0);
break;
}
ap->mode = am_freg;
ap->preg = 0;
}
else
if (flag && ap->mode != am_freg)
{
if (ap->mode == am_dreg)
{
AMODE *ap1 = floatconvpos();
do_extend(ap, BESZ_DWORD , 0);
gen_codes(op_mov, BESZ_DWORD , ap1, ap);
gen_codefs(op_fild, BESZ_DWORD, ap1, 0);
}
else
{
gen_codef(op_fld, ap, 0);
freeop(ap);
ap->mode = am_freg;
ap->preg = 0;
}
}
}
//-------------------------------------------------------------------------
int is_memory(AMODE *ap)
{
switch (ap->mode)
{
case am_indisp:
case am_indispscale:
case am_direct:
return TRUE;
}
return FALSE;
}
//-------------------------------------------------------------------------
AMODE *bit_load(AMODE *ap, ENODE *node)
{
if (ap->mode == am_dreg)
return ap;
do_extend(ap, ap->length, F_DREG | F_VOL);
if (node->startbit)
gen_code(op_shr, ap, make_immed(node->startbit));
gen_code(op_and, ap, make_immed(mod_mask(node->bits)));
return ap;
}
//-------------------------------------------------------------------------
void bit_store(AMODE *ap2, AMODE *ap1, ENODE *node, int novalue)
{
AMODE *ap3;
if (ap1->mode == am_immed)
{
int vb;
ap3 = make_immed(ap1->offset->v.i &mod_mask(node->bits));
#ifdef XXXXX
if (node->bits == 1)
gen_codes(op_btr, BESZ_DWORD , ap2, make_immed(node->startbit));
else
#endif
gen_code(op_and, ap2, make_immed(~(mod_mask(node->bits) << node
->startbit)));
#ifdef XXXXX
if ((vb = single_bit(ap1->offset->v.i)) != - 1)
{
gen_codes(op_bts, BESZ_DWORD , ap2, make_immed(vb + node->startbit));
}
else
#endif
if (ap3->offset->v.i)
{
ap3->offset->v.i <<= node->startbit;
gen_codes(op_or, ap2->length, ap2, ap3);
}
}
else
{
do_extend(ap1, ap2->length, F_DREG | F_VOL);
gen_code(op_and, ap1, make_immed(mod_mask(node->bits)));
if (!novalue)
gen_codes(op_push, BESZ_DWORD , ap1, 0);
if (node->startbit)
gen_code(op_shl, ap1, make_immed(node->startbit));
gen_code(op_and, ap2, make_immed(~(mod_mask(node->bits) << node
->startbit)));
gen_code(op_or, ap2, ap1);
if (!novalue)
gen_codes(op_pop, BESZ_DWORD , ap1, 0);
}
if (novalue)
freeop(ap2);
}
//-------------------------------------------------------------------------
AMODE *aprtocx(AMODE *ap)
{
AMODE *ap2;
if (ap->mode == am_indisp && (ap->preg == EAX || ap->preg == EDX) || ap
->mode == am_indispscale && (ap->preg == EAX || ap->preg == EDX || ap
->sreg == EAX || ap->sreg == EDX))
{
// || ap->mode == am_dreg && (ap->preg == EAX || ap->preg == EDX)) {
ap2 = tempcx();
if (ap->mode == am_dreg)
gen_code(op_mov, ap2, ap);
else
gen_code(op_lea, ap2, ap);
ap2->seg = ap->seg;
ap->seg = 0;
freeop(ap);
*ap = *ap2;
ap->mode = am_indisp;
ap->offset = makeintnode(en_icon, 0);
ap->length = BESZ_QWORD;
}
else if (ap->mode == am_dreg && (ap->preg == EAX || ap->preg == EDX))
{
ap2 = tempcx();
if (ap->mode == am_dreg)
gen_code(op_mov, ap2, ap);
else
gen_code(op_lea, ap2, ap);
ap2->length = ap->length;
ap2->seg = ap->seg;
ap->seg = 0;
freeop(ap);
*ap = *ap2;
}
return ap;
}
//-------------------------------------------------------------------------
void loadaxdx(AMODE *ap)
{
if (ap->mode == am_immed)
{
tempaxdx();
gen_codes(op_mov, BESZ_DWORD , makedreg(EAX), make_immed(ap->offset->v.i
&0xffffffff));
#if sizeof(ULLONG_TYPE) == 4
gen_codes(op_mov, BESZ_DWORD , makedreg(EDX), make_immed(ap->offset->v.i < 0
? - 1: 0));
#else
gen_codes(op_mov, BESZ_DWORD , makedreg(EDX), make_immed(ap->offset->v.i >>
32));
#endif
}
else
{
AMODE *ap3 = aprtocx(ap);
tempaxdx();
gen_codes(op_mov, BESZ_DWORD , makedreg(EAX), ap3);
ap3->offset = makenode(en_add, ap3->offset, makeintnode(en_icon, 4));
gen_codes(op_mov, BESZ_DWORD , makedreg(EDX), ap3);
freeop(ap3);
}
ap->mode = am_axdx;
ap->length = BESZ_QWORD;
}
//-------------------------------------------------------------------------
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, *ap3;
int isize = ap->length;
if (isize == - BESZ_BOOL)
isize = BESZ_BOOL;
if (osize == - BESZ_BOOL)
osize = BESZ_BOOL;
if (isize && isize != osize && isize != - osize && ap->mode != am_immed || osize == BESZ_CLDOUBLE && isize == BESZ_CLDOUBLE)
{
if (ap->mode == am_dreg && ap->preg > 3 && (osize == BESZ_BYTE || osize == - BESZ_BYTE)
)
flags |= F_VOL;
if (ap->mode == am_dreg && (!(flags &F_VOL) || ap->tempflag) && ((osize
!= BESZ_BYTE && osize != - BESZ_BYTE) || ap->preg < 4))
ap2 = ap;
else
{
if (!(flags &F_NOREUSE))
freeop(ap);
ap2 = temp_data();
}
if (chksize(isize, osize))
{
/* moving to a lower type */
if (isize > BESZ_QWORD)
{
if (isize >= BESZ_CFLOAT)
{
complexload(ap,TRUE) ;
if (osize < BESZ_CFLOAT)
if (osize >= BESZ_IFLOAT)
{
gen_codefs(op_fstp,BESZ_LDOUBLE,floatconvpos(),0);
ap->mode = am_freg;
ap->length = osize;
freeop(ap2);
}
else
{
gen_codef(op_fxch,0,0);
gen_codefs(op_fstp,BESZ_LDOUBLE,floatconvpos(),0);
ap->length = osize;
ap->mode = am_freg;
freeop(ap2);
goto join1 ;
}
}
else if (isize >= BESZ_IFLOAT)
{
if (osize < BESZ_IFLOAT)
{
if (ap->mode == am_freg)
gen_codefs(op_fstp,BESZ_LDOUBLE,floatconvpos(),0);
gen_codef(op_fldz,0,0);
freeop(ap2);
ap->mode = am_freg;
ap->length = osize;
goto join1;
}
else
{
if (ap->mode != am_freg) {
floatload(ap, TRUE);
ap->length = osize;
freeop(ap2);
}
}
}
else
{
if (ap->mode != am_freg)
floatload(ap, TRUE);
join1:
if (osize == BESZ_QWORD || osize == - BESZ_QWORD || osize == BESZ_BOOL)
{
freeop(ap2);
ap2 = floatconvpos();
memcpy(ap, ap2, sizeof(*ap));
gen_codes(op_fistp, BESZ_DOUBLE, ap, 0);
ap->length = BESZ_QWORD;
}
else if (osize < BESZ_QWORD)
{
int pushed = FALSE;
if (regs[0] && ap2->preg != 0)
{
pushed = 1;
gen_push(EAX, am_dreg, 0);
}
do_ftol();
if (ap2->preg != 0)
gen_codes(op_mov, BESZ_DWORD , ap2, makedreg(EAX));
if (pushed)
gen_pop(EAX, am_dreg, 0);
ap->mode = ap2->mode;
ap->preg = ap2->preg;
ap->tempflag = ap2->tempflag;
ap->seg = 0;
ap->length = osize;
}
else
{
freeop(ap2);
ap->mode = am_freg;
ap->preg = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -