| 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/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 { |
| 11 namespace compiler { | 11 namespace compiler { |
| 12 | 12 |
| 13 // Adds Arm-specific methods for generating InstructionOperands. | 13 // Adds Arm-specific methods for generating InstructionOperands. |
| 14 class ArmOperandGenerator FINAL : public OperandGenerator { | 14 class ArmOperandGenerator : public OperandGenerator { |
| 15 public: | 15 public: |
| 16 explicit ArmOperandGenerator(InstructionSelector* selector) | 16 explicit ArmOperandGenerator(InstructionSelector* selector) |
| 17 : OperandGenerator(selector) {} | 17 : OperandGenerator(selector) {} |
| 18 | 18 |
| 19 InstructionOperand* UseOperand(Node* node, InstructionCode opcode) { | 19 InstructionOperand* UseOperand(Node* node, InstructionCode opcode) { |
| 20 if (CanBeImmediate(node, opcode)) { | 20 if (CanBeImmediate(node, opcode)) { |
| 21 return UseImmediate(node); | 21 return UseImmediate(node); |
| 22 } | 22 } |
| 23 return UseRegister(node); | 23 return UseRegister(node); |
| 24 } | 24 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 42 return ImmediateFitsAddrMode1Instruction(value) || | 42 return ImmediateFitsAddrMode1Instruction(value) || |
| 43 ImmediateFitsAddrMode1Instruction(-value); | 43 ImmediateFitsAddrMode1Instruction(-value); |
| 44 | 44 |
| 45 case kArmTst: | 45 case kArmTst: |
| 46 case kArmTeq: | 46 case kArmTeq: |
| 47 case kArmOrr: | 47 case kArmOrr: |
| 48 case kArmEor: | 48 case kArmEor: |
| 49 case kArmRsb: | 49 case kArmRsb: |
| 50 return ImmediateFitsAddrMode1Instruction(value); | 50 return ImmediateFitsAddrMode1Instruction(value); |
| 51 | 51 |
| 52 case kArmVldr32: | 52 case kArmVldrF32: |
| 53 case kArmVstr32: | 53 case kArmVstrF32: |
| 54 case kArmVldr64: | 54 case kArmVldrF64: |
| 55 case kArmVstr64: | 55 case kArmVstrF64: |
| 56 return value >= -1020 && value <= 1020 && (value % 4) == 0; | 56 return value >= -1020 && value <= 1020 && (value % 4) == 0; |
| 57 | 57 |
| 58 case kArmLdrb: | 58 case kArmLdrb: |
| 59 case kArmLdrsb: | 59 case kArmLdrsb: |
| 60 case kArmStrb: | 60 case kArmStrb: |
| 61 case kArmLdr: | 61 case kArmLdr: |
| 62 case kArmStr: | 62 case kArmStr: |
| 63 case kArmStoreWriteBarrier: | 63 case kArmStoreWriteBarrier: |
| 64 return value >= -4095 && value <= 4095; | 64 return value >= -4095 && value <= 4095; |
| 65 | 65 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 84 case kArmVcmpF64: | 84 case kArmVcmpF64: |
| 85 case kArmVaddF64: | 85 case kArmVaddF64: |
| 86 case kArmVsubF64: | 86 case kArmVsubF64: |
| 87 case kArmVmulF64: | 87 case kArmVmulF64: |
| 88 case kArmVmlaF64: | 88 case kArmVmlaF64: |
| 89 case kArmVmlsF64: | 89 case kArmVmlsF64: |
| 90 case kArmVdivF64: | 90 case kArmVdivF64: |
| 91 case kArmVmodF64: | 91 case kArmVmodF64: |
| 92 case kArmVnegF64: | 92 case kArmVnegF64: |
| 93 case kArmVsqrtF64: | 93 case kArmVsqrtF64: |
| 94 case kArmVcvtF32F64: |
| 95 case kArmVcvtF64F32: |
| 94 case kArmVcvtF64S32: | 96 case kArmVcvtF64S32: |
| 95 case kArmVcvtF64U32: | 97 case kArmVcvtF64U32: |
| 96 case kArmVcvtS32F64: | 98 case kArmVcvtS32F64: |
| 97 case kArmVcvtU32F64: | 99 case kArmVcvtU32F64: |
| 98 case kArmPush: | 100 case kArmPush: |
| 99 return false; | 101 return false; |
| 100 } | 102 } |
| 101 UNREACHABLE(); | 103 UNREACHABLE(); |
| 102 return false; | 104 return false; |
| 103 } | 105 } |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 void InstructionSelector::VisitLoad(Node* node) { | 286 void InstructionSelector::VisitLoad(Node* node) { |
| 285 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 287 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); |
| 286 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | 288 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); |
| 287 ArmOperandGenerator g(this); | 289 ArmOperandGenerator g(this); |
| 288 Node* base = node->InputAt(0); | 290 Node* base = node->InputAt(0); |
| 289 Node* index = node->InputAt(1); | 291 Node* index = node->InputAt(1); |
| 290 | 292 |
| 291 ArchOpcode opcode; | 293 ArchOpcode opcode; |
| 292 switch (rep) { | 294 switch (rep) { |
| 293 case kRepFloat32: | 295 case kRepFloat32: |
| 294 opcode = kArmVldr32; | 296 opcode = kArmVldrF32; |
| 295 break; | 297 break; |
| 296 case kRepFloat64: | 298 case kRepFloat64: |
| 297 opcode = kArmVldr64; | 299 opcode = kArmVldrF64; |
| 298 break; | 300 break; |
| 299 case kRepBit: // Fall through. | 301 case kRepBit: // Fall through. |
| 300 case kRepWord8: | 302 case kRepWord8: |
| 301 opcode = typ == kTypeUint32 ? kArmLdrb : kArmLdrsb; | 303 opcode = typ == kTypeUint32 ? kArmLdrb : kArmLdrsb; |
| 302 break; | 304 break; |
| 303 case kRepWord16: | 305 case kRepWord16: |
| 304 opcode = typ == kTypeUint32 ? kArmLdrh : kArmLdrsh; | 306 opcode = typ == kTypeUint32 ? kArmLdrh : kArmLdrsh; |
| 305 break; | 307 break; |
| 306 case kRepTagged: // Fall through. | 308 case kRepTagged: // Fall through. |
| 307 case kRepWord32: | 309 case kRepWord32: |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 Emit(kArmStoreWriteBarrier, NULL, g.UseFixed(base, r4), | 341 Emit(kArmStoreWriteBarrier, NULL, g.UseFixed(base, r4), |
| 340 g.UseFixed(index, r5), g.UseFixed(value, r6), arraysize(temps), | 342 g.UseFixed(index, r5), g.UseFixed(value, r6), arraysize(temps), |
| 341 temps); | 343 temps); |
| 342 return; | 344 return; |
| 343 } | 345 } |
| 344 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); | 346 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); |
| 345 | 347 |
| 346 ArchOpcode opcode; | 348 ArchOpcode opcode; |
| 347 switch (rep) { | 349 switch (rep) { |
| 348 case kRepFloat32: | 350 case kRepFloat32: |
| 349 opcode = kArmVstr32; | 351 opcode = kArmVstrF32; |
| 350 break; | 352 break; |
| 351 case kRepFloat64: | 353 case kRepFloat64: |
| 352 opcode = kArmVstr64; | 354 opcode = kArmVstrF64; |
| 353 break; | 355 break; |
| 354 case kRepBit: // Fall through. | 356 case kRepBit: // Fall through. |
| 355 case kRepWord8: | 357 case kRepWord8: |
| 356 opcode = kArmStrb; | 358 opcode = kArmStrb; |
| 357 break; | 359 break; |
| 358 case kRepWord16: | 360 case kRepWord16: |
| 359 opcode = kArmStrh; | 361 opcode = kArmStrh; |
| 360 break; | 362 break; |
| 361 case kRepTagged: // Fall through. | 363 case kRepTagged: // Fall through. |
| 362 case kRepWord32: | 364 case kRepWord32: |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 676 void InstructionSelector::VisitInt32Mod(Node* node) { | 678 void InstructionSelector::VisitInt32Mod(Node* node) { |
| 677 VisitMod(this, node, kArmSdiv, kArmVcvtF64S32, kArmVcvtS32F64); | 679 VisitMod(this, node, kArmSdiv, kArmVcvtF64S32, kArmVcvtS32F64); |
| 678 } | 680 } |
| 679 | 681 |
| 680 | 682 |
| 681 void InstructionSelector::VisitInt32UMod(Node* node) { | 683 void InstructionSelector::VisitInt32UMod(Node* node) { |
| 682 VisitMod(this, node, kArmUdiv, kArmVcvtF64U32, kArmVcvtU32F64); | 684 VisitMod(this, node, kArmUdiv, kArmVcvtF64U32, kArmVcvtU32F64); |
| 683 } | 685 } |
| 684 | 686 |
| 685 | 687 |
| 688 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { |
| 689 ArmOperandGenerator g(this); |
| 690 Emit(kArmVcvtF64F32, g.DefineAsRegister(node), |
| 691 g.UseRegister(node->InputAt(0))); |
| 692 } |
| 693 |
| 694 |
| 686 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { | 695 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { |
| 687 ArmOperandGenerator g(this); | 696 ArmOperandGenerator g(this); |
| 688 Emit(kArmVcvtF64S32, g.DefineAsRegister(node), | 697 Emit(kArmVcvtF64S32, g.DefineAsRegister(node), |
| 689 g.UseRegister(node->InputAt(0))); | 698 g.UseRegister(node->InputAt(0))); |
| 690 } | 699 } |
| 691 | 700 |
| 692 | 701 |
| 693 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { | 702 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { |
| 694 ArmOperandGenerator g(this); | 703 ArmOperandGenerator g(this); |
| 695 Emit(kArmVcvtF64U32, g.DefineAsRegister(node), | 704 Emit(kArmVcvtF64U32, g.DefineAsRegister(node), |
| 696 g.UseRegister(node->InputAt(0))); | 705 g.UseRegister(node->InputAt(0))); |
| 697 } | 706 } |
| 698 | 707 |
| 699 | 708 |
| 700 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { | 709 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { |
| 701 ArmOperandGenerator g(this); | 710 ArmOperandGenerator g(this); |
| 702 Emit(kArmVcvtS32F64, g.DefineAsRegister(node), | 711 Emit(kArmVcvtS32F64, g.DefineAsRegister(node), |
| 703 g.UseRegister(node->InputAt(0))); | 712 g.UseRegister(node->InputAt(0))); |
| 704 } | 713 } |
| 705 | 714 |
| 706 | 715 |
| 707 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { | 716 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { |
| 708 ArmOperandGenerator g(this); | 717 ArmOperandGenerator g(this); |
| 709 Emit(kArmVcvtU32F64, g.DefineAsRegister(node), | 718 Emit(kArmVcvtU32F64, g.DefineAsRegister(node), |
| 710 g.UseRegister(node->InputAt(0))); | 719 g.UseRegister(node->InputAt(0))); |
| 711 } | 720 } |
| 712 | 721 |
| 713 | 722 |
| 723 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { |
| 724 ArmOperandGenerator g(this); |
| 725 Emit(kArmVcvtF32F64, g.DefineAsRegister(node), |
| 726 g.UseRegister(node->InputAt(0))); |
| 727 } |
| 728 |
| 729 |
| 714 void InstructionSelector::VisitFloat64Add(Node* node) { | 730 void InstructionSelector::VisitFloat64Add(Node* node) { |
| 715 ArmOperandGenerator g(this); | 731 ArmOperandGenerator g(this); |
| 716 Int32BinopMatcher m(node); | 732 Int32BinopMatcher m(node); |
| 717 if (m.left().IsFloat64Mul() && CanCover(node, m.left().node())) { | 733 if (m.left().IsFloat64Mul() && CanCover(node, m.left().node())) { |
| 718 Int32BinopMatcher mleft(m.left().node()); | 734 Int32BinopMatcher mleft(m.left().node()); |
| 719 Emit(kArmVmlaF64, g.DefineSameAsFirst(node), | 735 Emit(kArmVmlaF64, g.DefineSameAsFirst(node), |
| 720 g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), | 736 g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), |
| 721 g.UseRegister(mleft.right().node())); | 737 g.UseRegister(mleft.right().node())); |
| 722 return; | 738 return; |
| 723 } | 739 } |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 941 } else { | 957 } else { |
| 942 DCHECK(cont->IsSet()); | 958 DCHECK(cont->IsSet()); |
| 943 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), | 959 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), |
| 944 g.UseRegister(m.left().node()), g.UseRegister(m.right().node())); | 960 g.UseRegister(m.left().node()), g.UseRegister(m.right().node())); |
| 945 } | 961 } |
| 946 } | 962 } |
| 947 | 963 |
| 948 } // namespace compiler | 964 } // namespace compiler |
| 949 } // namespace internal | 965 } // namespace internal |
| 950 } // namespace v8 | 966 } // namespace v8 |
| OLD | NEW |