Commit edb6a55c authored by Junliang Yan's avatar Junliang Yan Committed by Commit Bot

s390x: cleanup and unify vfmin/vfmax simulation

Change-Id: Ia2b9861e720cb2d2ce1d0d88867f31467798278d
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2569771Reviewed-by: 's avatarMilad Fa <mfarazma@redhat.com>
Commit-Queue: Junliang Yan <junyan@redhat.com>
Cr-Commit-Position: refs/heads/master@{#71596}
parent c186b0be
...@@ -4004,64 +4004,112 @@ EVALUATE(VFNMS) { ...@@ -4004,64 +4004,112 @@ EVALUATE(VFNMS) {
#undef VECTOR_FP_MULTIPLY_QFMS #undef VECTOR_FP_MULTIPLY_QFMS
#undef VECTOR_FP_MULTIPLY_QFMS_OPERATION #undef VECTOR_FP_MULTIPLY_QFMS_OPERATION
template <class T, class Operation> template <class FP_Type>
void VectorFPMaxMin(Simulator* sim, int dst, int src1, int src2, int mode, static FP_Type JavaMathMax(FP_Type x, FP_Type y) {
Operation op) { if (std::isnan(x) || std::isnan(y)) return NAN;
for (size_t i = 0; i < kSimd128Size / sizeof(T); i++) { if (std::signbit(x) < std::signbit(y)) return x;
T src1_val = sim->get_simd_register_by_lane<T>(src1, i); return x > y ? x : y;
T src2_val = sim->get_simd_register_by_lane<T>(src2, i); }
T value = op(src1_val, src2_val, mode);
sim->set_simd_register_by_lane<T>(dst, i, value); template <class FP_Type>
static FP_Type IEEE_maxNum(FP_Type x, FP_Type y) {
if (x > y) return x;
if (x < y) return y;
if (x == y) return x;
if (!std::isnan(x)) return x;
if (!std::isnan(y)) return y;
return NAN;
}
template <class FP_Type>
static FP_Type FPMax(int m6, FP_Type lhs, FP_Type rhs) {
switch (m6) {
case 0:
return IEEE_maxNum(lhs, rhs);
case 1:
return JavaMathMax(lhs, rhs);
case 3:
return std::max(lhs, rhs);
case 4:
return std::fmax(lhs, rhs);
default:
UNIMPLEMENTED();
} }
return static_cast<FP_Type>(0);
} }
#define VECTOR_FP_MAX_MIN_FOR_TYPE(type, op, std_op) \ template <class FP_Type>
VectorFPMaxMin<type>(this, r1, r2, r3, m6, [](type a, type b, int mode) { \ static FP_Type JavaMathMin(FP_Type x, FP_Type y) {
if (mode == 3) { \ if (isnan(x) || isnan(y))
return std::std_op(a, b); \ return NAN;
} \ else if (signbit(y) < signbit(x))
if (isnan(a) || isnan(b)) \ return x;
return static_cast<type>(NAN); \ else if (signbit(y) != signbit(x))
else if (signbit(b) op signbit(a)) \ return y;
return a; \ return (x < y) ? x : y;
else if (signbit(b) != signbit(a)) \ }
return b; \
return (a op b) ? a : b; \ template <class FP_Type>
}); static FP_Type IEEE_minNum(FP_Type x, FP_Type y) {
if (x > y) return y;
#define VECTOR_FP_MAX_MIN(op, std_op) \ if (x < y) return x;
switch (m4) { \ if (x == y) return x;
case 2: \ if (!std::isnan(x)) return x;
if (m5 == 8) { \ if (!std::isnan(y)) return y;
float src1 = get_simd_register_by_lane<float>(r2, 0); \ return NAN;
float src2 = get_simd_register_by_lane<float>(r3, 0); \ }
set_simd_register_by_lane<float>(r1, 0, (src1 op src2) ? src1 : src2); \
} else { \ template <class FP_Type>
DCHECK_EQ(m5, 0); \ static FP_Type FPMin(int m6, FP_Type lhs, FP_Type rhs) {
VECTOR_FP_MAX_MIN_FOR_TYPE(float, op, std_op) \ switch (m6) {
} \ case 0:
break; \ return IEEE_minNum(lhs, rhs);
case 3: \ case 1:
if (m5 == 8) { \ return JavaMathMin(lhs, rhs);
double src1 = get_simd_register_by_lane<double>(r2, 0); \ case 3:
double src2 = get_simd_register_by_lane<double>(r3, 0); \ return std::min(lhs, rhs);
set_simd_register_by_lane<double>(r1, 0, \ case 4:
(src1 op src2) ? src1 : src2); \ return std::fmin(lhs, rhs);
} else { \ default:
DCHECK_EQ(m5, 0); \ UNIMPLEMENTED();
VECTOR_FP_MAX_MIN_FOR_TYPE(double, op, std_op) \
} \
break; \
default: \
UNREACHABLE(); \
break; \
} }
return static_cast<FP_Type>(0);
}
// TODO(john.yan): use generic binary operation
template <class FP_Type, class Operation>
static void FPMinMaxForEachLane(Simulator* sim, Operation Op, int dst, int lhs,
int rhs, int m5, int m6) {
DCHECK(m5 == 8 || m5 == 0);
if (m5 == 8) {
FP_Type src1 = sim->get_fpr<FP_Type>(lhs);
FP_Type src2 = sim->get_fpr<FP_Type>(rhs);
FP_Type res = Op(m6, src1, src2);
sim->set_fpr(dst, res);
} else {
FOR_EACH_LANE(i, FP_Type) {
FP_Type src1 = sim->get_simd_register_by_lane<FP_Type>(lhs, i);
FP_Type src2 = sim->get_simd_register_by_lane<FP_Type>(rhs, i);
FP_Type res = Op(m6, src1, src2);
sim->set_simd_register_by_lane<FP_Type>(dst, i, res);
}
}
}
#define CASE(i, type, op) \
case i: \
FPMinMaxForEachLane<type>(this, op<type>, r1, r2, r3, m5, m6); \
break;
EVALUATE(VFMIN) { EVALUATE(VFMIN) {
DCHECK(CpuFeatures::IsSupported(VECTOR_ENHANCE_FACILITY_1)); DCHECK(CpuFeatures::IsSupported(VECTOR_ENHANCE_FACILITY_1));
DCHECK_OPCODE(VFMIN); DCHECK_OPCODE(VFMIN);
DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4); DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4);
VECTOR_FP_MAX_MIN(<, min) // NOLINT switch (m4) {
CASE(2, float, FPMin);
CASE(3, double, FPMin);
default:
UNIMPLEMENTED();
}
return length; return length;
} }
...@@ -4069,10 +4117,15 @@ EVALUATE(VFMAX) { ...@@ -4069,10 +4117,15 @@ EVALUATE(VFMAX) {
DCHECK(CpuFeatures::IsSupported(VECTOR_ENHANCE_FACILITY_1)); DCHECK(CpuFeatures::IsSupported(VECTOR_ENHANCE_FACILITY_1));
DCHECK_OPCODE(VFMAX); DCHECK_OPCODE(VFMAX);
DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4); DECODE_VRR_C_INSTRUCTION(r1, r2, r3, m6, m5, m4);
USE(m6); switch (m4) {
VECTOR_FP_MAX_MIN(>, max) // NOLINT CASE(2, float, FPMax);
CASE(3, double, FPMax);
default:
UNIMPLEMENTED();
}
return length; return length;
} }
#undef CASE
template <class S, class D, class Operation> template <class S, class D, class Operation>
void VectorFPCompare(Simulator* sim, int dst, int src1, int src2, void VectorFPCompare(Simulator* sim, int dst, int src1, int src2,
......
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