| 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 | 
|---|