[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:
parent
07585a342f
commit
d0e6ff154c
@ -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;
|
||||
|
@ -277,7 +277,9 @@ namespace compiler {
|
||||
V(ArmI8x16RoundingAverageU) \
|
||||
V(ArmI8x16Abs) \
|
||||
V(ArmI8x16BitMask) \
|
||||
V(ArmS128Const) \
|
||||
V(ArmS128Zero) \
|
||||
V(ArmS128AllOnes) \
|
||||
V(ArmS128Dup) \
|
||||
V(ArmS128And) \
|
||||
V(ArmS128Or) \
|
||||
|
@ -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:
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user