[wasm-simd] Implement v128.const for arm

And removed the ifdef guards around instruction-selector and
tests since v128.const is now implemented for x86, x64, arm, arm64.

Bug: v8:8460
Change-Id: I0ed8aede0a07db2fd286bf0c3385eba1079558f8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2285149
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: Bill Budge <bbudge@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68745}
This commit is contained in:
Ng Zhi An 2020-07-07 18:35:04 -07:00 committed by Commit Bot
parent 07585a342f
commit d0e6ff154c
9 changed files with 47 additions and 13 deletions

View File

@ -2813,11 +2813,26 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ vmov(NeonU16, dst, tmp2.low(), 0);
break;
}
case kArmS128Const: {
QwNeonRegister dst = i.OutputSimd128Register();
uint64_t imm1 =
i.InputInt32(0) | (static_cast<uint64_t>(i.InputInt32(1)) << 32);
uint64_t imm2 =
i.InputInt32(2) | (static_cast<uint64_t>(i.InputInt32(3)) << 32);
__ vmov(dst.low(), Double(imm1));
__ vmov(dst.high(), Double(imm2));
break;
}
case kArmS128Zero: {
__ veor(i.OutputSimd128Register(), i.OutputSimd128Register(),
i.OutputSimd128Register());
break;
}
case kArmS128AllOnes: {
__ vceq(i.OutputSimd128Register(), i.OutputSimd128Register(),
i.OutputSimd128Register());
break;
}
case kArmS128Dup: {
NeonSize size = static_cast<NeonSize>(i.InputInt32(1));
int lanes = kSimd128Size >> size;

View File

@ -277,7 +277,9 @@ namespace compiler {
V(ArmI8x16RoundingAverageU) \
V(ArmI8x16Abs) \
V(ArmI8x16BitMask) \
V(ArmS128Const) \
V(ArmS128Zero) \
V(ArmS128AllOnes) \
V(ArmS128Dup) \
V(ArmS128And) \
V(ArmS128Or) \

View File

@ -257,7 +257,9 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kArmI8x16RoundingAverageU:
case kArmI8x16Abs:
case kArmI8x16BitMask:
case kArmS128Const:
case kArmS128Zero:
case kArmS128AllOnes:
case kArmS128Dup:
case kArmS128And:
case kArmS128Or:

View File

@ -2650,6 +2650,25 @@ void InstructionSelector::VisitI32x4DotI16x8S(Node* node) {
g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps);
}
void InstructionSelector::VisitS128Const(Node* node) {
ArmOperandGenerator g(this);
uint32_t val[kSimd128Size / sizeof(uint32_t)];
memcpy(val, S128ImmediateParameterOf(node->op()).data(), kSimd128Size);
// If all bytes are zeros, avoid emitting code for generic constants.
bool all_zeros = !(val[0] || val[1] || val[2] || val[3]);
bool all_ones = val[0] == UINT32_MAX && val[1] == UINT32_MAX &&
val[2] == UINT32_MAX && val[3] == UINT32_MAX;
InstructionOperand dst = g.DefineAsRegister(node);
if (all_zeros) {
Emit(kArmS128Zero, dst);
} else if (all_ones) {
Emit(kArmS128AllOnes, dst);
} else {
Emit(kArmS128Const, dst, g.UseImmediate(val[0]), g.UseImmediate(val[1]),
g.UseImmediate(val[2]), g.UseImmediate(val[3]));
}
}
void InstructionSelector::VisitS128Zero(Node* node) {
ArmOperandGenerator g(this);
Emit(kArmS128Zero, g.DefineAsRegister(node));

View File

@ -3317,7 +3317,7 @@ void InstructionSelector::VisitS128Const(Node* node) {
STATIC_ASSERT(sizeof(val) == kSimd128Size);
memcpy(val, S128ImmediateParameterOf(node->op()).data(), kSimd128Size);
// If all bytes are zeros, avoid emitting code for generic constants
bool all_zeros = !(val[0] && val[1] && val[2] && val[3]);
bool all_zeros = !(val[0] || val[1] || val[2] || val[3]);
InstructionOperand dst = g.DefineAsRegister(node);
if (all_zeros) {
Emit(kArm64S128Zero, dst);

View File

@ -2187,7 +2187,7 @@ void InstructionSelector::VisitS128Const(Node* node) {
uint32_t val[kUint32Immediates];
memcpy(val, S128ImmediateParameterOf(node->op()).data(), kSimd128Size);
// If all bytes are zeros or ones, avoid emitting code for generic constants
bool all_zeros = !(val[0] && val[1] && val[2] && val[3]);
bool all_zeros = !(val[0] || val[1] || val[2] || val[3]);
bool all_ones = val[0] == UINT32_MAX && val[1] == UINT32_MAX &&
val[2] == UINT32_MAX && val[3] == UINT32_MAX;
InstructionOperand dst = g.DefineAsRegister(node);

View File

@ -2712,12 +2712,6 @@ void InstructionSelector::VisitI32x4DotI16x8S(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_IA32 && !V8_TARGET_ARCH_ARM64
// && !V8_TARGET_ARCH_ARM
#if !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_S390X && \
!V8_TARGET_ARCH_IA32
void InstructionSelector::VisitS128Const(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_S390X
// && !V8_TARGET_ARCH_IA32
void InstructionSelector::VisitFinishRegion(Node* node) { EmitIdentity(node); }
void InstructionSelector::VisitParameter(Node* node) {

View File

@ -2815,7 +2815,7 @@ void InstructionSelector::VisitS128Const(Node* node) {
uint32_t val[kUint32Immediates];
memcpy(val, S128ImmediateParameterOf(node->op()).data(), kSimd128Size);
// If all bytes are zeros or ones, avoid emitting code for generic constants
bool all_zeros = !(val[0] && val[1] && val[2] && val[3]);
bool all_zeros = !(val[0] || val[1] || val[2] || val[3]);
bool all_ones = val[0] == UINT32_MAX && val[1] == UINT32_MAX &&
val[2] == UINT32_MAX && val[3] == UINT32_MAX;
InstructionOperand dst = g.DefineAsRegister(node);

View File

@ -3688,8 +3688,6 @@ void RunSimdConstTest(ExecutionTier execution_tier, LowerSimd lower_simd,
}
}
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_S390X || \
V8_TARGET_ARCH_IA32
WASM_SIMD_TEST_NO_LOWERING(S128Const) {
std::array<uint8_t, kSimd128Size> expected;
// Test for generic constant
@ -3706,6 +3704,12 @@ WASM_SIMD_TEST_NO_LOWERING(S128ConstAllZero) {
expected[i] = 0;
}
RunSimdConstTest(execution_tier, lower_simd, expected);
// Keep the first 4 lanes as 0, set the remaining ones.
for (int i = 4; i < kSimd128Size; i++) {
expected[i] = i;
}
RunSimdConstTest(execution_tier, lower_simd, expected);
}
WASM_SIMD_TEST_NO_LOWERING(S128ConstAllOnes) {
@ -3716,8 +3720,6 @@ WASM_SIMD_TEST_NO_LOWERING(S128ConstAllOnes) {
}
RunSimdConstTest(execution_tier, lower_simd, expected);
}
#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_S390X ||
// V8_TARGET_ARCH_IA32
void RunI8x16MixedRelationalOpTest(ExecutionTier execution_tier,
LowerSimd lower_simd, WasmOpcode opcode,