Commit e6cd991b authored by Milad Farazmand's avatar Milad Farazmand Committed by Commit Bot

S390: [wasm-simd] Implement f32x4 and f64x2 pmin and pmax

Change-Id: I395471a93b6df55ae8d45b7627b23067ae208f54
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2226552
Commit-Queue: Deepti Gandluri <gdeepti@chromium.org>
Reviewed-by: 's avatarDeepti Gandluri <gdeepti@chromium.org>
Reviewed-by: 's avatarJunliang Yan <jyan@ca.ibm.com>
Reviewed-by: 's avatarZhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68154}
parent f38e4e5f
......@@ -2661,14 +2661,14 @@ void InstructionSelector::VisitI64x2MaxU(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_S390X
#if !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_IA32 && \
!V8_TARGET_ARCH_X64
!V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_S390X
// TODO(v8:10501) Prototyping pmin and pmax instructions.
void InstructionSelector::VisitF32x4Pmin(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4Pmax(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Pmin(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF64x2Pmax(Node* node) { UNIMPLEMENTED(); }
#endif // !V8_TARGET_ARCH_ARM64 && !V8_TARGET_ARCH_ARM && !V8_TARGET_ARCH_IA32
// && !V8_TARGET_ARCH_X64
// && !V8_TARGET_ARCH_X64 && !V8_TARGET_ARCH_S390X
#if !V8_TARGET_ARCH_X64
// TODO(v8:10553) Prototyping floating point rounding instructions.
......
......@@ -4234,6 +4234,30 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Condition(1));
break;
}
case kS390_F32x4Pmin: {
__ vfmin(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1), Condition(3), Condition(0),
Condition(2));
break;
}
case kS390_F32x4Pmax: {
__ vfmax(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1), Condition(3), Condition(0),
Condition(2));
break;
}
case kS390_F64x2Pmin: {
__ vfmin(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1), Condition(3), Condition(0),
Condition(3));
break;
}
case kS390_F64x2Pmax: {
__ vfmax(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputSimd128Register(1), Condition(3), Condition(0),
Condition(3));
break;
}
case kS390_StoreCompressTagged: {
CHECK(!instr->HasOutput());
size_t index = 0;
......
......@@ -215,6 +215,8 @@ namespace compiler {
V(S390_F64x2ExtractLane) \
V(S390_F64x2Qfma) \
V(S390_F64x2Qfms) \
V(S390_F64x2Pmin) \
V(S390_F64x2Pmax) \
V(S390_F32x4Splat) \
V(S390_F32x4ExtractLane) \
V(S390_F32x4ReplaceLane) \
......@@ -238,6 +240,8 @@ namespace compiler {
V(S390_F32x4Max) \
V(S390_F32x4Qfma) \
V(S390_F32x4Qfms) \
V(S390_F32x4Pmin) \
V(S390_F32x4Pmax) \
V(S390_I64x2Neg) \
V(S390_I64x2Add) \
V(S390_I64x2Sub) \
......
......@@ -161,6 +161,8 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kS390_F64x2ExtractLane:
case kS390_F64x2Qfma:
case kS390_F64x2Qfms:
case kS390_F64x2Pmin:
case kS390_F64x2Pmax:
case kS390_F32x4Splat:
case kS390_F32x4ExtractLane:
case kS390_F32x4ReplaceLane:
......@@ -184,6 +186,8 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kS390_F32x4Max:
case kS390_F32x4Qfma:
case kS390_F32x4Qfms:
case kS390_F32x4Pmin:
case kS390_F32x4Pmax:
case kS390_I64x2Neg:
case kS390_I64x2Add:
case kS390_I64x2Sub:
......
......@@ -2805,6 +2805,18 @@ SIMD_VISIT_BITMASK(I8x16BitMask)
SIMD_VISIT_BITMASK(I16x8BitMask)
SIMD_VISIT_BITMASK(I32x4BitMask)
#undef SIMD_VISIT_BITMASK
#define SIMD_VISIT_PMIN_MAX(Type) \
void InstructionSelector::Visit##Type(Node* node) { \
S390OperandGenerator g(this); \
Emit(kS390_##Type, g.DefineAsRegister(node), \
g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); \
}
SIMD_VISIT_PMIN_MAX(F64x2Pmin)
SIMD_VISIT_PMIN_MAX(F32x4Pmin)
SIMD_VISIT_PMIN_MAX(F64x2Pmax)
SIMD_VISIT_PMIN_MAX(F32x4Pmax)
#undef SIMD_VISIT_PMIN_MAX
#undef SIMD_TYPES
void InstructionSelector::VisitS8x16Shuffle(Node* node) {
......
......@@ -4006,33 +4006,35 @@ EVALUATE(VFNMS) {
#undef VECTOR_FP_MULTIPLY_QFMS_OPERATION
template <class T, class Operation>
void VectorFPMaxMin(void* dst, void* src1, void* src2, Operation op) {
void VectorFPMaxMin(void* dst, void* src1, void* src2, int mode, Operation op) {
T* dst_ptr = reinterpret_cast<T*>(dst);
T* src1_ptr = reinterpret_cast<T*>(src1);
T* src2_ptr = reinterpret_cast<T*>(src2);
for (size_t i = 0; i < kSimd128Size / sizeof(T); i++) {
T src1_val = *(src1_ptr + i);
T src2_val = *(src2_ptr + i);
T value = op(src1_val, src2_val);
// using Java's Max Min functions
if (isnan(src1_val) || isnan(src2_val)) {
value = NAN;
}
T value = op(src1_val, src2_val, mode);
memcpy(dst_ptr + i, &value, sizeof(T));
}
}
#define VECTOR_FP_MAX_MIN_FOR_TYPE(type, op) \
#define VECTOR_FP_MAX_MIN_FOR_TYPE(type, op, std_op) \
VectorFPMaxMin<type>(&get_simd_register(r1), &get_simd_register(r2), \
&get_simd_register(r3), [](type a, type b) { \
if (signbit(b) op signbit(a)) \
&get_simd_register(r3), m6, \
[](type a, type b, int mode) { \
if (mode == 3) { \
return std::std_op(a, b); \
} \
if (isnan(a) || isnan(b)) \
return static_cast<type>(NAN); \
else if (signbit(b) op signbit(a)) \
return a; \
else if (signbit(b) != signbit(a)) \
return b; \
return (a op b) ? a : b; \
});
#define VECTOR_FP_MAX_MIN(op) \
#define VECTOR_FP_MAX_MIN(op, std_op) \
switch (m4) { \
case 2: \
if (m5 == 8) { \
......@@ -4041,8 +4043,7 @@ void VectorFPMaxMin(void* dst, void* src1, void* src2, Operation op) {
set_simd_register_by_lane<float>(r1, 0, (src1 op src2) ? src1 : src2); \
} else { \
DCHECK_EQ(m5, 0); \
DCHECK_EQ(m6, 1); \
VECTOR_FP_MAX_MIN_FOR_TYPE(float, op) \
VECTOR_FP_MAX_MIN_FOR_TYPE(float, op, std_op) \
} \
break; \
case 3: \
......@@ -4053,8 +4054,7 @@ void VectorFPMaxMin(void* dst, void* src1, void* src2, Operation op) {
(src1 op src2) ? src1 : src2); \
} else { \
DCHECK_EQ(m5, 0); \
DCHECK_EQ(m6, 1); \
VECTOR_FP_MAX_MIN_FOR_TYPE(double, op) \
VECTOR_FP_MAX_MIN_FOR_TYPE(double, op, std_op) \
} \
break; \
default: \
......@@ -4066,8 +4066,7 @@ EVALUATE(VFMIN) {
DCHECK(CpuFeatures::IsSupported(VECTOR_ENHANCE_FACILITY_1));
DCHECK_OPCODE(VFMIN);
DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4);
USE(m6);
VECTOR_FP_MAX_MIN(<) // NOLINT
VECTOR_FP_MAX_MIN(<, min) // NOLINT
return length;
}
......@@ -4076,7 +4075,7 @@ EVALUATE(VFMAX) {
DCHECK_OPCODE(VFMAX);
DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4);
USE(m6);
VECTOR_FP_MAX_MIN(>) // NOLINT
VECTOR_FP_MAX_MIN(>, max) // NOLINT
return length;
}
......
......@@ -783,7 +783,7 @@ WASM_SIMD_TEST(F32x4Max) {
// TODO(v8:10501) Prototyping pmin and pmax instructions.
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64 || \
V8_TARGET_ARCH_ARM
V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_S390X
WASM_SIMD_TEST_NO_LOWERING(F32x4Pmin) {
FLAG_SCOPE(wasm_simd_post_mvp);
RunF32x4BinOpTest(execution_tier, lower_simd, kExprF32x4Pmin, Minimum);
......@@ -794,7 +794,7 @@ WASM_SIMD_TEST_NO_LOWERING(F32x4Pmax) {
RunF32x4BinOpTest(execution_tier, lower_simd, kExprF32x4Pmax, Maximum);
}
#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64 ||
// V8_TARGET_ARCH_ARM
// V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_S390X
void RunF32x4CompareOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode opcode, FloatCompareOp expected_op) {
......@@ -1388,7 +1388,7 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2Div) {
// TODO(v8:10501) Prototyping pmin and pmax instructions.
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64 || \
V8_TARGET_ARCH_ARM
V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_S390X
WASM_SIMD_TEST_NO_LOWERING(F64x2Pmin) {
FLAG_SCOPE(wasm_simd_post_mvp);
RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Pmin, Minimum);
......@@ -1399,7 +1399,7 @@ WASM_SIMD_TEST_NO_LOWERING(F64x2Pmax) {
RunF64x2BinOpTest(execution_tier, lower_simd, kExprF64x2Pmax, Maximum);
}
#endif // V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_ARM64 ||
// V8_TARGET_ARCH_ARM
// V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_S390X
void RunF64x2CompareOpTest(ExecutionTier execution_tier, LowerSimd lower_simd,
WasmOpcode opcode, DoubleCompareOp expected_op) {
......
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