break;
}
+ /* -- Div -- */
+ case Iop_DivS32: {
+ 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)
+ e2 = IRExpr_Const(IRConst_U32(s32a / s32b));
+ break;
+ }
+ case Iop_DivS64: {
+ Long s64a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U64;
+ Long s64b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U64;
+ if (s64b != 0)
+ e2 = IRExpr_Const(IRConst_U64(s64a / s64b));
+ break;
+ }
+ case Iop_DivU32: {
+ 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)
+ e2 = IRExpr_Const(IRConst_U32(u32a / u32b));
+ break;
+ }
+ case Iop_DivU64: {
+ ULong u64a = e->Iex.Binop.arg1->Iex.Const.con->Ico.U64;
+ ULong u64b = e->Iex.Binop.arg2->Iex.Const.con->Ico.U64;
+ if (u64b != 0)
+ e2 = IRExpr_Const(IRConst_U64(u64a / u64b));
+ break;
+ }
+ case Iop_DivS32E: {
+ 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) {
+ Long s64a = (Long)s32a << 32;
+ e2 = IRExpr_Const(IRConst_U32(toUInt(s64a / s32b)));
+ }
+ break;
+ }
+ case Iop_DivU32E: {
+ 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) {
+ ULong u64a = (ULong)u32a << 32;
+ e2 = IRExpr_Const(IRConst_U32(toUInt(u64a / u32b)));
+ }
+ break;
+ }
+
/* -- Shl -- */
case Iop_Shl8:
vassert(e->Iex.Binop.arg2->Iex.Const.con->tag == Ico_U8);
static void run_tests(const irop_t *, test_data_t *);
static void run_shift_tests(const irop_t *, test_data_t *);
static int is_shift_op(IROp);
+static int is_division_op(IROp);
void
for (unsigned j = 0; j < num_val_r; ++j) {
opnd_r->value = values_r[j];
+ if (is_division_op(op->op) && opnd_r->value == 0) continue;
+
valgrind_execute_test(op, data);
check_result(op, data);
}
opnd_l->value = get_random_value(opnd_l->type);
opnd_r->value = get_random_value(opnd_r->type);
+ if (is_division_op(op->op) && opnd_r->value == 0) continue;
+
valgrind_execute_test(op, data);
check_result(op, data);
}
expected = (int64_t)(int32_t)opnd_l * (int64_t)(int32_t)opnd_r;
break;
+ case Iop_DivU32:
+ case Iop_DivU64:
+ expected = opnd_l / opnd_r;
+ break;
+
+ case Iop_DivS32:
+ expected = (int32_t)opnd_l / (int32_t)opnd_r;
+ break;
+
+ case Iop_DivS64:
+ expected = (int64_t)opnd_l / (int64_t)opnd_r;
+ break;
+
+ case Iop_DivU32E:
+ expected = (opnd_l << 32) / opnd_r;
+ break;
+
+ case Iop_DivS32E:
+ expected = (int64_t)(opnd_l << 32) / (int32_t)opnd_r;
+ break;
+
case Iop_Shl8:
case Iop_Shl16:
case Iop_Shl32:
return 0;
}
}
+
+
+static int
+is_division_op(IROp op)
+{
+ switch (op) {
+ case Iop_DivU32: case Iop_DivU64:
+ case Iop_DivS32: case Iop_DivS64:
+ case Iop_DivU32E:
+ case Iop_DivS32E:
+ return 1;
+ default:
+ return 0;
+ }
+}
{ OPNAME(MullS32), Ity_I64, 2, Ity_I32, Ity_I32 },
// { OPNAME(MullS64), Ity_I128, 2, Ity_I64, Ity_I64 }, // 128 bit
-// { OPNAME(DivU32), Ity_I32, 2, Ity_I32, Ity_I32 }, // no folding yet
-// { OPNAME(DivU64), Ity_I64, 2, Ity_I64, Ity_I64 }, // no folding yet
+ { OPNAME(DivU32), Ity_I32, 2, Ity_I32, Ity_I32 },
+ { OPNAME(DivU64), Ity_I64, 2, Ity_I64, Ity_I64 },
// { OPNAME(DivU128), Ity_I128, 2, Ity_I128, Ity_I128 }, // 128 bit
-// { OPNAME(DivS32), Ity_I32, 2, Ity_I32, Ity_I32 }, // no folding yet
-// { OPNAME(DivS64), Ity_I64, 2, Ity_I64, Ity_I64 }, // no folding yet
+ { OPNAME(DivS32), Ity_I32, 2, Ity_I32, Ity_I32 },
+ { OPNAME(DivS64), Ity_I64, 2, Ity_I64, Ity_I64 },
// { OPNAME(DivS128), Ity_I128, 2, Ity_I128, Ity_I128 }, // 128 bit
-// { OPNAME(DivU32E), Ity_I32, 2, Ity_I32, Ity_I32 }, // semantics ?
-// { OPNAME(DivU64E), Ity_I32, 2, Ity_I32, Ity_I32 }, // semantics ?
+ { OPNAME(DivU32E), Ity_I32, 2, Ity_I32, Ity_I32 },
+// { OPNAME(DivU64E), Ity_I64, 2, Ity_I64, Ity_I64 }, // 128 bit
// { OPNAME(DivU128E), Ity_I128, 2, Ity_I128, Ity_I128 }, // 128 bit
-// { OPNAME(DivS32E), Ity_I32, 2, Ity_I32, Ity_I32 }, // semantics ?
-// { OPNAME(DivS64E), Ity_I32, 2, Ity_I32, Ity_I32 }, // semantics ?
+ { OPNAME(DivS32E), Ity_I32, 2, Ity_I32, Ity_I32 },
+// { 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 }, // no folding yet