aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/test-assembler-mips64.cc
diff options
context:
space:
mode:
authorMichaƫl Zasso <targos@protonmail.com>2017-09-12 11:34:59 +0200
committerAnna Henningsen <anna@addaleax.net>2017-09-13 16:15:18 +0200
commitd82e1075dbc2cec2d6598ade10c1f43805f690fd (patch)
treeccd242b9b491dfc341d1099fe11b0ef528839877 /deps/v8/test/cctest/test-assembler-mips64.cc
parentb4b7ac6ae811b2b5a3082468115dfb5a5246fe3f (diff)
downloadandroid-node-v8-d82e1075dbc2cec2d6598ade10c1f43805f690fd.tar.gz
android-node-v8-d82e1075dbc2cec2d6598ade10c1f43805f690fd.tar.bz2
android-node-v8-d82e1075dbc2cec2d6598ade10c1f43805f690fd.zip
deps: update V8 to 6.1.534.36
PR-URL: https://github.com/nodejs/node/pull/14730 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Diffstat (limited to 'deps/v8/test/cctest/test-assembler-mips64.cc')
-rw-r--r--deps/v8/test/cctest/test-assembler-mips64.cc1958
1 files changed, 1852 insertions, 106 deletions
diff --git a/deps/v8/test/cctest/test-assembler-mips64.cc b/deps/v8/test/cctest/test-assembler-mips64.cc
index d796b4faad..b5a05f323b 100644
--- a/deps/v8/test/cctest/test-assembler-mips64.cc
+++ b/deps/v8/test/cctest/test-assembler-mips64.cc
@@ -46,7 +46,7 @@ typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4);
typedef Object* (*F2)(int x, int y, int p2, int p3, int p4);
typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4);
typedef Object* (*F4)(int64_t x, int64_t y, int64_t p2, int64_t p3, int64_t p4);
-
+typedef Object* (*F5)(void* p0, void* p1, int p2, int p3, int p4);
#define __ assm.
@@ -63,7 +63,7 @@ TEST(MIPS0) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F2 f = FUNCTION_CAST<F2>(code->entry());
@@ -99,7 +99,7 @@ TEST(MIPS1) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F1 f = FUNCTION_CAST<F1>(code->entry());
@@ -245,7 +245,7 @@ TEST(MIPS2) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F2 f = FUNCTION_CAST<F2>(code->entry());
@@ -316,7 +316,7 @@ TEST(MIPS3) {
if (kArchVariant == kMips64r2) {
__ Ldc1(f4, MemOperand(a0, offsetof(T, h)));
__ Ldc1(f6, MemOperand(a0, offsetof(T, i)));
- __ madd_d(f14, f6, f4, f6);
+ __ Madd_d(f14, f6, f4, f6, f8);
__ Sdc1(f14, MemOperand(a0, offsetof(T, h)));
}
@@ -348,7 +348,7 @@ TEST(MIPS3) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -442,7 +442,7 @@ TEST(MIPS4) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -508,7 +508,7 @@ TEST(MIPS5) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -578,7 +578,7 @@ TEST(MIPS6) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -665,7 +665,7 @@ TEST(MIPS7) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -763,7 +763,7 @@ TEST(MIPS8) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -809,7 +809,7 @@ TEST(MIPS9) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
}
@@ -885,7 +885,7 @@ TEST(MIPS10) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -1021,7 +1021,7 @@ TEST(MIPS11) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -1146,7 +1146,7 @@ TEST(MIPS12) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -1200,7 +1200,7 @@ TEST(MIPS13) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -1321,7 +1321,7 @@ TEST(MIPS14) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -1451,7 +1451,7 @@ TEST(MIPS16) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -1580,7 +1580,7 @@ TEST(seleqz_selnez) {
__ jr(ra);
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -1696,7 +1696,7 @@ TEST(min_max) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -1805,7 +1805,7 @@ TEST(rint_d) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -1853,7 +1853,7 @@ TEST(sel) {
__ jr(ra);
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -1986,7 +1986,7 @@ TEST(rint_s) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -2072,7 +2072,7 @@ TEST(mina_maxa) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -2154,7 +2154,7 @@ TEST(trunc_l) {
__ nop();
Test test;
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -2235,7 +2235,7 @@ TEST(movz_movn) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -2336,7 +2336,7 @@ TEST(movt_movd) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -2422,7 +2422,7 @@ TEST(cvt_w_d) {
__ nop();
Test test;
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -2489,7 +2489,7 @@ TEST(trunc_w) {
__ nop();
Test test;
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -2558,7 +2558,7 @@ TEST(round_w) {
__ nop();
Test test;
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -2629,7 +2629,7 @@ TEST(round_l) {
__ nop();
Test test;
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -2701,7 +2701,7 @@ TEST(sub) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -2773,7 +2773,7 @@ TEST(sqrt_rsqrt_recip) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -2851,7 +2851,7 @@ TEST(neg) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -2909,7 +2909,7 @@ TEST(mul) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -2964,7 +2964,7 @@ TEST(mov) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -3031,7 +3031,7 @@ TEST(floor_w) {
__ nop();
Test test;
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -3102,7 +3102,7 @@ TEST(floor_l) {
__ nop();
Test test;
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -3173,7 +3173,7 @@ TEST(ceil_w) {
__ nop();
Test test;
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -3244,7 +3244,7 @@ TEST(ceil_l) {
__ nop();
Test test;
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -3315,7 +3315,7 @@ TEST(jump_tables1) {
CHECK_EQ(0, assm.UnboundLabelsCount());
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
@@ -3385,7 +3385,7 @@ TEST(jump_tables2) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
@@ -3465,7 +3465,7 @@ TEST(jump_tables3) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
#ifdef OBJECT_PRINT
@@ -3539,7 +3539,7 @@ TEST(BITSWAP) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -3682,7 +3682,7 @@ TEST(class_fmt) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -3776,7 +3776,7 @@ TEST(ABS) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -3869,7 +3869,7 @@ TEST(ADD_FMT) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -4024,7 +4024,7 @@ TEST(C_COND_FMT) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -4225,7 +4225,7 @@ TEST(CMP_COND_FMT) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -4403,7 +4403,7 @@ TEST(CVT) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -4574,7 +4574,7 @@ TEST(DIV_FMT) {
__ jr(ra);
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -4665,7 +4665,7 @@ uint64_t run_align(uint64_t rs_value, uint64_t rt_value, uint8_t bp) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -4718,7 +4718,7 @@ uint64_t run_dalign(uint64_t rs_value, uint64_t rt_value, uint8_t bp) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -4776,7 +4776,7 @@ uint64_t run_aluipc(int16_t offset) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -4830,7 +4830,7 @@ uint64_t run_auipc(int16_t offset) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -4885,7 +4885,7 @@ uint64_t run_aui(uint64_t rs, uint16_t offset) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -4911,7 +4911,7 @@ uint64_t run_daui(uint64_t rs, uint16_t offset) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -4937,7 +4937,7 @@ uint64_t run_dahi(uint64_t rs, uint16_t offset) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -4963,7 +4963,7 @@ uint64_t run_dati(uint64_t rs, uint16_t offset) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -5053,22 +5053,27 @@ TEST(r6_aui_family) {
}
}
-
-uint64_t run_li_macro(uint64_t rs, LiFlags mode) {
+uint64_t run_li_macro(uint64_t imm, LiFlags mode, int32_t num_instr = 0) {
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
- __ li(a0, rs, mode);
- __ mov(v0, a0);
+ Label code_start;
+ __ bind(&code_start);
+ __ li(v0, imm, mode);
+ if (num_instr > 0) {
+ CHECK_EQ(assm.InstructionsGeneratedSince(&code_start), num_instr);
+ }
__ jr(ra);
__ nop();
CodeDesc desc;
- assm.GetCode(&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
F2 f = FUNCTION_CAST<F2>(code->entry());
uint64_t res = reinterpret_cast<uint64_t>(
@@ -5081,23 +5086,163 @@ uint64_t run_li_macro(uint64_t rs, LiFlags mode) {
TEST(li_macro) {
CcTest::InitializeVM();
- uint64_t inputs[] = {
- 0x0000000000000000, 0x000000000000ffff, 0x00000000ffffffff,
- 0x0000ffffffffffff, 0xffffffffffffffff, 0xffff000000000000,
- 0xffffffff00000000, 0xffffffffffff0000, 0xffff0000ffff0000,
- 0x0000ffffffff0000, 0x0000ffff0000ffff, 0x00007fffffffffff,
- 0x7fffffffffffffff, 0x000000007fffffff, 0x00007fff7fffffff,
+ // Test li macro-instruction for border cases.
+
+ struct TestCase_li {
+ uint64_t imm;
+ int32_t r2_num_instr;
+ int32_t r6_num_instr;
+ };
+
+ // We call li(v0, imm) to test cases listed below.
+ struct TestCase_li tc[] = {
+ // imm, r2_num_instr, r6_num_instr
+ {0xffffffffffff8000, 1, 1}, // min_int16
+ // The test case above generates daddiu instruction.
+ // This is int16 value and we can load it using just daddiu.
+ {0x8000, 1, 1}, // max_int16 + 1
+ // Generates ori
+ // max_int16 + 1 is not int16 but is uint16, just use ori.
+ {0xffffffffffff7fff, 2, 2}, // min_int16 - 1
+ // Generates lui + ori
+ // We load int32 value using lui + ori.
+ {0x8001, 1, 1}, // max_int16 + 2
+ // Generates ori
+ // Also an uint16 value, use ori.
+ {0x00010000, 1, 1}, // max_uint16 + 1
+ // Generates lui
+ // Low 16 bits are 0, load value using lui.
+ {0x00010001, 2, 2}, // max_uint16 + 2
+ // Generates lui + ori
+ // We have to generate two instructions in this case.
+ {0x00000000ffffffff, 2, 2}, // max_uint32
+ // r2 - daddiu + dsrl32
+ // r6 - daddiu + dahi
+ {0x00000000fffffffe, 3, 2}, // max_uint32 - 1
+ // r2 - lui + ori + dsll
+ // r6 - daddiu + dahi
+ {0x00ffff000000fffe, 3, 3},
+ // ori + dsll32 + ori
+ {0x00000001fffffffe, 4, 2}, // max_uint32 << 1
+ // r2 - lui + ori + dsll + ori
+ // r6 - daddiu + dahi
+ {0x0000fffffffffffe, 4, 2}, // max_uint48 - 1
+ // r2 - daddiu + dsll32 + ori + dsubu
+ // Loading imm directly would require ori + dsll + ori + dsll + ori.
+ // Optimized by loading -imm and using dsubu to get imm.
+ // r6 - daddiu + dati
+ {0xffffffff00000000, 2, 2}, // max_uint32 << 32
+ // r2 - daddiu + dsll32
+ // r6 - ori + dahi
+ // We need ori to clear register before loading value using dahi.
+ {0xffffffff80000000, 1, 1}, // min_int32
+ // The test case above generates lui instruction.
+ {0x0000000080000000, 2, 2}, // max_int32 + 1
+ // r2 - ori + dsll
+ // r6 - lui + dahi
+ {0x0000800000000000, 2, 2},
+ // ori + dsll32
+ {0xffff800000000000, 2, 2},
+ // r2 - daddiu + dsll32
+ // r6 - ori + dahi
+ {0xffff80000000ffff, 3, 2},
+ // r2 - daddiu + dsll32 + ori
+ // r6 - ori + dahi
+ {0xffffff123000ffff, 3, 3},
+ // daddiu + dsll + ori
+ {0xffff00000000ffff, 3, 2},
+ // r2 - daddiu + dsll32 + ori
+ // r6 - ori + dati
+ {0xffff8000ffff0000, 3, 2},
+ // r2 - lui + ori + dsll
+ // r6 - lui + dahi
+ {0x0000ffffffff0000, 4, 2},
+ // r2 - ori + dsll + ori + dsll
+ // r6 - lui + dati
+ {0x1234ffff80000000, 3, 2},
+ // r2 - lui + ori + dsll
+ // r6 - lui + dati
+ {0x1234ffff80010000, 5, 2},
+ // r2 - lui + ori + dsll + ori + dsll
+ // r6 - lui + dati
+ {0xffff8000ffff8000, 2, 2},
+ // r2 - daddiu + dinsu
+ // r6 - daddiu + dahi
+ {0xffff0000ffff8000, 4, 3},
+ // r2 - ori + dsll32 + ori + dsubu
+ // Loading imm directly would require lui + dsll + ori + dsll + ori.
+ // Optimized by loading -imm and using dsubu to get imm.
+ // r6 - daddiu + dahi + dati
+ {0x8000000080000000, 2, 2},
+ // lui + dinsu
+ {0xabcd0000abcd0000, 2, 2},
+ // lui + dinsu
+ {0x8000800080008000, 3, 3},
+ // lui + ori + dinsu
+ {0xabcd1234abcd1234, 3, 3},
+ // The test case above generates lui + ori + dinsu instruction sequence.
+ {0xffff800080008000, 4, 3},
+ // r2 - lui + ori + dsll + ori
+ // r6 - lui + ori + dahi
+ {0xffffabcd, 3, 2},
+ // r2 - ori + dsll + ori
+ // r6 - daddiu + dahi
+ {0x1ffffabcd, 4, 2},
+ // r2 - lui + ori + dsll + ori
+ // r6 - daddiu + dahi
+ {0xffffffffabcd, 4, 2},
+ // r2 - daddiu + dsll32 + ori + dsubu
+ // Loading imm directly would require ori + dsll + ori + dsll + ori.
+ // Optimized by loading -imm and using dsubu to get imm.
+ // r6 - daddiu + dati
+ {0x1ffffffffabcd, 4, 2},
+ // r2 - daddiu + dsll32 + ori + dsubu
+ // Loading imm directly would require lui + ori + dsll + ori + dsll + ori.
+ // Optimized by loading -imm and using dsubu to get imm.
+ // r6 - daddiu + dati
+ {0xffff7fff80010000, 5, 2},
+ // r2 - lui + ori + dsll + ori + dsll
+ // r6 - lui + dahi
+ // Here lui sets high 32 bits to 1 so dahi can be used to get target
+ // value.
+ {0x00007fff7fff0000, 3, 2},
+ // r2 - lui + ori + dsll
+ // r6 - lui + dahi
+ // High 32 bits are not set so dahi can be used to get target value.
+ {0xffff7fff7fff0000, 5, 3},
+ // r2 - lui + ori + dsll + ori + dsll
+ // r6 - lui + dahi + dati
+ // High 32 bits are not set so just dahi can't be used to get target
+ // value.
+ {0x00007fff80010000, 3, 3},
+ // r2 - lui + ori + dsll
+ // r6 - lui + ori + dsll
+ // High 32 bits are set so can't just use lui + dahi to get target value.
+ {0x1234abcd87654321, 6, 4},
+ // The test case above generates:
+ // r2 - lui + ori + dsll + ori + dsll + ori instruction sequence,
+ // r6 - lui + ori + dahi + dati.
+ // Load using full instruction sequence.
+ {0xffff0000ffffffff, 3, 3},
+ // r2 - ori + dsll32 + nor
+ // Loading imm directly would require lui + dsll + ori + dsll + ori.
+ // Optimized by loading ~imm and using nor to get imm. Loading -imm would
+ // require one instruction more.
+ // r6 - daddiu + dahi + dati
};
- size_t nr_test_cases = sizeof(inputs) / sizeof(inputs[0]);
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCase_li);
for (size_t i = 0; i < nr_test_cases; ++i) {
- uint64_t res = run_li_macro(inputs[i], OPTIMIZE_SIZE);
- CHECK_EQ(inputs[i], res);
- res = run_li_macro(inputs[i], CONSTANT_SIZE);
- CHECK_EQ(inputs[i], res);
- if (is_int48(inputs[i])) {
- res = run_li_macro(inputs[i], ADDRESS_LOAD);
- CHECK_EQ(inputs[i], res);
+ if (kArchVariant == kMips64r2) {
+ CHECK_EQ(tc[i].imm,
+ run_li_macro(tc[i].imm, OPTIMIZE_SIZE, tc[i].r2_num_instr));
+ } else {
+ CHECK_EQ(tc[i].imm,
+ run_li_macro(tc[i].imm, OPTIMIZE_SIZE, tc[i].r6_num_instr));
+ }
+ CHECK_EQ(tc[i].imm, run_li_macro(tc[i].imm, CONSTANT_SIZE));
+ if (is_int48(tc[i].imm)) {
+ CHECK_EQ(tc[i].imm, run_li_macro(tc[i].imm, ADDRESS_LOAD));
}
}
}
@@ -5136,7 +5281,7 @@ uint64_t run_lwpc(int offset) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -5212,7 +5357,7 @@ uint64_t run_lwupc(int offset) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -5296,7 +5441,7 @@ uint64_t run_jic(int16_t offset) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -5368,7 +5513,7 @@ uint64_t run_beqzc(int32_t value, int32_t offset) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -5462,7 +5607,7 @@ uint64_t run_jialc(int16_t offset) {
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -5514,7 +5659,7 @@ uint64_t run_addiupc(int32_t imm19) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -5590,7 +5735,7 @@ uint64_t run_ldpc(int offset) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -5679,7 +5824,7 @@ int64_t run_bc(int32_t offset) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -5761,7 +5906,7 @@ int64_t run_balc(int32_t offset) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -5811,7 +5956,7 @@ uint64_t run_dsll(uint64_t rt_value, uint16_t sa_value) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -5867,7 +6012,7 @@ uint64_t run_bal(int16_t offset) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
@@ -5921,7 +6066,7 @@ TEST(Trampoline) {
__ mov(v0, zero_reg);
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F2 f = FUNCTION_CAST<F2>(code->entry());
@@ -5988,7 +6133,7 @@ void helper_madd_msub_maddf_msubf(F func) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F3 f = FUNCTION_CAST<F3>(code->entry());
@@ -6020,9 +6165,9 @@ void helper_madd_msub_maddf_msubf(F func) {
TEST(madd_msub_s) {
if (kArchVariant == kMips64r6) return;
helper_madd_msub_maddf_msubf<float>([](MacroAssembler& assm) {
- __ madd_s(f10, f4, f6, f8);
+ __ Madd_s(f10, f4, f6, f8, f12);
__ Swc1(f10, MemOperand(a0, offsetof(TestCaseMaddMsub<float>, fd_add)));
- __ msub_s(f16, f4, f6, f8);
+ __ Msub_s(f16, f4, f6, f8, f12);
__ Swc1(f16, MemOperand(a0, offsetof(TestCaseMaddMsub<float>, fd_sub)));
});
}
@@ -6030,9 +6175,9 @@ TEST(madd_msub_s) {
TEST(madd_msub_d) {
if (kArchVariant == kMips64r6) return;
helper_madd_msub_maddf_msubf<double>([](MacroAssembler& assm) {
- __ madd_d(f10, f4, f6, f8);
+ __ Madd_d(f10, f4, f6, f8, f12);
__ Sdc1(f10, MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_add)));
- __ msub_d(f16, f4, f6, f8);
+ __ Msub_d(f16, f4, f6, f8, f12);
__ Sdc1(f16, MemOperand(a0, offsetof(TestCaseMaddMsub<double>, fd_sub)));
});
}
@@ -6057,6 +6202,185 @@ TEST(maddf_msubf_d) {
});
}
+uint64_t run_Subu(uint64_t imm, int32_t num_instr) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
+
+ Label code_start;
+ __ bind(&code_start);
+ __ Subu(v0, zero_reg, Operand(imm));
+ CHECK_EQ(assm.InstructionsGeneratedSince(&code_start), num_instr);
+ __ 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
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ uint64_t res = reinterpret_cast<uint64_t>(
+ CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+TEST(Subu) {
+ CcTest::InitializeVM();
+
+ // Test Subu macro-instruction for min_int16 and max_int16 border cases.
+ // For subtracting int16 immediate values we use addiu.
+
+ struct TestCaseSubu {
+ uint64_t imm;
+ uint64_t expected_res;
+ int32_t num_instr;
+ };
+
+ // We call Subu(v0, zero_reg, imm) to test cases listed below.
+ // 0 - imm = expected_res
+ struct TestCaseSubu tc[] = {
+ // imm, expected_res, num_instr
+ {0xffffffffffff8000, 0x8000, 2}, // min_int16
+ // The test case above generates ori + addu instruction sequence.
+ // We can't have just addiu because -min_int16 > max_int16 so use
+ // register. We can load min_int16 to at register with addiu and then
+ // subtract at with subu, but now we use ori + addu because -min_int16 can
+ // be loaded using ori.
+ {0x8000, 0xffffffffffff8000, 1}, // max_int16 + 1
+ // Generates addiu
+ // max_int16 + 1 is not int16 but -(max_int16 + 1) is, just use addiu.
+ {0xffffffffffff7fff, 0x8001, 2}, // min_int16 - 1
+ // Generates ori + addu
+ // To load this value to at we need two instructions and another one to
+ // subtract, lui + ori + subu. But we can load -value to at using just
+ // ori and then add at register with addu.
+ {0x8001, 0xffffffffffff7fff, 2}, // max_int16 + 2
+ // Generates ori + subu
+ // Not int16 but is uint16, load value to at with ori and subtract with
+ // subu.
+ {0x00010000, 0xffffffffffff0000, 2},
+ // Generates lui + subu
+ // Load value using lui to at and subtract with subu.
+ {0x00010001, 0xfffffffffffeffff, 3},
+ // Generates lui + ori + subu
+ // We have to generate three instructions in this case.
+ {0x7fffffff, 0xffffffff80000001, 3}, // max_int32
+ // Generates lui + ori + subu
+ {0xffffffff80000000, 0xffffffff80000000, 2}, // min_int32
+ // The test case above generates lui + subu intruction sequence.
+ // The result of 0 - min_int32 eqauls max_int32 + 1, which wraps around to
+ // min_int32 again.
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseSubu);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ CHECK_EQ(tc[i].expected_res, run_Subu(tc[i].imm, tc[i].num_instr));
+ }
+}
+
+uint64_t run_Dsubu(uint64_t imm, int32_t num_instr) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
+
+ Label code_start;
+ __ bind(&code_start);
+ __ Dsubu(v0, zero_reg, Operand(imm));
+ CHECK_EQ(assm.InstructionsGeneratedSince(&code_start), num_instr);
+ __ 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
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ uint64_t res = reinterpret_cast<uint64_t>(
+ CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+TEST(Dsubu) {
+ CcTest::InitializeVM();
+
+ // Test Dsubu macro-instruction for min_int16 and max_int16 border cases.
+ // For subtracting int16 immediate values we use daddiu.
+
+ struct TestCaseDsubu {
+ uint64_t imm;
+ uint64_t expected_res;
+ int32_t num_instr;
+ };
+
+ // We call Dsubu(v0, zero_reg, imm) to test cases listed below.
+ // 0 - imm = expected_res
+ struct TestCaseDsubu tc[] = {
+ // imm, expected_res, num_instr
+ {0xffffffffffff8000, 0x8000, 2}, // min_int16
+ // The test case above generates ori + daddu 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.
+ {0x8000, 0xffffffffffff8000, 1}, // max_int16 + 1
+ // Generates daddiu
+ // max_int16 + 1 is not int16 but -(max_int16 + 1) is, just use daddiu.
+ {0xffffffffffff7fff, 0x8001, 2}, // min_int16 - 1
+ // Generates ori + daddu
+ // To load this value to at we need two instructions and another one to
+ // subtract, lui + ori + dsubu. But we can load -value to at using just
+ // ori and then dadd at register with daddu.
+ {0x8001, 0xffffffffffff7fff, 2}, // max_int16 + 2
+ // Generates ori + dsubu
+ // Not int16 but is uint16, load value to at with ori and subtract with
+ // dsubu.
+ {0x00010000, 0xffffffffffff0000, 2},
+ // Generates lui + dsubu
+ // Load value using lui to at and subtract with dsubu.
+ {0x00010001, 0xfffffffffffeffff, 3},
+ // Generates lui + ori + dsubu
+ // We have to generate three instructions in this case.
+ {0x7fffffff, 0xffffffff80000001, 3}, // max_int32
+ // Generates lui + ori + dsubu
+ {0xffffffff80000000, 0x0000000080000000, 2}, // min_int32
+ // Generates lui + dsubu
+ // The result of 0 - min_int32 eqauls max_int32 + 1, which fits into a 64
+ // bit register, Dsubu gives a different result here.
+ {0x7fffffffffffffff, 0x8000000000000001, 3}, // max_int64
+ // r2 - Generates daddiu + dsrl + dsubu
+ // r6 - Generates daddiu + dati + dsubu
+ {0x8000000000000000, 0x8000000000000000, 3}, // min_int64
+ // The test case above generates:
+ // r2 - daddiu + dsrl32 + 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,
+ // 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.
+ };
+
+ size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseDsubu);
+ for (size_t i = 0; i < nr_test_cases; ++i) {
+ CHECK_EQ(tc[i].expected_res, run_Dsubu(tc[i].imm, tc[i].num_instr));
+ }
+}
+
uint64_t run_Dins(uint64_t imm, uint64_t source, uint16_t pos, uint16_t size) {
Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate);
@@ -6070,7 +6394,7 @@ uint64_t run_Dins(uint64_t imm, uint64_t source, uint16_t pos, uint16_t size) {
__ nop();
CodeDesc desc;
- assm.GetCode(&desc);
+ assm.GetCode(isolate, &desc);
Handle<Code> code = isolate->factory()->NewCode(
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
F2 f = FUNCTION_CAST<F2>(code->entry());
@@ -6098,15 +6422,15 @@ TEST(Dins) {
// Dins(v0, t0, pos, size) to test cases listed below.
struct TestCaseDins tc[] = {
// imm, source, pos, size, expected_res
- {0x5555555555555555, 0x1ABCDEF01, 31, 1, 0x55555555D5555555},
- {0x5555555555555555, 0x1ABCDEF02, 30, 2, 0x5555555595555555},
- {0x201234567, 0x1FABCDEFF, 0, 32, 0x2FABCDEFF},
- {0x201234567, 0x7FABCDEFF, 31, 2, 0x381234567},
- {0x800000000, 0x7FABCDEFF, 0, 33, 0x9FABCDEFF},
- {0x1234, 0xABCDABCDABCDABCD, 0, 64, 0xABCDABCDABCDABCD},
- {0xABCD, 0xABCEABCF, 32, 1, 0x10000ABCD},
- {0xABCD, 0xABCEABCF, 63, 1, 0x800000000000ABCD},
- {0xABCD, 0xABC1ABC2ABC3ABC4, 32, 32, 0xABC3ABC40000ABCD},
+ {0x5555555555555555, 0x1abcdef01, 31, 1, 0x55555555d5555555},
+ {0x5555555555555555, 0x1abcdef02, 30, 2, 0x5555555595555555},
+ {0x201234567, 0x1fabcdeff, 0, 32, 0x2fabcdeff},
+ {0x201234567, 0x7fabcdeff, 31, 2, 0x381234567},
+ {0x800000000, 0x7fabcdeff, 0, 33, 0x9fabcdeff},
+ {0x1234, 0xabcdabcdabcdabcd, 0, 64, 0xabcdabcdabcdabcd},
+ {0xabcd, 0xabceabcf, 32, 1, 0x10000abcd},
+ {0xabcd, 0xabceabcf, 63, 1, 0x800000000000abcd},
+ {0x10000abcd, 0xabc1abc2abc3abc4, 32, 32, 0xabc3abc40000abcd},
};
size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseDins);
@@ -6116,4 +6440,1426 @@ TEST(Dins) {
}
}
+uint64_t run_Ins(uint64_t imm, uint64_t source, uint16_t pos, uint16_t size) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
+
+ __ li(v0, imm);
+ __ li(t0, source);
+ __ Ins(v0, t0, pos, size);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(isolate, &desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ uint64_t res = reinterpret_cast<uint64_t>(
+ CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+TEST(Ins) {
+ CcTest::InitializeVM();
+
+ // run_Ins(rt_value, rs_value, pos, size),
+ // expected_result
+ CHECK_EQ(run_Ins(0x0000000055555555, 0xffffffffabcdef01, 31, 1),
+ 0xffffffffd5555555);
+ CHECK_EQ(run_Ins(0x0000000055555555, 0xffffffffabcdef02, 30, 2),
+ 0xffffffff95555555);
+ CHECK_EQ(run_Ins(0x0000000001234567, 0xfffffffffabcdeff, 0, 32),
+ 0xfffffffffabcdeff);
+
+ // Results with positive sign.
+ CHECK_EQ(run_Ins(0x0000000055555550, 0xffffffff80000001, 0, 1),
+ 0x0000000055555551);
+ CHECK_EQ(run_Ins(0x0000000055555555, 0x0000000040000001, 0, 32),
+ 0x0000000040000001);
+ CHECK_EQ(run_Ins(0x0000000055555555, 0x0000000020000001, 1, 31),
+ 0x0000000040000003);
+ CHECK_EQ(run_Ins(0x0000000055555555, 0xffffffff80700001, 8, 24),
+ 0x0000000070000155);
+ CHECK_EQ(run_Ins(0x0000000055555555, 0xffffffff80007001, 16, 16),
+ 0x0000000070015555);
+ CHECK_EQ(run_Ins(0x0000000055555555, 0xffffffff80000071, 24, 8),
+ 0x0000000071555555);
+ CHECK_EQ(run_Ins(0x0000000075555555, 0x0000000040000000, 31, 1),
+ 0x0000000075555555);
+
+ // Results with negative sign.
+ CHECK_EQ(run_Ins(0xffffffff85555550, 0xffffffff80000001, 0, 1),
+ 0xffffffff85555551);
+ CHECK_EQ(run_Ins(0x0000000055555555, 0xffffffff80000001, 0, 32),
+ 0xffffffff80000001);
+ CHECK_EQ(run_Ins(0x0000000055555555, 0x0000000040000001, 1, 31),
+ 0xffffffff80000003);
+ CHECK_EQ(run_Ins(0x0000000055555555, 0xffffffff80800001, 8, 24),
+ 0xffffffff80000155);
+ CHECK_EQ(run_Ins(0x0000000055555555, 0xffffffff80008001, 16, 16),
+ 0xffffffff80015555);
+ CHECK_EQ(run_Ins(0x0000000055555555, 0xffffffff80000081, 24, 8),
+ 0xffffffff81555555);
+ CHECK_EQ(run_Ins(0x0000000075555555, 0x0000000000000001, 31, 1),
+ 0xfffffffff5555555);
+}
+
+uint64_t run_Ext(uint64_t source, uint16_t pos, uint16_t size) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
+
+ __ li(v0, 0xffffffffffffffff);
+ __ li(t0, source);
+ __ Ext(v0, t0, pos, size);
+ __ jr(ra);
+ __ nop();
+
+ CodeDesc desc;
+ assm.GetCode(isolate, &desc);
+ Handle<Code> code = isolate->factory()->NewCode(
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
+ F2 f = FUNCTION_CAST<F2>(code->entry());
+
+ uint64_t res = reinterpret_cast<uint64_t>(
+ CALL_GENERATED_CODE(isolate, f, 0, 0, 0, 0, 0));
+
+ return res;
+}
+
+TEST(Ext) {
+ CcTest::InitializeVM();
+
+ // Source values with negative sign.
+ // run_Ext(rs_value, pos, size), expected_result
+ CHECK_EQ(run_Ext(0xffffffff80000001, 0, 1), 0x0000000000000001);
+ CHECK_EQ(run_Ext(0xffffffff80000001, 0, 32), 0xffffffff80000001);
+ CHECK_EQ(run_Ext(0xffffffff80000002, 1, 31), 0x0000000040000001);
+ CHECK_EQ(run_Ext(0xffffffff80000100, 8, 24), 0x0000000000800001);
+ CHECK_EQ(run_Ext(0xffffffff80010000, 16, 16), 0x0000000000008001);
+ CHECK_EQ(run_Ext(0xffffffff81000000, 24, 8), 0x0000000000000081);
+ CHECK_EQ(run_Ext(0xffffffff80000000, 31, 1), 0x0000000000000001);
+
+ // Source values with positive sign.
+ CHECK_EQ(run_Ext(0x0000000000000001, 0, 1), 0x0000000000000001);
+ CHECK_EQ(run_Ext(0x0000000040000001, 0, 32), 0x0000000040000001);
+ CHECK_EQ(run_Ext(0x0000000040000002, 1, 31), 0x0000000020000001);
+ CHECK_EQ(run_Ext(0x0000000040000100, 8, 24), 0x0000000000400001);
+ CHECK_EQ(run_Ext(0x0000000040010000, 16, 16), 0x0000000000004001);
+ CHECK_EQ(run_Ext(0x0000000041000000, 24, 8), 0x0000000000000041);
+ CHECK_EQ(run_Ext(0x0000000040000000, 31, 1), 0x0000000000000000);
+}
+
+TEST(MSA_fill_copy) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ uint64_t u8;
+ uint64_t u16;
+ uint64_t u32;
+ uint64_t s8;
+ uint64_t s16;
+ uint64_t s32;
+ uint64_t s64;
+ } T;
+ T t;
+
+ MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ {
+ CpuFeatureScope fscope(&assm, MIPS_SIMD);
+
+ __ li(t0, 0x9e7689aca512b683);
+
+ __ fill_b(w0, t0);
+ __ fill_h(w2, t0);
+ __ fill_w(w4, t0);
+ __ fill_d(w6, t0);
+ __ copy_u_b(t1, w0, 11);
+ __ sd(t1, MemOperand(a0, offsetof(T, u8)));
+ __ copy_u_h(t1, w2, 6);
+ __ sd(t1, MemOperand(a0, offsetof(T, u16)));
+ __ copy_u_w(t1, w4, 3);
+ __ sd(t1, MemOperand(a0, offsetof(T, u32)));
+
+ __ copy_s_b(t1, w0, 8);
+ __ sd(t1, MemOperand(a0, offsetof(T, s8)));
+ __ copy_s_h(t1, w2, 5);
+ __ sd(t1, MemOperand(a0, offsetof(T, s16)));
+ __ copy_s_w(t1, w4, 1);
+ __ sd(t1, MemOperand(a0, offsetof(T, s32)));
+ __ copy_s_d(t1, w6, 0);
+ __ sd(t1, MemOperand(a0, offsetof(T, s64)));
+
+ __ 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());
+
+ Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(0x83u, t.u8);
+ CHECK_EQ(0xb683u, t.u16);
+ CHECK_EQ(0xa512b683u, t.u32);
+ CHECK_EQ(0xffffffffffffff83u, t.s8);
+ CHECK_EQ(0xffffffffffffb683u, t.s16);
+ CHECK_EQ(0xffffffffa512b683u, t.s32);
+ CHECK_EQ(0x9e7689aca512b683u, t.s64);
+}
+
+TEST(MSA_fill_copy_2) {
+ // Similar to MSA_fill_copy test, but also check overlaping between MSA and
+ // FPU registers with same numbers
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ uint64_t d0;
+ uint64_t d1;
+ } T;
+ T t[2];
+
+ MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ {
+ CpuFeatureScope fscope(&assm, MIPS_SIMD);
+
+ __ li(t0, 0xaaaaaaaaaaaaaaaa);
+ __ li(t1, 0x5555555555555555);
+
+ __ fill_d(w0, t0);
+ __ fill_d(w2, t0);
+
+ __ Move(f0, t1);
+ __ Move(f2, t1);
+
+#define STORE_MSA_REG(w_reg, base, scratch) \
+ __ copy_s_d(scratch, w_reg, 0); \
+ __ sd(scratch, MemOperand(base, offsetof(T, d0))); \
+ __ copy_s_d(scratch, w_reg, 1); \
+ __ sd(scratch, MemOperand(base, offsetof(T, d1)));
+
+ STORE_MSA_REG(w0, a0, t2)
+ STORE_MSA_REG(w2, a1, t2)
+#undef STORE_MSA_REG
+
+ __ 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());
+
+ Object* dummy = CALL_GENERATED_CODE(isolate, f, &t[0], &t[1], 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(0x5555555555555555, t[0].d0);
+ CHECK_EQ(0xaaaaaaaaaaaaaaaa, t[0].d1);
+ CHECK_EQ(0x5555555555555555, t[1].d0);
+ CHECK_EQ(0xaaaaaaaaaaaaaaaa, t[1].d1);
+}
+
+TEST(MSA_fill_copy_3) {
+ // Similar to MSA_fill_copy test, but also check overlaping between MSA and
+ // FPU registers with same numbers
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ typedef struct {
+ uint64_t d0;
+ uint64_t d1;
+ } T;
+ T t[2];
+
+ MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ {
+ CpuFeatureScope fscope(&assm, MIPS_SIMD);
+
+ __ li(t0, 0xaaaaaaaaaaaaaaaa);
+ __ li(t1, 0x5555555555555555);
+
+ __ Move(f0, t0);
+ __ Move(f2, t0);
+
+ __ fill_d(w0, t1);
+ __ fill_d(w2, t1);
+
+ __ Sdc1(f0, MemOperand(a0, offsetof(T, d0)));
+ __ Sdc1(f2, MemOperand(a1, offsetof(T, d0)));
+
+ __ 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());
+
+ Object* dummy = CALL_GENERATED_CODE(isolate, f, &t[0], &t[1], 0, 0, 0);
+ USE(dummy);
+
+ CHECK_EQ(0x5555555555555555, t[0].d0);
+ CHECK_EQ(0x5555555555555555, t[1].d0);
+}
+
+typedef union {
+ uint8_t b[16];
+ uint16_t h[8];
+ uint32_t w[4];
+ uint64_t d[2];
+} msa_reg_t;
+
+template <typename T>
+void run_msa_insert(int64_t rs_value, int n, msa_reg_t* w) {
+ Isolate* isolate = CcTest::i_isolate();
+ HandleScope scope(isolate);
+
+ MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes);
+ CpuFeatureScope fscope(&assm, MIPS_SIMD);
+
+ __ li(t0, -1);
+ __ li(t1, rs_value);
+ __ fill_w(w0, t0);
+
+ if (std::is_same<T, int8_t>::value) {
+ DCHECK(n < 16);
+ __ insert_b(w0, n, t1);
+ } else if (std::is_same<T, int16_t>::value) {
+ DCHECK(n < 8);
+ __ insert_h(w0, n, t1);
+ } else if (std::is_same<T, int32_t>::value) {
+ DCHECK(n < 4);
+ __ insert_w(w0, n, t1);
+ } else if (std::is_same<T, int64_t>::value) {
+ DCHECK(n < 2);
+ __ insert_d(w0, n, t1);
+ } else {
+ UNREACHABLE();
+ }
+
+ __ 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, w, 0, 0, 0, 0));
+}
+
+TEST(MSA_insert) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ struct TestCaseInsert {
+ uint64_t input;
+ int n;
+ uint64_t exp_res_lo;
+ uint64_t exp_res_hi;
+ };
+
+ struct TestCaseInsert tc_b[] = {
+ // input, n, exp_res_lo, exp_res_hi
+ {0xa2, 13, 0xffffffffffffffffu, 0xffffa2ffffffffffu},
+ {0x73, 10, 0xffffffffffffffffu, 0xffffffffff73ffffu},
+ {0x3494, 5, 0xffff94ffffffffffu, 0xffffffffffffffffu},
+ {0xa6b8, 1, 0xffffffffffffb8ffu, 0xffffffffffffffffu}};
+
+ for (size_t i = 0; i < sizeof(tc_b) / sizeof(TestCaseInsert); ++i) {
+ msa_reg_t res;
+ run_msa_insert<int8_t>(tc_b[i].input, tc_b[i].n, &res);
+ CHECK_EQ(tc_b[i].exp_res_lo, res.d[0]);
+ CHECK_EQ(tc_b[i].exp_res_hi, res.d[1]);
+ }
+
+ struct TestCaseInsert tc_h[] = {
+ // input, n, exp_res_lo, exp_res_hi
+ {0x85a2, 7, 0xffffffffffffffffu, 0x85a2ffffffffffffu},
+ {0xe873, 5, 0xffffffffffffffffu, 0xffffffffe873ffffu},
+ {0x3494, 3, 0x3494ffffffffffffu, 0xffffffffffffffffu},
+ {0xa6b8, 1, 0xffffffffa6b8ffffu, 0xffffffffffffffffu}};
+
+ for (size_t i = 0; i < sizeof(tc_h) / sizeof(TestCaseInsert); ++i) {
+ msa_reg_t res;
+ run_msa_insert<int16_t>(tc_h[i].input, tc_h[i].n, &res);
+ CHECK_EQ(tc_h[i].exp_res_lo, res.d[0]);
+ CHECK_EQ(tc_h[i].exp_res_hi, res.d[1]);
+ }
+
+ struct TestCaseInsert tc_w[] = {
+ // input, n, exp_res_lo, exp_res_hi
+ {0xd2f085a2u, 3, 0xffffffffffffffffu, 0xd2f085a2ffffffffu},
+ {0x4567e873u, 2, 0xffffffffffffffffu, 0xffffffff4567e873u},
+ {0xacdb3494u, 1, 0xacdb3494ffffffffu, 0xffffffffffffffffu},
+ {0x89aba6b8u, 0, 0xffffffff89aba6b8u, 0xffffffffffffffffu}};
+
+ for (size_t i = 0; i < sizeof(tc_w) / sizeof(TestCaseInsert); ++i) {
+ msa_reg_t res;
+ run_msa_insert<int32_t>(tc_w[i].input, tc_w[i].n, &res);
+ CHECK_EQ(tc_w[i].exp_res_lo, res.d[0]);
+ CHECK_EQ(tc_w[i].exp_res_hi, res.d[1]);
+ }
+
+ struct TestCaseInsert tc_d[] = {
+ // input, n, exp_res_lo, exp_res_hi
+ {0xf35862e13e38f8b0, 1, 0xffffffffffffffffu, 0xf35862e13e38f8b0},
+ {0x4f41ffdef2bfe636, 0, 0x4f41ffdef2bfe636, 0xffffffffffffffffu}};
+
+ for (size_t i = 0; i < sizeof(tc_d) / sizeof(TestCaseInsert); ++i) {
+ msa_reg_t res;
+ run_msa_insert<int64_t>(tc_d[i].input, tc_d[i].n, &res);
+ CHECK_EQ(tc_d[i].exp_res_lo, res.d[0]);
+ CHECK_EQ(tc_d[i].exp_res_hi, res.d[1]);
+ }
+}
+
+struct ExpResShf {
+ uint8_t i8;
+ uint64_t lo;
+ uint64_t hi;
+};
+
+void run_msa_i8(SecondaryField opcode, uint64_t ws_lo, uint64_t ws_hi,
+ uint8_t i8) {
+ 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;
+ uint64_t wd_lo = 0xf35862e13e38f8b0;
+ uint64_t wd_hi = 0x4f41ffdef2bfe636;
+
+#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(ws_lo, ws_hi, w0)
+
+ switch (opcode) {
+ case ANDI_B:
+ __ andi_b(w2, w0, i8);
+ break;
+ case ORI_B:
+ __ ori_b(w2, w0, i8);
+ break;
+ case NORI_B:
+ __ nori_b(w2, w0, i8);
+ break;
+ case XORI_B:
+ __ xori_b(w2, w0, i8);
+ break;
+ case BMNZI_B:
+ LOAD_W_REG(wd_lo, wd_hi, w2);
+ __ bmnzi_b(w2, w0, i8);
+ break;
+ case BMZI_B:
+ LOAD_W_REG(wd_lo, wd_hi, w2);
+ __ bmzi_b(w2, w0, i8);
+ break;
+ case BSELI_B:
+ LOAD_W_REG(wd_lo, wd_hi, w2);
+ __ bseli_b(w2, w0, i8);
+ break;
+ case SHF_B:
+ __ shf_b(w2, w0, i8);
+ break;
+ case SHF_H:
+ __ shf_h(w2, w0, i8);
+ break;
+ case SHF_W:
+ __ shf_w(w2, w0, i8);
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ __ 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();
+
+#undef LOAD_W_REG
+
+ 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));
+
+ uint64_t mask = i8 * 0x0101010101010101ull;
+ switch (opcode) {
+ case ANDI_B:
+ CHECK_EQ(ws_lo & mask, res.d[0]);
+ CHECK_EQ(ws_hi & mask, res.d[1]);
+ break;
+ case ORI_B:
+ CHECK_EQ(ws_lo | mask, res.d[0]);
+ CHECK_EQ(ws_hi | mask, res.d[1]);
+ break;
+ case NORI_B:
+ CHECK_EQ(~(ws_lo | mask), res.d[0]);
+ CHECK_EQ(~(ws_hi | mask), res.d[1]);
+ break;
+ case XORI_B:
+ CHECK_EQ(ws_lo ^ mask, res.d[0]);
+ CHECK_EQ(ws_hi ^ mask, res.d[1]);
+ break;
+ case BMNZI_B:
+ CHECK_EQ((ws_lo & mask) | (wd_lo & ~mask), res.d[0]);
+ CHECK_EQ((ws_hi & mask) | (wd_hi & ~mask), res.d[1]);
+ break;
+ case BMZI_B:
+ CHECK_EQ((ws_lo & ~mask) | (wd_lo & mask), res.d[0]);
+ CHECK_EQ((ws_hi & ~mask) | (wd_hi & mask), res.d[1]);
+ break;
+ case BSELI_B:
+ CHECK_EQ((ws_lo & ~wd_lo) | (mask & wd_lo), res.d[0]);
+ CHECK_EQ((ws_hi & ~wd_hi) | (mask & wd_hi), res.d[1]);
+ break;
+ case SHF_B: {
+ struct ExpResShf exp_b[] = {
+ // i8, exp_lo, exp_hi
+ {0xffu, 0x11111111b9b9b9b9, 0xf7f7f7f7c8c8c8c8},
+ {0x0u, 0x62626262dfdfdfdf, 0xd6d6d6d6c8c8c8c8},
+ {0xe4u, 0xf35862e13e38f8b0, 0x4f41ffdef2bfe636},
+ {0x1bu, 0x1b756911c3d9a7b9, 0xae94a5f79c8aefc8},
+ {0xb1u, 0x662b6253e8c4df12, 0x0d3ad6803f8bc88b},
+ {0x4eu, 0x62e1f358f8b03e38, 0xffde4f41e636f2bf},
+ {0x27u, 0x1b697511c3a7d9b9, 0xaea594f79cef8ac8}};
+ for (size_t i = 0; i < sizeof(exp_b) / sizeof(ExpResShf); ++i) {
+ if (exp_b[i].i8 == i8) {
+ CHECK_EQ(exp_b[i].lo, res.d[0]);
+ CHECK_EQ(exp_b[i].hi, res.d[1]);
+ }
+ }
+ } break;
+ case SHF_H: {
+ struct ExpResShf exp_h[] = {
+ // i8, exp_lo, exp_hi
+ {0xffu, 0x1169116911691169, 0xf7a5f7a5f7a5f7a5},
+ {0x0u, 0x12df12df12df12df, 0x8bc88bc88bc88bc8},
+ {0xe4u, 0xf35862e13e38f8b0, 0x4f41ffdef2bfe636},
+ {0x1bu, 0xd9c3b9a7751b1169, 0x8a9cc8ef94aef7a5},
+ {0xb1u, 0x53622b6612dfc4e8, 0x80d63a0d8bc88b3f},
+ {0x4eu, 0x3e38f8b0f35862e1, 0xf2bfe6364f41ffde},
+ {0x27u, 0xd9c3751bb9a71169, 0x8a9c94aec8eff7a5}};
+ for (size_t i = 0; i < sizeof(exp_h) / sizeof(ExpResShf); ++i) {
+ if (exp_h[i].i8 == i8) {
+ CHECK_EQ(exp_h[i].lo, res.d[0]);
+ CHECK_EQ(exp_h[i].hi, res.d[1]);
+ }
+ }
+ } break;
+ case SHF_W: {
+ struct ExpResShf exp_w[] = {
+ // i8, exp_lo, exp_hi
+ {0xffu, 0xf7a594aef7a594ae, 0xf7a594aef7a594ae},
+ {0x0u, 0xc4e812dfc4e812df, 0xc4e812dfc4e812df},
+ {0xe4u, 0xf35862e13e38f8b0, 0x4f41ffdef2bfe636},
+ {0x1bu, 0xc8ef8a9cf7a594ae, 0xb9a7d9c31169751b},
+ {0xb1u, 0xc4e812df2b665362, 0x8b3f8bc83a0d80d6},
+ {0x4eu, 0x4f41ffdef2bfe636, 0xf35862e13e38f8b0},
+ {0x27u, 0x1169751bf7a594ae, 0xb9a7d9c3c8ef8a9c}};
+ for (size_t i = 0; i < sizeof(exp_w) / sizeof(ExpResShf); ++i) {
+ if (exp_w[i].i8 == i8) {
+ CHECK_EQ(exp_w[i].lo, res.d[0]);
+ CHECK_EQ(exp_w[i].hi, res.d[1]);
+ }
+ }
+ } break;
+ default:
+ UNREACHABLE();
+ }
+}
+
+struct TestCaseMsaI8 {
+ uint64_t input_lo;
+ uint64_t input_hi;
+ uint8_t i8;
+};
+
+TEST(MSA_andi_ori_nori_xori) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ struct TestCaseMsaI8 tc[] = {// input_lo, input_hi, i8
+ {0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 0xffu},
+ {0x2b665362c4e812df, 0x3a0d80d68b3f8bc8, 0x0u},
+ {0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 0x3bu},
+ {0x2b665362c4e812df, 0x3a0d80d68b3f8bc8, 0xd9u}};
+
+ for (size_t i = 0; i < sizeof(tc) / sizeof(TestCaseMsaI8); ++i) {
+ run_msa_i8(ANDI_B, tc[i].input_lo, tc[i].input_hi, tc[i].i8);
+ run_msa_i8(ORI_B, tc[i].input_lo, tc[i].input_hi, tc[i].i8);
+ run_msa_i8(NORI_B, tc[i].input_lo, tc[i].input_hi, tc[i].i8);
+ run_msa_i8(XORI_B, tc[i].input_lo, tc[i].input_hi, tc[i].i8);
+ }
+}
+
+TEST(MSA_bmnzi_bmzi_bseli) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ struct TestCaseMsaI8 tc[] = {// input_lo, input_hi, i8
+ {0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 0xffu},
+ {0x2b665362c4e812df, 0x3a0d80d68b3f8bc8, 0x0u},
+ {0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 0x3bu},
+ {0x2b665362c4e812df, 0x3a0d80d68b3f8bc8, 0xd9u}};
+
+ for (size_t i = 0; i < sizeof(tc) / sizeof(TestCaseMsaI8); ++i) {
+ run_msa_i8(BMNZI_B, tc[i].input_lo, tc[i].input_hi, tc[i].i8);
+ run_msa_i8(BMZI_B, tc[i].input_lo, tc[i].input_hi, tc[i].i8);
+ run_msa_i8(BSELI_B, tc[i].input_lo, tc[i].input_hi, tc[i].i8);
+ }
+}
+
+TEST(MSA_shf) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ struct TestCaseMsaI8 tc[] = {
+ // input_lo, input_hi, i8
+ {0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 0xffu}, // 3333
+ {0x2b665362c4e812df, 0x3a0d80d68b3f8bc8, 0x0u}, // 0000
+ {0xf35862e13e38f8b0, 0x4f41ffdef2bfe636, 0xe4u}, // 3210
+ {0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 0x1bu}, // 0123
+ {0x2b665362c4e812df, 0x3a0d80d68b3f8bc8, 0xb1u}, // 2301
+ {0xf35862e13e38f8b0, 0x4f41ffdef2bfe636, 0x4eu}, // 1032
+ {0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 0x27u} // 0213
+ };
+
+ for (size_t i = 0; i < sizeof(tc) / sizeof(TestCaseMsaI8); ++i) {
+ run_msa_i8(SHF_B, tc[i].input_lo, tc[i].input_hi, tc[i].i8);
+ run_msa_i8(SHF_H, tc[i].input_lo, tc[i].input_hi, tc[i].i8);
+ run_msa_i8(SHF_W, tc[i].input_lo, tc[i].input_hi, tc[i].i8);
+ }
+}
+
+struct TestCaseMsaI5 {
+ uint64_t ws_lo;
+ uint64_t ws_hi;
+ uint32_t i5;
+};
+
+template <typename InstFunc, typename OperFunc>
+void run_msa_i5(struct TestCaseMsaI5* input, bool i5_sign_ext,
+ InstFunc GenerateI5InstructionFunc,
+ 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;
+ int32_t i5 =
+ i5_sign_ext ? static_cast<int32_t>(input->i5 << 27) >> 27 : input->i5;
+
+ __ li(t0, input->ws_lo);
+ __ li(t1, input->ws_hi);
+ __ insert_d(w0, 0, t0);
+ __ insert_d(w0, 1, t1);
+
+ GenerateI5InstructionFunc(assm, i5);
+
+ __ 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->ws_lo, input->i5), res.d[0]);
+ CHECK_EQ(GenerateOperationFunc(input->ws_hi, input->i5), res.d[1]);
+}
+
+TEST(MSA_addvi_subvi) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ struct TestCaseMsaI5 tc[] = {
+ // ws_lo, ws_hi, i5
+ {0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 0x0000001f},
+ {0x2b665362c4e812df, 0x3a0d80d68b3f8bc8, 0x0000000f},
+ {0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 0x00000005},
+ {0x2b665362c4e812df, 0x3a0d80d68b3f8bc8, 0x00000010},
+ {0xffab807f807fffcd, 0x7f23ff80ff567f80, 0x0000000f},
+ {0x80ffefff7f12807f, 0x807f80ff7fdeff78, 0x00000010}};
+
+#define ADDVI_DF(lanes, mask) \
+ uint64_t res = 0; \
+ for (int i = 0; i < lanes / 2; ++i) { \
+ int shift = (kMSARegSize / lanes) * i; \
+ res |= ((((ws >> shift) & mask) + i5) & mask) << shift; \
+ } \
+ return res
+
+#define SUBVI_DF(lanes, mask) \
+ uint64_t res = 0; \
+ for (int i = 0; i < lanes / 2; ++i) { \
+ int shift = (kMSARegSize / lanes) * i; \
+ res |= ((((ws >> shift) & mask) - i5) & mask) << shift; \
+ } \
+ return res
+
+ for (size_t i = 0; i < sizeof(tc) / sizeof(TestCaseMsaI5); ++i) {
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ addvi_b(w2, w0, i5); },
+ [](uint64_t ws, uint32_t i5) { ADDVI_DF(kMSALanesByte, UINT8_MAX); });
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ addvi_h(w2, w0, i5); },
+ [](uint64_t ws, uint32_t i5) { ADDVI_DF(kMSALanesHalf, UINT16_MAX); });
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ addvi_w(w2, w0, i5); },
+ [](uint64_t ws, uint32_t i5) { ADDVI_DF(kMSALanesWord, UINT32_MAX); });
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ addvi_d(w2, w0, i5); },
+ [](uint64_t ws, uint32_t i5) { ADDVI_DF(kMSALanesDword, UINT64_MAX); });
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ subvi_b(w2, w0, i5); },
+ [](uint64_t ws, uint32_t i5) { SUBVI_DF(kMSALanesByte, UINT8_MAX); });
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ subvi_h(w2, w0, i5); },
+ [](uint64_t ws, uint32_t i5) { SUBVI_DF(kMSALanesHalf, UINT16_MAX); });
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ subvi_w(w2, w0, i5); },
+ [](uint64_t ws, uint32_t i5) { SUBVI_DF(kMSALanesWord, UINT32_MAX); });
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ subvi_d(w2, w0, i5); },
+ [](uint64_t ws, uint32_t i5) { SUBVI_DF(kMSALanesDword, UINT64_MAX); });
+ }
+#undef ADDVI_DF
+#undef SUBVI_DF
+}
+
+TEST(MSA_maxi_mini) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ struct TestCaseMsaI5 tc[] = {
+ // ws_lo, ws_hi, i5
+ {0x7f80ff3480ff7f00, 0x8d7fff80ff7f6780, 0x0000001f},
+ {0x7f80ff3480ff7f00, 0x8d7fff80ff7f6780, 0x0000000f},
+ {0x7f80ff3480ff7f00, 0x8d7fff80ff7f6780, 0x00000010},
+ {0x80007fff91daffff, 0x7fff8000ffff5678, 0x0000001f},
+ {0x80007fff91daffff, 0x7fff8000ffff5678, 0x0000000f},
+ {0x80007fff91daffff, 0x7fff8000ffff5678, 0x00000010},
+ {0x7fffffff80000000, 0x12345678ffffffff, 0x0000001f},
+ {0x7fffffff80000000, 0x12345678ffffffff, 0x0000000f},
+ {0x7fffffff80000000, 0x12345678ffffffff, 0x00000010},
+ {0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 0x0000001f},
+ {0x2b665362c4e812df, 0x3a0d80d68b3f8bc8, 0x0000000f},
+ {0xf35862e13e38f8b0, 0x4f41ffdef2bfe636, 0x00000010},
+ {0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 0x00000015},
+ {0x2b665362c4e812df, 0x3a0d80d68b3f8bc8, 0x00000009},
+ {0xf35862e13e38f8b0, 0x4f41ffdef2bfe636, 0x00000003}};
+
+#define MAXI_MINI_S_DF(lanes, mask, func) \
+ [](uint64_t ws, uint32_t ui5) { \
+ uint64_t res = 0; \
+ int64_t i5 = ArithmeticShiftRight(static_cast<int64_t>(ui5) << 59, 59); \
+ 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(elem, i5) & mask) << shift; \
+ } \
+ return res; \
+ }
+
+#define MAXI_MINI_U_DF(lanes, mask, func) \
+ [](uint64_t ws, uint32_t ui5) { \
+ 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(elem, static_cast<uint64_t>(ui5)) & mask) << shift; \
+ } \
+ return res; \
+ }
+
+ for (size_t i = 0; i < sizeof(tc) / sizeof(TestCaseMsaI5); ++i) {
+ run_msa_i5(
+ &tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ maxi_s_b(w2, w0, i5); },
+ MAXI_MINI_S_DF(kMSALanesByte, UINT8_MAX, Max));
+
+ run_msa_i5(
+ &tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ maxi_s_h(w2, w0, i5); },
+ MAXI_MINI_S_DF(kMSALanesHalf, UINT16_MAX, Max));
+
+ run_msa_i5(
+ &tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ maxi_s_w(w2, w0, i5); },
+ MAXI_MINI_S_DF(kMSALanesWord, UINT32_MAX, Max));
+
+ run_msa_i5(
+ &tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ maxi_s_d(w2, w0, i5); },
+ MAXI_MINI_S_DF(kMSALanesDword, UINT64_MAX, Max));
+
+ run_msa_i5(
+ &tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ mini_s_b(w2, w0, i5); },
+ MAXI_MINI_S_DF(kMSALanesByte, UINT8_MAX, Min));
+
+ run_msa_i5(
+ &tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ mini_s_h(w2, w0, i5); },
+ MAXI_MINI_S_DF(kMSALanesHalf, UINT16_MAX, Min));
+
+ run_msa_i5(
+ &tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ mini_s_w(w2, w0, i5); },
+ MAXI_MINI_S_DF(kMSALanesWord, UINT32_MAX, Min));
+
+ run_msa_i5(
+ &tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ mini_s_d(w2, w0, i5); },
+ MAXI_MINI_S_DF(kMSALanesDword, UINT64_MAX, Min));
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ maxi_u_b(w2, w0, i5); },
+ MAXI_MINI_U_DF(kMSALanesByte, UINT8_MAX, Max));
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ maxi_u_h(w2, w0, i5); },
+ MAXI_MINI_U_DF(kMSALanesHalf, UINT16_MAX, Max));
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ maxi_u_w(w2, w0, i5); },
+ MAXI_MINI_U_DF(kMSALanesWord, UINT32_MAX, Max));
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ maxi_u_d(w2, w0, i5); },
+ MAXI_MINI_U_DF(kMSALanesDword, UINT64_MAX, Max));
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ mini_u_b(w2, w0, i5); },
+ MAXI_MINI_U_DF(kMSALanesByte, UINT8_MAX, Min));
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ mini_u_h(w2, w0, i5); },
+ MAXI_MINI_U_DF(kMSALanesHalf, UINT16_MAX, Min));
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ mini_u_w(w2, w0, i5); },
+ MAXI_MINI_U_DF(kMSALanesWord, UINT32_MAX, Min));
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ mini_u_d(w2, w0, i5); },
+ MAXI_MINI_U_DF(kMSALanesDword, UINT64_MAX, Min));
+ }
+#undef MAXI_MINI_S_DF
+#undef MAXI_MINI_U_DF
+}
+
+TEST(MSA_ceqi_clti_clei) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ struct TestCaseMsaI5 tc[] = {
+ {0xff69751bb9a7d9c3, 0xf7a594aec8ff8a9c, 0x0000001f},
+ {0xe669ffffb9a7d9c3, 0xf7a594aeffff8a9c, 0x0000001f},
+ {0xffffffffb9a7d9c3, 0xf7a594aeffffffff, 0x0000001f},
+ {0x2b0b5362c4e812df, 0x3a0d80d68b3f0bc8, 0x0000000b},
+ {0x2b66000bc4e812df, 0x3a0d000b8b3f8bc8, 0x0000000b},
+ {0x0000000bc4e812df, 0x3a0d80d60000000b, 0x0000000b},
+ {0xf38062e13e38f8b0, 0x8041ffdef2bfe636, 0x00000010},
+ {0xf35880003e38f8b0, 0x4f41ffdef2bf8000, 0x00000010},
+ {0xf35862e180000000, 0x80000000f2bfe636, 0x00000010},
+ {0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 0x00000015},
+ {0x2b665362c4e812df, 0x3a0d80d68b3f8bc8, 0x00000009},
+ {0xf30062e13e38f800, 0x4f00ffdef2bf0036, 0x00000000}};
+
+#define CEQI_CLTI_CLEI_S_DF(lanes, mask, func) \
+ [](uint64_t ws, uint32_t ui5) { \
+ uint64_t res = 0; \
+ int elem_size = kMSARegSize / lanes; \
+ int64_t i5 = ArithmeticShiftRight(static_cast<int64_t>(ui5) << 59, 59); \
+ 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; \
+ }
+
+#define CEQI_CLTI_CLEI_U_DF(lanes, mask, func) \
+ [](uint64_t ws, uint64_t ui5) { \
+ 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(TestCaseMsaI5); ++i) {
+ run_msa_i5(&tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ ceqi_b(w2, w0, i5); },
+ CEQI_CLTI_CLEI_S_DF(kMSALanesByte, UINT8_MAX,
+ !Compare(elem, i5) ? -1u : 0u));
+
+ run_msa_i5(&tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ ceqi_h(w2, w0, i5); },
+ CEQI_CLTI_CLEI_S_DF(kMSALanesHalf, UINT16_MAX,
+ !Compare(elem, i5) ? -1u : 0u));
+
+ run_msa_i5(&tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ ceqi_w(w2, w0, i5); },
+ CEQI_CLTI_CLEI_S_DF(kMSALanesWord, UINT32_MAX,
+ !Compare(elem, i5) ? -1u : 0u));
+
+ run_msa_i5(&tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ ceqi_d(w2, w0, i5); },
+ CEQI_CLTI_CLEI_S_DF(kMSALanesDword, UINT64_MAX,
+ !Compare(elem, i5) ? -1u : 0u));
+
+ run_msa_i5(
+ &tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ clti_s_b(w2, w0, i5); },
+ CEQI_CLTI_CLEI_S_DF(kMSALanesByte, UINT8_MAX,
+ (Compare(elem, i5) == -1) ? -1u : 0u));
+
+ run_msa_i5(
+ &tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ clti_s_h(w2, w0, i5); },
+ CEQI_CLTI_CLEI_S_DF(kMSALanesHalf, UINT16_MAX,
+ (Compare(elem, i5) == -1) ? -1u : 0u));
+
+ run_msa_i5(
+ &tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ clti_s_w(w2, w0, i5); },
+ CEQI_CLTI_CLEI_S_DF(kMSALanesWord, UINT32_MAX,
+ (Compare(elem, i5) == -1) ? -1u : 0u));
+
+ run_msa_i5(
+ &tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ clti_s_d(w2, w0, i5); },
+ CEQI_CLTI_CLEI_S_DF(kMSALanesDword, UINT64_MAX,
+ (Compare(elem, i5) == -1) ? -1ull : 0ull));
+
+ run_msa_i5(
+ &tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ clei_s_b(w2, w0, i5); },
+ CEQI_CLTI_CLEI_S_DF(kMSALanesByte, UINT8_MAX,
+ (Compare(elem, i5) != 1) ? -1u : 0u));
+
+ run_msa_i5(
+ &tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ clei_s_h(w2, w0, i5); },
+ CEQI_CLTI_CLEI_S_DF(kMSALanesHalf, UINT16_MAX,
+ (Compare(elem, i5) != 1) ? -1u : 0u));
+
+ run_msa_i5(
+ &tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ clei_s_w(w2, w0, i5); },
+ CEQI_CLTI_CLEI_S_DF(kMSALanesWord, UINT32_MAX,
+ (Compare(elem, i5) != 1) ? -1u : 0u));
+
+ run_msa_i5(
+ &tc[i], true,
+ [](MacroAssembler& assm, int32_t i5) { __ clei_s_d(w2, w0, i5); },
+ CEQI_CLTI_CLEI_S_DF(kMSALanesDword, UINT64_MAX,
+ (Compare(elem, i5) != 1) ? -1ull : 0ull));
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ clti_u_b(w2, w0, i5); },
+ CEQI_CLTI_CLEI_U_DF(kMSALanesByte, UINT8_MAX,
+ (Compare(elem, ui5) == -1) ? -1ull : 0ull));
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ clti_u_h(w2, w0, i5); },
+ CEQI_CLTI_CLEI_U_DF(kMSALanesHalf, UINT16_MAX,
+ (Compare(elem, ui5) == -1) ? -1ull : 0ull));
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ clti_u_w(w2, w0, i5); },
+ CEQI_CLTI_CLEI_U_DF(kMSALanesWord, UINT32_MAX,
+ (Compare(elem, ui5) == -1) ? -1ull : 0ull));
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ clti_u_d(w2, w0, i5); },
+ CEQI_CLTI_CLEI_U_DF(kMSALanesDword, UINT64_MAX,
+ (Compare(elem, ui5) == -1) ? -1ull : 0ull));
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ clei_u_b(w2, w0, i5); },
+ CEQI_CLTI_CLEI_U_DF(kMSALanesByte, UINT8_MAX,
+ (Compare(elem, ui5) != 1) ? -1ull : 0ull));
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ clei_u_h(w2, w0, i5); },
+ CEQI_CLTI_CLEI_U_DF(kMSALanesHalf, UINT16_MAX,
+ (Compare(elem, ui5) != 1) ? -1ull : 0ull));
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ clei_u_w(w2, w0, i5); },
+ CEQI_CLTI_CLEI_U_DF(kMSALanesWord, UINT32_MAX,
+ (Compare(elem, ui5) != 1) ? -1ull : 0ull));
+
+ run_msa_i5(
+ &tc[i], false,
+ [](MacroAssembler& assm, int32_t i5) { __ clei_u_d(w2, w0, i5); },
+ CEQI_CLTI_CLEI_U_DF(kMSALanesDword, UINT64_MAX,
+ (Compare(elem, ui5) != 1) ? -1ull : 0ull));
+ }
+#undef CEQI_CLTI_CLEI_S_DF
+#undef CEQI_CLTI_CLEI_U_DF
+}
+
+struct TestCaseMsa2R {
+ uint64_t ws_lo;
+ uint64_t ws_hi;
+ uint64_t exp_res_lo;
+ uint64_t exp_res_hi;
+};
+
+template <typename Func>
+void run_msa_2r(struct TestCaseMsa2R* input, Func Generate2RInstructionFunc) {
+ 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;
+
+ __ li(t0, input->ws_lo);
+ __ li(t1, input->ws_hi);
+ __ insert_d(w0, 0, t0);
+ __ insert_d(w0, 1, t1);
+
+ Generate2RInstructionFunc(assm);
+
+ __ 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(input->exp_res_lo, res.d[0]);
+ CHECK_EQ(input->exp_res_hi, res.d[1]);
+}
+
+TEST(MSA_pcnt) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ struct TestCaseMsa2R tc_b[] = {// ws_lo, ws_hi, exp_res_lo, exp_res_hi
+ {0x0000000000000000, 0x0000000000000000, 0, 0},
+ {0xffffffffffffffff, 0xffffffffffffffff,
+ 0x0808080808080808, 0x0808080808080808},
+ {0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c,
+ 0x0204050405050504, 0x0704030503070304},
+ {0x2b665362c4e812df, 0x3a0d80d68b3f8bc8,
+ 0x0404040303040207, 0x0403010504060403},
+ {0xf35862e13e38f8b0, 0x4f41ffdef2bfe636,
+ 0x0603030405030503, 0x0502080605070504}};
+
+ struct TestCaseMsa2R tc_h[] = {// ws_lo, ws_hi, exp_res_lo, exp_res_hi
+ {0x0000000000000000, 0x0000000000000000, 0, 0},
+ {0xffffffffffffffff, 0xffffffffffffffff,
+ 0x0010001000100010, 0x0010001000100010},
+ {0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c,
+ 0x00060009000a0009, 0x000b0008000a0007},
+ {0x2b665362c4e812df, 0x3a0d80d68b3f8bc8,
+ 0x0008000700070009, 0x00070006000a0007},
+ {0xf35862e13e38f8b0, 0x4f41ffdef2bfe636,
+ 0x0009000700080008, 0x0007000e000c0009}};
+
+ struct TestCaseMsa2R tc_w[] = {// ws_lo, ws_hi, exp_res_lo, exp_res_hi
+ {0x0000000000000000, 0x0000000000000000, 0, 0},
+ {0xffffffffffffffff, 0xffffffffffffffff,
+ 0x0000002000000020, 0x0000002000000020},
+ {0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c,
+ 0x0000000f00000013, 0x0000001300000011},
+ {0x2b665362c4e812df, 0x3a0d80d68b3f8bc8,
+ 0x0000000f00000010, 0x0000000d00000011},
+ {0xf35862e13e38f8b0, 0x4f41ffdef2bfe636,
+ 0x0000001000000010, 0x0000001500000015}};
+
+ struct TestCaseMsa2R tc_d[] = {
+ // ws_lo, ws_hi, exp_res_lo, exp_res_hi
+ {0x0000000000000000, 0x0000000000000000, 0, 0},
+ {0xffffffffffffffff, 0xffffffffffffffff, 0x40, 0x40},
+ {0x1169751bb9a7d9c3, 0xf7a594aec8ef8a9c, 0x22, 0x24},
+ {0x2b665362c4e812df, 0x3a0d80d68b3f8bc8, 0x1f, 0x1e},
+ {0xf35862e13e38f8b0, 0x4f41ffdef2bfe636, 0x20, 0x2a}};
+
+ for (size_t i = 0; i < sizeof(tc_b) / sizeof(TestCaseMsa2R); ++i) {
+ run_msa_2r(&tc_b[i], [](MacroAssembler& assm) { __ pcnt_b(w2, w0); });
+ run_msa_2r(&tc_h[i], [](MacroAssembler& assm) { __ pcnt_h(w2, w0); });
+ run_msa_2r(&tc_w[i], [](MacroAssembler& assm) { __ pcnt_w(w2, w0); });
+ run_msa_2r(&tc_d[i], [](MacroAssembler& assm) { __ pcnt_d(w2, w0); });
+ }
+}
+
+TEST(MSA_nlzc) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ struct TestCaseMsa2R tc_b[] = {// ws_lo, ws_hi, exp_res_lo, exp_res_hi
+ {0x0000000000000000, 0x0000000000000000,
+ 0x0808080808080808, 0x0808080808080808},
+ {0xffffffffffffffff, 0xffffffffffffffff, 0, 0},
+ {0x1169350b07030100, 0x7f011402381f0a6c,
+ 0x0301020405060708, 0x0107030602030401},
+ {0x010806003478121f, 0x03013016073f7b08,
+ 0x0704050802010303, 0x0607020305020104},
+ {0x0168321100083803, 0x07113f03013f1676,
+ 0x0701020308040206, 0x0503020607020301}};
+
+ struct TestCaseMsa2R tc_h[] = {// ws_lo, ws_hi, exp_res_lo, exp_res_hi
+ {0x0000000000000000, 0x0000000000000000,
+ 0x0010001000100010, 0x0010001000100010},
+ {0xffffffffffffffff, 0xffffffffffffffff, 0, 0},
+ {0x00010007000a003c, 0x37a5001e00010002,
+ 0x000f000d000c000a, 0x0002000b000f000e},
+ {0x0026066200780edf, 0x003d0003000f00c8,
+ 0x000a000500090004, 0x000a000e000c0008},
+ {0x335807e100480030, 0x01410fde12bf5636,
+ 0x000200050009000a, 0x0007000400030001}};
+
+ struct TestCaseMsa2R tc_w[] = {// ws_lo, ws_hi, exp_res_lo, exp_res_hi
+ {0x0000000000000000, 0x0000000000000000,
+ 0x0000002000000020, 0x0000002000000020},
+ {0xffffffffffffffff, 0xffffffffffffffff, 0, 0},
+ {0x00000005000007c3, 0x000014ae00006a9c,
+ 0x0000001d00000015, 0x0000001300000011},
+ {0x00009362000112df, 0x000380d6003f8bc8,
+ 0x000000100000000f, 0x0000000e0000000a},
+ {0x135862e17e38f8b0, 0x0061ffde03bfe636,
+ 0x0000000300000001, 0x0000000900000006}};
+
+ struct TestCaseMsa2R tc_d[] = {
+ // ws_lo, ws_hi, exp_res_lo, exp_res_hi
+ {0x0000000000000000, 0x0000000000000000, 0x40, 0x40},
+ {0xffffffffffffffff, 0xffffffffffffffff, 0, 0},
+ {0x000000000000014e, 0x00000000000176da, 0x37, 0x2f},
+ {0x00000062c4e812df, 0x000065d68b3f8bc8, 0x19, 0x11},
+ {0x00000000e338f8b0, 0x0754534acab32654, 0x20, 0x5}};
+
+ for (size_t i = 0; i < sizeof(tc_b) / sizeof(TestCaseMsa2R); ++i) {
+ run_msa_2r(&tc_b[i], [](MacroAssembler& assm) { __ nlzc_b(w2, w0); });
+ run_msa_2r(&tc_h[i], [](MacroAssembler& assm) { __ nlzc_h(w2, w0); });
+ run_msa_2r(&tc_w[i], [](MacroAssembler& assm) { __ nlzc_w(w2, w0); });
+ run_msa_2r(&tc_d[i], [](MacroAssembler& assm) { __ nlzc_d(w2, w0); });
+ }
+}
+
+TEST(MSA_nloc) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ struct TestCaseMsa2R tc_b[] = {// ws_lo, ws_hi, exp_res_lo, exp_res_hi
+ {0xffffffffffffffff, 0xffffffffffffffff,
+ 0x0808080808080808, 0x0808080808080808},
+ {0x0000000000000000, 0x0000000000000000, 0, 0},
+ {0xEE96CAF4F8FCFEFF, 0x80FEEBFDC7E0F593,
+ 0x0301020405060708, 0x0107030602030401},
+ {0xFEF7F9FFCB87EDE0, 0xFCFECFE9F8C084F7,
+ 0x0704050802010303, 0x0607020305020104},
+ {0xFE97CDEEFFF7C7FC, 0xF8EEC0FCFEC0E989,
+ 0x0701020308040206, 0x0503020607020301}};
+
+ struct TestCaseMsa2R tc_h[] = {// ws_lo, ws_hi, exp_res_lo, exp_res_hi
+ {0xffffffffffffffff, 0xffffffffffffffff,
+ 0x0010001000100010, 0x0010001000100010},
+ {0x0000000000000000, 0x0000000000000000, 0, 0},
+ {0xFFFEFFF8FFF5FFC3, 0xC85AFFE1FFFEFFFD,
+ 0x000f000d000c000a, 0x0002000b000f000e},
+ {0xFFD9F99DFF87F120, 0xFFC2FFFCFFF0FF37,
+ 0x000a000500090004, 0x000a000e000c0008},
+ {0xCCA7F81EFFB7FFCF, 0xFEBEF021ED40A9C9,
+ 0x000200050009000a, 0x0007000400030001}};
+
+ struct TestCaseMsa2R tc_w[] = {// ws_lo, ws_hi, exp_res_lo, exp_res_hi
+ {0xffffffffffffffff, 0xffffffffffffffff,
+ 0x0000002000000020, 0x0000002000000020},
+ {0x0000000000000000, 0x0000000000000000, 0, 0},
+ {0xFFFFFFFAFFFFF83C, 0xFFFFEB51FFFF9563,
+ 0x0000001d00000015, 0x0000001300000011},
+ {0xFFFF6C9DFFFEED20, 0xFFFC7F29FFC07437,
+ 0x000000100000000f, 0x0000000e0000000a},
+ {0xECA79D1E81C7074F, 0xFF9E0021FC4019C9,
+ 0x0000000300000001, 0x0000000900000006}};
+
+ struct TestCaseMsa2R tc_d[] = {
+ // ws_lo, ws_hi, exp_res_lo, exp_res_hi
+ {0xffffffffffffffff, 0xffffffffffffffff, 0x40, 0x40},
+ {0x0000000000000000, 0x0000000000000000, 0, 0},
+ {0xFFFFFFFFFFFFFEB1, 0xFFFFFFFFFFFE8925, 0x37, 0x2f},
+ {0xFFFFFF9D3B17ED20, 0xFFFF9A2974C07437, 0x19, 0x11},
+ {0xFFFFFFFF1CC7074F, 0xF8ABACB5354CD9AB, 0x20, 0x5}};
+
+ for (size_t i = 0; i < sizeof(tc_b) / sizeof(TestCaseMsa2R); ++i) {
+ run_msa_2r(&tc_b[i], [](MacroAssembler& assm) { __ nloc_b(w2, w0); });
+ run_msa_2r(&tc_h[i], [](MacroAssembler& assm) { __ nloc_h(w2, w0); });
+ run_msa_2r(&tc_w[i], [](MacroAssembler& assm) { __ nloc_w(w2, w0); });
+ run_msa_2r(&tc_d[i], [](MacroAssembler& assm) { __ nloc_d(w2, w0); });
+ }
+}
+
+struct TestCaseMsaVector {
+ uint64_t wd_lo;
+ uint64_t wd_hi;
+ uint64_t ws_lo;
+ uint64_t ws_hi;
+ uint64_t wt_lo;
+ uint64_t wt_hi;
+};
+
+template <typename InstFunc, typename OperFunc>
+void run_msa_vector(struct TestCaseMsaVector* 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;
+
+#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->wt_lo, input->wt_hi, w2);
+ LOAD_W_REG(input->wd_lo, input->wd_hi, w4);
+#undef LOAD_W_REG
+
+ GenerateVectorInstructionFunc(assm);
+
+ __ copy_u_w(t2, w4, 0);
+ __ sw(t2, MemOperand(a0, 0));
+ __ copy_u_w(t2, w4, 1);
+ __ sw(t2, MemOperand(a0, 4));
+ __ copy_u_w(t2, w4, 2);
+ __ sw(t2, MemOperand(a0, 8));
+ __ copy_u_w(t2, w4, 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->wt_lo),
+ res.d[0]);
+ CHECK_EQ(GenerateOperationFunc(input->wd_hi, input->ws_hi, input->wt_hi),
+ res.d[1]);
+}
+
+TEST(MSA_vector) {
+ if ((kArchVariant != kMips64r6) || !CpuFeatures::IsSupported(MIPS_SIMD))
+ return;
+
+ CcTest::InitializeVM();
+
+ struct TestCaseMsaVector tc[] = {
+ // wd_lo, wd_hi, ws_lo, ws_hi, wt_lo, wt_hi
+ {0xf35862e13e38f8b0, 0x4f41ffdef2bfe636, 0xdcd39d91f9057627,
+ 0x64be4f6dbe9caa51, 0x6b23de1a687d9cb9, 0x49547aad691da4ca},
+ {0xf35862e13e38f8b0, 0x4f41ffdef2bfe636, 0x401614523d830549,
+ 0xd7c46d613f50eddd, 0x52284cbc60a1562b, 0x1756ed510d8849cd},
+ {0xf35862e13e38f8b0, 0x4f41ffdef2bfe636, 0xd6e2d2ebcb40d72f,
+ 0x13a619afce67b079, 0x36cce284343e40f9, 0xb4e8f44fd148bf7f}};
+
+ for (size_t i = 0; i < sizeof(tc) / sizeof(TestCaseMsaVector); ++i) {
+ run_msa_vector(
+ &tc[i], [](MacroAssembler& assm) { __ and_v(w4, w0, w2); },
+ [](uint64_t wd, uint64_t ws, uint64_t wt) { return ws & wt; });
+ run_msa_vector(
+ &tc[i], [](MacroAssembler& assm) { __ or_v(w4, w0, w2); },
+ [](uint64_t wd, uint64_t ws, uint64_t wt) { return ws | wt; });
+ run_msa_vector(
+ &tc[i], [](MacroAssembler& assm) { __ nor_v(w4, w0, w2); },
+ [](uint64_t wd, uint64_t ws, uint64_t wt) { return ~(ws | wt); });
+ run_msa_vector(
+ &tc[i], [](MacroAssembler& assm) { __ xor_v(w4, w0, w2); },
+ [](uint64_t wd, uint64_t ws, uint64_t wt) { return ws ^ wt; });
+ run_msa_vector(&tc[i], [](MacroAssembler& assm) { __ bmnz_v(w4, w0, w2); },
+ [](uint64_t wd, uint64_t ws, uint64_t wt) {
+ return (ws & wt) | (wd & ~wt);
+ });
+ run_msa_vector(&tc[i], [](MacroAssembler& assm) { __ bmz_v(w4, w0, w2); },
+ [](uint64_t wd, uint64_t ws, uint64_t wt) {
+ return (ws & ~wt) | (wd & wt);
+ });
+ run_msa_vector(&tc[i], [](MacroAssembler& assm) { __ bsel_v(w4, w0, w2); },
+ [](uint64_t wd, uint64_t ws, uint64_t wt) {
+ return (ws & ~wd) | (wt & wd);
+ });
+ }
+}
+
#undef __