mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-15 07:07:01 +00:00
Rehash handling of multiply insns in the x86 front end, so as to make
the flags work right. git-svn-id: svn://svn.valgrind.org/vex/trunk@160
This commit is contained in:
@@ -92,17 +92,13 @@ enum {
|
||||
CC_OP_RORW,
|
||||
CC_OP_RORL, /* 33 */
|
||||
|
||||
CC_OP_MULB, /* modify all flags, CC_DST = one arg */
|
||||
CC_OP_MULW, /* CC_SRC = the other arg */
|
||||
CC_OP_MULL, /* 36 */
|
||||
CC_OP_UMULB, /* modify all flags, CC_DST = one arg */
|
||||
CC_OP_UMULW, /* CC_SRC = the other arg */
|
||||
CC_OP_UMULL, /* 36 */
|
||||
|
||||
CC_OP_MULLSB, /* modify all flags, CC_DST = one arg */
|
||||
CC_OP_MULLSW, /* CC_SRC = the other arg */
|
||||
CC_OP_MULLSL, /* 39 */
|
||||
|
||||
CC_OP_MULLUB, /* modify all flags, CC_DST = one arg */
|
||||
CC_OP_MULLUW, /* CC_SRC = the other arg */
|
||||
CC_OP_MULLUL, /* 42 */
|
||||
CC_OP_SMULB, /* modify all flags, CC_DST = one arg */
|
||||
CC_OP_SMULW, /* CC_SRC = the other arg */
|
||||
CC_OP_SMULL, /* 39 */
|
||||
|
||||
CC_OP_NUMBER
|
||||
};
|
||||
|
||||
@@ -256,17 +256,38 @@ static inline int lshift(int x, int n)
|
||||
return fl; \
|
||||
}
|
||||
|
||||
#define ACTIONS_MUL(DATA_BITS,DATA_UTYPE,DATA_S2TYPE) \
|
||||
#define ACTIONS_SMUL(DATA_BITS,DATA_STYPE,DATA_S2TYPE) \
|
||||
{ \
|
||||
PREAMBLE(DATA_BITS); \
|
||||
int cf, pf, af, zf, sf, of; \
|
||||
DATA_UTYPE r = ((DATA_UTYPE)CC_SRC) * ((DATA_UTYPE)CC_DST); \
|
||||
DATA_S2TYPE rr = ((DATA_S2TYPE)CC_SRC) * ((DATA_S2TYPE)CC_DST); \
|
||||
cf = (r == (DATA_UTYPE)(rr >>/*signed*/ DATA_BITS)); \
|
||||
pf = parity_table[(uint8_t)r]; \
|
||||
DATA_STYPE hi; \
|
||||
DATA_STYPE lo = ((DATA_STYPE)CC_SRC) * ((DATA_STYPE)CC_DST); \
|
||||
DATA_S2TYPE rr = ((DATA_S2TYPE)((DATA_STYPE)CC_SRC)) \
|
||||
* ((DATA_S2TYPE)((DATA_STYPE)CC_DST)); \
|
||||
hi = (DATA_STYPE)(rr >>/*s*/ DATA_BITS); \
|
||||
cf = (hi != (lo >>/*s*/ (DATA_BITS-1))); \
|
||||
pf = parity_table[(uint8_t)lo]; \
|
||||
af = 0; /* undefined */ \
|
||||
zf = (r == 0) << 6; \
|
||||
sf = lshift(r, 8 - DATA_BITS) & 0x80; \
|
||||
zf = (lo == 0) << 6; \
|
||||
sf = lshift(lo, 8 - DATA_BITS) & 0x80; \
|
||||
of = cf << 11; \
|
||||
return cf | pf | af | zf | sf | of; \
|
||||
}
|
||||
|
||||
#define ACTIONS_UMUL(DATA_BITS,DATA_UTYPE,DATA_U2TYPE) \
|
||||
{ \
|
||||
PREAMBLE(DATA_BITS); \
|
||||
int cf, pf, af, zf, sf, of; \
|
||||
DATA_UTYPE hi; \
|
||||
DATA_UTYPE lo = ((DATA_UTYPE)CC_SRC) * ((DATA_UTYPE)CC_DST); \
|
||||
DATA_U2TYPE rr = ((DATA_U2TYPE)((DATA_UTYPE)CC_SRC)) \
|
||||
* ((DATA_U2TYPE)((DATA_UTYPE)CC_DST)); \
|
||||
hi = (DATA_UTYPE)(rr >>/*u*/ DATA_BITS); \
|
||||
cf = (hi != 0); \
|
||||
pf = parity_table[(uint8_t)lo]; \
|
||||
af = 0; /* undefined */ \
|
||||
zf = (lo == 0) << 6; \
|
||||
sf = lshift(lo, 8 - DATA_BITS) & 0x80; \
|
||||
of = cf << 11; \
|
||||
return cf | pf | af | zf | sf | of; \
|
||||
}
|
||||
@@ -324,7 +345,9 @@ static inline int lshift(int x, int n)
|
||||
case CC_OP_RORW: ACTIONS_ROR( 16, UShort );
|
||||
case CC_OP_RORL: ACTIONS_ROR( 32, UInt );
|
||||
|
||||
case CC_OP_MULL: ACTIONS_MUL( 32, UInt, Long );
|
||||
case CC_OP_UMULL: ACTIONS_UMUL( 32, UInt, ULong );
|
||||
|
||||
case CC_OP_SMULL: ACTIONS_SMUL( 32, Int, Long );
|
||||
|
||||
default:
|
||||
/* shouldn't really make these calls from generated code */
|
||||
|
||||
@@ -653,6 +653,10 @@ static IRExpr* calculate_condition ( Condcode cond )
|
||||
: mk_calculate_eflags_all() );
|
||||
|
||||
switch (cond) {
|
||||
case CondNO:
|
||||
case CondO: /* OF == 1 */
|
||||
e = flag_to_bit0( CC_MASK_O, eflags );
|
||||
break;
|
||||
case CondNZ:
|
||||
case CondZ: /* ZF == 1 */
|
||||
e = flag_to_bit0( CC_MASK_Z, eflags );
|
||||
@@ -671,6 +675,7 @@ static IRExpr* calculate_condition ( Condcode cond )
|
||||
case CondS: /* SF == 1 */
|
||||
e = flag_to_bit0( CC_MASK_S, eflags );
|
||||
break;
|
||||
case CondNP:
|
||||
case CondP: /* PF == 1 */
|
||||
e = flag_to_bit0( CC_MASK_P, eflags );
|
||||
break;
|
||||
@@ -2457,13 +2462,25 @@ static void codegen_mulL_A_D ( Int sz, Bool syned,
|
||||
case Ity_I32: {
|
||||
IRTemp res64 = newTemp(Ity_I64);
|
||||
IROp mulOp = syned ? Iop_MullS32 : Iop_MullU32;
|
||||
UInt thunkOp = syned ? CC_OP_MULLSB : CC_OP_MULLUB;
|
||||
UInt thunkOp = syned ? CC_OP_SMULB : CC_OP_UMULB;
|
||||
setFlags_MUL ( Ity_I32, t1, tmp, thunkOp );
|
||||
assign( res64, binop(mulOp, mkexpr(t1), mkexpr(tmp)) );
|
||||
putIReg(4, R_EDX, unop(Iop_64HIto32,mkexpr(res64)));
|
||||
putIReg(4, R_EAX, unop(Iop_64to32,mkexpr(res64)));
|
||||
break;
|
||||
}
|
||||
#if 0
|
||||
case Ity_I16: {
|
||||
IRTemp res32 = newTemp(Ity_I32);
|
||||
IROp mulOp = syned ? Iop_MullS16 : Iop_MullU16;
|
||||
UInt thunkOp = syned ? CC_OP_MULLSB : CC_OP_MULLUB;
|
||||
setFlags_MUL ( Ity_I16, t1, tmp, thunkOp );
|
||||
assign( res32, binop(mulOp, mkexpr(t1), mkexpr(tmp)) );
|
||||
putIReg(2, R_EDX, unop(Iop_32HIto16,mkexpr(res32)));
|
||||
putIReg(2, R_EAX, unop(Iop_32to16,mkexpr(res32)));
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
vpanic("codegen_mulL_A_D(x86)");
|
||||
}
|
||||
@@ -2964,7 +2981,7 @@ static
|
||||
UInt dis_mul_E_G ( UChar sorb,
|
||||
Int size,
|
||||
UInt delta0,
|
||||
Bool signed_multiply )
|
||||
Bool syned )
|
||||
{
|
||||
Int alen;
|
||||
UChar dis_buf[50];
|
||||
@@ -2973,17 +2990,17 @@ UInt dis_mul_E_G ( UChar sorb,
|
||||
IRTemp te = newTemp(ty);
|
||||
IRTemp tg = newTemp(ty);
|
||||
|
||||
vassert(signed_multiply);
|
||||
vassert(syned);
|
||||
|
||||
if (epartIsReg(rm)) {
|
||||
assign( tg, getIReg(size, gregOfRM(rm)) );
|
||||
assign( te, getIReg(size, eregOfRM(rm)) );
|
||||
setFlags_MUL ( ty, te, tg, CC_OP_MULB );
|
||||
setFlags_MUL ( ty, te, tg, syned ? CC_OP_SMULB : CC_OP_UMULB );
|
||||
putIReg(size, gregOfRM(rm),
|
||||
binop(mkSizedOp(ty,Iop_Mul8),
|
||||
mkexpr(te), mkexpr(tg)));
|
||||
|
||||
DIP("%smul%c %s, %s\n", signed_multiply ? "i" : "",
|
||||
DIP("%smul%c %s, %s\n", syned ? "i" : "",
|
||||
nameISize(size),
|
||||
nameIReg(size,eregOfRM(rm)),
|
||||
nameIReg(size,gregOfRM(rm)));
|
||||
@@ -2992,12 +3009,12 @@ UInt dis_mul_E_G ( UChar sorb,
|
||||
IRTemp addr = disAMode( &alen, sorb, delta0, dis_buf );
|
||||
assign( tg, getIReg(size, gregOfRM(rm)) );
|
||||
assign( te, loadLE(ty,mkexpr(addr)) );
|
||||
setFlags_MUL ( ty, te, tg, CC_OP_MULB );
|
||||
setFlags_MUL ( ty, te, tg, syned ? CC_OP_SMULB : CC_OP_UMULB );
|
||||
putIReg(size, gregOfRM(rm),
|
||||
binop(mkSizedOp(ty,Iop_Mul8),
|
||||
mkexpr(te), mkexpr(tg)));
|
||||
|
||||
DIP("%smul%c %s, %s\n", signed_multiply ? "i" : "",
|
||||
DIP("%smul%c %s, %s\n", syned ? "i" : "",
|
||||
nameISize(size),
|
||||
dis_buf, nameIReg(size,gregOfRM(rm)));
|
||||
return alen+delta0;
|
||||
@@ -3036,7 +3053,7 @@ UInt dis_imul_I_E_G ( UChar sorb,
|
||||
delta += litsize;
|
||||
|
||||
assign(tl, mkU(ty,d32));
|
||||
setFlags_MUL ( ty, te, tl, CC_OP_MULB );
|
||||
setFlags_MUL ( ty, te, tl, CC_OP_SMULB );
|
||||
putIReg(size, gregOfRM(rm),
|
||||
binop(mkSizedOp(ty,Iop_Mul8),
|
||||
mkexpr(te), mkexpr(tl)));
|
||||
|
||||
Reference in New Issue
Block a user