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:
Julian Seward
2004-07-30 01:52:45 +00:00
parent 96a469f190
commit 42b522cf9b
3 changed files with 62 additions and 26 deletions

View File

@@ -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
};

View File

@@ -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 */

View File

@@ -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)));