/* We right-shift by left-shifting by 32 - shift and taking the top 32 bits
* of the result. This assumes the top 32 bits are zero.
*/
+ if (shift > 64)
+ return gen_mi_imm(0);
+
+ if (shift > 32) {
+ struct gen_mi_value tmp = gen_mi_new_gpr(b);
+ _gen_mi_copy_no_unref(b, gen_mi_value_half(tmp, false),
+ gen_mi_value_half(src, true));
+ _gen_mi_copy_no_unref(b, gen_mi_value_half(tmp, true), gen_mi_imm(0));
+ gen_mi_value_unref(b, src);
+ src = tmp;
+ shift -= 32;
+ }
assert(shift <= 32);
struct gen_mi_value tmp = gen_mi_ishl_imm(b, src, 32 - shift);
struct gen_mi_value dst = gen_mi_new_gpr(b);
const uint64_t value = 0x0123456789abcdef;
memcpy(input, &value, sizeof(value));
- const unsigned max_shift = 31;
+ const unsigned max_shift = 64;
for (unsigned i = 0; i <= max_shift; i++)
gen_mi_store(&b, out_mem64(i * 8), gen_mi_ushr32_imm(&b, in_mem64(0), i));
submit_batch();
- for (unsigned i = 0; i <= max_shift; i++)
- EXPECT_EQ(*(uint64_t *)(output + i * 8), (value >> i) & UINT32_MAX);
+ for (unsigned i = 0; i <= max_shift; i++) {
+ if (i >= 64) {
+ EXPECT_EQ(*(uint64_t *)(output + i * 8), 0);
+ } else {
+ EXPECT_EQ(*(uint64_t *)(output + i * 8), (value >> i) & UINT32_MAX);
+ }
+ }
}
TEST_F(gen_mi_builder_test, udiv32_imm)