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; \
}
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 */
: 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 );
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;
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)");
}
UInt dis_mul_E_G ( UChar sorb,
Int size,
UInt delta0,
- Bool signed_multiply )
+ Bool syned )
{
Int alen;
UChar dis_buf[50];
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)));
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;
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)));