Commit 3e0bf580 authored by Predrag Rudic's avatar Predrag Rudic Committed by Commit Bot

MIPS[64] Implementation of MSA instructions in builtin simulator

This commit is a step toward enabling test-run-wasm-simd tests for MIPS.
36 of those were failing in V8 builtin simulator because some instructions
were not implemented.  Also there are minor fixes to some of the already
implemented instructions.

This commit has only 32-bit implementation. After review I will add
64-bit version.

Bug: 
Change-Id: I25b0cac352db3efb56b922ace64ab2aaef82472d
Reviewed-on: https://chromium-review.googlesource.com/744008Reviewed-by: 's avatarIvica Bogosavljevic <ivica.bogosavljevic@mips.com>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Ivica Bogosavljevic <ivica.bogosavljevic@mips.com>
Cr-Commit-Position: refs/heads/master@{#49439}
parent dec077ae
This diff is collapsed.
This diff is collapsed.
......@@ -288,7 +288,7 @@ T SaturateAdd(T a, T b) {
template <typename T>
T SaturateSub(T a, T b) {
if (std::is_signed<T>::value) {
if (a > 0 && b < 0) {
if (a >= 0 && b < 0) {
if (a > std::numeric_limits<T>::max() + b) {
return std::numeric_limits<T>::max();
}
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -7,6 +7,7 @@
#include <limits>
#include <set>
#include "src/utils.h"
#include "test/unittests/test-utils.h"
namespace v8 {
......@@ -211,5 +212,117 @@ TEST(FunctionalTest, BitHashDoubleDifferentForZeroAndMinusZero) {
EXPECT_NE(h(0.0), h(-0.0));
}
// src/utils.h functions
template <typename T>
class UtilsTest : public ::testing::Test {};
typedef ::testing::Types<signed char, unsigned char,
short, // NOLINT(runtime/int)
unsigned short, // NOLINT(runtime/int)
int, unsigned int, long, // NOLINT(runtime/int)
unsigned long, // NOLINT(runtime/int)
long long, // NOLINT(runtime/int)
unsigned long long, // NOLINT(runtime/int)
int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t,
int64_t, uint64_t>
IntegerTypes;
TYPED_TEST_CASE(UtilsTest, IntegerTypes);
TYPED_TEST(UtilsTest, SaturateSub) {
TypeParam min = std::numeric_limits<TypeParam>::min();
TypeParam max = std::numeric_limits<TypeParam>::max();
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(min, 0), min);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(max, 0), max);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(max, min), max);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(min, max), min);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(min, max / 3), min);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(min + 1, 2), min);
if (std::numeric_limits<TypeParam>::is_signed) {
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(min, min),
static_cast<TypeParam>(0));
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(0, min), max);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(0, max), -max);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(max - 1, -2), max);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(max / 3, min), max);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(max / 5, min), max);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(min / 3, max), min);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(min / 9, max), min);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(max, min / 3), max);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(min, max / 3), min);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(max / 3 * 2, min / 2), max);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(min / 3 * 2, max / 2), min);
} else {
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(min, min), min);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(0, min), min);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(0, max), min);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(max / 3, max), min);
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(max - 3, max), min);
}
TypeParam test_cases[] = {static_cast<TypeParam>(min / 23),
static_cast<TypeParam>(max / 3),
63,
static_cast<TypeParam>(min / 6),
static_cast<TypeParam>(max / 55),
static_cast<TypeParam>(min / 2),
static_cast<TypeParam>(max / 2),
0,
1,
2,
3,
4,
42};
TRACED_FOREACH(TypeParam, x, test_cases) {
TRACED_FOREACH(TypeParam, y, test_cases) {
if (std::numeric_limits<TypeParam>::is_signed) {
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(x, y), x - y);
} else {
EXPECT_EQ(v8::internal::SaturateSub<TypeParam>(x, y),
y > x ? min : x - y);
}
}
}
}
TYPED_TEST(UtilsTest, SaturateAdd) {
TypeParam min = std::numeric_limits<TypeParam>::min();
TypeParam max = std::numeric_limits<TypeParam>::max();
EXPECT_EQ(v8::internal::SaturateAdd<TypeParam>(min, min), min);
EXPECT_EQ(v8::internal::SaturateAdd<TypeParam>(max, max), max);
EXPECT_EQ(v8::internal::SaturateAdd<TypeParam>(min, min / 3), min);
EXPECT_EQ(v8::internal::SaturateAdd<TypeParam>(max / 8 * 7, max / 3 * 2),
max);
EXPECT_EQ(v8::internal::SaturateAdd<TypeParam>(min / 3 * 2, min / 8 * 7),
min);
EXPECT_EQ(v8::internal::SaturateAdd<TypeParam>(max / 20 * 18, max / 25 * 18),
max);
EXPECT_EQ(v8::internal::SaturateAdd<TypeParam>(min / 3 * 2, min / 3 * 2),
min);
EXPECT_EQ(v8::internal::SaturateAdd<TypeParam>(max - 1, 2), max);
EXPECT_EQ(v8::internal::SaturateAdd<TypeParam>(max - 100, 101), max);
if (std::numeric_limits<TypeParam>::is_signed) {
EXPECT_EQ(v8::internal::SaturateAdd<TypeParam>(min + 100, -101), min);
EXPECT_EQ(v8::internal::SaturateAdd<TypeParam>(min + 1, -2), min);
}
TypeParam test_cases[] = {static_cast<TypeParam>(min / 23),
static_cast<TypeParam>(max / 3),
63,
static_cast<TypeParam>(min / 6),
static_cast<TypeParam>(max / 55),
static_cast<TypeParam>(min / 2),
static_cast<TypeParam>(max / 2),
0,
1,
2,
3,
4,
42};
TRACED_FOREACH(TypeParam, x, test_cases) {
TRACED_FOREACH(TypeParam, y, test_cases) {
EXPECT_EQ(v8::internal::SaturateAdd<TypeParam>(x, y), x + y);
}
}
}
} // namespace base
} // 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