OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 "test/unittests/compiler/instruction-selector-unittest.h" | 5 #include "test/unittests/compiler/instruction-selector-unittest.h" |
6 | 6 |
7 namespace v8 { | 7 namespace v8 { |
8 namespace internal { | 8 namespace internal { |
9 namespace compiler { | 9 namespace compiler { |
10 | 10 |
11 namespace { | 11 namespace { |
12 | 12 |
13 // Immediates (random subset). | 13 // Immediates (random subset). |
14 const int32_t kImmediates[] = {kMinInt, -42, -1, 0, 1, 2, | 14 const int32_t kImmediates[] = {kMinInt, -42, -1, 0, 1, 2, |
15 3, 4, 5, 6, 7, 8, | 15 3, 4, 5, 6, 7, 8, |
16 16, 42, 0xff, 0xffff, 0x0f0f0f0f, kMaxInt}; | 16 16, 42, 0xff, 0xffff, 0x0f0f0f0f, kMaxInt}; |
17 | 17 |
18 } // namespace | 18 } // namespace |
19 | 19 |
20 | 20 |
21 TEST_F(InstructionSelectorTest, Int32AddWithParameter) { | 21 TEST_F(InstructionSelectorTest, Int32AddWithParameter) { |
22 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 22 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 23 MachineType::Int32()); |
23 m.Return(m.Int32Add(m.Parameter(0), m.Parameter(1))); | 24 m.Return(m.Int32Add(m.Parameter(0), m.Parameter(1))); |
24 Stream s = m.Build(); | 25 Stream s = m.Build(); |
25 ASSERT_EQ(1U, s.size()); | 26 ASSERT_EQ(1U, s.size()); |
26 EXPECT_EQ(kIA32Lea, s[0]->arch_opcode()); | 27 EXPECT_EQ(kIA32Lea, s[0]->arch_opcode()); |
27 } | 28 } |
28 | 29 |
29 | 30 |
30 TEST_F(InstructionSelectorTest, Int32AddWithImmediate) { | 31 TEST_F(InstructionSelectorTest, Int32AddWithImmediate) { |
31 TRACED_FOREACH(int32_t, imm, kImmediates) { | 32 TRACED_FOREACH(int32_t, imm, kImmediates) { |
32 { | 33 { |
33 StreamBuilder m(this, kMachInt32, kMachInt32); | 34 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
34 m.Return(m.Int32Add(m.Parameter(0), m.Int32Constant(imm))); | 35 m.Return(m.Int32Add(m.Parameter(0), m.Int32Constant(imm))); |
35 Stream s = m.Build(); | 36 Stream s = m.Build(); |
36 ASSERT_EQ(1U, s.size()); | 37 ASSERT_EQ(1U, s.size()); |
37 EXPECT_EQ(kIA32Lea, s[0]->arch_opcode()); | 38 EXPECT_EQ(kIA32Lea, s[0]->arch_opcode()); |
38 if (imm == 0) { | 39 if (imm == 0) { |
39 ASSERT_EQ(1U, s[0]->InputCount()); | 40 ASSERT_EQ(1U, s[0]->InputCount()); |
40 } else { | 41 } else { |
41 ASSERT_EQ(2U, s[0]->InputCount()); | 42 ASSERT_EQ(2U, s[0]->InputCount()); |
42 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 43 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
43 } | 44 } |
44 } | 45 } |
45 { | 46 { |
46 StreamBuilder m(this, kMachInt32, kMachInt32); | 47 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
47 m.Return(m.Int32Add(m.Int32Constant(imm), m.Parameter(0))); | 48 m.Return(m.Int32Add(m.Int32Constant(imm), m.Parameter(0))); |
48 Stream s = m.Build(); | 49 Stream s = m.Build(); |
49 ASSERT_EQ(1U, s.size()); | 50 ASSERT_EQ(1U, s.size()); |
50 EXPECT_EQ(kIA32Lea, s[0]->arch_opcode()); | 51 EXPECT_EQ(kIA32Lea, s[0]->arch_opcode()); |
51 if (imm == 0) { | 52 if (imm == 0) { |
52 ASSERT_EQ(1U, s[0]->InputCount()); | 53 ASSERT_EQ(1U, s[0]->InputCount()); |
53 } else { | 54 } else { |
54 ASSERT_EQ(2U, s[0]->InputCount()); | 55 ASSERT_EQ(2U, s[0]->InputCount()); |
55 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 56 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
56 } | 57 } |
57 } | 58 } |
58 } | 59 } |
59 } | 60 } |
60 | 61 |
61 | 62 |
62 TEST_F(InstructionSelectorTest, Int32SubWithParameter) { | 63 TEST_F(InstructionSelectorTest, Int32SubWithParameter) { |
63 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 64 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 65 MachineType::Int32()); |
64 m.Return(m.Int32Sub(m.Parameter(0), m.Parameter(1))); | 66 m.Return(m.Int32Sub(m.Parameter(0), m.Parameter(1))); |
65 Stream s = m.Build(); | 67 Stream s = m.Build(); |
66 ASSERT_EQ(1U, s.size()); | 68 ASSERT_EQ(1U, s.size()); |
67 EXPECT_EQ(kIA32Sub, s[0]->arch_opcode()); | 69 EXPECT_EQ(kIA32Sub, s[0]->arch_opcode()); |
68 EXPECT_EQ(1U, s[0]->OutputCount()); | 70 EXPECT_EQ(1U, s[0]->OutputCount()); |
69 } | 71 } |
70 | 72 |
71 | 73 |
72 TEST_F(InstructionSelectorTest, Int32SubWithImmediate) { | 74 TEST_F(InstructionSelectorTest, Int32SubWithImmediate) { |
73 TRACED_FOREACH(int32_t, imm, kImmediates) { | 75 TRACED_FOREACH(int32_t, imm, kImmediates) { |
74 StreamBuilder m(this, kMachInt32, kMachInt32); | 76 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
75 m.Return(m.Int32Sub(m.Parameter(0), m.Int32Constant(imm))); | 77 m.Return(m.Int32Sub(m.Parameter(0), m.Int32Constant(imm))); |
76 Stream s = m.Build(); | 78 Stream s = m.Build(); |
77 ASSERT_EQ(1U, s.size()); | 79 ASSERT_EQ(1U, s.size()); |
78 EXPECT_EQ(kIA32Sub, s[0]->arch_opcode()); | 80 EXPECT_EQ(kIA32Sub, s[0]->arch_opcode()); |
79 ASSERT_EQ(2U, s[0]->InputCount()); | 81 ASSERT_EQ(2U, s[0]->InputCount()); |
80 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); | 82 EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1))); |
81 } | 83 } |
82 } | 84 } |
83 | 85 |
84 | 86 |
85 // ----------------------------------------------------------------------------- | 87 // ----------------------------------------------------------------------------- |
86 // Conversions. | 88 // Conversions. |
87 | 89 |
88 | 90 |
89 TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter) { | 91 TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter) { |
90 StreamBuilder m(this, kMachFloat32, kMachFloat64); | 92 StreamBuilder m(this, MachineType::Float32(), MachineType::Float64()); |
91 m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0))); | 93 m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0))); |
92 Stream s = m.Build(); | 94 Stream s = m.Build(); |
93 ASSERT_EQ(1U, s.size()); | 95 ASSERT_EQ(1U, s.size()); |
94 EXPECT_EQ(kSSEFloat32ToFloat64, s[0]->arch_opcode()); | 96 EXPECT_EQ(kSSEFloat32ToFloat64, s[0]->arch_opcode()); |
95 EXPECT_EQ(1U, s[0]->InputCount()); | 97 EXPECT_EQ(1U, s[0]->InputCount()); |
96 EXPECT_EQ(1U, s[0]->OutputCount()); | 98 EXPECT_EQ(1U, s[0]->OutputCount()); |
97 } | 99 } |
98 | 100 |
99 | 101 |
100 TEST_F(InstructionSelectorTest, TruncateFloat64ToFloat32WithParameter) { | 102 TEST_F(InstructionSelectorTest, TruncateFloat64ToFloat32WithParameter) { |
101 StreamBuilder m(this, kMachFloat64, kMachFloat32); | 103 StreamBuilder m(this, MachineType::Float64(), MachineType::Float32()); |
102 m.Return(m.TruncateFloat64ToFloat32(m.Parameter(0))); | 104 m.Return(m.TruncateFloat64ToFloat32(m.Parameter(0))); |
103 Stream s = m.Build(); | 105 Stream s = m.Build(); |
104 ASSERT_EQ(1U, s.size()); | 106 ASSERT_EQ(1U, s.size()); |
105 EXPECT_EQ(kSSEFloat64ToFloat32, s[0]->arch_opcode()); | 107 EXPECT_EQ(kSSEFloat64ToFloat32, s[0]->arch_opcode()); |
106 EXPECT_EQ(1U, s[0]->InputCount()); | 108 EXPECT_EQ(1U, s[0]->InputCount()); |
107 EXPECT_EQ(1U, s[0]->OutputCount()); | 109 EXPECT_EQ(1U, s[0]->OutputCount()); |
108 } | 110 } |
109 | 111 |
110 | 112 |
111 // ----------------------------------------------------------------------------- | 113 // ----------------------------------------------------------------------------- |
112 // Better left operand for commutative binops | 114 // Better left operand for commutative binops |
113 | 115 |
114 | 116 |
115 TEST_F(InstructionSelectorTest, BetterLeftOperandTestAddBinop) { | 117 TEST_F(InstructionSelectorTest, BetterLeftOperandTestAddBinop) { |
116 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 118 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 119 MachineType::Int32()); |
117 Node* param1 = m.Parameter(0); | 120 Node* param1 = m.Parameter(0); |
118 Node* param2 = m.Parameter(1); | 121 Node* param2 = m.Parameter(1); |
119 Node* add = m.Int32Add(param1, param2); | 122 Node* add = m.Int32Add(param1, param2); |
120 m.Return(m.Int32Add(add, param1)); | 123 m.Return(m.Int32Add(add, param1)); |
121 Stream s = m.Build(); | 124 Stream s = m.Build(); |
122 ASSERT_EQ(2U, s.size()); | 125 ASSERT_EQ(2U, s.size()); |
123 EXPECT_EQ(kIA32Lea, s[0]->arch_opcode()); | 126 EXPECT_EQ(kIA32Lea, s[0]->arch_opcode()); |
124 ASSERT_EQ(2U, s[0]->InputCount()); | 127 ASSERT_EQ(2U, s[0]->InputCount()); |
125 ASSERT_TRUE(s[0]->InputAt(0)->IsUnallocated()); | 128 ASSERT_TRUE(s[0]->InputAt(0)->IsUnallocated()); |
126 EXPECT_EQ(s.ToVreg(param1), s.ToVreg(s[0]->InputAt(0))); | 129 EXPECT_EQ(s.ToVreg(param1), s.ToVreg(s[0]->InputAt(0))); |
127 EXPECT_EQ(s.ToVreg(param2), s.ToVreg(s[0]->InputAt(1))); | 130 EXPECT_EQ(s.ToVreg(param2), s.ToVreg(s[0]->InputAt(1))); |
128 ASSERT_EQ(2U, s[1]->InputCount()); | 131 ASSERT_EQ(2U, s[1]->InputCount()); |
129 EXPECT_EQ(s.ToVreg(param1), s.ToVreg(s[0]->InputAt(0))); | 132 EXPECT_EQ(s.ToVreg(param1), s.ToVreg(s[0]->InputAt(0))); |
130 } | 133 } |
131 | 134 |
132 | 135 |
133 TEST_F(InstructionSelectorTest, BetterLeftOperandTestMulBinop) { | 136 TEST_F(InstructionSelectorTest, BetterLeftOperandTestMulBinop) { |
134 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 137 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 138 MachineType::Int32()); |
135 Node* param1 = m.Parameter(0); | 139 Node* param1 = m.Parameter(0); |
136 Node* param2 = m.Parameter(1); | 140 Node* param2 = m.Parameter(1); |
137 Node* mul = m.Int32Mul(param1, param2); | 141 Node* mul = m.Int32Mul(param1, param2); |
138 m.Return(m.Int32Mul(mul, param1)); | 142 m.Return(m.Int32Mul(mul, param1)); |
139 Stream s = m.Build(); | 143 Stream s = m.Build(); |
140 ASSERT_EQ(2U, s.size()); | 144 ASSERT_EQ(2U, s.size()); |
141 EXPECT_EQ(kIA32Imul, s[0]->arch_opcode()); | 145 EXPECT_EQ(kIA32Imul, s[0]->arch_opcode()); |
142 ASSERT_EQ(2U, s[0]->InputCount()); | 146 ASSERT_EQ(2U, s[0]->InputCount()); |
143 ASSERT_TRUE(s[0]->InputAt(0)->IsUnallocated()); | 147 ASSERT_TRUE(s[0]->InputAt(0)->IsUnallocated()); |
144 EXPECT_EQ(s.ToVreg(param2), s.ToVreg(s[0]->InputAt(0))); | 148 EXPECT_EQ(s.ToVreg(param2), s.ToVreg(s[0]->InputAt(0))); |
145 EXPECT_EQ(s.ToVreg(param1), s.ToVreg(s[0]->InputAt(1))); | 149 EXPECT_EQ(s.ToVreg(param1), s.ToVreg(s[0]->InputAt(1))); |
146 } | 150 } |
147 | 151 |
148 | 152 |
149 // ----------------------------------------------------------------------------- | 153 // ----------------------------------------------------------------------------- |
150 // Conversions. | 154 // Conversions. |
151 | 155 |
152 | 156 |
153 TEST_F(InstructionSelectorTest, ChangeUint32ToFloat64WithParameter) { | 157 TEST_F(InstructionSelectorTest, ChangeUint32ToFloat64WithParameter) { |
154 StreamBuilder m(this, kMachFloat64, kMachUint32); | 158 StreamBuilder m(this, MachineType::Float64(), MachineType::Uint32()); |
155 m.Return(m.ChangeUint32ToFloat64(m.Parameter(0))); | 159 m.Return(m.ChangeUint32ToFloat64(m.Parameter(0))); |
156 Stream s = m.Build(); | 160 Stream s = m.Build(); |
157 ASSERT_EQ(1U, s.size()); | 161 ASSERT_EQ(1U, s.size()); |
158 EXPECT_EQ(kSSEUint32ToFloat64, s[0]->arch_opcode()); | 162 EXPECT_EQ(kSSEUint32ToFloat64, s[0]->arch_opcode()); |
159 } | 163 } |
160 | 164 |
161 | 165 |
162 // ----------------------------------------------------------------------------- | 166 // ----------------------------------------------------------------------------- |
163 // Loads and stores | 167 // Loads and stores |
164 | 168 |
165 | 169 |
166 namespace { | 170 namespace { |
167 | 171 |
168 struct MemoryAccess { | 172 struct MemoryAccess { |
169 MachineType type; | 173 MachineType type; |
170 ArchOpcode load_opcode; | 174 ArchOpcode load_opcode; |
171 ArchOpcode store_opcode; | 175 ArchOpcode store_opcode; |
172 }; | 176 }; |
173 | 177 |
174 | 178 |
175 std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) { | 179 std::ostream& operator<<(std::ostream& os, const MemoryAccess& memacc) { |
176 return os << memacc.type; | 180 return os << memacc.type; |
177 } | 181 } |
178 | 182 |
179 | 183 |
180 static const MemoryAccess kMemoryAccesses[] = { | 184 static const MemoryAccess kMemoryAccesses[] = { |
181 {kMachInt8, kIA32Movsxbl, kIA32Movb}, | 185 {MachineType::Int8(), kIA32Movsxbl, kIA32Movb}, |
182 {kMachUint8, kIA32Movzxbl, kIA32Movb}, | 186 {MachineType::Uint8(), kIA32Movzxbl, kIA32Movb}, |
183 {kMachInt16, kIA32Movsxwl, kIA32Movw}, | 187 {MachineType::Int16(), kIA32Movsxwl, kIA32Movw}, |
184 {kMachUint16, kIA32Movzxwl, kIA32Movw}, | 188 {MachineType::Uint16(), kIA32Movzxwl, kIA32Movw}, |
185 {kMachInt32, kIA32Movl, kIA32Movl}, | 189 {MachineType::Int32(), kIA32Movl, kIA32Movl}, |
186 {kMachUint32, kIA32Movl, kIA32Movl}, | 190 {MachineType::Uint32(), kIA32Movl, kIA32Movl}, |
187 {kMachFloat32, kIA32Movss, kIA32Movss}, | 191 {MachineType::Float32(), kIA32Movss, kIA32Movss}, |
188 {kMachFloat64, kIA32Movsd, kIA32Movsd}}; | 192 {MachineType::Float64(), kIA32Movsd, kIA32Movsd}}; |
189 | 193 |
190 } // namespace | 194 } // namespace |
191 | 195 |
192 | 196 |
193 typedef InstructionSelectorTestWithParam<MemoryAccess> | 197 typedef InstructionSelectorTestWithParam<MemoryAccess> |
194 InstructionSelectorMemoryAccessTest; | 198 InstructionSelectorMemoryAccessTest; |
195 | 199 |
196 | 200 |
197 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) { | 201 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithParameters) { |
198 const MemoryAccess memacc = GetParam(); | 202 const MemoryAccess memacc = GetParam(); |
199 StreamBuilder m(this, memacc.type, kMachPtr, kMachInt32); | 203 StreamBuilder m(this, memacc.type, MachineType::Pointer(), |
| 204 MachineType::Int32()); |
200 m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1))); | 205 m.Return(m.Load(memacc.type, m.Parameter(0), m.Parameter(1))); |
201 Stream s = m.Build(); | 206 Stream s = m.Build(); |
202 ASSERT_EQ(1U, s.size()); | 207 ASSERT_EQ(1U, s.size()); |
203 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode()); | 208 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode()); |
204 EXPECT_EQ(2U, s[0]->InputCount()); | 209 EXPECT_EQ(2U, s[0]->InputCount()); |
205 EXPECT_EQ(1U, s[0]->OutputCount()); | 210 EXPECT_EQ(1U, s[0]->OutputCount()); |
206 } | 211 } |
207 | 212 |
208 | 213 |
209 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateBase) { | 214 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateBase) { |
210 const MemoryAccess memacc = GetParam(); | 215 const MemoryAccess memacc = GetParam(); |
211 TRACED_FOREACH(int32_t, base, kImmediates) { | 216 TRACED_FOREACH(int32_t, base, kImmediates) { |
212 StreamBuilder m(this, memacc.type, kMachPtr); | 217 StreamBuilder m(this, memacc.type, MachineType::Pointer()); |
213 m.Return(m.Load(memacc.type, m.Int32Constant(base), m.Parameter(0))); | 218 m.Return(m.Load(memacc.type, m.Int32Constant(base), m.Parameter(0))); |
214 Stream s = m.Build(); | 219 Stream s = m.Build(); |
215 ASSERT_EQ(1U, s.size()); | 220 ASSERT_EQ(1U, s.size()); |
216 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode()); | 221 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode()); |
217 if (base == 0) { | 222 if (base == 0) { |
218 ASSERT_EQ(1U, s[0]->InputCount()); | 223 ASSERT_EQ(1U, s[0]->InputCount()); |
219 } else { | 224 } else { |
220 ASSERT_EQ(2U, s[0]->InputCount()); | 225 ASSERT_EQ(2U, s[0]->InputCount()); |
221 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 226 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
222 EXPECT_EQ(base, s.ToInt32(s[0]->InputAt(1))); | 227 EXPECT_EQ(base, s.ToInt32(s[0]->InputAt(1))); |
223 } | 228 } |
224 EXPECT_EQ(1U, s[0]->OutputCount()); | 229 EXPECT_EQ(1U, s[0]->OutputCount()); |
225 } | 230 } |
226 } | 231 } |
227 | 232 |
228 | 233 |
229 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) { | 234 TEST_P(InstructionSelectorMemoryAccessTest, LoadWithImmediateIndex) { |
230 const MemoryAccess memacc = GetParam(); | 235 const MemoryAccess memacc = GetParam(); |
231 TRACED_FOREACH(int32_t, index, kImmediates) { | 236 TRACED_FOREACH(int32_t, index, kImmediates) { |
232 StreamBuilder m(this, memacc.type, kMachPtr); | 237 StreamBuilder m(this, memacc.type, MachineType::Pointer()); |
233 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index))); | 238 m.Return(m.Load(memacc.type, m.Parameter(0), m.Int32Constant(index))); |
234 Stream s = m.Build(); | 239 Stream s = m.Build(); |
235 ASSERT_EQ(1U, s.size()); | 240 ASSERT_EQ(1U, s.size()); |
236 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode()); | 241 EXPECT_EQ(memacc.load_opcode, s[0]->arch_opcode()); |
237 if (index == 0) { | 242 if (index == 0) { |
238 ASSERT_EQ(1U, s[0]->InputCount()); | 243 ASSERT_EQ(1U, s[0]->InputCount()); |
239 } else { | 244 } else { |
240 ASSERT_EQ(2U, s[0]->InputCount()); | 245 ASSERT_EQ(2U, s[0]->InputCount()); |
241 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 246 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
242 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); | 247 EXPECT_EQ(index, s.ToInt32(s[0]->InputAt(1))); |
243 } | 248 } |
244 EXPECT_EQ(1U, s[0]->OutputCount()); | 249 EXPECT_EQ(1U, s[0]->OutputCount()); |
245 } | 250 } |
246 } | 251 } |
247 | 252 |
248 | 253 |
249 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { | 254 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithParameters) { |
250 const MemoryAccess memacc = GetParam(); | 255 const MemoryAccess memacc = GetParam(); |
251 StreamBuilder m(this, kMachInt32, kMachPtr, kMachInt32, memacc.type); | 256 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 257 MachineType::Int32(), memacc.type); |
252 m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2), | 258 m.Store(memacc.type, m.Parameter(0), m.Parameter(1), m.Parameter(2), |
253 kNoWriteBarrier); | 259 kNoWriteBarrier); |
254 m.Return(m.Int32Constant(0)); | 260 m.Return(m.Int32Constant(0)); |
255 Stream s = m.Build(); | 261 Stream s = m.Build(); |
256 ASSERT_EQ(1U, s.size()); | 262 ASSERT_EQ(1U, s.size()); |
257 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode()); | 263 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode()); |
258 EXPECT_EQ(3U, s[0]->InputCount()); | 264 EXPECT_EQ(3U, s[0]->InputCount()); |
259 EXPECT_EQ(0U, s[0]->OutputCount()); | 265 EXPECT_EQ(0U, s[0]->OutputCount()); |
260 } | 266 } |
261 | 267 |
262 | 268 |
263 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateBase) { | 269 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateBase) { |
264 const MemoryAccess memacc = GetParam(); | 270 const MemoryAccess memacc = GetParam(); |
265 TRACED_FOREACH(int32_t, base, kImmediates) { | 271 TRACED_FOREACH(int32_t, base, kImmediates) { |
266 StreamBuilder m(this, kMachInt32, kMachInt32, memacc.type); | 272 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 273 memacc.type); |
267 m.Store(memacc.type, m.Int32Constant(base), m.Parameter(0), m.Parameter(1), | 274 m.Store(memacc.type, m.Int32Constant(base), m.Parameter(0), m.Parameter(1), |
268 kNoWriteBarrier); | 275 kNoWriteBarrier); |
269 m.Return(m.Int32Constant(0)); | 276 m.Return(m.Int32Constant(0)); |
270 Stream s = m.Build(); | 277 Stream s = m.Build(); |
271 ASSERT_EQ(1U, s.size()); | 278 ASSERT_EQ(1U, s.size()); |
272 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode()); | 279 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode()); |
273 if (base == 0) { | 280 if (base == 0) { |
274 ASSERT_EQ(2U, s[0]->InputCount()); | 281 ASSERT_EQ(2U, s[0]->InputCount()); |
275 } else { | 282 } else { |
276 ASSERT_EQ(3U, s[0]->InputCount()); | 283 ASSERT_EQ(3U, s[0]->InputCount()); |
277 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 284 ASSERT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
278 EXPECT_EQ(base, s.ToInt32(s[0]->InputAt(1))); | 285 EXPECT_EQ(base, s.ToInt32(s[0]->InputAt(1))); |
279 } | 286 } |
280 EXPECT_EQ(0U, s[0]->OutputCount()); | 287 EXPECT_EQ(0U, s[0]->OutputCount()); |
281 } | 288 } |
282 } | 289 } |
283 | 290 |
284 | 291 |
285 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) { | 292 TEST_P(InstructionSelectorMemoryAccessTest, StoreWithImmediateIndex) { |
286 const MemoryAccess memacc = GetParam(); | 293 const MemoryAccess memacc = GetParam(); |
287 TRACED_FOREACH(int32_t, index, kImmediates) { | 294 TRACED_FOREACH(int32_t, index, kImmediates) { |
288 StreamBuilder m(this, kMachInt32, kMachPtr, memacc.type); | 295 StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(), |
| 296 memacc.type); |
289 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1), | 297 m.Store(memacc.type, m.Parameter(0), m.Int32Constant(index), m.Parameter(1), |
290 kNoWriteBarrier); | 298 kNoWriteBarrier); |
291 m.Return(m.Int32Constant(0)); | 299 m.Return(m.Int32Constant(0)); |
292 Stream s = m.Build(); | 300 Stream s = m.Build(); |
293 ASSERT_EQ(1U, s.size()); | 301 ASSERT_EQ(1U, s.size()); |
294 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode()); | 302 EXPECT_EQ(memacc.store_opcode, s[0]->arch_opcode()); |
295 if (index == 0) { | 303 if (index == 0) { |
296 ASSERT_EQ(2U, s[0]->InputCount()); | 304 ASSERT_EQ(2U, s[0]->InputCount()); |
297 } else { | 305 } else { |
298 ASSERT_EQ(3U, s[0]->InputCount()); | 306 ASSERT_EQ(3U, s[0]->InputCount()); |
(...skipping 14 matching lines...) Expand all Loading... |
313 // AddressingMode for loads and stores. | 321 // AddressingMode for loads and stores. |
314 | 322 |
315 | 323 |
316 class AddressingModeUnitTest : public InstructionSelectorTest { | 324 class AddressingModeUnitTest : public InstructionSelectorTest { |
317 public: | 325 public: |
318 AddressingModeUnitTest() : m(NULL) { Reset(); } | 326 AddressingModeUnitTest() : m(NULL) { Reset(); } |
319 ~AddressingModeUnitTest() { delete m; } | 327 ~AddressingModeUnitTest() { delete m; } |
320 | 328 |
321 void Run(Node* base, Node* load_index, Node* store_index, | 329 void Run(Node* base, Node* load_index, Node* store_index, |
322 AddressingMode mode) { | 330 AddressingMode mode) { |
323 Node* load = m->Load(kMachInt32, base, load_index); | 331 Node* load = m->Load(MachineType::Int32(), base, load_index); |
324 m->Store(kMachInt32, base, store_index, load, kNoWriteBarrier); | 332 m->Store(MachineType::Int32(), base, store_index, load, kNoWriteBarrier); |
325 m->Return(m->Int32Constant(0)); | 333 m->Return(m->Int32Constant(0)); |
326 Stream s = m->Build(); | 334 Stream s = m->Build(); |
327 ASSERT_EQ(2U, s.size()); | 335 ASSERT_EQ(2U, s.size()); |
328 EXPECT_EQ(mode, s[0]->addressing_mode()); | 336 EXPECT_EQ(mode, s[0]->addressing_mode()); |
329 EXPECT_EQ(mode, s[1]->addressing_mode()); | 337 EXPECT_EQ(mode, s[1]->addressing_mode()); |
330 } | 338 } |
331 | 339 |
332 Node* zero; | 340 Node* zero; |
333 Node* null_ptr; | 341 Node* null_ptr; |
334 Node* non_zero; | 342 Node* non_zero; |
335 Node* base_reg; // opaque value to generate base as register | 343 Node* base_reg; // opaque value to generate base as register |
336 Node* index_reg; // opaque value to generate index as register | 344 Node* index_reg; // opaque value to generate index as register |
337 Node* scales[4]; | 345 Node* scales[4]; |
338 StreamBuilder* m; | 346 StreamBuilder* m; |
339 | 347 |
340 void Reset() { | 348 void Reset() { |
341 delete m; | 349 delete m; |
342 m = new StreamBuilder(this, kMachInt32, kMachInt32, kMachInt32); | 350 m = new StreamBuilder(this, MachineType::Int32(), MachineType::Int32(), |
| 351 MachineType::Int32()); |
343 zero = m->Int32Constant(0); | 352 zero = m->Int32Constant(0); |
344 null_ptr = m->Int32Constant(0); | 353 null_ptr = m->Int32Constant(0); |
345 non_zero = m->Int32Constant(127); | 354 non_zero = m->Int32Constant(127); |
346 base_reg = m->Parameter(0); | 355 base_reg = m->Parameter(0); |
347 index_reg = m->Parameter(0); | 356 index_reg = m->Parameter(0); |
348 | 357 |
349 scales[0] = m->Int32Constant(1); | 358 scales[0] = m->Int32Constant(1); |
350 scales[1] = m->Int32Constant(2); | 359 scales[1] = m->Int32Constant(2); |
351 scales[2] = m->Int32Constant(4); | 360 scales[2] = m->Int32Constant(4); |
352 scales[3] = m->Int32Constant(8); | 361 scales[3] = m->Int32Constant(8); |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 return kMode_MRI; | 567 return kMode_MRI; |
559 default: | 568 default: |
560 UNREACHABLE(); | 569 UNREACHABLE(); |
561 return kMode_None; | 570 return kMode_None; |
562 } | 571 } |
563 } | 572 } |
564 | 573 |
565 | 574 |
566 TEST_P(InstructionSelectorMultTest, Mult32) { | 575 TEST_P(InstructionSelectorMultTest, Mult32) { |
567 const MultParam m_param = GetParam(); | 576 const MultParam m_param = GetParam(); |
568 StreamBuilder m(this, kMachInt32, kMachInt32); | 577 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
569 Node* param = m.Parameter(0); | 578 Node* param = m.Parameter(0); |
570 Node* mult = m.Int32Mul(param, m.Int32Constant(m_param.value)); | 579 Node* mult = m.Int32Mul(param, m.Int32Constant(m_param.value)); |
571 m.Return(mult); | 580 m.Return(mult); |
572 Stream s = m.Build(); | 581 Stream s = m.Build(); |
573 ASSERT_EQ(1U, s.size()); | 582 ASSERT_EQ(1U, s.size()); |
574 EXPECT_EQ(m_param.addressing_mode, s[0]->addressing_mode()); | 583 EXPECT_EQ(m_param.addressing_mode, s[0]->addressing_mode()); |
575 if (m_param.lea_expected) { | 584 if (m_param.lea_expected) { |
576 EXPECT_EQ(kIA32Lea, s[0]->arch_opcode()); | 585 EXPECT_EQ(kIA32Lea, s[0]->arch_opcode()); |
577 ASSERT_EQ(InputCountForLea(s[0]->addressing_mode()), s[0]->InputCount()); | 586 ASSERT_EQ(InputCountForLea(s[0]->addressing_mode()), s[0]->InputCount()); |
578 } else { | 587 } else { |
579 EXPECT_EQ(kIA32Imul, s[0]->arch_opcode()); | 588 EXPECT_EQ(kIA32Imul, s[0]->arch_opcode()); |
580 ASSERT_EQ(2U, s[0]->InputCount()); | 589 ASSERT_EQ(2U, s[0]->InputCount()); |
581 } | 590 } |
582 EXPECT_EQ(s.ToVreg(param), s.ToVreg(s[0]->InputAt(0))); | 591 EXPECT_EQ(s.ToVreg(param), s.ToVreg(s[0]->InputAt(0))); |
583 } | 592 } |
584 | 593 |
585 | 594 |
586 TEST_P(InstructionSelectorMultTest, MultAdd32) { | 595 TEST_P(InstructionSelectorMultTest, MultAdd32) { |
587 TRACED_FOREACH(int32_t, imm, kImmediates) { | 596 TRACED_FOREACH(int32_t, imm, kImmediates) { |
588 const MultParam m_param = GetParam(); | 597 const MultParam m_param = GetParam(); |
589 StreamBuilder m(this, kMachInt32, kMachInt32); | 598 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
590 Node* param = m.Parameter(0); | 599 Node* param = m.Parameter(0); |
591 Node* mult = m.Int32Add(m.Int32Mul(param, m.Int32Constant(m_param.value)), | 600 Node* mult = m.Int32Add(m.Int32Mul(param, m.Int32Constant(m_param.value)), |
592 m.Int32Constant(imm)); | 601 m.Int32Constant(imm)); |
593 m.Return(mult); | 602 m.Return(mult); |
594 Stream s = m.Build(); | 603 Stream s = m.Build(); |
595 if (m_param.lea_expected) { | 604 if (m_param.lea_expected) { |
596 ASSERT_EQ(1U, s.size()); | 605 ASSERT_EQ(1U, s.size()); |
597 EXPECT_EQ(kIA32Lea, s[0]->arch_opcode()); | 606 EXPECT_EQ(kIA32Lea, s[0]->arch_opcode()); |
598 EXPECT_EQ(AddressingModeForAddMult(imm, m_param), | 607 EXPECT_EQ(AddressingModeForAddMult(imm, m_param), |
599 s[0]->addressing_mode()); | 608 s[0]->addressing_mode()); |
(...skipping 11 matching lines...) Expand all Loading... |
611 } | 620 } |
612 } | 621 } |
613 } | 622 } |
614 | 623 |
615 | 624 |
616 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMultTest, | 625 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMultTest, |
617 ::testing::ValuesIn(kMultParams)); | 626 ::testing::ValuesIn(kMultParams)); |
618 | 627 |
619 | 628 |
620 TEST_F(InstructionSelectorTest, Int32MulHigh) { | 629 TEST_F(InstructionSelectorTest, Int32MulHigh) { |
621 StreamBuilder m(this, kMachInt32, kMachInt32, kMachInt32); | 630 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(), |
| 631 MachineType::Int32()); |
622 Node* const p0 = m.Parameter(0); | 632 Node* const p0 = m.Parameter(0); |
623 Node* const p1 = m.Parameter(1); | 633 Node* const p1 = m.Parameter(1); |
624 Node* const n = m.Int32MulHigh(p0, p1); | 634 Node* const n = m.Int32MulHigh(p0, p1); |
625 m.Return(n); | 635 m.Return(n); |
626 Stream s = m.Build(); | 636 Stream s = m.Build(); |
627 ASSERT_EQ(1U, s.size()); | 637 ASSERT_EQ(1U, s.size()); |
628 EXPECT_EQ(kIA32ImulHigh, s[0]->arch_opcode()); | 638 EXPECT_EQ(kIA32ImulHigh, s[0]->arch_opcode()); |
629 ASSERT_EQ(2U, s[0]->InputCount()); | 639 ASSERT_EQ(2U, s[0]->InputCount()); |
630 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 640 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
631 EXPECT_TRUE(s.IsFixed(s[0]->InputAt(0), eax)); | 641 EXPECT_TRUE(s.IsFixed(s[0]->InputAt(0), eax)); |
632 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); | 642 EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1))); |
633 EXPECT_TRUE(!s.IsUsedAtStart(s[0]->InputAt(1))); | 643 EXPECT_TRUE(!s.IsUsedAtStart(s[0]->InputAt(1))); |
634 ASSERT_EQ(1U, s[0]->OutputCount()); | 644 ASSERT_EQ(1U, s[0]->OutputCount()); |
635 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 645 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
636 EXPECT_TRUE(s.IsFixed(s[0]->OutputAt(0), edx)); | 646 EXPECT_TRUE(s.IsFixed(s[0]->OutputAt(0), edx)); |
637 } | 647 } |
638 | 648 |
639 | 649 |
640 // ----------------------------------------------------------------------------- | 650 // ----------------------------------------------------------------------------- |
641 // Floating point operations. | 651 // Floating point operations. |
642 | 652 |
643 | 653 |
644 TEST_F(InstructionSelectorTest, Float32Abs) { | 654 TEST_F(InstructionSelectorTest, Float32Abs) { |
645 { | 655 { |
646 StreamBuilder m(this, kMachFloat32, kMachFloat32); | 656 StreamBuilder m(this, MachineType::Float32(), MachineType::Float32()); |
647 Node* const p0 = m.Parameter(0); | 657 Node* const p0 = m.Parameter(0); |
648 Node* const n = m.Float32Abs(p0); | 658 Node* const n = m.Float32Abs(p0); |
649 m.Return(n); | 659 m.Return(n); |
650 Stream s = m.Build(); | 660 Stream s = m.Build(); |
651 ASSERT_EQ(1U, s.size()); | 661 ASSERT_EQ(1U, s.size()); |
652 EXPECT_EQ(kSSEFloat32Abs, s[0]->arch_opcode()); | 662 EXPECT_EQ(kSSEFloat32Abs, s[0]->arch_opcode()); |
653 ASSERT_EQ(1U, s[0]->InputCount()); | 663 ASSERT_EQ(1U, s[0]->InputCount()); |
654 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 664 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
655 ASSERT_EQ(1U, s[0]->OutputCount()); | 665 ASSERT_EQ(1U, s[0]->OutputCount()); |
656 EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output())); | 666 EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output())); |
657 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 667 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
658 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); | 668 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
659 } | 669 } |
660 { | 670 { |
661 StreamBuilder m(this, kMachFloat32, kMachFloat32); | 671 StreamBuilder m(this, MachineType::Float32(), MachineType::Float32()); |
662 Node* const p0 = m.Parameter(0); | 672 Node* const p0 = m.Parameter(0); |
663 Node* const n = m.Float32Abs(p0); | 673 Node* const n = m.Float32Abs(p0); |
664 m.Return(n); | 674 m.Return(n); |
665 Stream s = m.Build(AVX); | 675 Stream s = m.Build(AVX); |
666 ASSERT_EQ(1U, s.size()); | 676 ASSERT_EQ(1U, s.size()); |
667 EXPECT_EQ(kAVXFloat32Abs, s[0]->arch_opcode()); | 677 EXPECT_EQ(kAVXFloat32Abs, s[0]->arch_opcode()); |
668 ASSERT_EQ(1U, s[0]->InputCount()); | 678 ASSERT_EQ(1U, s[0]->InputCount()); |
669 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 679 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
670 ASSERT_EQ(1U, s[0]->OutputCount()); | 680 ASSERT_EQ(1U, s[0]->OutputCount()); |
671 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 681 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
672 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); | 682 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
673 } | 683 } |
674 } | 684 } |
675 | 685 |
676 | 686 |
677 TEST_F(InstructionSelectorTest, Float64Abs) { | 687 TEST_F(InstructionSelectorTest, Float64Abs) { |
678 { | 688 { |
679 StreamBuilder m(this, kMachFloat64, kMachFloat64); | 689 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64()); |
680 Node* const p0 = m.Parameter(0); | 690 Node* const p0 = m.Parameter(0); |
681 Node* const n = m.Float64Abs(p0); | 691 Node* const n = m.Float64Abs(p0); |
682 m.Return(n); | 692 m.Return(n); |
683 Stream s = m.Build(); | 693 Stream s = m.Build(); |
684 ASSERT_EQ(1U, s.size()); | 694 ASSERT_EQ(1U, s.size()); |
685 EXPECT_EQ(kSSEFloat64Abs, s[0]->arch_opcode()); | 695 EXPECT_EQ(kSSEFloat64Abs, s[0]->arch_opcode()); |
686 ASSERT_EQ(1U, s[0]->InputCount()); | 696 ASSERT_EQ(1U, s[0]->InputCount()); |
687 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 697 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
688 ASSERT_EQ(1U, s[0]->OutputCount()); | 698 ASSERT_EQ(1U, s[0]->OutputCount()); |
689 EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output())); | 699 EXPECT_TRUE(s.IsSameAsFirst(s[0]->Output())); |
690 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 700 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
691 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); | 701 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
692 } | 702 } |
693 { | 703 { |
694 StreamBuilder m(this, kMachFloat64, kMachFloat64); | 704 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64()); |
695 Node* const p0 = m.Parameter(0); | 705 Node* const p0 = m.Parameter(0); |
696 Node* const n = m.Float64Abs(p0); | 706 Node* const n = m.Float64Abs(p0); |
697 m.Return(n); | 707 m.Return(n); |
698 Stream s = m.Build(AVX); | 708 Stream s = m.Build(AVX); |
699 ASSERT_EQ(1U, s.size()); | 709 ASSERT_EQ(1U, s.size()); |
700 EXPECT_EQ(kAVXFloat64Abs, s[0]->arch_opcode()); | 710 EXPECT_EQ(kAVXFloat64Abs, s[0]->arch_opcode()); |
701 ASSERT_EQ(1U, s[0]->InputCount()); | 711 ASSERT_EQ(1U, s[0]->InputCount()); |
702 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 712 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
703 ASSERT_EQ(1U, s[0]->OutputCount()); | 713 ASSERT_EQ(1U, s[0]->OutputCount()); |
704 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 714 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
705 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); | 715 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
706 } | 716 } |
707 } | 717 } |
708 | 718 |
709 | 719 |
710 TEST_F(InstructionSelectorTest, Float64BinopArithmetic) { | 720 TEST_F(InstructionSelectorTest, Float64BinopArithmetic) { |
711 { | 721 { |
712 StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64); | 722 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64(), |
| 723 MachineType::Float64()); |
713 Node* add = m.Float64Add(m.Parameter(0), m.Parameter(1)); | 724 Node* add = m.Float64Add(m.Parameter(0), m.Parameter(1)); |
714 Node* mul = m.Float64Mul(add, m.Parameter(1)); | 725 Node* mul = m.Float64Mul(add, m.Parameter(1)); |
715 Node* sub = m.Float64Sub(mul, add); | 726 Node* sub = m.Float64Sub(mul, add); |
716 Node* ret = m.Float64Div(mul, sub); | 727 Node* ret = m.Float64Div(mul, sub); |
717 m.Return(ret); | 728 m.Return(ret); |
718 Stream s = m.Build(AVX); | 729 Stream s = m.Build(AVX); |
719 ASSERT_EQ(4U, s.size()); | 730 ASSERT_EQ(4U, s.size()); |
720 EXPECT_EQ(kAVXFloat64Add, s[0]->arch_opcode()); | 731 EXPECT_EQ(kAVXFloat64Add, s[0]->arch_opcode()); |
721 EXPECT_EQ(kAVXFloat64Mul, s[1]->arch_opcode()); | 732 EXPECT_EQ(kAVXFloat64Mul, s[1]->arch_opcode()); |
722 EXPECT_EQ(kAVXFloat64Sub, s[2]->arch_opcode()); | 733 EXPECT_EQ(kAVXFloat64Sub, s[2]->arch_opcode()); |
723 EXPECT_EQ(kAVXFloat64Div, s[3]->arch_opcode()); | 734 EXPECT_EQ(kAVXFloat64Div, s[3]->arch_opcode()); |
724 } | 735 } |
725 { | 736 { |
726 StreamBuilder m(this, kMachFloat64, kMachFloat64, kMachFloat64); | 737 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64(), |
| 738 MachineType::Float64()); |
727 Node* add = m.Float64Add(m.Parameter(0), m.Parameter(1)); | 739 Node* add = m.Float64Add(m.Parameter(0), m.Parameter(1)); |
728 Node* mul = m.Float64Mul(add, m.Parameter(1)); | 740 Node* mul = m.Float64Mul(add, m.Parameter(1)); |
729 Node* sub = m.Float64Sub(mul, add); | 741 Node* sub = m.Float64Sub(mul, add); |
730 Node* ret = m.Float64Div(mul, sub); | 742 Node* ret = m.Float64Div(mul, sub); |
731 m.Return(ret); | 743 m.Return(ret); |
732 Stream s = m.Build(); | 744 Stream s = m.Build(); |
733 ASSERT_EQ(4U, s.size()); | 745 ASSERT_EQ(4U, s.size()); |
734 EXPECT_EQ(kSSEFloat64Add, s[0]->arch_opcode()); | 746 EXPECT_EQ(kSSEFloat64Add, s[0]->arch_opcode()); |
735 EXPECT_EQ(kSSEFloat64Mul, s[1]->arch_opcode()); | 747 EXPECT_EQ(kSSEFloat64Mul, s[1]->arch_opcode()); |
736 EXPECT_EQ(kSSEFloat64Sub, s[2]->arch_opcode()); | 748 EXPECT_EQ(kSSEFloat64Sub, s[2]->arch_opcode()); |
737 EXPECT_EQ(kSSEFloat64Div, s[3]->arch_opcode()); | 749 EXPECT_EQ(kSSEFloat64Div, s[3]->arch_opcode()); |
738 } | 750 } |
739 } | 751 } |
740 | 752 |
741 | 753 |
742 TEST_F(InstructionSelectorTest, Float32SubWithMinusZeroAndParameter) { | 754 TEST_F(InstructionSelectorTest, Float32SubWithMinusZeroAndParameter) { |
743 { | 755 { |
744 StreamBuilder m(this, kMachFloat32, kMachFloat32); | 756 StreamBuilder m(this, MachineType::Float32(), MachineType::Float32()); |
745 Node* const p0 = m.Parameter(0); | 757 Node* const p0 = m.Parameter(0); |
746 Node* const n = m.Float32Sub(m.Float32Constant(-0.0f), p0); | 758 Node* const n = m.Float32Sub(m.Float32Constant(-0.0f), p0); |
747 m.Return(n); | 759 m.Return(n); |
748 Stream s = m.Build(); | 760 Stream s = m.Build(); |
749 ASSERT_EQ(1U, s.size()); | 761 ASSERT_EQ(1U, s.size()); |
750 EXPECT_EQ(kSSEFloat32Neg, s[0]->arch_opcode()); | 762 EXPECT_EQ(kSSEFloat32Neg, s[0]->arch_opcode()); |
751 ASSERT_EQ(1U, s[0]->InputCount()); | 763 ASSERT_EQ(1U, s[0]->InputCount()); |
752 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 764 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
753 ASSERT_EQ(1U, s[0]->OutputCount()); | 765 ASSERT_EQ(1U, s[0]->OutputCount()); |
754 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 766 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
755 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); | 767 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
756 } | 768 } |
757 { | 769 { |
758 StreamBuilder m(this, kMachFloat32, kMachFloat32); | 770 StreamBuilder m(this, MachineType::Float32(), MachineType::Float32()); |
759 Node* const p0 = m.Parameter(0); | 771 Node* const p0 = m.Parameter(0); |
760 Node* const n = m.Float32Sub(m.Float32Constant(-0.0f), p0); | 772 Node* const n = m.Float32Sub(m.Float32Constant(-0.0f), p0); |
761 m.Return(n); | 773 m.Return(n); |
762 Stream s = m.Build(AVX); | 774 Stream s = m.Build(AVX); |
763 ASSERT_EQ(1U, s.size()); | 775 ASSERT_EQ(1U, s.size()); |
764 EXPECT_EQ(kAVXFloat32Neg, s[0]->arch_opcode()); | 776 EXPECT_EQ(kAVXFloat32Neg, s[0]->arch_opcode()); |
765 ASSERT_EQ(1U, s[0]->InputCount()); | 777 ASSERT_EQ(1U, s[0]->InputCount()); |
766 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 778 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
767 ASSERT_EQ(1U, s[0]->OutputCount()); | 779 ASSERT_EQ(1U, s[0]->OutputCount()); |
768 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 780 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
769 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); | 781 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
770 } | 782 } |
771 } | 783 } |
772 | 784 |
773 | 785 |
774 TEST_F(InstructionSelectorTest, Float64SubWithMinusZeroAndParameter) { | 786 TEST_F(InstructionSelectorTest, Float64SubWithMinusZeroAndParameter) { |
775 { | 787 { |
776 StreamBuilder m(this, kMachFloat64, kMachFloat64); | 788 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64()); |
777 Node* const p0 = m.Parameter(0); | 789 Node* const p0 = m.Parameter(0); |
778 Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0); | 790 Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0); |
779 m.Return(n); | 791 m.Return(n); |
780 Stream s = m.Build(); | 792 Stream s = m.Build(); |
781 ASSERT_EQ(1U, s.size()); | 793 ASSERT_EQ(1U, s.size()); |
782 EXPECT_EQ(kSSEFloat64Neg, s[0]->arch_opcode()); | 794 EXPECT_EQ(kSSEFloat64Neg, s[0]->arch_opcode()); |
783 ASSERT_EQ(1U, s[0]->InputCount()); | 795 ASSERT_EQ(1U, s[0]->InputCount()); |
784 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 796 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
785 ASSERT_EQ(1U, s[0]->OutputCount()); | 797 ASSERT_EQ(1U, s[0]->OutputCount()); |
786 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 798 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
787 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); | 799 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
788 } | 800 } |
789 { | 801 { |
790 StreamBuilder m(this, kMachFloat64, kMachFloat64); | 802 StreamBuilder m(this, MachineType::Float64(), MachineType::Float64()); |
791 Node* const p0 = m.Parameter(0); | 803 Node* const p0 = m.Parameter(0); |
792 Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0); | 804 Node* const n = m.Float64Sub(m.Float64Constant(-0.0), p0); |
793 m.Return(n); | 805 m.Return(n); |
794 Stream s = m.Build(AVX); | 806 Stream s = m.Build(AVX); |
795 ASSERT_EQ(1U, s.size()); | 807 ASSERT_EQ(1U, s.size()); |
796 EXPECT_EQ(kAVXFloat64Neg, s[0]->arch_opcode()); | 808 EXPECT_EQ(kAVXFloat64Neg, s[0]->arch_opcode()); |
797 ASSERT_EQ(1U, s[0]->InputCount()); | 809 ASSERT_EQ(1U, s[0]->InputCount()); |
798 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 810 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
799 ASSERT_EQ(1U, s[0]->OutputCount()); | 811 ASSERT_EQ(1U, s[0]->OutputCount()); |
800 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 812 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
801 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); | 813 EXPECT_EQ(kFlags_none, s[0]->flags_mode()); |
802 } | 814 } |
803 } | 815 } |
804 | 816 |
805 | 817 |
806 // ----------------------------------------------------------------------------- | 818 // ----------------------------------------------------------------------------- |
807 // Miscellaneous. | 819 // Miscellaneous. |
808 | 820 |
809 | 821 |
810 TEST_F(InstructionSelectorTest, Uint32LessThanWithLoadAndLoadStackPointer) { | 822 TEST_F(InstructionSelectorTest, Uint32LessThanWithLoadAndLoadStackPointer) { |
811 StreamBuilder m(this, kMachBool); | 823 StreamBuilder m(this, MachineType::Bool()); |
812 Node* const sl = m.Load( | 824 Node* const sl = m.Load( |
813 kMachPtr, | 825 MachineType::Pointer(), |
814 m.ExternalConstant(ExternalReference::address_of_stack_limit(isolate()))); | 826 m.ExternalConstant(ExternalReference::address_of_stack_limit(isolate()))); |
815 Node* const sp = m.LoadStackPointer(); | 827 Node* const sp = m.LoadStackPointer(); |
816 Node* const n = m.Uint32LessThan(sl, sp); | 828 Node* const n = m.Uint32LessThan(sl, sp); |
817 m.Return(n); | 829 m.Return(n); |
818 Stream s = m.Build(); | 830 Stream s = m.Build(); |
819 ASSERT_EQ(1U, s.size()); | 831 ASSERT_EQ(1U, s.size()); |
820 EXPECT_EQ(kIA32StackCheck, s[0]->arch_opcode()); | 832 EXPECT_EQ(kIA32StackCheck, s[0]->arch_opcode()); |
821 ASSERT_EQ(0U, s[0]->InputCount()); | 833 ASSERT_EQ(0U, s[0]->InputCount()); |
822 ASSERT_EQ(1U, s[0]->OutputCount()); | 834 ASSERT_EQ(1U, s[0]->OutputCount()); |
823 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 835 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
824 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); | 836 EXPECT_EQ(kFlags_set, s[0]->flags_mode()); |
825 EXPECT_EQ(kUnsignedGreaterThan, s[0]->flags_condition()); | 837 EXPECT_EQ(kUnsignedGreaterThan, s[0]->flags_condition()); |
826 } | 838 } |
827 | 839 |
828 | 840 |
829 TEST_F(InstructionSelectorTest, Word32Clz) { | 841 TEST_F(InstructionSelectorTest, Word32Clz) { |
830 StreamBuilder m(this, kMachUint32, kMachUint32); | 842 StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32()); |
831 Node* const p0 = m.Parameter(0); | 843 Node* const p0 = m.Parameter(0); |
832 Node* const n = m.Word32Clz(p0); | 844 Node* const n = m.Word32Clz(p0); |
833 m.Return(n); | 845 m.Return(n); |
834 Stream s = m.Build(); | 846 Stream s = m.Build(); |
835 ASSERT_EQ(1U, s.size()); | 847 ASSERT_EQ(1U, s.size()); |
836 EXPECT_EQ(kIA32Lzcnt, s[0]->arch_opcode()); | 848 EXPECT_EQ(kIA32Lzcnt, s[0]->arch_opcode()); |
837 ASSERT_EQ(1U, s[0]->InputCount()); | 849 ASSERT_EQ(1U, s[0]->InputCount()); |
838 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 850 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
839 ASSERT_EQ(1U, s[0]->OutputCount()); | 851 ASSERT_EQ(1U, s[0]->OutputCount()); |
840 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 852 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
841 } | 853 } |
842 | 854 |
843 } // namespace compiler | 855 } // namespace compiler |
844 } // namespace internal | 856 } // namespace internal |
845 } // namespace v8 | 857 } // namespace v8 |
OLD | NEW |