// significant bits.
Int32BinopMatcher mleft(m.left().node());
if (mleft.right().IsInRange(0, 31)) {
+ // Ubfx cannot extract bits past the register size, however since
+ // shifting the original value would have introduced some zeros we can
+ // still use ubfx with a smaller mask and the remaining bits will be
+ // zeros.
+ uint32_t lsb = mleft.right().Value();
+ if (lsb + mask_width > 32) mask_width = 32 - lsb;
+
Emit(kArm64Ubfx32, g.DefineAsRegister(node),
g.UseRegister(mleft.left().node()),
g.UseImmediate(mleft.right().node()), g.TempImmediate(mask_width));
// significant bits.
Int64BinopMatcher mleft(m.left().node());
if (mleft.right().IsInRange(0, 63)) {
+ // Ubfx cannot extract bits past the register size, however since
+ // shifting the original value would have introduced some zeros we can
+ // still use ubfx with a smaller mask and the remaining bits will be
+ // zeros.
+ uint64_t lsb = mleft.right().Value();
+ if (lsb + mask_width > 64) mask_width = 64 - lsb;
+
Emit(kArm64Ubfx, g.DefineAsRegister(node),
g.UseRegister(mleft.left().node()),
g.UseImmediate(mleft.right().node()), g.TempImmediate(mask_width));
'unicodelctest-no-optimization': [PASS, SLOW],
'unicodelctest': [PASS, SLOW],
'unicode-test': [PASS, SLOW],
-
- # TODO(bmeurer, Rodolph.Perfetta@arm.com): Fails with turbo fan.
- 'numops-fuzz-part1': [PASS, NO_VARIANTS],
- 'numops-fuzz-part2': [PASS, NO_VARIANTS],
}], # 'arch == arm64'
['arch == arm64 and mode == debug and simulator_run == True', {
EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
ASSERT_EQ(3U, s[0]->InputCount());
EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
- EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
+ int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width;
+ EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2)));
}
}
TRACED_FORRANGE(int32_t, lsb, 1, 31) {
EXPECT_EQ(kArm64Ubfx32, s[0]->arch_opcode());
ASSERT_EQ(3U, s[0]->InputCount());
EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1)));
- EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2)));
+ int32_t actual_width = (lsb + width > 32) ? (32 - lsb) : width;
+ EXPECT_EQ(actual_width, s.ToInt32(s[0]->InputAt(2)));
}
}
}
TEST_F(InstructionSelectorTest, Word64AndWithImmediateWithWord64Shr) {
- TRACED_FORRANGE(int32_t, lsb, 1, 31) {
- TRACED_FORRANGE(int32_t, width, 1, 31) {
+ TRACED_FORRANGE(int64_t, lsb, 1, 63) {
+ TRACED_FORRANGE(int64_t, width, 1, 63) {
uint64_t msk = (V8_UINT64_C(1) << width) - 1;
StreamBuilder m(this, kMachInt64, kMachInt64);
m.Return(m.Word64And(m.Word64Shr(m.Parameter(0), m.Int64Constant(lsb)),
EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode());
ASSERT_EQ(3U, s[0]->InputCount());
EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1)));
- EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2)));
+ int64_t actual_width = (lsb + width > 64) ? (64 - lsb) : width;
+ EXPECT_EQ(actual_width, s.ToInt64(s[0]->InputAt(2)));
}
}
- TRACED_FORRANGE(int32_t, lsb, 1, 31) {
- TRACED_FORRANGE(int32_t, width, 1, 31) {
+ TRACED_FORRANGE(int64_t, lsb, 1, 63) {
+ TRACED_FORRANGE(int64_t, width, 1, 63) {
uint64_t msk = (V8_UINT64_C(1) << width) - 1;
StreamBuilder m(this, kMachInt64, kMachInt64);
m.Return(m.Word64And(m.Int64Constant(msk),
EXPECT_EQ(kArm64Ubfx, s[0]->arch_opcode());
ASSERT_EQ(3U, s[0]->InputCount());
EXPECT_EQ(lsb, s.ToInt64(s[0]->InputAt(1)));
- EXPECT_EQ(width, s.ToInt64(s[0]->InputAt(2)));
+ int64_t actual_width = (lsb + width > 64) ? (64 - lsb) : width;
+ EXPECT_EQ(actual_width, s.ToInt64(s[0]->InputAt(2)));
}
}
}