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

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

Issue 687193002: [turbofan] Bug fix in arm64 ubfx selection. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 1 month 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 | « no previous file | test/mjsunit/mjsunit.status » ('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-impl.h" 5 #include "src/compiler/instruction-selector-impl.h"
6 #include "src/compiler/node-matchers.h" 6 #include "src/compiler/node-matchers.h"
7 7
8 namespace v8 { 8 namespace v8 {
9 namespace internal { 9 namespace internal {
10 namespace compiler { 10 namespace compiler {
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 uint32_t mask_width = base::bits::CountPopulation32(mask); 431 uint32_t mask_width = base::bits::CountPopulation32(mask);
432 uint32_t mask_msb = base::bits::CountLeadingZeros32(mask); 432 uint32_t mask_msb = base::bits::CountLeadingZeros32(mask);
433 if ((mask_width != 0) && (mask_msb + mask_width == 32)) { 433 if ((mask_width != 0) && (mask_msb + mask_width == 32)) {
434 // The mask must be contiguous, and occupy the least-significant bits. 434 // The mask must be contiguous, and occupy the least-significant bits.
435 DCHECK_EQ(0, base::bits::CountTrailingZeros32(mask)); 435 DCHECK_EQ(0, base::bits::CountTrailingZeros32(mask));
436 436
437 // Select Ubfx for And(Shr(x, imm), mask) where the mask is in the least 437 // Select Ubfx for And(Shr(x, imm), mask) where the mask is in the least
438 // significant bits. 438 // significant bits.
439 Int32BinopMatcher mleft(m.left().node()); 439 Int32BinopMatcher mleft(m.left().node());
440 if (mleft.right().IsInRange(0, 31)) { 440 if (mleft.right().IsInRange(0, 31)) {
441 // Ubfx cannot extract bits past the register size, however since
442 // shifting the original value would have introduced some zeros we can
443 // still use ubfx with a smaller mask and the remaining bits will be
444 // zeros.
445 uint32_t lsb = mleft.right().Value();
446 if (lsb + mask_width > 32) mask_width = 32 - lsb;
447
441 Emit(kArm64Ubfx32, g.DefineAsRegister(node), 448 Emit(kArm64Ubfx32, g.DefineAsRegister(node),
442 g.UseRegister(mleft.left().node()), 449 g.UseRegister(mleft.left().node()),
443 g.UseImmediate(mleft.right().node()), g.TempImmediate(mask_width)); 450 g.UseImmediate(mleft.right().node()), g.TempImmediate(mask_width));
444 return; 451 return;
445 } 452 }
446 // Other cases fall through to the normal And operation. 453 // Other cases fall through to the normal And operation.
447 } 454 }
448 } 455 }
449 VisitLogical<Int32BinopMatcher>( 456 VisitLogical<Int32BinopMatcher>(
450 this, node, &m, kArm64And32, CanCover(node, m.left().node()), 457 this, node, &m, kArm64And32, CanCover(node, m.left().node()),
(...skipping 10 matching lines...) Expand all
461 uint64_t mask_width = base::bits::CountPopulation64(mask); 468 uint64_t mask_width = base::bits::CountPopulation64(mask);
462 uint64_t mask_msb = base::bits::CountLeadingZeros64(mask); 469 uint64_t mask_msb = base::bits::CountLeadingZeros64(mask);
463 if ((mask_width != 0) && (mask_msb + mask_width == 64)) { 470 if ((mask_width != 0) && (mask_msb + mask_width == 64)) {
464 // The mask must be contiguous, and occupy the least-significant bits. 471 // The mask must be contiguous, and occupy the least-significant bits.
465 DCHECK_EQ(0, base::bits::CountTrailingZeros64(mask)); 472 DCHECK_EQ(0, base::bits::CountTrailingZeros64(mask));
466 473
467 // Select Ubfx for And(Shr(x, imm), mask) where the mask is in the least 474 // Select Ubfx for And(Shr(x, imm), mask) where the mask is in the least
468 // significant bits. 475 // significant bits.
469 Int64BinopMatcher mleft(m.left().node()); 476 Int64BinopMatcher mleft(m.left().node());
470 if (mleft.right().IsInRange(0, 63)) { 477 if (mleft.right().IsInRange(0, 63)) {
478 // Ubfx cannot extract bits past the register size, however since
479 // shifting the original value would have introduced some zeros we can
480 // still use ubfx with a smaller mask and the remaining bits will be
481 // zeros.
482 uint64_t lsb = mleft.right().Value();
483 if (lsb + mask_width > 64) mask_width = 64 - lsb;
484
471 Emit(kArm64Ubfx, g.DefineAsRegister(node), 485 Emit(kArm64Ubfx, g.DefineAsRegister(node),
472 g.UseRegister(mleft.left().node()), 486 g.UseRegister(mleft.left().node()),
473 g.UseImmediate(mleft.right().node()), g.TempImmediate(mask_width)); 487 g.UseImmediate(mleft.right().node()), g.TempImmediate(mask_width));
474 return; 488 return;
475 } 489 }
476 // Other cases fall through to the normal And operation. 490 // Other cases fall through to the normal And operation.
477 } 491 }
478 } 492 }
479 VisitLogical<Int64BinopMatcher>( 493 VisitLogical<Int64BinopMatcher>(
480 this, node, &m, kArm64And, CanCover(node, m.left().node()), 494 this, node, &m, kArm64And, CanCover(node, m.left().node()),
(...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after
1302 1316
1303 // static 1317 // static
1304 MachineOperatorBuilder::Flags 1318 MachineOperatorBuilder::Flags
1305 InstructionSelector::SupportedMachineOperatorFlags() { 1319 InstructionSelector::SupportedMachineOperatorFlags() {
1306 return MachineOperatorBuilder::kNoFlags; 1320 return MachineOperatorBuilder::kNoFlags;
1307 } 1321 }
1308 1322
1309 } // namespace compiler 1323 } // namespace compiler
1310 } // namespace internal 1324 } // namespace internal
1311 } // namespace v8 1325 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/mjsunit.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698