aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/test-assembler-mips64.cc
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2017-10-18 15:03:02 -0700
committerMichaël Zasso <targos@protonmail.com>2017-10-18 17:01:41 -0700
commit3d1b3df9486c0e7708065257f7311902f6b7b366 (patch)
treecb051bdeaead11e06dcd97725783e0f113afb1bf /deps/v8/test/cctest/test-assembler-mips64.cc
parente2cddbb8ccdb7b3c4a40c8acc630f68703bc77b5 (diff)
downloadandroid-node-v8-3d1b3df9486c0e7708065257f7311902f6b7b366.tar.gz
android-node-v8-3d1b3df9486c0e7708065257f7311902f6b7b366.tar.bz2
android-node-v8-3d1b3df9486c0e7708065257f7311902f6b7b366.zip
deps: update V8 to 6.2.414.32
PR-URL: https://github.com/nodejs/node/pull/15362 Reviewed-By: Myles Borins <myles.borins@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps/v8/test/cctest/test-assembler-mips64.cc')
-rw-r--r--deps/v8/test/cctest/test-assembler-mips64.cc659
1 files changed, 653 insertions, 6 deletions
diff --git a/deps/v8/test/cctest/test-assembler-mips64.cc b/deps/v8/test/cctest/test-assembler-mips64.cc
index b5a05f323b..4a828c9785 100644
--- a/deps/v8/test/cctest/test-assembler-mips64.cc
+++ b/deps/v8/test/cctest/test-assembler-mips64.cc
@@ -6329,11 +6329,10 @@ TEST(Dsubu) {
struct TestCaseDsubu tc[] = {
// imm, expected_res, num_instr
{0xffffffffffff8000, 0x8000, 2}, // min_int16
- // The test case above generates ori + daddu instruction sequence.
+ // The test case above generates daddiu + dsubu instruction sequence.
// We can't have just daddiu because -min_int16 > max_int16 so use
- // register. We can load min_int16 to at register with daddiu and then
- // subtract at with dsubu, but now we use ori + daddu because -min_int16
- // can be loaded using ori.
+ // register, but we can load min_int16 to at register with daddiu and then
+ // subtract at with dsubu.
{0x8000, 0xffffffffffff8000, 1}, // max_int16 + 1
// Generates daddiu
// max_int16 + 1 is not int16 but -(max_int16 + 1) is, just use daddiu.
@@ -6363,13 +6362,13 @@ TEST(Dsubu) {
// r6 - Generates daddiu + dati + dsubu
{0x8000000000000000, 0x8000000000000000, 3}, // min_int64
// The test case above generates:
- // r2 - daddiu + dsrl32 + dsubu instruction sequence,
+ // r2 - daddiu + dsll32 + dsubu instruction sequence,
// r6 - ori + dati + dsubu.
// The result of 0 - min_int64 eqauls max_int64 + 1, which wraps around to
// min_int64 again.
{0xffff0000ffffffff, 0x0000ffff00000001, 4},
// The test case above generates:
- // r2 - ori + dsrl32 + ori + daddu instruction sequence,
+ // r2 - ori + dsll32 + ori + daddu instruction sequence,
// r6 - daddiu + dahi + dati + dsubu.
// For r2 loading imm would take more instructions than loading -imm so we
// can load -imm and add with daddu.
@@ -7862,4 +7861,652 @@ TEST(MSA_vector) {
}
}
+struct TestCaseMsaBit {
+ uint64_t wd_lo;
+ uint64_t wd_hi;
+ uint64_t ws_lo;
+ uint64_t ws_hi;
+ uint32_t m;
+};
+
+template <typename InstFunc, typename OperFunc>
+void run_msa_bit(struct TestCaseMsaBit* input, InstFunc GenerateInstructionFunc,
+ OperFunc GenerateOperationFunc) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
+ CpuFeatureScope fscope(&assm, MIPS_SIMD);
+ msa_reg_t res;
+
+#define LOAD_W_REG(lo, hi, w_reg) \
+ __ li(t0, lo); \
+ __ li(t1, hi); \
+ __ insert_d(w_reg, 0, t0); \
+ __ insert_d(w_reg, 1, t1)
+
+ LOAD_W_REG(input->ws_lo, input->ws_hi, w0);
+ LOAD_W_REG(input->wd_lo, input->wd_hi, w2);
+#undef LOAD_W_REG
+
+ GenerateInstructionFunc(assm, input->m);
+
+ __ copy_u_w(t2, w2, 0);
+ __ sw(t2, MemOperand(a0, 0));
+ __ copy_u_w(t2, w2, 1);
+ __ sw(t2, MemOperand(a0, 4));
+ __ copy_u_w(t2, w2, 2);
+ __ sw(t2, MemOperand(a0, 8));
+ __ copy_u_w(t2, w2, 3);
+ __ sw(t2, MemOperand(a0, 12));
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(isolate, &desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+ code->Print(std::cout);
+#endif
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ (CALL_GENERATED_CODE(isolate, f, &res, 0, 0, 0, 0));
+
+ CHECK_EQ(GenerateOperationFunc(input->wd_lo, input->ws_lo, input->m),
+ res.d[0]);
+ CHECK_EQ(GenerateOperationFunc(input->wd_hi, input->ws_hi, input->m),
+ res.d[1]);
+}
+
+TEST(MSA_slli_srai_srli) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ struct TestCaseMsaBit tc[] = {
+ // wd_lo, wd_hi ws_lo, ws_hi, m
+ {0, 0, 0xf35862e13e38f8b0, 0x4f41ffdef2bfe636, 3},
+ {0, 0, 0x64be4f6dbe9caa51, 0x6b23de1a687d9cb9, 5},
+ {0, 0, 0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 9},
+ {0, 0, 0x2b665362c4e812df, 0x3a0d80d68b3f8bc8, 13},
+ {0, 0, 0x566be7ba4365b70a, 0x01ebbc1937d76cb4, 21},
+ {0, 0, 0x380e2deb9d3f8aae, 0x017e0de0bcc6ca42, 30},
+ {0, 0, 0xa46a3a9bcb43f4e5, 0x1c62c8473bdfcffb, 45},
+ {0, 0, 0xf6759d85f23b5a2b, 0x5c042ae42c6d12c1, 61}};
+
+#define SLLI_SRLI_DF(lanes, mask, func) \
+ [](uint64_t wd, uint64_t ws, uint32_t m) { \
+ uint64_t res = 0; \
+ int elem_size = kMSARegSize / lanes; \
+ for (int i = 0; i < lanes / 2; ++i) { \
+ int shift = elem_size * i; \
+ uint64_t elem = (ws >> shift) & mask; \
+ res |= ((func)&mask) << shift; \
+ } \
+ return res; \
+ }
+
+#define SRAI_DF(lanes, mask, func) \
+ [](uint64_t wd, uint64_t ws, uint32_t m) { \
+ uint64_t res = 0; \
+ int elem_size = kMSARegSize / lanes; \
+ for (int i = 0; i < lanes / 2; ++i) { \
+ int shift = elem_size * i; \
+ int64_t elem = \
+ static_cast<int64_t>(((ws >> shift) & mask) << (64 - elem_size)) >> \
+ (64 - elem_size); \
+ res |= static_cast<uint64_t>((func)&mask) << shift; \
+ } \
+ return res; \
+ }
+
+ for (size_t i = 0; i < sizeof(tc) / sizeof(TestCaseMsaBit); ++i) {
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ slli_b(w2, w0, m % 8); },
+ SLLI_SRLI_DF(kMSALanesByte, UINT8_MAX, (elem << (m % elem_size))));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ slli_h(w2, w0, m % 16); },
+ SLLI_SRLI_DF(kMSALanesHalf, UINT16_MAX, (elem << (m % elem_size))));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ slli_w(w2, w0, m % 32); },
+ SLLI_SRLI_DF(kMSALanesWord, UINT32_MAX, (elem << (m % elem_size))));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ slli_d(w2, w0, m % 64); },
+ SLLI_SRLI_DF(kMSALanesDword, UINT64_MAX, (elem << (m % elem_size))));
+
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ srli_b(w2, w0, m % 8); },
+ SLLI_SRLI_DF(kMSALanesByte, UINT8_MAX, (elem >> (m % elem_size))));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ srli_h(w2, w0, m % 16); },
+ SLLI_SRLI_DF(kMSALanesHalf, UINT16_MAX, (elem >> (m % elem_size))));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ srli_w(w2, w0, m % 32); },
+ SLLI_SRLI_DF(kMSALanesWord, UINT32_MAX, (elem >> (m % elem_size))));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ srli_d(w2, w0, m % 64); },
+ SLLI_SRLI_DF(kMSALanesDword, UINT64_MAX, (elem >> (m % elem_size))));
+
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ srlri_b(w2, w0, m % 8); },
+ SLLI_SRLI_DF(
+ kMSALanesByte, UINT8_MAX,
+ (elem >> (m % elem_size)) + ((elem >> (m % elem_size - 1)) & 0x1)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ srlri_h(w2, w0, m % 16); },
+ SLLI_SRLI_DF(
+ kMSALanesHalf, UINT16_MAX,
+ (elem >> (m % elem_size)) + ((elem >> (m % elem_size - 1)) & 0x1)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ srlri_w(w2, w0, m % 32); },
+ SLLI_SRLI_DF(
+ kMSALanesWord, UINT32_MAX,
+ (elem >> (m % elem_size)) + ((elem >> (m % elem_size - 1)) & 0x1)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ srlri_d(w2, w0, m % 64); },
+ SLLI_SRLI_DF(
+ kMSALanesDword, UINT64_MAX,
+ (elem >> (m % elem_size)) + ((elem >> (m % elem_size - 1)) & 0x1)));
+
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ srai_b(w2, w0, m % 8); },
+ SRAI_DF(kMSALanesByte, UINT8_MAX,
+ ArithmeticShiftRight(elem, m % elem_size)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ srai_h(w2, w0, m % 16); },
+ SRAI_DF(kMSALanesHalf, UINT16_MAX,
+ ArithmeticShiftRight(elem, m % elem_size)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ srai_w(w2, w0, m % 32); },
+ SRAI_DF(kMSALanesWord, UINT32_MAX,
+ ArithmeticShiftRight(elem, m % elem_size)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ srai_d(w2, w0, m % 64); },
+ SRAI_DF(kMSALanesDword, UINT64_MAX,
+ ArithmeticShiftRight(elem, m % elem_size)));
+
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ srari_b(w2, w0, m % 8); },
+ SRAI_DF(kMSALanesByte, UINT8_MAX,
+ ArithmeticShiftRight(elem, m % elem_size) +
+ ((elem >> (m % elem_size - 1)) & 0x1)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ srari_h(w2, w0, m % 16); },
+ SRAI_DF(kMSALanesHalf, UINT16_MAX,
+ ArithmeticShiftRight(elem, m % elem_size) +
+ ((elem >> (m % elem_size - 1)) & 0x1)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ srari_w(w2, w0, m % 32); },
+ SRAI_DF(kMSALanesWord, UINT32_MAX,
+ ArithmeticShiftRight(elem, m % elem_size) +
+ ((elem >> (m % elem_size - 1)) & 0x1)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ srari_d(w2, w0, m % 64); },
+ SRAI_DF(kMSALanesDword, UINT64_MAX,
+ ArithmeticShiftRight(elem, m % elem_size) +
+ ((elem >> (m % elem_size - 1)) & 0x1)));
+ }
+#undef SLLI_SRLI_DF
+#undef SRAI_DF
+}
+
+TEST(MSA_bclri_bseti_bnegi) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ struct TestCaseMsaBit tc[] = {
+ // wd_lo, wd_hi, ws_lo, ws_hi, m
+ {0, 0, 0xf35862e13e38f8b0, 0x4f41ffdef2bfe636, 3},
+ {0, 0, 0x64be4f6dbe9caa51, 0x6b23de1a687d9cb9, 5},
+ {0, 0, 0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 9},
+ {0, 0, 0x2b665362c4e812df, 0x3a0d80d68b3f8bc8, 13},
+ {0, 0, 0x566be7ba4365b70a, 0x01ebbc1937d76cb4, 21},
+ {0, 0, 0x380e2deb9d3f8aae, 0x017e0de0bcc6ca42, 30},
+ {0, 0, 0xa46a3a9bcb43f4e5, 0x1c62c8473bdfcffb, 45},
+ {0, 0, 0xf6759d85f23b5a2b, 0x5c042ae42c6d12c1, 61}};
+
+#define BCLRI_BSETI_BNEGI_DF(lanes, mask, func) \
+ [](uint64_t wd, uint64_t ws, uint32_t m) { \
+ uint64_t res = 0; \
+ int elem_size = kMSARegSize / lanes; \
+ for (int i = 0; i < lanes / 2; ++i) { \
+ int shift = elem_size * i; \
+ uint64_t elem = (ws >> shift) & mask; \
+ res |= ((func)&mask) << shift; \
+ } \
+ return res; \
+ }
+
+ for (size_t i = 0; i < sizeof(tc) / sizeof(TestCaseMsaBit); ++i) {
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ bclri_b(w2, w0, m % 8); },
+ BCLRI_BSETI_BNEGI_DF(kMSALanesByte, UINT8_MAX,
+ (~(1ull << (m % elem_size)) & elem)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ bclri_h(w2, w0, m % 16); },
+ BCLRI_BSETI_BNEGI_DF(kMSALanesHalf, UINT16_MAX,
+ (~(1ull << (m % elem_size)) & elem)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ bclri_w(w2, w0, m % 32); },
+ BCLRI_BSETI_BNEGI_DF(kMSALanesWord, UINT32_MAX,
+ (~(1ull << (m % elem_size)) & elem)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ bclri_d(w2, w0, m % 64); },
+ BCLRI_BSETI_BNEGI_DF(kMSALanesDword, UINT64_MAX,
+ (~(1ull << (m % elem_size)) & elem)));
+
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ bseti_b(w2, w0, m % 8); },
+ BCLRI_BSETI_BNEGI_DF(kMSALanesByte, UINT8_MAX,
+ ((1ull << (m % elem_size)) | elem)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ bseti_h(w2, w0, m % 16); },
+ BCLRI_BSETI_BNEGI_DF(kMSALanesHalf, UINT16_MAX,
+ ((1ull << (m % elem_size)) | elem)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ bseti_w(w2, w0, m % 32); },
+ BCLRI_BSETI_BNEGI_DF(kMSALanesWord, UINT32_MAX,
+ ((1ull << (m % elem_size)) | elem)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ bseti_d(w2, w0, m % 64); },
+ BCLRI_BSETI_BNEGI_DF(kMSALanesDword, UINT64_MAX,
+ ((1ull << (m % elem_size)) | elem)));
+
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ bnegi_b(w2, w0, m % 8); },
+ BCLRI_BSETI_BNEGI_DF(kMSALanesByte, UINT8_MAX,
+ ((1ull << (m % elem_size)) ^ elem)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ bnegi_h(w2, w0, m % 16); },
+ BCLRI_BSETI_BNEGI_DF(kMSALanesHalf, UINT16_MAX,
+ ((1ull << (m % elem_size)) ^ elem)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ bnegi_w(w2, w0, m % 32); },
+ BCLRI_BSETI_BNEGI_DF(kMSALanesWord, UINT32_MAX,
+ ((1ull << (m % elem_size)) ^ elem)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ bnegi_d(w2, w0, m % 64); },
+ BCLRI_BSETI_BNEGI_DF(kMSALanesDword, UINT64_MAX,
+ ((1ull << (m % elem_size)) ^ elem)));
+ }
+#undef BCLRI_BSETI_BNEGI_DF
+}
+
+TEST(MSA_binsli_binsri) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ struct TestCaseMsaBit tc[] = {// wd_lo, wd_hi, ws_lo, ws_hi, m
+ {0x53f4457553bbd5b4, 0x5fb8250eacc296b2,
+ 0xf35862e13e38f8b0, 0x4f41ffdef2bfe636, 3},
+ {0xf61bfdb0f312e6fc, 0xc9437568dd1ea925,
+ 0x64be4f6dbe9caa51, 0x6b23de1a687d9cb9, 5},
+ {0x53f4457553bbd5b4, 0x5fb8250eacc296b2,
+ 0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 9},
+ {0xf61bfdb0f312e6fc, 0xc9437568dd1ea925,
+ 0x2b665362c4e812df, 0x3a0d80d68b3f8bc8, 13},
+ {0x53f4457553bbd5b4, 0x5fb8250eacc296b2,
+ 0x566be7ba4365b70a, 0x01ebbc1937d76cb4, 21},
+ {0xf61bfdb0f312e6fc, 0xc9437568dd1ea925,
+ 0x380e2deb9d3f8aae, 0x017e0de0bcc6ca42, 30},
+ {0x53f4457553bbd5b4, 0x5fb8250eacc296b2,
+ 0xa46a3a9bcb43f4e5, 0x1c62c8473bdfcffb, 45},
+ {0xf61bfdb0f312e6fc, 0xc9437568dd1ea925,
+ 0xf6759d85f23b5a2b, 0x5c042ae42c6d12c1, 61}};
+
+#define BINSLI_BINSRI_DF(lanes, mask, func) \
+ [](uint64_t wd, uint64_t ws, uint32_t m) { \
+ uint64_t res = 0; \
+ int elem_size = kMSARegSize / lanes; \
+ int bits = m % elem_size + 1; \
+ for (int i = 0; i < lanes / 2; ++i) { \
+ int shift = elem_size * i; \
+ uint64_t ws_elem = (ws >> shift) & mask; \
+ if (bits == elem_size) { \
+ res |= (ws_elem & mask) << shift; \
+ } else { \
+ uint64_t r_mask = (1ull << bits) - 1; \
+ uint64_t l_mask = r_mask << (elem_size - bits); \
+ USE(l_mask); \
+ uint64_t wd_elem = (wd >> shift) & mask; \
+ res |= ((func)&mask) << shift; \
+ } \
+ } \
+ return res; \
+ }
+
+ for (size_t i = 0; i < sizeof(tc) / sizeof(TestCaseMsaBit); ++i) {
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ binsli_b(w2, w0, m % 8); },
+ BINSLI_BINSRI_DF(kMSALanesByte, UINT8_MAX,
+ ((ws_elem & l_mask) | (wd_elem & ~l_mask))));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ binsli_h(w2, w0, m % 16); },
+ BINSLI_BINSRI_DF(kMSALanesHalf, UINT16_MAX,
+ ((ws_elem & l_mask) | (wd_elem & ~l_mask))));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ binsli_w(w2, w0, m % 32); },
+ BINSLI_BINSRI_DF(kMSALanesWord, UINT32_MAX,
+ ((ws_elem & l_mask) | (wd_elem & ~l_mask))));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ binsli_d(w2, w0, m % 64); },
+ BINSLI_BINSRI_DF(kMSALanesDword, UINT64_MAX,
+ ((ws_elem & l_mask) | (wd_elem & ~l_mask))));
+
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ binsri_b(w2, w0, m % 8); },
+ BINSLI_BINSRI_DF(kMSALanesByte, UINT8_MAX,
+ ((ws_elem & r_mask) | (wd_elem & ~r_mask))));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ binsri_h(w2, w0, m % 16); },
+ BINSLI_BINSRI_DF(kMSALanesHalf, UINT16_MAX,
+ ((ws_elem & r_mask) | (wd_elem & ~r_mask))));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ binsri_w(w2, w0, m % 32); },
+ BINSLI_BINSRI_DF(kMSALanesWord, UINT32_MAX,
+ ((ws_elem & r_mask) | (wd_elem & ~r_mask))));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ binsri_d(w2, w0, m % 64); },
+ BINSLI_BINSRI_DF(kMSALanesDword, UINT64_MAX,
+ ((ws_elem & r_mask) | (wd_elem & ~r_mask))));
+ }
+#undef BINSLI_BINSRI_DF
+}
+
+TEST(MSA_sat_s_sat_u) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ struct TestCaseMsaBit tc[] = {
+ // wd_lo, wd_hi, ws_lo, ws_hi, m
+ {0, 0, 0xf35862e13e3808b0, 0x4f41ffdef2bfe636, 3},
+ {0, 0, 0x64be4f6dbe9caa51, 0x6b23de1a687d9cb9, 5},
+ {0, 0, 0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 9},
+ {0, 0, 0x2b665362c4e812df, 0x3a0d80d68b3f8bc8, 13},
+ {0, 0, 0x566be7ba4365b70a, 0x01ebbc1937d76cb4, 21},
+ {0, 0, 0x380e2deb9d3f8aae, 0x017e0de0bcc6ca42, 30},
+ {0, 0, 0xa46a3a9bcb43f4e5, 0x1c62c8473bdfcffb, 45},
+ {0, 0, 0xf6759d85f23b5a2b, 0x5c042ae42c6d12c1, 61}};
+
+#define SAT_DF(lanes, mask, func) \
+ [](uint64_t wd, uint64_t ws, uint32_t m) { \
+ uint64_t res = 0; \
+ int elem_size = kMSARegSize / lanes; \
+ m %= elem_size; \
+ for (int i = 0; i < lanes / 2; ++i) { \
+ int shift = elem_size * i; \
+ uint64_t elem_u64 = (ws >> shift) & mask; \
+ int64_t elem_i64 = static_cast<int64_t>(elem_u64 << (64 - elem_size)) >> \
+ (64 - elem_size); \
+ USE(elem_i64); \
+ res |= ((func)&mask) << shift; \
+ } \
+ return res; \
+ }
+
+#define M_MAX_INT(x) static_cast<int64_t>((1LL << ((x)-1)) - 1)
+#define M_MIN_INT(x) static_cast<int64_t>(-(1LL << ((x)-1)))
+#define M_MAX_UINT(x) static_cast<uint64_t>(-1ULL >> (64 - (x)))
+
+ for (size_t i = 0; i < sizeof(tc) / sizeof(TestCaseMsaBit); ++i) {
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ sat_u_b(w2, w0, m % 8); },
+ SAT_DF(kMSALanesByte, UINT8_MAX,
+ (elem_u64 < M_MAX_UINT(m + 1) ? elem_u64 : M_MAX_UINT(m + 1))));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ sat_u_h(w2, w0, m % 16); },
+ SAT_DF(kMSALanesHalf, UINT16_MAX,
+ (elem_u64 < M_MAX_UINT(m + 1) ? elem_u64 : M_MAX_UINT(m + 1))));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ sat_u_w(w2, w0, m % 32); },
+ SAT_DF(kMSALanesWord, UINT32_MAX,
+ (elem_u64 < M_MAX_UINT(m + 1) ? elem_u64 : M_MAX_UINT(m + 1))));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ sat_u_d(w2, w0, m % 64); },
+ SAT_DF(kMSALanesDword, UINT64_MAX,
+ (elem_u64 < M_MAX_UINT(m + 1) ? elem_u64 : M_MAX_UINT(m + 1))));
+
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ sat_s_b(w2, w0, m % 8); },
+ SAT_DF(
+ kMSALanesByte, UINT8_MAX,
+ (elem_i64 < M_MIN_INT(m + 1)
+ ? M_MIN_INT(m + 1)
+ : elem_i64 > M_MAX_INT(m + 1) ? M_MAX_INT(m + 1) : elem_i64)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ sat_s_h(w2, w0, m % 16); },
+ SAT_DF(
+ kMSALanesHalf, UINT16_MAX,
+ (elem_i64 < M_MIN_INT(m + 1)
+ ? M_MIN_INT(m + 1)
+ : elem_i64 > M_MAX_INT(m + 1) ? M_MAX_INT(m + 1) : elem_i64)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ sat_s_w(w2, w0, m % 32); },
+ SAT_DF(
+ kMSALanesWord, UINT32_MAX,
+ (elem_i64 < M_MIN_INT(m + 1)
+ ? M_MIN_INT(m + 1)
+ : elem_i64 > M_MAX_INT(m + 1) ? M_MAX_INT(m + 1) : elem_i64)));
+ run_msa_bit(
+ &tc[i],
+ [](MacroAssembler& assm, uint32_t m) { __ sat_s_d(w2, w0, m % 64); },
+ SAT_DF(
+ kMSALanesDword, UINT64_MAX,
+ (elem_i64 < M_MIN_INT(m + 1)
+ ? M_MIN_INT(m + 1)
+ : elem_i64 > M_MAX_INT(m + 1) ? M_MAX_INT(m + 1) : elem_i64)));
+ }
+
+#undef SAT_DF
+#undef M_MAX_INT
+#undef M_MIN_INT
+#undef M_MAX_UINT
+}
+
+template <typename InstFunc, typename OperFunc>
+void run_msa_i10(int32_t input, InstFunc GenerateVectorInstructionFunc,
+ OperFunc GenerateOperationFunc) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
+ CpuFeatureScope fscope(&assm, MIPS_SIMD);
+ msa_reg_t res;
+
+ GenerateVectorInstructionFunc(assm, input);
+
+ __ copy_u_w(t2, w0, 0);
+ __ sw(t2, MemOperand(a0, 0));
+ __ copy_u_w(t2, w0, 1);
+ __ sw(t2, MemOperand(a0, 4));
+ __ copy_u_w(t2, w0, 2);
+ __ sw(t2, MemOperand(a0, 8));
+ __ copy_u_w(t2, w0, 3);
+ __ sw(t2, MemOperand(a0, 12));
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(isolate, &desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+ code->Print(std::cout);
+#endif
+ F3 f = FUNCTION_CAST<F3>(code->entry());
+
+ (CALL_GENERATED_CODE(isolate, f, &res, 0, 0, 0, 0));
+
+ CHECK_EQ(GenerateOperationFunc(input), res.d[0]);
+ CHECK_EQ(GenerateOperationFunc(input), res.d[1]);
+}
+
+TEST(MSA_ldi) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ // signed 10bit integers: -512 .. 511
+ int32_t tc[] = {0, -1, 1, 256, -256, -178, 352, -512, 511};
+
+#define LDI_DF(lanes, mask) \
+ [](int32_t s10) { \
+ uint64_t res = 0; \
+ int elem_size = kMSARegSize / lanes; \
+ int64_t s10_64 = \
+ ArithmeticShiftRight(static_cast<int64_t>(s10) << 54, 54); \
+ for (int i = 0; i < lanes / 2; ++i) { \
+ int shift = elem_size * i; \
+ res |= static_cast<uint64_t>(s10_64 & mask) << shift; \
+ } \
+ return res; \
+ }
+
+ for (size_t i = 0; i < sizeof(tc) / sizeof(int32_t); ++i) {
+ run_msa_i10(tc[i],
+ [](MacroAssembler& assm, int32_t s10) { __ ldi_b(w0, s10); },
+ LDI_DF(kMSALanesByte, UINT8_MAX));
+ run_msa_i10(tc[i],
+ [](MacroAssembler& assm, int32_t s10) { __ ldi_h(w0, s10); },
+ LDI_DF(kMSALanesHalf, UINT16_MAX));
+ run_msa_i10(tc[i],
+ [](MacroAssembler& assm, int32_t s10) { __ ldi_w(w0, s10); },
+ LDI_DF(kMSALanesWord, UINT32_MAX));
+ run_msa_i10(tc[i],
+ [](MacroAssembler& assm, int32_t s10) { __ ldi_d(w0, s10); },
+ LDI_DF(kMSALanesDword, UINT64_MAX));
+ }
+#undef LDI_DF
+}
+
+template <typename T, typename InstFunc>
+void run_msa_mi10(InstFunc GenerateVectorInstructionFunc) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
+ CpuFeatureScope fscope(&assm, MIPS_SIMD);
+ T in_test_vector[1024];
+ T out_test_vector[1024];
+
+ T* in_array_middle = in_test_vector + arraysize(in_test_vector) / 2;
+ T* out_array_middle = out_test_vector + arraysize(out_test_vector) / 2;
+
+ v8::base::RandomNumberGenerator rand_gen(FLAG_random_seed);
+ for (unsigned int i = 0; i < arraysize(in_test_vector); i++) {
+ in_test_vector[i] = static_cast<T>(rand_gen.NextInt());
+ out_test_vector[i] = 0;
+ }
+
+ GenerateVectorInstructionFunc(assm);
+
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(isolate, &desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+#ifdef OBJECT_PRINT
+ code->Print(std::cout);
+#endif
+ F5 f = FUNCTION_CAST<F5>(code->entry());
+
+ (CALL_GENERATED_CODE(isolate, f, in_array_middle, out_array_middle, 0, 0, 0));
+
+ CHECK_EQ(memcmp(in_test_vector, out_test_vector, arraysize(in_test_vector)),
+ 0);
+}
+
+TEST(MSA_load_store_vector) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ run_msa_mi10<uint8_t>([](MacroAssembler& assm) {
+ for (int i = -512; i < 512; i += 16) {
+ __ ld_b(w0, MemOperand(a0, i));
+ __ st_b(w0, MemOperand(a1, i));
+ }
+ });
+ run_msa_mi10<uint16_t>([](MacroAssembler& assm) {
+ for (int i = -512; i < 512; i += 8) {
+ __ ld_h(w0, MemOperand(a0, i));
+ __ st_h(w0, MemOperand(a1, i));
+ }
+ });
+ run_msa_mi10<uint32_t>([](MacroAssembler& assm) {
+ for (int i = -512; i < 512; i += 4) {
+ __ ld_w(w0, MemOperand(a0, i));
+ __ st_w(w0, MemOperand(a1, i));
+ }
+ });
+ run_msa_mi10<uint64_t>([](MacroAssembler& assm) {
+ for (int i = -512; i < 512; i += 2) {
+ __ ld_d(w0, MemOperand(a0, i));
+ __ st_d(w0, MemOperand(a1, i));
+ }
+ });
+#undef LDI_DF
+}
+
#undef __