Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: src/compiler/x64/instruction-selector-x64-unittest.cc

Issue 615483003: [turbofan] x64 lea multiplication matching (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/compiler/x64/instruction-selector-x64.cc ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "src/compiler/instruction-selector-unittest.h" 5 #include "src/compiler/instruction-selector-unittest.h"
6 #include "src/compiler/node-matchers.h"
6 7
7 namespace v8 { 8 namespace v8 {
8 namespace internal { 9 namespace internal {
9 namespace compiler { 10 namespace compiler {
10 11
11 // ----------------------------------------------------------------------------- 12 // -----------------------------------------------------------------------------
12 // Conversions. 13 // Conversions.
13 14
14 15
15 TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter) { 16 TEST_F(InstructionSelectorTest, ChangeFloat32ToFloat64WithParameter) {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 ASSERT_EQ(2U, s.size()); 178 ASSERT_EQ(2U, s.size());
178 EXPECT_EQ(mode, s[0]->addressing_mode()); 179 EXPECT_EQ(mode, s[0]->addressing_mode());
179 EXPECT_EQ(mode, s[1]->addressing_mode()); 180 EXPECT_EQ(mode, s[1]->addressing_mode());
180 } 181 }
181 182
182 Node* zero; 183 Node* zero;
183 Node* null_ptr; 184 Node* null_ptr;
184 Node* non_zero; 185 Node* non_zero;
185 Node* base_reg; // opaque value to generate base as register 186 Node* base_reg; // opaque value to generate base as register
186 Node* index_reg; // opaque value to generate index as register 187 Node* index_reg; // opaque value to generate index as register
187 Node* scales[4]; 188 Node* scales[arraysize(ScaleFactorMatcher::kMatchedFactors)];
188 StreamBuilder* m; 189 StreamBuilder* m;
189 190
190 void Reset() { 191 void Reset() {
191 delete m; 192 delete m;
192 m = new StreamBuilder(this, kMachInt32, kMachInt32, kMachInt32); 193 m = new StreamBuilder(this, kMachInt32, kMachInt32, kMachInt32);
193 zero = m->Int32Constant(0); 194 zero = m->Int32Constant(0);
194 null_ptr = m->Int64Constant(0); 195 null_ptr = m->Int64Constant(0);
195 non_zero = m->Int32Constant(127); 196 non_zero = m->Int32Constant(127);
196 base_reg = m->Parameter(0); 197 base_reg = m->Parameter(0);
197 index_reg = m->Parameter(0); 198 index_reg = m->Parameter(0);
198 199 for (size_t i = 0; i < arraysize(ScaleFactorMatcher::kMatchedFactors);
199 scales[0] = m->Int32Constant(1); 200 ++i) {
200 scales[1] = m->Int32Constant(2); 201 scales[i] = m->Int32Constant(ScaleFactorMatcher::kMatchedFactors[i]);
201 scales[2] = m->Int32Constant(4); 202 }
202 scales[3] = m->Int32Constant(8);
203 } 203 }
204 }; 204 };
205 205
206 206
207 TEST_F(AddressingModeUnitTest, AddressingMode_MR) { 207 TEST_F(AddressingModeUnitTest, AddressingMode_MR) {
208 Node* base = base_reg; 208 Node* base = base_reg;
209 Node* index = zero; 209 Node* index = zero;
210 Run(base, index, kMode_MR); 210 Run(base, index, kMode_MR);
211 } 211 }
212 212
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 TEST_F(AddressingModeUnitTest, AddressingMode_MNI) { 282 TEST_F(AddressingModeUnitTest, AddressingMode_MNI) {
283 AddressingMode expected[] = {kMode_M1I, kMode_M2I, kMode_M4I, kMode_M8I}; 283 AddressingMode expected[] = {kMode_M1I, kMode_M2I, kMode_M4I, kMode_M8I};
284 for (size_t i = 0; i < arraysize(scales); ++i) { 284 for (size_t i = 0; i < arraysize(scales); ++i) {
285 Reset(); 285 Reset();
286 Node* base = null_ptr; 286 Node* base = null_ptr;
287 Node* index = m->Int32Add(m->Int32Mul(index_reg, scales[i]), non_zero); 287 Node* index = m->Int32Add(m->Int32Mul(index_reg, scales[i]), non_zero);
288 Run(base, index, expected[i]); 288 Run(base, index, expected[i]);
289 } 289 }
290 } 290 }
291 291
292
293 // -----------------------------------------------------------------------------
294 // Multiplication.
295
296 namespace {
297
298 struct MultParam {
299 int value;
300 bool lea_expected;
301 AddressingMode addressing_mode;
302 };
303
304
305 std::ostream& operator<<(std::ostream& os, const MultParam& m) {
306 OStringStream ost;
307 ost << m.value << "." << m.lea_expected << "." << m.addressing_mode;
308 return os << ost.c_str();
309 }
310
311
312 const MultParam kMultParams[] = {{-1, false, kMode_None},
313 {0, false, kMode_None},
314 {1, true, kMode_M1},
315 {2, true, kMode_M2},
316 {3, true, kMode_MR2},
317 {4, true, kMode_M4},
318 {5, true, kMode_MR4},
319 {6, false, kMode_None},
320 {7, false, kMode_None},
321 {8, true, kMode_M8},
322 {9, true, kMode_MR8},
323 {10, false, kMode_None},
324 {11, false, kMode_None}};
325
326 } // namespace
327
328
329 typedef InstructionSelectorTestWithParam<MultParam> InstructionSelectorMultTest;
330
331
332 static unsigned InputCountForLea(AddressingMode mode) {
333 switch (mode) {
334 case kMode_MR1:
335 case kMode_MR2:
336 case kMode_MR4:
337 case kMode_MR8:
338 return 2U;
339 case kMode_M1:
340 case kMode_M2:
341 case kMode_M4:
342 case kMode_M8:
343 return 1U;
344 default:
345 UNREACHABLE();
346 return 0U;
347 }
348 }
349
350
351 TEST_P(InstructionSelectorMultTest, Mult32) {
352 const MultParam m_param = GetParam();
353 StreamBuilder m(this, kMachInt32, kMachInt32);
354 Node* param = m.Parameter(0);
355 Node* mult = m.Int32Mul(param, m.Int32Constant(m_param.value));
356 m.Return(mult);
357 Stream s = m.Build();
358 ASSERT_EQ(1U, s.size());
359 EXPECT_EQ(m_param.addressing_mode, s[0]->addressing_mode());
360 if (m_param.lea_expected) {
361 EXPECT_EQ(kX64Lea32, s[0]->arch_opcode());
362 ASSERT_EQ(InputCountForLea(s[0]->addressing_mode()), s[0]->InputCount());
363 } else {
364 EXPECT_EQ(kX64Imul32, s[0]->arch_opcode());
365 ASSERT_EQ(2U, s[0]->InputCount());
366 }
367 EXPECT_EQ(param->id(), s.ToVreg(s[0]->InputAt(0)));
368 }
369
370
371 TEST_P(InstructionSelectorMultTest, Mult64) {
372 const MultParam m_param = GetParam();
373 StreamBuilder m(this, kMachInt64, kMachInt64);
374 Node* param = m.Parameter(0);
375 Node* mult = m.Int64Mul(param, m.Int64Constant(m_param.value));
376 m.Return(mult);
377 Stream s = m.Build();
378 ASSERT_EQ(1U, s.size());
379 EXPECT_EQ(m_param.addressing_mode, s[0]->addressing_mode());
380 if (m_param.lea_expected) {
381 EXPECT_EQ(kX64Lea, s[0]->arch_opcode());
382 ASSERT_EQ(InputCountForLea(s[0]->addressing_mode()), s[0]->InputCount());
383 EXPECT_EQ(param->id(), s.ToVreg(s[0]->InputAt(0)));
384 } else {
385 EXPECT_EQ(kX64Imul, s[0]->arch_opcode());
386 ASSERT_EQ(2U, s[0]->InputCount());
387 // TODO(dcarney): why is this happening?
388 EXPECT_EQ(param->id(), s.ToVreg(s[0]->InputAt(1)));
389 }
390 }
391
392
393 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, InstructionSelectorMultTest,
394 ::testing::ValuesIn(kMultParams));
395
292 } // namespace compiler 396 } // namespace compiler
293 } // namespace internal 397 } // namespace internal
294 } // namespace v8 398 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/x64/instruction-selector-x64.cc ('k') | tools/gyp/v8.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698