}
break;
}
+ case Iop_DivModU32to32: {
+ UInt u32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32;
+ UInt u32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32;
+ if (u32b != 0) {
+ UInt q = u32a / u32b;
+ UInt r = u32a % u32b;
+ e2 = IRExpr_Const(IRConst_U64(((ULong)r << 32) | q));
+ }
+ break;
+ }
+ case Iop_DivModS32to32: {
+ Int s32a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U32;
+ Int s32b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U32;
+ if (s32b != 0) {
+ /* Division may trap when result overflows i.e. when
+ attempting: INT32_MAX / -1 */
+ if (e->Iex.Binop.arg1->Iex.Const.con->Ico.U32 == (1UL << 31)
+ && s32b == -1)
+ break;
+ Int q = s32a / s32b;
+ Int r = s32a % s32b;
+ e2 = IRExpr_Const(IRConst_U64(((ULong)(UInt)r << 32) | (UInt)q));
+ }
+ break;
+ }
/* -- Shl -- */
case Iop_Shl8:
expected = (int64_t)(opnd_l << 32) / (int32_t)opnd_r;
break;
+ case Iop_DivModU32to32: {
+ uint32_t q = opnd_l / opnd_r;
+ uint32_t r = opnd_l % opnd_r;
+ expected = ((uint64_t)r << 32) | q;
+ break;
+ }
+
+ case Iop_DivModS32to32: {
+ int32_t q = (int32_t)opnd_l / (int32_t)opnd_r;
+ int32_t r = (int32_t)opnd_l % (int32_t)opnd_r;
+ expected = ((uint64_t)r << 32) | (uint32_t)q;
+ break;
+ }
+
case Iop_DivModU64to32: {
uint64_t q = opnd_l / opnd_r;
uint64_t r = opnd_l % opnd_r;
case Iop_DivS32: case Iop_DivS64:
case Iop_DivU32E:
case Iop_DivS32E:
+ case Iop_DivModU32to32:
return o2 != 0;
/* Check that result can be represented */
return q <= INT32_MAX && q >= INT32_MIN;
}
+ case Iop_DivModS32to32: {
+ int32_t divisor = o2;
+
+ if (divisor == 0) return 0;
+ /* Division may trap on overflow */
+ if (divisor == -1 && o1 == (0x1UL << 31)) // INT32_MIN
+ return 0;
+ return 1;
+ }
+
default:
return 1;
}
// { OPNAME(DivS64E), Ity_I32, 2, Ity_I32, Ity_I32, }, // 128 bit
// { OPNAME(DivS128E), Ity_I128, 2, Ity_I128, Ity_I128 }, // 128 bit
-// { OPNAME(DivModU32to32), Ity_I64, 2, Ity_I32, Ity_I64 }, // mips no folding yet
+ { OPNAME(DivModU32to32), Ity_I64, 2, Ity_I32, Ity_I32, ONLY(mipsx) },
{ OPNAME(DivModU64to32), Ity_I64, 2, Ity_I64, Ity_I32, EXCEPT2(ppc, mipsx) },
// { OPNAME(DivModU64to64), Ity_I64, 2, Ity_I64, Ity_I128 }, // 128 bit
// { OPNAME(DivModU128to64), Ity_I128, 2, Ity_I64, Ity_I128 }, // 128 bit
-// { OPNAME(DivModS32to32), Ity_I64, 2, Ity_I32, Ity_I32 }, // mips no folding yet
+ { OPNAME(DivModS32to32), Ity_I64, 2, Ity_I32, Ity_I32, ONLY(mipsx) },
{ OPNAME(DivModS64to32), Ity_I64, 2, Ity_I64, Ity_I32, EXCEPT2(ppc, mipsx) },
// { OPNAME(DivModS64to64), Ity_I64, 2, Ity_I64, Ity_I128 }, // 128 bit
// { OPNAME(DivModU128to64), Ity_I128, 2, Ity_I64, Ity_I128 }, // 128 bit
int
main(int argc, char *argv[])
{
-// FIXME: temporarily until ppc has been fixed
+// FIXME: temporarily until ppc and mips have been fixed
#if !defined(__s390x__) && !defined(__i386__) && !defined(__x86_64__)
return 0;
#endif
#ifdef __s390x__
return op->enabled_arch & ARCH_s390;
#endif
+#ifdef __mips__
+ return op->enabled_arch & ((__mips == 64) ? ARCH_mips64 : ARCH_mips32);
+#endif
#ifdef __powerpc__ /* defined for both 32-bit and 64-bit */
#define MIN_POWER_ISA "../../../tests/min_power_isa"
int rc;