OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 28 matching lines...) Expand all Loading... |
39 #include "test/cctest/cctest.h" | 39 #include "test/cctest/cctest.h" |
40 | 40 |
41 | 41 |
42 using namespace v8::internal; | 42 using namespace v8::internal; |
43 | 43 |
44 | 44 |
45 // Define these function prototypes to match JSEntryFunction in execution.cc. | 45 // Define these function prototypes to match JSEntryFunction in execution.cc. |
46 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); | 46 typedef Object* (*F1)(int x, int p1, int p2, int p3, int p4); |
47 typedef Object* (*F2)(int x, int y, int p2, int p3, int p4); | 47 typedef Object* (*F2)(int x, int y, int p2, int p3, int p4); |
48 typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); | 48 typedef Object* (*F3)(void* p, int p1, int p2, int p3, int p4); |
49 | 49 typedef Object* (*F4)(void* p0, void* p1, int p2, int p3, int p4); |
50 | 50 |
51 #define __ assm. | 51 #define __ assm. |
52 | 52 |
53 TEST(MIPS0) { | 53 TEST(MIPS0) { |
54 CcTest::InitializeVM(); | 54 CcTest::InitializeVM(); |
55 Isolate* isolate = CcTest::i_isolate(); | 55 Isolate* isolate = CcTest::i_isolate(); |
56 HandleScope scope(isolate); | 56 HandleScope scope(isolate); |
57 | 57 |
58 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); | 58 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); |
59 | 59 |
(...skipping 5520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5580 // Generates lui + ori + subu | 5580 // Generates lui + ori + subu |
5581 // We have to generate three instructions in this case. | 5581 // We have to generate three instructions in this case. |
5582 }; | 5582 }; |
5583 | 5583 |
5584 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseSubu); | 5584 size_t nr_test_cases = sizeof(tc) / sizeof(TestCaseSubu); |
5585 for (size_t i = 0; i < nr_test_cases; ++i) { | 5585 for (size_t i = 0; i < nr_test_cases; ++i) { |
5586 CHECK_EQ(tc[i].expected_res, run_Subu(tc[i].imm, tc[i].num_instr)); | 5586 CHECK_EQ(tc[i].expected_res, run_Subu(tc[i].imm, tc[i].num_instr)); |
5587 } | 5587 } |
5588 } | 5588 } |
5589 | 5589 |
| 5590 TEST(MSA_fill_copy) { |
| 5591 CcTest::InitializeVM(); |
| 5592 Isolate* isolate = CcTest::i_isolate(); |
| 5593 HandleScope scope(isolate); |
| 5594 |
| 5595 typedef struct { |
| 5596 uint32_t u8; |
| 5597 uint32_t u16; |
| 5598 uint32_t u32; |
| 5599 uint32_t s8; |
| 5600 uint32_t s16; |
| 5601 uint32_t s32; |
| 5602 } T; |
| 5603 T t; |
| 5604 |
| 5605 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); |
| 5606 if (!IsMipsArchVariant(kMips32r6) || !CpuFeatures::IsSupported(MIPS_SIMD)) |
| 5607 return; |
| 5608 |
| 5609 { |
| 5610 CpuFeatureScope fscope(&assm, MIPS_SIMD); |
| 5611 |
| 5612 __ li(t0, 0xa512b683); |
| 5613 |
| 5614 __ fill_b(w0, t0); |
| 5615 __ fill_h(w2, t0); |
| 5616 __ fill_w(w4, t0); |
| 5617 __ copy_u_b(t1, w0, 11); |
| 5618 __ sw(t1, MemOperand(a0, offsetof(T, u8))); |
| 5619 __ copy_u_h(t1, w2, 6); |
| 5620 __ sw(t1, MemOperand(a0, offsetof(T, u16))); |
| 5621 __ copy_u_w(t1, w4, 3); |
| 5622 __ sw(t1, MemOperand(a0, offsetof(T, u32))); |
| 5623 |
| 5624 __ copy_s_b(t1, w0, 8); |
| 5625 __ sw(t1, MemOperand(a0, offsetof(T, s8))); |
| 5626 __ copy_s_h(t1, w2, 5); |
| 5627 __ sw(t1, MemOperand(a0, offsetof(T, s16))); |
| 5628 __ copy_s_w(t1, w4, 1); |
| 5629 __ sw(t1, MemOperand(a0, offsetof(T, s32))); |
| 5630 |
| 5631 __ jr(ra); |
| 5632 __ nop(); |
| 5633 } |
| 5634 |
| 5635 CodeDesc desc; |
| 5636 assm.GetCode(&desc); |
| 5637 Handle<Code> code = isolate->factory()->NewCode( |
| 5638 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 5639 #ifdef OBJECT_PRINT |
| 5640 code->Print(std::cout); |
| 5641 #endif |
| 5642 F3 f = FUNCTION_CAST<F3>(code->entry()); |
| 5643 |
| 5644 Object* dummy = CALL_GENERATED_CODE(isolate, f, &t, 0, 0, 0, 0); |
| 5645 USE(dummy); |
| 5646 |
| 5647 CHECK_EQ(0x83u, t.u8); |
| 5648 CHECK_EQ(0xb683u, t.u16); |
| 5649 CHECK_EQ(0xa512b683u, t.u32); |
| 5650 CHECK_EQ(0xffffff83u, t.s8); |
| 5651 CHECK_EQ(0xffffb683u, t.s16); |
| 5652 CHECK_EQ(0xa512b683u, t.s32); |
| 5653 } |
| 5654 |
| 5655 TEST(MSA_fill_copy_2) { |
| 5656 // Similar to MSA_fill_copy test, but also check overlaping between MSA and |
| 5657 // FPU registers with same numbers |
| 5658 CcTest::InitializeVM(); |
| 5659 Isolate* isolate = CcTest::i_isolate(); |
| 5660 HandleScope scope(isolate); |
| 5661 |
| 5662 typedef struct { |
| 5663 uint32_t w0; |
| 5664 uint32_t w1; |
| 5665 uint32_t w2; |
| 5666 uint32_t w3; |
| 5667 } T; |
| 5668 T t[2]; |
| 5669 |
| 5670 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); |
| 5671 if (!IsMipsArchVariant(kMips32r6) || !CpuFeatures::IsSupported(MIPS_SIMD)) |
| 5672 return; |
| 5673 |
| 5674 { |
| 5675 CpuFeatureScope fscope(&assm, MIPS_SIMD); |
| 5676 |
| 5677 __ li(t0, 0xaaaaaaaa); |
| 5678 __ li(t1, 0x55555555); |
| 5679 |
| 5680 __ fill_w(w0, t0); |
| 5681 __ fill_w(w2, t0); |
| 5682 |
| 5683 __ FmoveLow(f0, t1); |
| 5684 __ FmoveHigh(f2, t1); |
| 5685 |
| 5686 #define STORE_MSA_REG(w_reg, base, scratch) \ |
| 5687 __ copy_u_w(scratch, w_reg, 0); \ |
| 5688 __ sw(scratch, MemOperand(base, offsetof(T, w0))); \ |
| 5689 __ copy_u_w(scratch, w_reg, 1); \ |
| 5690 __ sw(scratch, MemOperand(base, offsetof(T, w1))); \ |
| 5691 __ copy_u_w(scratch, w_reg, 2); \ |
| 5692 __ sw(scratch, MemOperand(base, offsetof(T, w2))); \ |
| 5693 __ copy_u_w(scratch, w_reg, 3); \ |
| 5694 __ sw(scratch, MemOperand(base, offsetof(T, w3))); |
| 5695 |
| 5696 STORE_MSA_REG(w0, a0, t2) |
| 5697 STORE_MSA_REG(w2, a1, t2) |
| 5698 #undef STORE_MSA_REG |
| 5699 |
| 5700 __ jr(ra); |
| 5701 __ nop(); |
| 5702 } |
| 5703 |
| 5704 CodeDesc desc; |
| 5705 assm.GetCode(&desc); |
| 5706 Handle<Code> code = isolate->factory()->NewCode( |
| 5707 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 5708 #ifdef OBJECT_PRINT |
| 5709 code->Print(std::cout); |
| 5710 #endif |
| 5711 F4 f = FUNCTION_CAST<F4>(code->entry()); |
| 5712 |
| 5713 Object* dummy = CALL_GENERATED_CODE(isolate, f, &t[0], &t[1], 0, 0, 0); |
| 5714 USE(dummy); |
| 5715 |
| 5716 CHECK_EQ(0x55555555, t[0].w0); |
| 5717 CHECK_EQ(0xaaaaaaaa, t[0].w1); |
| 5718 CHECK_EQ(0xaaaaaaaa, t[0].w2); |
| 5719 CHECK_EQ(0xaaaaaaaa, t[0].w3); |
| 5720 CHECK_EQ(0xaaaaaaaa, t[1].w0); |
| 5721 CHECK_EQ(0x55555555, t[1].w1); |
| 5722 CHECK_EQ(0xaaaaaaaa, t[1].w2); |
| 5723 CHECK_EQ(0xaaaaaaaa, t[1].w3); |
| 5724 } |
| 5725 |
| 5726 TEST(MSA_fill_copy_3) { |
| 5727 // Similar to MSA_fill_copy test, but also check overlaping between MSA and |
| 5728 // FPU registers with same numbers |
| 5729 CcTest::InitializeVM(); |
| 5730 Isolate* isolate = CcTest::i_isolate(); |
| 5731 HandleScope scope(isolate); |
| 5732 |
| 5733 typedef struct { |
| 5734 uint64_t d0; |
| 5735 uint64_t d1; |
| 5736 } T; |
| 5737 T t[2]; |
| 5738 |
| 5739 MacroAssembler assm(isolate, NULL, 0, v8::internal::CodeObjectRequired::kYes); |
| 5740 if (!IsMipsArchVariant(kMips32r6) || !CpuFeatures::IsSupported(MIPS_SIMD)) |
| 5741 return; |
| 5742 |
| 5743 { |
| 5744 CpuFeatureScope fscope(&assm, MIPS_SIMD); |
| 5745 |
| 5746 __ li(t0, 0xaaaaaaaa); |
| 5747 __ li(t1, 0x55555555); |
| 5748 |
| 5749 __ Move(f0, t0, t0); |
| 5750 __ Move(f2, t0, t0); |
| 5751 |
| 5752 __ fill_w(w0, t1); |
| 5753 __ fill_w(w2, t1); |
| 5754 |
| 5755 __ Sdc1(f0, MemOperand(a0, offsetof(T, d0))); |
| 5756 __ Sdc1(f2, MemOperand(a1, offsetof(T, d0))); |
| 5757 |
| 5758 __ jr(ra); |
| 5759 __ nop(); |
| 5760 } |
| 5761 |
| 5762 CodeDesc desc; |
| 5763 assm.GetCode(&desc); |
| 5764 Handle<Code> code = isolate->factory()->NewCode( |
| 5765 desc, Code::ComputeFlags(Code::STUB), Handle<Code>()); |
| 5766 #ifdef OBJECT_PRINT |
| 5767 code->Print(std::cout); |
| 5768 #endif |
| 5769 F4 f = FUNCTION_CAST<F4>(code->entry()); |
| 5770 |
| 5771 Object* dummy = CALL_GENERATED_CODE(isolate, f, &t[0], &t[1], 0, 0, 0); |
| 5772 USE(dummy); |
| 5773 |
| 5774 CHECK_EQ(0x5555555555555555, t[0].d0); |
| 5775 CHECK_EQ(0x5555555555555555, t[1].d0); |
| 5776 } |
| 5777 |
5590 #undef __ | 5778 #undef __ |
OLD | NEW |