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

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

Issue 709123005: [arm] Recognize SXTB, SXTH, UXTB and UXTH. (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 | « src/compiler/arm/instruction-codes-arm.h ('k') | test/cctest/test-assembler-arm.cc » ('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/base/bits.h" 5 #include "src/base/bits.h"
6 #include "src/compiler/instruction-selector-impl.h" 6 #include "src/compiler/instruction-selector-impl.h"
7 #include "src/compiler/node-matchers.h" 7 #include "src/compiler/node-matchers.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 case kArmMul: 84 case kArmMul:
85 case kArmMla: 85 case kArmMla:
86 case kArmMls: 86 case kArmMls:
87 case kArmSmmul: 87 case kArmSmmul:
88 case kArmSmmla: 88 case kArmSmmla:
89 case kArmUmull: 89 case kArmUmull:
90 case kArmSdiv: 90 case kArmSdiv:
91 case kArmUdiv: 91 case kArmUdiv:
92 case kArmBfc: 92 case kArmBfc:
93 case kArmUbfx: 93 case kArmUbfx:
94 case kArmSxtb:
95 case kArmSxth:
96 case kArmSxtab:
97 case kArmSxtah:
98 case kArmUxtb:
99 case kArmUxth:
100 case kArmUxtab:
101 case kArmUxtah:
94 case kArmVcmpF64: 102 case kArmVcmpF64:
95 case kArmVaddF64: 103 case kArmVaddF64:
96 case kArmVsubF64: 104 case kArmVsubF64:
97 case kArmVmulF64: 105 case kArmVmulF64:
98 case kArmVmlaF64: 106 case kArmVmlaF64:
99 case kArmVmlsF64: 107 case kArmVmlsF64:
100 case kArmVdivF64: 108 case kArmVdivF64:
101 case kArmVmodF64: 109 case kArmVmodF64:
102 case kArmVnegF64: 110 case kArmVnegF64:
103 case kArmVsqrtF64: 111 case kArmVsqrtF64:
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 static void VisitBinop(InstructionSelector* selector, Node* node, 256 static void VisitBinop(InstructionSelector* selector, Node* node,
249 InstructionCode opcode, InstructionCode reverse_opcode, 257 InstructionCode opcode, InstructionCode reverse_opcode,
250 FlagsContinuation* cont) { 258 FlagsContinuation* cont) {
251 ArmOperandGenerator g(selector); 259 ArmOperandGenerator g(selector);
252 Int32BinopMatcher m(node); 260 Int32BinopMatcher m(node);
253 InstructionOperand* inputs[5]; 261 InstructionOperand* inputs[5];
254 size_t input_count = 0; 262 size_t input_count = 0;
255 InstructionOperand* outputs[2]; 263 InstructionOperand* outputs[2];
256 size_t output_count = 0; 264 size_t output_count = 0;
257 265
258 if (TryMatchImmediateOrShift(selector, &opcode, m.right().node(), 266 if (m.left().node() == m.right().node()) {
259 &input_count, &inputs[1])) { 267 // If both inputs refer to the same operand, enforce allocating a register
268 // for both of them to ensure that we don't end up generating code like
269 // this:
270 //
271 // mov r0, r1, asr #16
272 // adds r0, r0, r1, asr #16
273 // bvs label
274 InstructionOperand* const input = g.UseRegister(m.left().node());
275 opcode |= AddressingModeField::encode(kMode_Operand2_R);
276 inputs[input_count++] = input;
277 inputs[input_count++] = input;
278 } else if (TryMatchImmediateOrShift(selector, &opcode, m.right().node(),
279 &input_count, &inputs[1])) {
260 inputs[0] = g.UseRegister(m.left().node()); 280 inputs[0] = g.UseRegister(m.left().node());
261 input_count++; 281 input_count++;
262 } else if (TryMatchImmediateOrShift(selector, &reverse_opcode, 282 } else if (TryMatchImmediateOrShift(selector, &reverse_opcode,
263 m.left().node(), &input_count, 283 m.left().node(), &input_count,
264 &inputs[1])) { 284 &inputs[1])) {
265 inputs[0] = g.UseRegister(m.right().node()); 285 inputs[0] = g.UseRegister(m.right().node());
266 opcode = reverse_opcode; 286 opcode = reverse_opcode;
267 input_count++; 287 input_count++;
268 } else { 288 } else {
269 opcode |= AddressingModeField::encode(kMode_Operand2_R); 289 opcode |= AddressingModeField::encode(kMode_Operand2_R);
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 return; 443 return;
424 } 444 }
425 } 445 }
426 if (m.right().IsWord32Xor() && CanCover(node, m.right().node())) { 446 if (m.right().IsWord32Xor() && CanCover(node, m.right().node())) {
427 Int32BinopMatcher mright(m.right().node()); 447 Int32BinopMatcher mright(m.right().node());
428 if (mright.right().Is(-1)) { 448 if (mright.right().Is(-1)) {
429 EmitBic(this, node, m.left().node(), mright.left().node()); 449 EmitBic(this, node, m.left().node(), mright.left().node());
430 return; 450 return;
431 } 451 }
432 } 452 }
433 if (IsSupported(ARMv7) && m.right().HasValue()) { 453 if (m.right().HasValue()) {
434 // Try to interpret this AND as UBFX.
435 uint32_t const value = m.right().Value(); 454 uint32_t const value = m.right().Value();
436 uint32_t width = base::bits::CountPopulation32(value); 455 uint32_t width = base::bits::CountPopulation32(value);
437 uint32_t msb = base::bits::CountLeadingZeros32(value); 456 uint32_t msb = base::bits::CountLeadingZeros32(value);
438 if (width != 0 && msb + width == 32) { 457 // Try to interpret this AND as UBFX.
458 if (IsSupported(ARMv7) && width != 0 && msb + width == 32) {
439 DCHECK_EQ(0, base::bits::CountTrailingZeros32(value)); 459 DCHECK_EQ(0, base::bits::CountTrailingZeros32(value));
440 if (m.left().IsWord32Shr()) { 460 if (m.left().IsWord32Shr()) {
441 Int32BinopMatcher mleft(m.left().node()); 461 Int32BinopMatcher mleft(m.left().node());
442 if (mleft.right().IsInRange(0, 31)) { 462 if (mleft.right().IsInRange(0, 31)) {
443 Emit(kArmUbfx, g.DefineAsRegister(node), 463 Emit(kArmUbfx, g.DefineAsRegister(node),
444 g.UseRegister(mleft.left().node()), 464 g.UseRegister(mleft.left().node()),
445 g.UseImmediate(mleft.right().node()), g.TempImmediate(width)); 465 g.UseImmediate(mleft.right().node()), g.TempImmediate(width));
446 return; 466 return;
447 } 467 }
448 } 468 }
449 Emit(kArmUbfx, g.DefineAsRegister(node), g.UseRegister(m.left().node()), 469 Emit(kArmUbfx, g.DefineAsRegister(node), g.UseRegister(m.left().node()),
450 g.TempImmediate(0), g.TempImmediate(width)); 470 g.TempImmediate(0), g.TempImmediate(width));
451 return; 471 return;
452 } 472 }
453
454 // Try to interpret this AND as BIC. 473 // Try to interpret this AND as BIC.
455 if (g.CanBeImmediate(~value)) { 474 if (g.CanBeImmediate(~value)) {
456 Emit(kArmBic | AddressingModeField::encode(kMode_Operand2_I), 475 Emit(kArmBic | AddressingModeField::encode(kMode_Operand2_I),
457 g.DefineAsRegister(node), g.UseRegister(m.left().node()), 476 g.DefineAsRegister(node), g.UseRegister(m.left().node()),
458 g.TempImmediate(~value)); 477 g.TempImmediate(~value));
459 return; 478 return;
460 } 479 }
461 480 // Try to interpret this AND as UXTH.
481 if (value == 0xffff) {
482 Emit(kArmUxth, g.DefineAsRegister(m.node()),
483 g.UseRegister(m.left().node()), g.TempImmediate(0));
484 return;
485 }
462 // Try to interpret this AND as BFC. 486 // Try to interpret this AND as BFC.
463 width = 32 - width; 487 if (IsSupported(ARMv7)) {
464 msb = base::bits::CountLeadingZeros32(~value); 488 width = 32 - width;
465 uint32_t lsb = base::bits::CountTrailingZeros32(~value); 489 msb = base::bits::CountLeadingZeros32(~value);
466 if (msb + width + lsb == 32) { 490 uint32_t lsb = base::bits::CountTrailingZeros32(~value);
467 Emit(kArmBfc, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()), 491 if (msb + width + lsb == 32) {
468 g.TempImmediate(lsb), g.TempImmediate(width)); 492 Emit(kArmBfc, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
469 return; 493 g.TempImmediate(lsb), g.TempImmediate(width));
494 return;
495 }
470 } 496 }
471 } 497 }
472 VisitBinop(this, node, kArmAnd, kArmAnd); 498 VisitBinop(this, node, kArmAnd, kArmAnd);
473 } 499 }
474 500
475 501
476 void InstructionSelector::VisitWord32Or(Node* node) { 502 void InstructionSelector::VisitWord32Or(Node* node) {
477 VisitBinop(this, node, kArmOrr, kArmOrr); 503 VisitBinop(this, node, kArmOrr, kArmOrr);
478 } 504 }
479 505
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 g.TempImmediate(width)); 590 g.TempImmediate(width));
565 return; 591 return;
566 } 592 }
567 } 593 }
568 } 594 }
569 VisitShift(this, node, TryMatchLSR); 595 VisitShift(this, node, TryMatchLSR);
570 } 596 }
571 597
572 598
573 void InstructionSelector::VisitWord32Sar(Node* node) { 599 void InstructionSelector::VisitWord32Sar(Node* node) {
600 ArmOperandGenerator g(this);
601 Int32BinopMatcher m(node);
602 if (CanCover(m.node(), m.left().node()) && m.left().IsWord32Shl()) {
603 Int32BinopMatcher mleft(m.left().node());
604 if (mleft.right().Is(16) && m.right().Is(16)) {
605 Emit(kArmSxth, g.DefineAsRegister(node),
606 g.UseRegister(mleft.left().node()), g.TempImmediate(0));
607 return;
608 } else if (mleft.right().Is(24) && m.right().Is(24)) {
609 Emit(kArmSxtb, g.DefineAsRegister(node),
610 g.UseRegister(mleft.left().node()), g.TempImmediate(0));
611 return;
612 }
613 }
574 VisitShift(this, node, TryMatchASR); 614 VisitShift(this, node, TryMatchASR);
575 } 615 }
576 616
577 617
578 void InstructionSelector::VisitWord32Ror(Node* node) { 618 void InstructionSelector::VisitWord32Ror(Node* node) {
579 VisitShift(this, node, TryMatchROR); 619 VisitShift(this, node, TryMatchROR);
580 } 620 }
581 621
582 622
583 void InstructionSelector::VisitInt32Add(Node* node) { 623 void InstructionSelector::VisitInt32Add(Node* node) {
584 ArmOperandGenerator g(this); 624 ArmOperandGenerator g(this);
585 Int32BinopMatcher m(node); 625 Int32BinopMatcher m(node);
586 if (m.left().IsInt32Mul() && CanCover(node, m.left().node())) { 626 if (CanCover(node, m.left().node())) {
587 Int32BinopMatcher mleft(m.left().node()); 627 switch (m.left().opcode()) {
588 Emit(kArmMla, g.DefineAsRegister(node), g.UseRegister(mleft.left().node()), 628 case IrOpcode::kInt32Mul: {
589 g.UseRegister(mleft.right().node()), g.UseRegister(m.right().node())); 629 Int32BinopMatcher mleft(m.left().node());
590 return; 630 Emit(kArmMla, g.DefineAsRegister(node),
631 g.UseRegister(mleft.left().node()),
632 g.UseRegister(mleft.right().node()),
633 g.UseRegister(m.right().node()));
634 return;
635 }
636 case IrOpcode::kInt32MulHigh: {
637 Int32BinopMatcher mleft(m.left().node());
638 Emit(kArmSmmla, g.DefineAsRegister(node),
639 g.UseRegister(mleft.left().node()),
640 g.UseRegister(mleft.right().node()),
641 g.UseRegister(m.right().node()));
642 return;
643 }
644 case IrOpcode::kWord32And: {
645 Int32BinopMatcher mleft(m.left().node());
646 if (mleft.right().Is(0xff)) {
647 Emit(kArmUxtab, g.DefineAsRegister(node),
648 g.UseRegister(m.right().node()),
649 g.UseRegister(mleft.left().node()), g.TempImmediate(0));
650 return;
651 } else if (mleft.right().Is(0xffff)) {
652 Emit(kArmUxtah, g.DefineAsRegister(node),
653 g.UseRegister(m.right().node()),
654 g.UseRegister(mleft.left().node()), g.TempImmediate(0));
655 return;
656 }
657 }
658 case IrOpcode::kWord32Sar: {
659 Int32BinopMatcher mleft(m.left().node());
660 if (CanCover(mleft.node(), mleft.left().node()) &&
661 mleft.left().IsWord32Shl()) {
662 Int32BinopMatcher mleftleft(mleft.left().node());
663 if (mleft.right().Is(24) && mleftleft.right().Is(24)) {
664 Emit(kArmSxtab, g.DefineAsRegister(node),
665 g.UseRegister(m.right().node()),
666 g.UseRegister(mleftleft.left().node()), g.TempImmediate(0));
667 return;
668 } else if (mleft.right().Is(16) && mleftleft.right().Is(16)) {
669 Emit(kArmSxtah, g.DefineAsRegister(node),
670 g.UseRegister(m.right().node()),
671 g.UseRegister(mleftleft.left().node()), g.TempImmediate(0));
672 return;
673 }
674 }
675 }
676 default:
677 break;
678 }
591 } 679 }
592 if (m.right().IsInt32Mul() && CanCover(node, m.right().node())) { 680 if (CanCover(node, m.right().node())) {
593 Int32BinopMatcher mright(m.right().node()); 681 switch (m.right().opcode()) {
594 Emit(kArmMla, g.DefineAsRegister(node), g.UseRegister(mright.left().node()), 682 case IrOpcode::kInt32Mul: {
595 g.UseRegister(mright.right().node()), g.UseRegister(m.left().node())); 683 Int32BinopMatcher mright(m.right().node());
596 return; 684 Emit(kArmMla, g.DefineAsRegister(node),
597 } 685 g.UseRegister(mright.left().node()),
598 if (m.left().IsInt32MulHigh() && CanCover(node, m.left().node())) { 686 g.UseRegister(mright.right().node()),
599 Int32BinopMatcher mleft(m.left().node()); 687 g.UseRegister(m.left().node()));
600 Emit(kArmSmmla, g.DefineAsRegister(node), 688 return;
601 g.UseRegister(mleft.left().node()), 689 }
602 g.UseRegister(mleft.right().node()), g.UseRegister(m.right().node())); 690 case IrOpcode::kInt32MulHigh: {
603 return; 691 Int32BinopMatcher mright(m.right().node());
604 } 692 Emit(kArmSmmla, g.DefineAsRegister(node),
605 if (m.right().IsInt32MulHigh() && CanCover(node, m.right().node())) { 693 g.UseRegister(mright.left().node()),
606 Int32BinopMatcher mright(m.right().node()); 694 g.UseRegister(mright.right().node()),
607 Emit(kArmSmmla, g.DefineAsRegister(node), 695 g.UseRegister(m.left().node()));
608 g.UseRegister(mright.left().node()), 696 return;
609 g.UseRegister(mright.right().node()), g.UseRegister(m.left().node())); 697 }
610 return; 698 case IrOpcode::kWord32And: {
699 Int32BinopMatcher mright(m.right().node());
700 if (mright.right().Is(0xff)) {
701 Emit(kArmUxtab, g.DefineAsRegister(node),
702 g.UseRegister(m.left().node()),
703 g.UseRegister(mright.left().node()), g.TempImmediate(0));
704 return;
705 } else if (mright.right().Is(0xffff)) {
706 Emit(kArmUxtah, g.DefineAsRegister(node),
707 g.UseRegister(m.left().node()),
708 g.UseRegister(mright.left().node()), g.TempImmediate(0));
709 return;
710 }
711 }
712 case IrOpcode::kWord32Sar: {
713 Int32BinopMatcher mright(m.right().node());
714 if (CanCover(mright.node(), mright.left().node()) &&
715 mright.left().IsWord32Shl()) {
716 Int32BinopMatcher mrightleft(mright.left().node());
717 if (mright.right().Is(24) && mrightleft.right().Is(24)) {
718 Emit(kArmSxtab, g.DefineAsRegister(node),
719 g.UseRegister(m.left().node()),
720 g.UseRegister(mrightleft.left().node()), g.TempImmediate(0));
721 return;
722 } else if (mright.right().Is(16) && mrightleft.right().Is(16)) {
723 Emit(kArmSxtah, g.DefineAsRegister(node),
724 g.UseRegister(m.left().node()),
725 g.UseRegister(mrightleft.left().node()), g.TempImmediate(0));
726 return;
727 }
728 }
729 }
730 default:
731 break;
732 }
611 } 733 }
612 VisitBinop(this, node, kArmAdd, kArmAdd); 734 VisitBinop(this, node, kArmAdd, kArmAdd);
613 } 735 }
614 736
615 737
616 void InstructionSelector::VisitInt32Sub(Node* node) { 738 void InstructionSelector::VisitInt32Sub(Node* node) {
617 ArmOperandGenerator g(this); 739 ArmOperandGenerator g(this);
618 Int32BinopMatcher m(node); 740 Int32BinopMatcher m(node);
619 if (IsSupported(MLS) && m.right().IsInt32Mul() && 741 if (IsSupported(MLS) && m.right().IsInt32Mul() &&
620 CanCover(node, m.right().node())) { 742 CanCover(node, m.right().node())) {
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after
1196 MachineOperatorBuilder::kFloat64Ceil | 1318 MachineOperatorBuilder::kFloat64Ceil |
1197 MachineOperatorBuilder::kFloat64RoundTruncate | 1319 MachineOperatorBuilder::kFloat64RoundTruncate |
1198 MachineOperatorBuilder::kFloat64RoundTiesAway; 1320 MachineOperatorBuilder::kFloat64RoundTiesAway;
1199 } 1321 }
1200 return flags; 1322 return flags;
1201 } 1323 }
1202 1324
1203 } // namespace compiler 1325 } // namespace compiler
1204 } // namespace internal 1326 } // namespace internal
1205 } // namespace v8 1327 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/arm/instruction-codes-arm.h ('k') | test/cctest/test-assembler-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698