OLD | NEW |
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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 ArchOpcode opcode_; | 188 ArchOpcode opcode_; |
189 | 189 |
190 void Initialize(Node* node) { | 190 void Initialize(Node* node) { |
191 Int64BinopMatcher m(node); | 191 Int64BinopMatcher m(node); |
192 // When loading a 64-bit value and shifting by 32, we should | 192 // When loading a 64-bit value and shifting by 32, we should |
193 // just load and sign-extend the interesting 4 bytes instead. | 193 // just load and sign-extend the interesting 4 bytes instead. |
194 // This happens, for example, when we're loading and untagging SMIs. | 194 // This happens, for example, when we're loading and untagging SMIs. |
195 DCHECK(m.IsWord64Sar()); | 195 DCHECK(m.IsWord64Sar()); |
196 if (m.left().IsLoad() && m.right().Is(32) && | 196 if (m.left().IsLoad() && m.right().Is(32) && |
197 selector_->CanCover(m.node(), m.left().node())) { | 197 selector_->CanCover(m.node(), m.left().node())) { |
| 198 MachineRepresentation rep = |
| 199 LoadRepresentationOf(m.left().node()->op()).representation(); |
| 200 DCHECK(ElementSizeLog2Of(rep) == 3); |
| 201 if (rep != MachineRepresentation::kTaggedSigned && |
| 202 rep != MachineRepresentation::kTaggedPointer && |
| 203 rep != MachineRepresentation::kTagged && |
| 204 rep != MachineRepresentation::kWord64) { |
| 205 return; |
| 206 } |
| 207 |
198 Mips64OperandGenerator g(selector_); | 208 Mips64OperandGenerator g(selector_); |
199 Node* load = m.left().node(); | 209 Node* load = m.left().node(); |
200 Node* offset = load->InputAt(1); | 210 Node* offset = load->InputAt(1); |
201 base_ = load->InputAt(0); | 211 base_ = load->InputAt(0); |
202 opcode_ = kMips64Lw; | 212 opcode_ = kMips64Lw; |
203 if (g.CanBeImmediate(offset, opcode_)) { | 213 if (g.CanBeImmediate(offset, opcode_)) { |
204 #if defined(V8_TARGET_LITTLE_ENDIAN) | 214 #if defined(V8_TARGET_LITTLE_ENDIAN) |
205 immediate_ = g.GetIntegerConstantValue(offset) + 4; | 215 immediate_ = g.GetIntegerConstantValue(offset) + 4; |
206 #elif defined(V8_TARGET_BIG_ENDIAN) | 216 #elif defined(V8_TARGET_BIG_ENDIAN) |
207 immediate_ = g.GetIntegerConstantValue(offset); | 217 immediate_ = g.GetIntegerConstantValue(offset); |
208 #endif | 218 #endif |
209 matches_ = g.CanBeImmediate(immediate_, kMips64Lw); | 219 matches_ = g.CanBeImmediate(immediate_, kMips64Lw); |
210 } | 220 } |
211 } | 221 } |
212 } | 222 } |
213 }; | 223 }; |
214 | 224 |
215 bool TryEmitExtendingLoad(InstructionSelector* selector, Node* node) { | 225 bool TryEmitExtendingLoad(InstructionSelector* selector, Node* node, |
| 226 Node* output_node) { |
216 ExtendingLoadMatcher m(node, selector); | 227 ExtendingLoadMatcher m(node, selector); |
217 Mips64OperandGenerator g(selector); | 228 Mips64OperandGenerator g(selector); |
218 if (m.Matches()) { | 229 if (m.Matches()) { |
219 InstructionOperand inputs[2]; | 230 InstructionOperand inputs[2]; |
220 inputs[0] = g.UseRegister(m.base()); | 231 inputs[0] = g.UseRegister(m.base()); |
221 InstructionCode opcode = | 232 InstructionCode opcode = |
222 m.opcode() | AddressingModeField::encode(kMode_MRI); | 233 m.opcode() | AddressingModeField::encode(kMode_MRI); |
223 DCHECK(is_int32(m.immediate())); | 234 DCHECK(is_int32(m.immediate())); |
224 inputs[1] = g.TempImmediate(static_cast<int32_t>(m.immediate())); | 235 inputs[1] = g.TempImmediate(static_cast<int32_t>(m.immediate())); |
225 InstructionOperand outputs[] = {g.DefineAsRegister(node)}; | 236 InstructionOperand outputs[] = {g.DefineAsRegister(output_node)}; |
226 selector->Emit(opcode, arraysize(outputs), outputs, arraysize(inputs), | 237 selector->Emit(opcode, arraysize(outputs), outputs, arraysize(inputs), |
227 inputs); | 238 inputs); |
228 return true; | 239 return true; |
229 } | 240 } |
230 return false; | 241 return false; |
231 } | 242 } |
232 | 243 |
233 bool TryMatchImmediate(InstructionSelector* selector, | 244 bool TryMatchImmediate(InstructionSelector* selector, |
234 InstructionCode* opcode_return, Node* node, | 245 InstructionCode* opcode_return, Node* node, |
235 size_t* input_count_return, InstructionOperand* inputs) { | 246 size_t* input_count_return, InstructionOperand* inputs) { |
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 g.TempImmediate(mask_width)); | 778 g.TempImmediate(mask_width)); |
768 return; | 779 return; |
769 } | 780 } |
770 } | 781 } |
771 } | 782 } |
772 VisitRRO(this, kMips64Dshr, node); | 783 VisitRRO(this, kMips64Dshr, node); |
773 } | 784 } |
774 | 785 |
775 | 786 |
776 void InstructionSelector::VisitWord64Sar(Node* node) { | 787 void InstructionSelector::VisitWord64Sar(Node* node) { |
777 if (TryEmitExtendingLoad(this, node)) return; | 788 if (TryEmitExtendingLoad(this, node, node)) return; |
778 VisitRRO(this, kMips64Dsar, node); | 789 VisitRRO(this, kMips64Dsar, node); |
779 } | 790 } |
780 | 791 |
781 | 792 |
782 void InstructionSelector::VisitWord32Ror(Node* node) { | 793 void InstructionSelector::VisitWord32Ror(Node* node) { |
783 VisitRRO(this, kMips64Ror, node); | 794 VisitRRO(this, kMips64Ror, node); |
784 } | 795 } |
785 | 796 |
786 | 797 |
787 void InstructionSelector::VisitWord32Clz(Node* node) { | 798 void InstructionSelector::VisitWord32Clz(Node* node) { |
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1337 g.TempImmediate(0), g.TempImmediate(32)); | 1348 g.TempImmediate(0), g.TempImmediate(32)); |
1338 } | 1349 } |
1339 | 1350 |
1340 | 1351 |
1341 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { | 1352 void InstructionSelector::VisitTruncateInt64ToInt32(Node* node) { |
1342 Mips64OperandGenerator g(this); | 1353 Mips64OperandGenerator g(this); |
1343 Node* value = node->InputAt(0); | 1354 Node* value = node->InputAt(0); |
1344 if (CanCover(node, value)) { | 1355 if (CanCover(node, value)) { |
1345 switch (value->opcode()) { | 1356 switch (value->opcode()) { |
1346 case IrOpcode::kWord64Sar: { | 1357 case IrOpcode::kWord64Sar: { |
1347 Int64BinopMatcher m(value); | 1358 if (TryEmitExtendingLoad(this, value, node)) { |
1348 if (m.right().IsInRange(32, 63)) { | |
1349 // After smi untagging no need for truncate. Combine sequence. | |
1350 Emit(kMips64Dsar, g.DefineSameAsFirst(node), | |
1351 g.UseRegister(m.left().node()), | |
1352 g.UseImmediate(m.right().node())); | |
1353 return; | 1359 return; |
| 1360 } else { |
| 1361 Int64BinopMatcher m(value); |
| 1362 if (m.right().IsInRange(32, 63)) { |
| 1363 // After smi untagging no need for truncate. Combine sequence. |
| 1364 Emit(kMips64Dsar, g.DefineSameAsFirst(node), |
| 1365 g.UseRegister(m.left().node()), |
| 1366 g.UseImmediate(m.right().node())); |
| 1367 return; |
| 1368 } |
1354 } | 1369 } |
1355 break; | 1370 break; |
1356 } | 1371 } |
1357 default: | 1372 default: |
1358 break; | 1373 break; |
1359 } | 1374 } |
1360 } | 1375 } |
1361 Emit(kMips64Ext, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)), | 1376 Emit(kMips64Ext, g.DefineAsRegister(node), g.UseRegister(node->InputAt(0)), |
1362 g.TempImmediate(0), g.TempImmediate(32)); | 1377 g.TempImmediate(0), g.TempImmediate(32)); |
1363 } | 1378 } |
(...skipping 1261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2625 } else { | 2640 } else { |
2626 DCHECK(kArchVariant == kMips64r2); | 2641 DCHECK(kArchVariant == kMips64r2); |
2627 return MachineOperatorBuilder::AlignmentRequirements:: | 2642 return MachineOperatorBuilder::AlignmentRequirements:: |
2628 NoUnalignedAccessSupport(); | 2643 NoUnalignedAccessSupport(); |
2629 } | 2644 } |
2630 } | 2645 } |
2631 | 2646 |
2632 } // namespace compiler | 2647 } // namespace compiler |
2633 } // namespace internal | 2648 } // namespace internal |
2634 } // namespace v8 | 2649 } // namespace v8 |
OLD | NEW |