Index: test/cctest/test-assembler-mips.cc |
diff --git a/test/cctest/test-assembler-mips.cc b/test/cctest/test-assembler-mips.cc |
index 09b85fad1e3b3c1e9fa9b80318882a163ee052a3..d3019f7af07168d4035e554798082777975c8c14 100644 |
--- a/test/cctest/test-assembler-mips.cc |
+++ b/test/cctest/test-assembler-mips.cc |
@@ -46,7 +46,7 @@ using namespace v8::internal; |
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)(void* p0, void* p1, int p2, int p3, int p4); |
#define __ assm. |
@@ -5587,4 +5587,192 @@ TEST(Subu) { |
} |
} |
+TEST(MSA_fill_copy) { |
+ CcTest::InitializeVM(); |
+ Isolate* isolate = CcTest::i_isolate(); |
+ HandleScope scope(isolate); |
+ |
+ typedef struct { |
+ uint32_t u8; |
+ uint32_t u16; |
+ uint32_t u32; |
+ uint32_t s8; |
+ uint32_t s16; |
+ uint32_t s32; |
+ } T; |
+ T t; |
+ |
+ MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); |
+ if (!IsMipsArchVariant(kMips32r6) || !CpuFeatures::IsSupported(MIPS_SIMD)) |
+ return; |
+ |
+ { |
+ CpuFeatureScope fscope(&assm, MIPS_SIMD); |
+ |
+ __ li(t0, 0xa512b683); |
+ |
+ __ fill_b(w0, t0); |
+ __ fill_h(w2, t0); |
+ __ fill_w(w4, t0); |
+ __ copy_u_b(t1, w0, 11); |
+ __ sw(t1, MemOperand(a0, offsetof(T, u8))); |
+ __ copy_u_h(t1, w2, 6); |
+ __ sw(t1, MemOperand(a0, offsetof(T, u16))); |
+ __ copy_u_w(t1, w4, 3); |
+ __ sw(t1, MemOperand(a0, offsetof(T, u32))); |
+ |
+ __ copy_s_b(t1, w0, 8); |
+ __ sw(t1, MemOperand(a0, offsetof(T, s8))); |
+ __ copy_s_h(t1, w2, 5); |
+ __ sw(t1, MemOperand(a0, offsetof(T, s16))); |
+ __ copy_s_w(t1, w4, 1); |
+ __ sw(t1, MemOperand(a0, offsetof(T, s32))); |
+ |
+ __ jr(ra); |
+ __ nop(); |
+ } |
+ |
+ CodeDesc desc; |
+ assm.GetCode(&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(0xffffff83u, t.s8); |
+ CHECK_EQ(0xffffb683u, t.s16); |
+ CHECK_EQ(0xa512b683u, t.s32); |
+} |
+ |
+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 { |
+ uint32_t w0; |
+ uint32_t w1; |
+ uint32_t w2; |
+ uint32_t w3; |
+ } T; |
+ T t[2]; |
+ |
+ MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); |
+ if (!IsMipsArchVariant(kMips32r6) || !CpuFeatures::IsSupported(MIPS_SIMD)) |
+ return; |
+ |
+ { |
+ CpuFeatureScope fscope(&assm, MIPS_SIMD); |
+ |
+ __ li(t0, 0xaaaaaaaa); |
+ __ li(t1, 0x55555555); |
+ |
+ __ fill_w(w0, t0); |
+ __ fill_w(w2, t0); |
+ |
+ __ FmoveLow(f0, t1); |
+ __ FmoveHigh(f2, t1); |
+ |
+#define STORE_MSA_REG(w_reg, base, scratch) \ |
+ __ copy_u_w(scratch, w_reg, 0); \ |
+ __ sw(scratch, MemOperand(base, offsetof(T, w0))); \ |
+ __ copy_u_w(scratch, w_reg, 1); \ |
+ __ sw(scratch, MemOperand(base, offsetof(T, w1))); \ |
+ __ copy_u_w(scratch, w_reg, 2); \ |
+ __ sw(scratch, MemOperand(base, offsetof(T, w2))); \ |
+ __ copy_u_w(scratch, w_reg, 3); \ |
+ __ sw(scratch, MemOperand(base, offsetof(T, w3))); |
+ |
+ STORE_MSA_REG(w0, a0, t2) |
+ STORE_MSA_REG(w2, a1, t2) |
+#undef STORE_MSA_REG |
+ |
+ __ jr(ra); |
+ __ nop(); |
+ } |
+ |
+ CodeDesc desc; |
+ assm.GetCode(&desc); |
+ Handle<Code> code = isolate->factory()->NewCode( |
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
+#ifdef OBJECT_PRINT |
+ code->Print(std::cout); |
+#endif |
+ F4 f = FUNCTION_CAST<F4>(code->entry()); |
+ |
+ Object* dummy = CALL_GENERATED_CODE(isolate, f, &t[0], &t[1], 0, 0, 0); |
+ USE(dummy); |
+ |
+ CHECK_EQ(0x55555555, t[0].w0); |
+ CHECK_EQ(0xaaaaaaaa, t[0].w1); |
+ CHECK_EQ(0xaaaaaaaa, t[0].w2); |
+ CHECK_EQ(0xaaaaaaaa, t[0].w3); |
+ CHECK_EQ(0xaaaaaaaa, t[1].w0); |
+ CHECK_EQ(0x55555555, t[1].w1); |
+ CHECK_EQ(0xaaaaaaaa, t[1].w2); |
+ CHECK_EQ(0xaaaaaaaa, t[1].w3); |
+} |
+ |
+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 (!IsMipsArchVariant(kMips32r6) || !CpuFeatures::IsSupported(MIPS_SIMD)) |
+ return; |
+ |
+ { |
+ CpuFeatureScope fscope(&assm, MIPS_SIMD); |
+ |
+ __ li(t0, 0xaaaaaaaa); |
+ __ li(t1, 0x55555555); |
+ |
+ __ Move(f0, t0, t0); |
+ __ Move(f2, t0, t0); |
+ |
+ __ fill_w(w0, t1); |
+ __ fill_w(w2, t1); |
+ |
+ __ Sdc1(f0, MemOperand(a0, offsetof(T, d0))); |
+ __ Sdc1(f2, MemOperand(a1, offsetof(T, d0))); |
+ |
+ __ jr(ra); |
+ __ nop(); |
+ } |
+ |
+ CodeDesc desc; |
+ assm.GetCode(&desc); |
+ Handle<Code> code = isolate->factory()->NewCode( |
+ desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
+#ifdef OBJECT_PRINT |
+ code->Print(std::cout); |
+#endif |
+ F4 f = FUNCTION_CAST<F4>(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); |
+} |
+ |
#undef __ |