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

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

Issue 2437593006: MIPS64: Port '[ARM64] Optimize load followed by shift.' (Closed)
Patch Set: Add big endian support to tests 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
« no previous file with comments | « no previous file | test/unittests/compiler/mips64/instruction-selector-mips64-unittest.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/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 bool CanBeImmediate(Node* node, InstructionCode opcode) { 34 bool IsIntegerConstant(Node* node) {
35 int64_t value; 35 return (node->opcode() == IrOpcode::kInt32Constant) ||
36 if (node->opcode() == IrOpcode::kInt32Constant) 36 (node->opcode() == IrOpcode::kInt64Constant);
37 value = OpParameter<int32_t>(node); 37 }
38 else if (node->opcode() == IrOpcode::kInt64Constant) 38
39 value = OpParameter<int64_t>(node); 39 int64_t GetIntegerConstantValue(Node* node) {
40 else 40 if (node->opcode() == IrOpcode::kInt32Constant) {
41 return false; 41 return OpParameter<int32_t>(node);
42 }
43 DCHECK(node->opcode() == IrOpcode::kInt64Constant);
44 return OpParameter<int64_t>(node);
45 }
46
47 bool CanBeImmediate(Node* node, InstructionCode mode) {
48 return IsIntegerConstant(node) &&
49 CanBeImmediate(GetIntegerConstantValue(node), mode);
50 }
51
52 bool CanBeImmediate(int64_t value, InstructionCode opcode) {
42 switch (ArchOpcodeField::decode(opcode)) { 53 switch (ArchOpcodeField::decode(opcode)) {
43 case kMips64Shl: 54 case kMips64Shl:
44 case kMips64Sar: 55 case kMips64Sar:
45 case kMips64Shr: 56 case kMips64Shr:
46 return is_uint5(value); 57 return is_uint5(value);
47 case kMips64Dshl: 58 case kMips64Dshl:
48 case kMips64Dsar: 59 case kMips64Dsar:
49 case kMips64Dshr: 60 case kMips64Dshr:
50 return is_uint6(value); 61 return is_uint6(value);
51 case kMips64Xor: 62 case kMips64Xor:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 95
85 96
86 static void VisitRRO(InstructionSelector* selector, ArchOpcode opcode, 97 static void VisitRRO(InstructionSelector* selector, ArchOpcode opcode,
87 Node* node) { 98 Node* node) {
88 Mips64OperandGenerator g(selector); 99 Mips64OperandGenerator g(selector);
89 selector->Emit(opcode, g.DefineAsRegister(node), 100 selector->Emit(opcode, g.DefineAsRegister(node),
90 g.UseRegister(node->InputAt(0)), 101 g.UseRegister(node->InputAt(0)),
91 g.UseOperand(node->InputAt(1), opcode)); 102 g.UseOperand(node->InputAt(1), opcode));
92 } 103 }
93 104
105 struct ExtendingLoadMatcher {
106 ExtendingLoadMatcher(Node* node, InstructionSelector* selector)
107 : matches_(false), selector_(selector), base_(nullptr), immediate_(0) {
108 Initialize(node);
109 }
110
111 bool Matches() const { return matches_; }
112
113 Node* base() const {
114 DCHECK(Matches());
115 return base_;
116 }
117 int64_t immediate() const {
118 DCHECK(Matches());
119 return immediate_;
120 }
121 ArchOpcode opcode() const {
122 DCHECK(Matches());
123 return opcode_;
124 }
125
126 private:
127 bool matches_;
128 InstructionSelector* selector_;
129 Node* base_;
130 int64_t immediate_;
131 ArchOpcode opcode_;
132
133 void Initialize(Node* node) {
134 Int64BinopMatcher m(node);
135 // When loading a 64-bit value and shifting by 32, we should
136 // just load and sign-extend the interesting 4 bytes instead.
137 // This happens, for example, when we're loading and untagging SMIs.
138 DCHECK(m.IsWord64Sar());
139 if (m.left().IsLoad() && m.right().Is(32) &&
140 selector_->CanCover(m.node(), m.left().node())) {
141 Mips64OperandGenerator g(selector_);
142 Node* load = m.left().node();
143 Node* offset = load->InputAt(1);
144 base_ = load->InputAt(0);
145 opcode_ = kMips64Lw;
146 if (g.CanBeImmediate(offset, opcode_)) {
147 #if defined(V8_TARGET_LITTLE_ENDIAN)
148 immediate_ = g.GetIntegerConstantValue(offset) + 4;
149 #elif defined(V8_TARGET_BIG_ENDIAN)
150 immediate_ = g.GetIntegerConstantValue(offset);
151 #endif
152 matches_ = g.CanBeImmediate(immediate_, kMips64Lw);
153 }
154 }
155 }
156 };
157
158 bool TryEmitExtendingLoad(InstructionSelector* selector, Node* node) {
159 ExtendingLoadMatcher m(node, selector);
160 Mips64OperandGenerator g(selector);
161 if (m.Matches()) {
162 InstructionOperand inputs[2];
163 inputs[0] = g.UseRegister(m.base());
164 InstructionCode opcode =
165 m.opcode() | AddressingModeField::encode(kMode_MRI);
166 DCHECK(is_int32(m.immediate()));
167 inputs[1] = g.TempImmediate(static_cast<int32_t>(m.immediate()));
168 InstructionOperand outputs[] = {g.DefineAsRegister(node)};
169 selector->Emit(opcode, arraysize(outputs), outputs, arraysize(inputs),
170 inputs);
171 return true;
172 }
173 return false;
174 }
94 175
95 static void VisitBinop(InstructionSelector* selector, Node* node, 176 static void VisitBinop(InstructionSelector* selector, Node* node,
96 InstructionCode opcode, FlagsContinuation* cont) { 177 InstructionCode opcode, FlagsContinuation* cont) {
97 Mips64OperandGenerator g(selector); 178 Mips64OperandGenerator g(selector);
98 Int32BinopMatcher m(node); 179 Int32BinopMatcher m(node);
99 InstructionOperand inputs[4]; 180 InstructionOperand inputs[4];
100 size_t input_count = 0; 181 size_t input_count = 0;
101 InstructionOperand outputs[2]; 182 InstructionOperand outputs[2];
102 size_t output_count = 0; 183 size_t output_count = 0;
103 184
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 g.TempImmediate(mask_width)); 671 g.TempImmediate(mask_width));
591 return; 672 return;
592 } 673 }
593 } 674 }
594 } 675 }
595 VisitRRO(this, kMips64Dshr, node); 676 VisitRRO(this, kMips64Dshr, node);
596 } 677 }
597 678
598 679
599 void InstructionSelector::VisitWord64Sar(Node* node) { 680 void InstructionSelector::VisitWord64Sar(Node* node) {
681 if (TryEmitExtendingLoad(this, node)) return;
600 VisitRRO(this, kMips64Dsar, node); 682 VisitRRO(this, kMips64Dsar, node);
601 } 683 }
602 684
603 685
604 void InstructionSelector::VisitWord32Ror(Node* node) { 686 void InstructionSelector::VisitWord32Ror(Node* node) {
605 VisitRRO(this, kMips64Ror, node); 687 VisitRRO(this, kMips64Ror, node);
606 } 688 }
607 689
608 690
609 void InstructionSelector::VisitWord32Clz(Node* node) { 691 void InstructionSelector::VisitWord32Clz(Node* node) {
(...skipping 1800 matching lines...) Expand 10 before | Expand all | Expand 10 after
2410 } else { 2492 } else {
2411 DCHECK(kArchVariant == kMips64r2); 2493 DCHECK(kArchVariant == kMips64r2);
2412 return MachineOperatorBuilder::AlignmentRequirements:: 2494 return MachineOperatorBuilder::AlignmentRequirements::
2413 NoUnalignedAccessSupport(); 2495 NoUnalignedAccessSupport();
2414 } 2496 }
2415 } 2497 }
2416 2498
2417 } // namespace compiler 2499 } // namespace compiler
2418 } // namespace internal 2500 } // namespace internal
2419 } // namespace v8 2501 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/unittests/compiler/mips64/instruction-selector-mips64-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698