Commit 6243a86a authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm-simd] Move more helper functions into simd-shuffle

Also add some simple unittests for these functions.

Bug: v8:10696
Change-Id: Ic7607780b4eaf275b20d0937bf214846bf51d539
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2330806Reviewed-by: 's avatarBill Budge <bbudge@chromium.org>
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69183}
parent 67bd376c
......@@ -2890,7 +2890,7 @@ void InstructionSelector::VisitS8x16Shuffle(Node* node) {
InstructionOperand src0 = g.UseUniqueRegister(input0);
InstructionOperand src1 = is_swizzle ? src0 : g.UseUniqueRegister(input1);
Emit(kArmS32x4Shuffle, g.DefineAsRegister(node), src0, src1,
g.UseImmediate(Pack4Lanes(shuffle32x4)));
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle32x4)));
}
return;
}
......@@ -2922,10 +2922,10 @@ void InstructionSelector::VisitS8x16Shuffle(Node* node) {
InstructionOperand src0, src1;
ArrangeShuffleTable(&g, input0, input1, &src0, &src1);
Emit(kArmS8x16Shuffle, g.DefineAsRegister(node), src0, src1,
g.UseImmediate(Pack4Lanes(shuffle)),
g.UseImmediate(Pack4Lanes(shuffle + 4)),
g.UseImmediate(Pack4Lanes(shuffle + 8)),
g.UseImmediate(Pack4Lanes(shuffle + 12)));
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 4)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 8)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 12)));
}
void InstructionSelector::VisitS8x16Swizzle(Node* node) {
......
......@@ -3624,7 +3624,8 @@ void InstructionSelector::VisitS8x16Shuffle(Node* node) {
EmitIdentity(node);
} else {
Emit(kArm64S32x4Shuffle, g.DefineAsRegister(node), g.UseRegister(input0),
g.UseRegister(input1), g.UseImmediate(Pack4Lanes(shuffle32x4)));
g.UseRegister(input1),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle32x4)));
}
return;
}
......@@ -3644,10 +3645,10 @@ void InstructionSelector::VisitS8x16Shuffle(Node* node) {
InstructionOperand src0, src1;
ArrangeShuffleTable(&g, input0, input1, &src0, &src1);
Emit(kArm64S8x16Shuffle, g.DefineAsRegister(node), src0, src1,
g.UseImmediate(Pack4Lanes(shuffle)),
g.UseImmediate(Pack4Lanes(shuffle + 4)),
g.UseImmediate(Pack4Lanes(shuffle + 8)),
g.UseImmediate(Pack4Lanes(shuffle + 12)));
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 4)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 8)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 12)));
}
void InstructionSelector::VisitSignExtendWord8ToInt32(Node* node) {
......
......@@ -2808,10 +2808,10 @@ void InstructionSelector::VisitS8x16Shuffle(Node* node) {
// Use same-as-first for general swizzle, but not shuffle.
no_same_as_first = !is_swizzle;
src0_needs_reg = !no_same_as_first;
imms[imm_count++] = Pack4Lanes(shuffle);
imms[imm_count++] = Pack4Lanes(shuffle + 4);
imms[imm_count++] = Pack4Lanes(shuffle + 8);
imms[imm_count++] = Pack4Lanes(shuffle + 12);
imms[imm_count++] = wasm::SimdShuffle::Pack4Lanes(shuffle);
imms[imm_count++] = wasm::SimdShuffle::Pack4Lanes(shuffle + 4);
imms[imm_count++] = wasm::SimdShuffle::Pack4Lanes(shuffle + 8);
imms[imm_count++] = wasm::SimdShuffle::Pack4Lanes(shuffle + 12);
temps[temp_count++] = g.TempRegister();
}
......
......@@ -3184,15 +3184,6 @@ void InstructionSelector::SwapShuffleInputs(Node* node) {
}
// static
int32_t InstructionSelector::Pack4Lanes(const uint8_t* shuffle) {
int32_t result = 0;
for (int i = 3; i >= 0; --i) {
result <<= 8;
result |= shuffle[i];
}
return result;
}
bool InstructionSelector::NeedsPoisoning(IsSafetyCheck safety_check) const {
switch (poisoning_level_) {
case PoisoningMitigationLevel::kDontPoison:
......
......@@ -636,9 +636,6 @@ class V8_EXPORT_PRIVATE InstructionSelector final {
// to specific architectural instructions.
void SwapShuffleInputs(Node* node);
// Packs 4 bytes of shuffle into a 32 bit immediate.
static int32_t Pack4Lanes(const uint8_t* shuffle);
// ===========================================================================
Schedule* schedule() const { return schedule_; }
......
......@@ -2400,14 +2400,16 @@ void InstructionSelector::VisitS8x16Shuffle(Node* node) {
}
if (wasm::SimdShuffle::TryMatch32x4Shuffle(shuffle, shuffle32x4)) {
Emit(kMipsS32x4Shuffle, g.DefineAsRegister(node), g.UseRegister(input0),
g.UseRegister(input1), g.UseImmediate(Pack4Lanes(shuffle32x4)));
g.UseRegister(input1),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle32x4)));
return;
}
Emit(kMipsS8x16Shuffle, g.DefineAsRegister(node), g.UseRegister(input0),
g.UseRegister(input1), g.UseImmediate(Pack4Lanes(shuffle)),
g.UseImmediate(Pack4Lanes(shuffle + 4)),
g.UseImmediate(Pack4Lanes(shuffle + 8)),
g.UseImmediate(Pack4Lanes(shuffle + 12)));
g.UseRegister(input1),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 4)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 8)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 12)));
}
void InstructionSelector::VisitS8x16Swizzle(Node* node) {
......
......@@ -3095,14 +3095,16 @@ void InstructionSelector::VisitS8x16Shuffle(Node* node) {
}
if (wasm::SimdShuffle::TryMatch32x4Shuffle(shuffle, shuffle32x4)) {
Emit(kMips64S32x4Shuffle, g.DefineAsRegister(node), g.UseRegister(input0),
g.UseRegister(input1), g.UseImmediate(Pack4Lanes(shuffle32x4)));
g.UseRegister(input1),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle32x4)));
return;
}
Emit(kMips64S8x16Shuffle, g.DefineAsRegister(node), g.UseRegister(input0),
g.UseRegister(input1), g.UseImmediate(Pack4Lanes(shuffle)),
g.UseImmediate(Pack4Lanes(shuffle + 4)),
g.UseImmediate(Pack4Lanes(shuffle + 8)),
g.UseImmediate(Pack4Lanes(shuffle + 12)));
g.UseRegister(input1),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 4)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 8)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle + 12)));
}
void InstructionSelector::VisitS8x16Swizzle(Node* node) {
......
......@@ -2377,10 +2377,10 @@ void InstructionSelector::VisitS8x16Shuffle(Node* node) {
}
Emit(kPPC_S8x16Shuffle, g.DefineAsRegister(node), g.UseUniqueRegister(input0),
g.UseUniqueRegister(input1),
g.UseImmediate(Pack4Lanes(shuffle_remapped)),
g.UseImmediate(Pack4Lanes(shuffle_remapped + 4)),
g.UseImmediate(Pack4Lanes(shuffle_remapped + 8)),
g.UseImmediate(Pack4Lanes(shuffle_remapped + 12)));
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle_remapped)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle_remapped + 4)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle_remapped + 8)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle_remapped + 12)));
}
void InstructionSelector::VisitS128Zero(Node* node) {
......
......@@ -2851,10 +2851,10 @@ void InstructionSelector::VisitS8x16Shuffle(Node* node) {
#endif
Emit(kS390_S8x16Shuffle, g.DefineAsRegister(node),
g.UseUniqueRegister(input0), g.UseUniqueRegister(input1),
g.UseImmediate(Pack4Lanes(shuffle_p)),
g.UseImmediate(Pack4Lanes(shuffle_p + 4)),
g.UseImmediate(Pack4Lanes(shuffle_p + 8)),
g.UseImmediate(Pack4Lanes(shuffle_p + 12)));
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle_p)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle_p + 4)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle_p + 8)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(shuffle_p + 12)));
}
void InstructionSelector::VisitS8x16Swizzle(Node* node) {
......@@ -2881,10 +2881,14 @@ void InstructionSelector::VisitS128Const(Node* node) {
// We have to use Pack4Lanes to reverse the bytes (lanes) on BE,
// Which in this case is ineffective on LE.
Emit(kS390_S128Const, g.DefineAsRegister(node),
g.UseImmediate(Pack4Lanes(reinterpret_cast<uint8_t*>(val))),
g.UseImmediate(Pack4Lanes(reinterpret_cast<uint8_t*>(val) + 4)),
g.UseImmediate(Pack4Lanes(reinterpret_cast<uint8_t*>(val) + 8)),
g.UseImmediate(Pack4Lanes(reinterpret_cast<uint8_t*>(val) + 12)));
g.UseImmediate(
wasm::SimdShuffle::Pack4Lanes(reinterpret_cast<uint8_t*>(val))),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(
reinterpret_cast<uint8_t*>(val) + 4)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(
reinterpret_cast<uint8_t*>(val) + 8)),
g.UseImmediate(wasm::SimdShuffle::Pack4Lanes(
reinterpret_cast<uint8_t*>(val) + 12)));
}
}
......
......@@ -3378,10 +3378,10 @@ void InstructionSelector::VisitS8x16Shuffle(Node* node) {
// Use same-as-first for general swizzle, but not shuffle.
no_same_as_first = !is_swizzle;
src0_needs_reg = !no_same_as_first;
imms[imm_count++] = Pack4Lanes(shuffle);
imms[imm_count++] = Pack4Lanes(shuffle + 4);
imms[imm_count++] = Pack4Lanes(shuffle + 8);
imms[imm_count++] = Pack4Lanes(shuffle + 12);
imms[imm_count++] = wasm::SimdShuffle::Pack4Lanes(shuffle);
imms[imm_count++] = wasm::SimdShuffle::Pack4Lanes(shuffle + 4);
imms[imm_count++] = wasm::SimdShuffle::Pack4Lanes(shuffle + 8);
imms[imm_count++] = wasm::SimdShuffle::Pack4Lanes(shuffle + 12);
temps[temp_count++] = g.TempSimd128Register();
}
......
......@@ -127,6 +127,15 @@ uint8_t SimdShuffle::PackBlend4(const uint8_t* shuffle32x4) {
return result;
}
int32_t SimdShuffle::Pack4Lanes(const uint8_t* shuffle) {
int32_t result = 0;
for (int i = 3; i >= 0; --i) {
result <<= 8;
result |= shuffle[i];
}
return result;
}
} // namespace wasm
} // namespace internal
} // namespace v8
......@@ -80,6 +80,8 @@ class V8_EXPORT_PRIVATE SimdShuffle {
static uint8_t PackBlend8(const uint8_t* shuffle16x8);
// Gets an 8 bit lane mask suitable for 32x4 pblendw.
static uint8_t PackBlend4(const uint8_t* shuffle32x4);
// Packs 4 bytes of shuffle into a 32 bit immediate.
static int32_t Pack4Lanes(const uint8_t* shuffle);
};
} // namespace wasm
} // namespace internal
......
......@@ -252,6 +252,26 @@ TEST_F(SimdShuffleTest, TryMatchBlend) {
{{1, 17, 2, 19, 4, 21, 6, 23, 8, 25, 10, 27, 12, 29, 14, 31}}));
}
TEST(SimdShufflePackTest, PackShuffle4) {
uint8_t arr[4]{0b0001, 0b0010, 0b0100, 0b1000};
EXPECT_EQ(0b00001001, SimdShuffle::PackShuffle4(arr));
}
TEST(SimdShufflePackTest, PackBlend8) {
uint8_t arr[8]{0, 2, 4, 6, 8, 10, 12, 14};
EXPECT_EQ(0b11110000, SimdShuffle::PackBlend8(arr));
}
TEST(SimdShufflePackTest, PackBlend4) {
uint8_t arr[4]{0, 2, 4, 6};
EXPECT_EQ(0b11110000, SimdShuffle::PackBlend4(arr));
}
TEST(SimdShufflePackTest, Pack4Lanes) {
uint8_t arr[4]{0x01, 0x08, 0xa0, 0x7c};
EXPECT_EQ(0x7ca00801, SimdShuffle::Pack4Lanes(arr));
}
} // namespace wasm
} // namespace internal
} // namespace v8
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment