OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/assembler.h" | 5 #include "src/assembler.h" |
6 #include "src/codegen.h" | 6 #include "src/codegen.h" |
7 #include "src/compiler/linkage.h" | 7 #include "src/compiler/linkage.h" |
8 #include "src/compiler/machine-type.h" | 8 #include "src/compiler/machine-type.h" |
9 #include "src/compiler/raw-machine-assembler.h" | 9 #include "src/compiler/raw-machine-assembler.h" |
| 10 #include "src/register-configuration.h" |
10 | 11 |
11 #include "test/cctest/cctest.h" | 12 #include "test/cctest/cctest.h" |
12 #include "test/cctest/compiler/codegen-tester.h" | 13 #include "test/cctest/compiler/codegen-tester.h" |
13 #include "test/cctest/compiler/graph-builder-tester.h" | 14 #include "test/cctest/compiler/graph-builder-tester.h" |
14 #include "test/cctest/compiler/value-helper.h" | 15 #include "test/cctest/compiler/value-helper.h" |
15 | 16 |
16 using namespace v8::base; | 17 using namespace v8::base; |
17 using namespace v8::internal; | 18 using namespace v8::internal; |
18 using namespace v8::internal::compiler; | 19 using namespace v8::internal::compiler; |
19 | 20 |
20 typedef RawMachineAssembler::Label MLabel; | 21 typedef RawMachineAssembler::Label MLabel; |
21 | 22 |
22 #if V8_TARGET_ARCH_ARM64 | 23 #if V8_TARGET_ARCH_ARM64 |
23 // TODO(titzer): fix native stack parameters on arm64 | 24 // TODO(titzer): fix native stack parameters on arm64 |
24 #define DISABLE_NATIVE_STACK_PARAMS true | 25 #define DISABLE_NATIVE_STACK_PARAMS true |
25 #else | 26 #else |
26 #define DISABLE_NATIVE_STACK_PARAMS false | 27 #define DISABLE_NATIVE_STACK_PARAMS false |
27 #endif | 28 #endif |
28 | 29 |
29 namespace { | 30 namespace { |
30 typedef float float32; | 31 typedef float float32; |
31 typedef double float64; | 32 typedef double float64; |
32 | 33 |
33 // Picks a representative pair of integers from the given range. | 34 // Picks a representative pair of integers from the given range. |
34 // If there are less than {max_pairs} possible pairs, do them all, otherwise try | 35 // If there are less than {max_pairs} possible pairs, do them all, otherwise try |
35 // to select a representative set. | 36 // to select a representative set. |
36 class Pairs { | 37 class Pairs { |
37 public: | 38 public: |
38 Pairs(int max_pairs, int range) | 39 Pairs(int max_pairs, int range, const int* codes) |
39 : range_(range), | 40 : range_(range), |
| 41 codes_(codes), |
40 max_pairs_(std::min(max_pairs, range_ * range_)), | 42 max_pairs_(std::min(max_pairs, range_ * range_)), |
41 counter_(0) {} | 43 counter_(0) {} |
42 | 44 |
43 bool More() { return counter_ < max_pairs_; } | 45 bool More() { return counter_ < max_pairs_; } |
44 | 46 |
45 void Next(int* r0, int* r1, bool same_is_ok) { | 47 void Next(int* r0, int* r1, bool same_is_ok) { |
46 do { | 48 do { |
47 // Find the next pair. | 49 // Find the next pair. |
48 if (exhaustive()) { | 50 if (exhaustive()) { |
49 *r0 = counter_ % range_; | 51 *r0 = codes_[counter_ % range_]; |
50 *r1 = counter_ / range_; | 52 *r1 = codes_[counter_ / range_]; |
51 } else { | 53 } else { |
52 // Try each integer at least once for both r0 and r1. | 54 // Try each integer at least once for both r0 and r1. |
53 int index = counter_ / 2; | 55 int index = counter_ / 2; |
54 if (counter_ & 1) { | 56 if (counter_ & 1) { |
55 *r0 = index % range_; | 57 *r0 = codes_[index % range_]; |
56 *r1 = index / range_; | 58 *r1 = codes_[index / range_]; |
57 } else { | 59 } else { |
58 *r1 = index % range_; | 60 *r1 = codes_[index % range_]; |
59 *r0 = index / range_; | 61 *r0 = codes_[index / range_]; |
60 } | 62 } |
61 } | 63 } |
62 counter_++; | 64 counter_++; |
63 if (same_is_ok) break; | 65 if ((same_is_ok) || (*r0 != *r1)) break; |
64 if (*r0 == *r1) { | 66 if (counter_ == max_pairs_) { |
65 if (counter_ >= max_pairs_) { | 67 // For the last hurrah, reg#0 with reg#n-1 |
66 // For the last hurrah, reg#0 with reg#n-1 | 68 *r0 = codes_[0]; |
67 *r0 = 0; | 69 *r1 = codes_[range_ - 1]; |
68 *r1 = range_ - 1; | 70 break; |
69 break; | |
70 } | |
71 } | 71 } |
72 } while (true); | 72 } while (true); |
73 | |
74 DCHECK(*r0 >= 0 && *r0 < range_); | |
75 DCHECK(*r1 >= 0 && *r1 < range_); | |
76 } | 73 } |
77 | 74 |
78 private: | 75 private: |
79 int range_; | 76 int range_; |
| 77 const int* codes_; |
80 int max_pairs_; | 78 int max_pairs_; |
81 int counter_; | 79 int counter_; |
82 bool exhaustive() { return max_pairs_ == (range_ * range_); } | 80 bool exhaustive() { return max_pairs_ == (range_ * range_); } |
83 }; | 81 }; |
84 | 82 |
85 | 83 |
86 // Pairs of general purpose registers. | 84 // Pairs of general purpose registers. |
87 class RegisterPairs : public Pairs { | 85 class RegisterPairs : public Pairs { |
88 public: | 86 public: |
89 RegisterPairs() : Pairs(100, Register::kMaxNumAllocatableRegisters) {} | 87 RegisterPairs() |
| 88 : Pairs( |
| 89 100, RegisterConfiguration::ArchDefault() |
| 90 ->num_allocatable_general_registers(), |
| 91 RegisterConfiguration::ArchDefault()->allocatable_general_codes()) { |
| 92 } |
90 }; | 93 }; |
91 | 94 |
92 | 95 |
93 // Pairs of double registers. | 96 // Pairs of double registers. |
94 class Float32RegisterPairs : public Pairs { | 97 class Float32RegisterPairs : public Pairs { |
95 public: | 98 public: |
96 Float32RegisterPairs() | 99 Float32RegisterPairs() |
97 : Pairs(100, DoubleRegister::NumAllocatableAliasedRegisters()) {} | 100 : Pairs( |
| 101 100, RegisterConfiguration::ArchDefault() |
| 102 ->num_allocatable_aliased_double_registers(), |
| 103 RegisterConfiguration::ArchDefault()->allocatable_double_codes()) {} |
98 }; | 104 }; |
99 | 105 |
100 | 106 |
101 // Pairs of double registers. | 107 // Pairs of double registers. |
102 class Float64RegisterPairs : public Pairs { | 108 class Float64RegisterPairs : public Pairs { |
103 public: | 109 public: |
104 Float64RegisterPairs() | 110 Float64RegisterPairs() |
105 : Pairs(100, DoubleRegister::NumAllocatableAliasedRegisters()) {} | 111 : Pairs( |
| 112 100, RegisterConfiguration::ArchDefault() |
| 113 ->num_allocatable_aliased_double_registers(), |
| 114 RegisterConfiguration::ArchDefault()->allocatable_double_codes()) {} |
106 }; | 115 }; |
107 | 116 |
108 | 117 |
109 // Helper for allocating either an GP or FP reg, or the next stack slot. | 118 // Helper for allocating either an GP or FP reg, or the next stack slot. |
110 struct Allocator { | 119 struct Allocator { |
111 Allocator(int* gp, int gpc, int* fp, int fpc) | 120 Allocator(int* gp, int gpc, int* fp, int fpc) |
112 : gp_count(gpc), | 121 : gp_count(gpc), |
113 gp_offset(0), | 122 gp_offset(0), |
114 gp_regs(gp), | 123 gp_regs(gp), |
115 fp_count(fpc), | 124 fp_count(fpc), |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 Allocator params(parray, 2, nullptr, 0); | 626 Allocator params(parray, 2, nullptr, 0); |
618 Allocator rets(rarray, 1, nullptr, 0); | 627 Allocator rets(rarray, 1, nullptr, 0); |
619 RegisterConfig config(params, rets); | 628 RegisterConfig config(params, rets); |
620 CallDescriptor* desc = config.Create(&zone, &sig); | 629 CallDescriptor* desc = config.Create(&zone, &sig); |
621 TestInt32Sub(desc); | 630 TestInt32Sub(desc); |
622 } | 631 } |
623 } | 632 } |
624 | 633 |
625 | 634 |
626 // Separate tests for parallelization. | 635 // Separate tests for parallelization. |
627 #define TEST_INT32_SUB_WITH_RET(x) \ | 636 #define TEST_INT32_SUB_WITH_RET(x) \ |
628 TEST(Run_Int32Sub_all_allocatable_pairs_##x) { \ | 637 TEST(Run_Int32Sub_all_allocatable_pairs_##x) { \ |
629 if (Register::kMaxNumAllocatableRegisters > x) Test_RunInt32SubWithRet(x); \ | 638 if (x < Register::kNumRegisters && \ |
| 639 Register::from_code(x).IsAllocatable()) { \ |
| 640 Test_RunInt32SubWithRet(x); \ |
| 641 } \ |
630 } | 642 } |
631 | 643 |
632 | 644 |
633 TEST_INT32_SUB_WITH_RET(0) | 645 TEST_INT32_SUB_WITH_RET(0) |
634 TEST_INT32_SUB_WITH_RET(1) | 646 TEST_INT32_SUB_WITH_RET(1) |
635 TEST_INT32_SUB_WITH_RET(2) | 647 TEST_INT32_SUB_WITH_RET(2) |
636 TEST_INT32_SUB_WITH_RET(3) | 648 TEST_INT32_SUB_WITH_RET(3) |
637 TEST_INT32_SUB_WITH_RET(4) | 649 TEST_INT32_SUB_WITH_RET(4) |
638 TEST_INT32_SUB_WITH_RET(5) | 650 TEST_INT32_SUB_WITH_RET(5) |
639 TEST_INT32_SUB_WITH_RET(6) | 651 TEST_INT32_SUB_WITH_RET(6) |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 for (int i = 0; i < ParamCount(desc); i++) { | 729 for (int i = 0; i < ParamCount(desc); i++) { |
718 result += static_cast<uint32_t>(input[i]) * coeff[i]; | 730 result += static_cast<uint32_t>(input[i]) * coeff[i]; |
719 } | 731 } |
720 return static_cast<int32_t>(result); | 732 return static_cast<int32_t>(result); |
721 } | 733 } |
722 | 734 |
723 | 735 |
724 static void Test_Int32_WeightedSum_of_size(int count) { | 736 static void Test_Int32_WeightedSum_of_size(int count) { |
725 if (DISABLE_NATIVE_STACK_PARAMS) return; | 737 if (DISABLE_NATIVE_STACK_PARAMS) return; |
726 Int32Signature sig(count); | 738 Int32Signature sig(count); |
727 for (int p0 = 0; p0 < Register::kMaxNumAllocatableRegisters; p0++) { | 739 for (int p0 = 0; p0 < Register::kNumRegisters; p0++) { |
728 Zone zone; | 740 if (Register::from_code(p0).IsAllocatable()) { |
| 741 Zone zone; |
729 | 742 |
730 int parray[] = {p0}; | 743 int parray[] = {p0}; |
731 int rarray[] = {0}; | 744 int rarray[] = {0}; |
732 Allocator params(parray, 1, nullptr, 0); | 745 Allocator params(parray, 1, nullptr, 0); |
733 Allocator rets(rarray, 1, nullptr, 0); | 746 Allocator rets(rarray, 1, nullptr, 0); |
734 RegisterConfig config(params, rets); | 747 RegisterConfig config(params, rets); |
735 CallDescriptor* desc = config.Create(&zone, &sig); | 748 CallDescriptor* desc = config.Create(&zone, &sig); |
736 Run_Computation<int32_t>(desc, Build_Int32_WeightedSum, | 749 Run_Computation<int32_t>(desc, Build_Int32_WeightedSum, |
737 Compute_Int32_WeightedSum, 257 + count); | 750 Compute_Int32_WeightedSum, 257 + count); |
| 751 } |
738 } | 752 } |
739 } | 753 } |
740 | 754 |
741 | 755 |
742 // Separate tests for parallelization. | 756 // Separate tests for parallelization. |
743 #define TEST_INT32_WEIGHTEDSUM(x) \ | 757 #define TEST_INT32_WEIGHTEDSUM(x) \ |
744 TEST(Run_Int32_WeightedSum_##x) { Test_Int32_WeightedSum_of_size(x); } | 758 TEST(Run_Int32_WeightedSum_##x) { Test_Int32_WeightedSum_of_size(x); } |
745 | 759 |
746 | 760 |
747 TEST_INT32_WEIGHTEDSUM(1) | 761 TEST_INT32_WEIGHTEDSUM(1) |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
812 TEST_INT32_SELECT(6) | 826 TEST_INT32_SELECT(6) |
813 TEST_INT32_SELECT(11) | 827 TEST_INT32_SELECT(11) |
814 TEST_INT32_SELECT(15) | 828 TEST_INT32_SELECT(15) |
815 TEST_INT32_SELECT(19) | 829 TEST_INT32_SELECT(19) |
816 TEST_INT32_SELECT(45) | 830 TEST_INT32_SELECT(45) |
817 TEST_INT32_SELECT(62) | 831 TEST_INT32_SELECT(62) |
818 TEST_INT32_SELECT(63) | 832 TEST_INT32_SELECT(63) |
819 | 833 |
820 | 834 |
821 TEST(Int64Select_registers) { | 835 TEST(Int64Select_registers) { |
822 if (Register::kMaxNumAllocatableRegisters < 2) return; | 836 if (RegisterConfiguration::ArchDefault() |
| 837 ->num_allocatable_general_registers() < 2) |
| 838 return; |
823 if (kPointerSize < 8) return; // TODO(titzer): int64 on 32-bit platforms | 839 if (kPointerSize < 8) return; // TODO(titzer): int64 on 32-bit platforms |
824 | 840 |
825 int rarray[] = {0}; | 841 int rarray[] = {0}; |
826 ArgsBuffer<int64_t>::Sig sig(2); | 842 ArgsBuffer<int64_t>::Sig sig(2); |
827 | 843 |
828 RegisterPairs pairs; | 844 RegisterPairs pairs; |
829 Zone zone; | 845 Zone zone; |
830 while (pairs.More()) { | 846 while (pairs.More()) { |
831 int parray[2]; | 847 int parray[2]; |
832 pairs.Next(&parray[0], &parray[1], false); | 848 pairs.Next(&parray[0], &parray[1], false); |
833 Allocator params(parray, 2, nullptr, 0); | 849 Allocator params(parray, 2, nullptr, 0); |
834 Allocator rets(rarray, 1, nullptr, 0); | 850 Allocator rets(rarray, 1, nullptr, 0); |
835 RegisterConfig config(params, rets); | 851 RegisterConfig config(params, rets); |
836 | 852 |
837 CallDescriptor* desc = config.Create(&zone, &sig); | 853 CallDescriptor* desc = config.Create(&zone, &sig); |
838 RunSelect<int64_t, 0>(desc); | 854 RunSelect<int64_t, 0>(desc); |
839 RunSelect<int64_t, 1>(desc); | 855 RunSelect<int64_t, 1>(desc); |
840 } | 856 } |
841 } | 857 } |
842 | 858 |
843 | 859 |
844 TEST(Float32Select_registers) { | 860 TEST(Float32Select_registers) { |
845 if (RegisterConfiguration::ArchDefault()->num_double_registers() < 2) return; | 861 if (RegisterConfiguration::ArchDefault()->num_allocatable_double_registers() < |
| 862 2) { |
| 863 return; |
| 864 } |
846 | 865 |
847 int rarray[] = {0}; | 866 int rarray[] = {0}; |
848 ArgsBuffer<float32>::Sig sig(2); | 867 ArgsBuffer<float32>::Sig sig(2); |
849 | 868 |
850 Float32RegisterPairs pairs; | 869 Float32RegisterPairs pairs; |
851 Zone zone; | 870 Zone zone; |
852 while (pairs.More()) { | 871 while (pairs.More()) { |
853 int parray[2]; | 872 int parray[2]; |
854 pairs.Next(&parray[0], &parray[1], false); | 873 pairs.Next(&parray[0], &parray[1], false); |
855 Allocator params(nullptr, 0, parray, 2); | 874 Allocator params(nullptr, 0, parray, 2); |
856 Allocator rets(nullptr, 0, rarray, 1); | 875 Allocator rets(nullptr, 0, rarray, 1); |
857 RegisterConfig config(params, rets); | 876 RegisterConfig config(params, rets); |
858 | 877 |
859 CallDescriptor* desc = config.Create(&zone, &sig); | 878 CallDescriptor* desc = config.Create(&zone, &sig); |
860 RunSelect<float32, 0>(desc); | 879 RunSelect<float32, 0>(desc); |
861 RunSelect<float32, 1>(desc); | 880 RunSelect<float32, 1>(desc); |
862 } | 881 } |
863 } | 882 } |
864 | 883 |
865 | 884 |
866 TEST(Float64Select_registers) { | 885 TEST(Float64Select_registers) { |
867 if (RegisterConfiguration::ArchDefault()->num_double_registers() < 2) return; | 886 if (RegisterConfiguration::ArchDefault()->num_allocatable_double_registers() < |
868 | 887 2) |
| 888 return; |
| 889 if (RegisterConfiguration::ArchDefault() |
| 890 ->num_allocatable_general_registers() < 2) |
| 891 return; |
869 int rarray[] = {0}; | 892 int rarray[] = {0}; |
870 ArgsBuffer<float64>::Sig sig(2); | 893 ArgsBuffer<float64>::Sig sig(2); |
871 | 894 |
872 Float64RegisterPairs pairs; | 895 Float64RegisterPairs pairs; |
873 Zone zone; | 896 Zone zone; |
874 while (pairs.More()) { | 897 while (pairs.More()) { |
875 int parray[2]; | 898 int parray[2]; |
876 pairs.Next(&parray[0], &parray[1], false); | 899 pairs.Next(&parray[0], &parray[1], false); |
877 Allocator params(nullptr, 0, parray, 2); | 900 Allocator params(nullptr, 0, parray, 2); |
878 Allocator rets(nullptr, 0, rarray, 1); | 901 Allocator rets(nullptr, 0, rarray, 1); |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1092 } | 1115 } |
1093 } | 1116 } |
1094 } | 1117 } |
1095 } | 1118 } |
1096 | 1119 |
1097 | 1120 |
1098 TEST(MixedParams_0) { MixedParamTest(0); } | 1121 TEST(MixedParams_0) { MixedParamTest(0); } |
1099 TEST(MixedParams_1) { MixedParamTest(1); } | 1122 TEST(MixedParams_1) { MixedParamTest(1); } |
1100 TEST(MixedParams_2) { MixedParamTest(2); } | 1123 TEST(MixedParams_2) { MixedParamTest(2); } |
1101 TEST(MixedParams_3) { MixedParamTest(3); } | 1124 TEST(MixedParams_3) { MixedParamTest(3); } |
OLD | NEW |