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

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

Issue 2470133005: MIPS[64]: Port '[turbofan] Use zr to store immediate zero' (Closed)
Patch Set: Created 4 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
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/adapters.h" 5 #include "src/base/adapters.h"
6 #include "src/base/bits.h" 6 #include "src/base/bits.h"
7 #include "src/compiler/instruction-selector-impl.h" 7 #include "src/compiler/instruction-selector-impl.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/compiler/node-properties.h" 9 #include "src/compiler/node-properties.h"
10 10
(...skipping 13 matching lines...) Expand all
24 explicit Mips64OperandGenerator(InstructionSelector* selector) 24 explicit Mips64OperandGenerator(InstructionSelector* selector)
25 : OperandGenerator(selector) {} 25 : OperandGenerator(selector) {}
26 26
27 InstructionOperand UseOperand(Node* node, InstructionCode opcode) { 27 InstructionOperand UseOperand(Node* node, InstructionCode opcode) {
28 if (CanBeImmediate(node, opcode)) { 28 if (CanBeImmediate(node, opcode)) {
29 return UseImmediate(node); 29 return UseImmediate(node);
30 } 30 }
31 return UseRegister(node); 31 return UseRegister(node);
32 } 32 }
33 33
34 // Use the zero register if the node has the immediate value zero, otherwise
35 // assign a register.
36 InstructionOperand UseRegisterOrImmediateZero(Node* node) {
37 if ((IsIntegerConstant(node) && (GetIntegerConstantValue(node) == 0)) ||
38 (IsFloatConstant(node) &&
39 (bit_cast<int64_t>(GetFloatConstantValue(node)) == V8_INT64_C(0)))) {
40 return UseImmediate(node);
41 }
42 return UseRegister(node);
43 }
44
34 bool IsIntegerConstant(Node* node) { 45 bool IsIntegerConstant(Node* node) {
35 return (node->opcode() == IrOpcode::kInt32Constant) || 46 return (node->opcode() == IrOpcode::kInt32Constant) ||
36 (node->opcode() == IrOpcode::kInt64Constant); 47 (node->opcode() == IrOpcode::kInt64Constant);
37 } 48 }
38 49
39 int64_t GetIntegerConstantValue(Node* node) { 50 int64_t GetIntegerConstantValue(Node* node) {
40 if (node->opcode() == IrOpcode::kInt32Constant) { 51 if (node->opcode() == IrOpcode::kInt32Constant) {
41 return OpParameter<int32_t>(node); 52 return OpParameter<int32_t>(node);
42 } 53 }
43 DCHECK(node->opcode() == IrOpcode::kInt64Constant); 54 DCHECK(node->opcode() == IrOpcode::kInt64Constant);
44 return OpParameter<int64_t>(node); 55 return OpParameter<int64_t>(node);
45 } 56 }
46 57
58 bool IsFloatConstant(Node* node) {
59 return (node->opcode() == IrOpcode::kFloat32Constant) ||
60 (node->opcode() == IrOpcode::kFloat64Constant);
61 }
62
63 double GetFloatConstantValue(Node* node) {
64 if (node->opcode() == IrOpcode::kFloat32Constant) {
65 return OpParameter<float>(node);
66 }
67 DCHECK_EQ(IrOpcode::kFloat64Constant, node->opcode());
68 return OpParameter<double>(node);
69 }
70
47 bool CanBeImmediate(Node* node, InstructionCode mode) { 71 bool CanBeImmediate(Node* node, InstructionCode mode) {
48 return IsIntegerConstant(node) && 72 return IsIntegerConstant(node) &&
49 CanBeImmediate(GetIntegerConstantValue(node), mode); 73 CanBeImmediate(GetIntegerConstantValue(node), mode);
50 } 74 }
51 75
52 bool CanBeImmediate(int64_t value, InstructionCode opcode) { 76 bool CanBeImmediate(int64_t value, InstructionCode opcode) {
53 switch (ArchOpcodeField::decode(opcode)) { 77 switch (ArchOpcodeField::decode(opcode)) {
54 case kMips64Shl: 78 case kMips64Shl:
55 case kMips64Sar: 79 case kMips64Sar:
56 case kMips64Shr: 80 case kMips64Shr:
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 opcode = kMips64Sd; 417 opcode = kMips64Sd;
394 break; 418 break;
395 case MachineRepresentation::kSimd128: // Fall through. 419 case MachineRepresentation::kSimd128: // Fall through.
396 case MachineRepresentation::kNone: 420 case MachineRepresentation::kNone:
397 UNREACHABLE(); 421 UNREACHABLE();
398 return; 422 return;
399 } 423 }
400 424
401 if (g.CanBeImmediate(index, opcode)) { 425 if (g.CanBeImmediate(index, opcode)) {
402 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), 426 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
403 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); 427 g.UseRegister(base), g.UseImmediate(index),
428 g.UseRegisterOrImmediateZero(value));
404 } else { 429 } else {
405 InstructionOperand addr_reg = g.TempRegister(); 430 InstructionOperand addr_reg = g.TempRegister();
406 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, 431 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg,
407 g.UseRegister(index), g.UseRegister(base)); 432 g.UseRegister(index), g.UseRegister(base));
408 // Emit desired store opcode, using temp addr_reg. 433 // Emit desired store opcode, using temp addr_reg.
409 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), 434 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
410 addr_reg, g.TempImmediate(0), g.UseRegister(value)); 435 addr_reg, g.TempImmediate(0), g.UseRegisterOrImmediateZero(value));
411 } 436 }
412 } 437 }
413 } 438 }
414 439
415 440
416 void InstructionSelector::VisitWord32And(Node* node) { 441 void InstructionSelector::VisitWord32And(Node* node) {
417 Mips64OperandGenerator g(this); 442 Mips64OperandGenerator g(this);
418 Int32BinopMatcher m(node); 443 Int32BinopMatcher m(node);
419 if (m.left().IsWord32Shr() && CanCover(node, m.left().node()) && 444 if (m.left().IsWord32Shr() && CanCover(node, m.left().node()) &&
420 m.right().HasValue()) { 445 m.right().HasValue()) {
(...skipping 1311 matching lines...) Expand 10 before | Expand all | Expand 10 after
1732 opcode = kMips64Usd; 1757 opcode = kMips64Usd;
1733 break; 1758 break;
1734 case MachineRepresentation::kSimd128: // Fall through. 1759 case MachineRepresentation::kSimd128: // Fall through.
1735 case MachineRepresentation::kNone: 1760 case MachineRepresentation::kNone:
1736 UNREACHABLE(); 1761 UNREACHABLE();
1737 return; 1762 return;
1738 } 1763 }
1739 1764
1740 if (g.CanBeImmediate(index, opcode)) { 1765 if (g.CanBeImmediate(index, opcode)) {
1741 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), 1766 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
1742 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); 1767 g.UseRegister(base), g.UseImmediate(index),
1768 g.UseRegisterOrImmediateZero(value));
1743 } else { 1769 } else {
1744 InstructionOperand addr_reg = g.TempRegister(); 1770 InstructionOperand addr_reg = g.TempRegister();
1745 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, 1771 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg,
1746 g.UseRegister(index), g.UseRegister(base)); 1772 g.UseRegister(index), g.UseRegister(base));
1747 // Emit desired store opcode, using temp addr_reg. 1773 // Emit desired store opcode, using temp addr_reg.
1748 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), 1774 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
1749 addr_reg, g.TempImmediate(0), g.UseRegister(value)); 1775 addr_reg, g.TempImmediate(0), g.UseRegisterOrImmediateZero(value));
1750 } 1776 }
1751 } 1777 }
1752 1778
1753 void InstructionSelector::VisitCheckedLoad(Node* node) { 1779 void InstructionSelector::VisitCheckedLoad(Node* node) {
1754 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op()); 1780 CheckedLoadRepresentation load_rep = CheckedLoadRepresentationOf(node->op());
1755 Mips64OperandGenerator g(this); 1781 Mips64OperandGenerator g(this);
1756 Node* const buffer = node->InputAt(0); 1782 Node* const buffer = node->InputAt(0);
1757 Node* const offset = node->InputAt(1); 1783 Node* const offset = node->InputAt(1);
1758 Node* const length = node->InputAt(2); 1784 Node* const length = node->InputAt(2);
1759 ArchOpcode opcode = kArchNop; 1785 ArchOpcode opcode = kArchNop;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1841 ? g.UseImmediate(offset) 1867 ? g.UseImmediate(offset)
1842 : g.UseRegister(offset); 1868 : g.UseRegister(offset);
1843 1869
1844 InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode)) 1870 InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode))
1845 ? g.CanBeImmediate(length, opcode) 1871 ? g.CanBeImmediate(length, opcode)
1846 ? g.UseImmediate(length) 1872 ? g.UseImmediate(length)
1847 : g.UseRegister(length) 1873 : g.UseRegister(length)
1848 : g.UseRegister(length); 1874 : g.UseRegister(length);
1849 1875
1850 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), 1876 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
1851 offset_operand, length_operand, g.UseRegister(value), 1877 offset_operand, length_operand, g.UseRegisterOrImmediateZero(value),
1852 g.UseRegister(buffer)); 1878 g.UseRegister(buffer));
1853 } 1879 }
1854 1880
1855 1881
1856 namespace { 1882 namespace {
1857 1883
1858 // Shared routine for multiple compare operations. 1884 // Shared routine for multiple compare operations.
1859 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, 1885 static void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
1860 InstructionOperand left, InstructionOperand right, 1886 InstructionOperand left, InstructionOperand right,
1861 FlagsContinuation* cont) { 1887 FlagsContinuation* cont) {
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after
2484 case MachineRepresentation::kWord32: 2510 case MachineRepresentation::kWord32:
2485 opcode = kAtomicStoreWord32; 2511 opcode = kAtomicStoreWord32;
2486 break; 2512 break;
2487 default: 2513 default:
2488 UNREACHABLE(); 2514 UNREACHABLE();
2489 return; 2515 return;
2490 } 2516 }
2491 2517
2492 if (g.CanBeImmediate(index, opcode)) { 2518 if (g.CanBeImmediate(index, opcode)) {
2493 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), 2519 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
2494 g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); 2520 g.UseRegister(base), g.UseImmediate(index),
2521 g.UseRegisterOrImmediateZero(value));
2495 } else { 2522 } else {
2496 InstructionOperand addr_reg = g.TempRegister(); 2523 InstructionOperand addr_reg = g.TempRegister();
2497 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, 2524 Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg,
2498 g.UseRegister(index), g.UseRegister(base)); 2525 g.UseRegister(index), g.UseRegister(base));
2499 // Emit desired store opcode, using temp addr_reg. 2526 // Emit desired store opcode, using temp addr_reg.
2500 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), 2527 Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
2501 addr_reg, g.TempImmediate(0), g.UseRegister(value)); 2528 addr_reg, g.TempImmediate(0), g.UseRegisterOrImmediateZero(value));
2502 } 2529 }
2503 } 2530 }
2504 2531
2505 // static 2532 // static
2506 MachineOperatorBuilder::Flags 2533 MachineOperatorBuilder::Flags
2507 InstructionSelector::SupportedMachineOperatorFlags() { 2534 InstructionSelector::SupportedMachineOperatorFlags() {
2508 MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags; 2535 MachineOperatorBuilder::Flags flags = MachineOperatorBuilder::kNoFlags;
2509 return flags | MachineOperatorBuilder::kWord32Ctz | 2536 return flags | MachineOperatorBuilder::kWord32Ctz |
2510 MachineOperatorBuilder::kWord64Ctz | 2537 MachineOperatorBuilder::kWord64Ctz |
2511 MachineOperatorBuilder::kWord32Popcnt | 2538 MachineOperatorBuilder::kWord32Popcnt |
(...skipping 22 matching lines...) Expand all
2534 } else { 2561 } else {
2535 DCHECK(kArchVariant == kMips64r2); 2562 DCHECK(kArchVariant == kMips64r2);
2536 return MachineOperatorBuilder::AlignmentRequirements:: 2563 return MachineOperatorBuilder::AlignmentRequirements::
2537 NoUnalignedAccessSupport(); 2564 NoUnalignedAccessSupport();
2538 } 2565 }
2539 } 2566 }
2540 2567
2541 } // namespace compiler 2568 } // namespace compiler
2542 } // namespace internal 2569 } // namespace internal
2543 } // namespace v8 2570 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/mips64/code-generator-mips64.cc ('k') | test/unittests/compiler/instruction-selector-unittest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698