| 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 17 matching lines...) Expand all Loading... |
| 83 case kArmUbfx: | 83 case kArmUbfx: |
| 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 kArmVcvtF32F64: |
| 94 case kArmVcvtF64F32: |
| 93 case kArmVcvtF64S32: | 95 case kArmVcvtF64S32: |
| 94 case kArmVcvtF64U32: | 96 case kArmVcvtF64U32: |
| 95 case kArmVcvtS32F64: | 97 case kArmVcvtS32F64: |
| 96 case kArmVcvtU32F64: | 98 case kArmVcvtU32F64: |
| 97 case kArmPush: | 99 case kArmPush: |
| 98 return false; | 100 return false; |
| 99 } | 101 } |
| 100 UNREACHABLE(); | 102 UNREACHABLE(); |
| 101 return false; | 103 return false; |
| 102 } | 104 } |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 void InstructionSelector::VisitLoad(Node* node) { | 285 void InstructionSelector::VisitLoad(Node* node) { |
| 284 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); | 286 MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); |
| 285 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); | 287 MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); |
| 286 ArmOperandGenerator g(this); | 288 ArmOperandGenerator g(this); |
| 287 Node* base = node->InputAt(0); | 289 Node* base = node->InputAt(0); |
| 288 Node* index = node->InputAt(1); | 290 Node* index = node->InputAt(1); |
| 289 | 291 |
| 290 ArchOpcode opcode; | 292 ArchOpcode opcode; |
| 291 switch (rep) { | 293 switch (rep) { |
| 292 case kRepFloat32: | 294 case kRepFloat32: |
| 293 opcode = kArmVldr32; | 295 opcode = kArmVldrF32; |
| 294 break; | 296 break; |
| 295 case kRepFloat64: | 297 case kRepFloat64: |
| 296 opcode = kArmVldr64; | 298 opcode = kArmVldrF64; |
| 297 break; | 299 break; |
| 298 case kRepBit: // Fall through. | 300 case kRepBit: // Fall through. |
| 299 case kRepWord8: | 301 case kRepWord8: |
| 300 opcode = typ == kTypeUint32 ? kArmLdrb : kArmLdrsb; | 302 opcode = typ == kTypeUint32 ? kArmLdrb : kArmLdrsb; |
| 301 break; | 303 break; |
| 302 case kRepWord16: | 304 case kRepWord16: |
| 303 opcode = typ == kTypeUint32 ? kArmLdrh : kArmLdrsh; | 305 opcode = typ == kTypeUint32 ? kArmLdrh : kArmLdrsh; |
| 304 break; | 306 break; |
| 305 case kRepTagged: // Fall through. | 307 case kRepTagged: // Fall through. |
| 306 case kRepWord32: | 308 case kRepWord32: |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 Emit(kArmStoreWriteBarrier, NULL, g.UseFixed(base, r4), | 340 Emit(kArmStoreWriteBarrier, NULL, g.UseFixed(base, r4), |
| 339 g.UseFixed(index, r5), g.UseFixed(value, r6), arraysize(temps), | 341 g.UseFixed(index, r5), g.UseFixed(value, r6), arraysize(temps), |
| 340 temps); | 342 temps); |
| 341 return; | 343 return; |
| 342 } | 344 } |
| 343 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); | 345 DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); |
| 344 | 346 |
| 345 ArchOpcode opcode; | 347 ArchOpcode opcode; |
| 346 switch (rep) { | 348 switch (rep) { |
| 347 case kRepFloat32: | 349 case kRepFloat32: |
| 348 opcode = kArmVstr32; | 350 opcode = kArmVstrF32; |
| 349 break; | 351 break; |
| 350 case kRepFloat64: | 352 case kRepFloat64: |
| 351 opcode = kArmVstr64; | 353 opcode = kArmVstrF64; |
| 352 break; | 354 break; |
| 353 case kRepBit: // Fall through. | 355 case kRepBit: // Fall through. |
| 354 case kRepWord8: | 356 case kRepWord8: |
| 355 opcode = kArmStrb; | 357 opcode = kArmStrb; |
| 356 break; | 358 break; |
| 357 case kRepWord16: | 359 case kRepWord16: |
| 358 opcode = kArmStrh; | 360 opcode = kArmStrh; |
| 359 break; | 361 break; |
| 360 case kRepTagged: // Fall through. | 362 case kRepTagged: // Fall through. |
| 361 case kRepWord32: | 363 case kRepWord32: |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 675 void InstructionSelector::VisitInt32Mod(Node* node) { | 677 void InstructionSelector::VisitInt32Mod(Node* node) { |
| 676 VisitMod(this, node, kArmSdiv, kArmVcvtF64S32, kArmVcvtS32F64); | 678 VisitMod(this, node, kArmSdiv, kArmVcvtF64S32, kArmVcvtS32F64); |
| 677 } | 679 } |
| 678 | 680 |
| 679 | 681 |
| 680 void InstructionSelector::VisitInt32UMod(Node* node) { | 682 void InstructionSelector::VisitInt32UMod(Node* node) { |
| 681 VisitMod(this, node, kArmUdiv, kArmVcvtF64U32, kArmVcvtU32F64); | 683 VisitMod(this, node, kArmUdiv, kArmVcvtF64U32, kArmVcvtU32F64); |
| 682 } | 684 } |
| 683 | 685 |
| 684 | 686 |
| 687 void InstructionSelector::VisitChangeFloat32ToFloat64(Node* node) { |
| 688 ArmOperandGenerator g(this); |
| 689 Emit(kArmVcvtF64F32, g.DefineAsRegister(node), |
| 690 g.UseRegister(node->InputAt(0))); |
| 691 } |
| 692 |
| 693 |
| 685 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { | 694 void InstructionSelector::VisitChangeInt32ToFloat64(Node* node) { |
| 686 ArmOperandGenerator g(this); | 695 ArmOperandGenerator g(this); |
| 687 Emit(kArmVcvtF64S32, g.DefineAsRegister(node), | 696 Emit(kArmVcvtF64S32, g.DefineAsRegister(node), |
| 688 g.UseRegister(node->InputAt(0))); | 697 g.UseRegister(node->InputAt(0))); |
| 689 } | 698 } |
| 690 | 699 |
| 691 | 700 |
| 692 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { | 701 void InstructionSelector::VisitChangeUint32ToFloat64(Node* node) { |
| 693 ArmOperandGenerator g(this); | 702 ArmOperandGenerator g(this); |
| 694 Emit(kArmVcvtF64U32, g.DefineAsRegister(node), | 703 Emit(kArmVcvtF64U32, g.DefineAsRegister(node), |
| 695 g.UseRegister(node->InputAt(0))); | 704 g.UseRegister(node->InputAt(0))); |
| 696 } | 705 } |
| 697 | 706 |
| 698 | 707 |
| 699 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { | 708 void InstructionSelector::VisitChangeFloat64ToInt32(Node* node) { |
| 700 ArmOperandGenerator g(this); | 709 ArmOperandGenerator g(this); |
| 701 Emit(kArmVcvtS32F64, g.DefineAsRegister(node), | 710 Emit(kArmVcvtS32F64, g.DefineAsRegister(node), |
| 702 g.UseRegister(node->InputAt(0))); | 711 g.UseRegister(node->InputAt(0))); |
| 703 } | 712 } |
| 704 | 713 |
| 705 | 714 |
| 706 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { | 715 void InstructionSelector::VisitChangeFloat64ToUint32(Node* node) { |
| 707 ArmOperandGenerator g(this); | 716 ArmOperandGenerator g(this); |
| 708 Emit(kArmVcvtU32F64, g.DefineAsRegister(node), | 717 Emit(kArmVcvtU32F64, g.DefineAsRegister(node), |
| 709 g.UseRegister(node->InputAt(0))); | 718 g.UseRegister(node->InputAt(0))); |
| 710 } | 719 } |
| 711 | 720 |
| 712 | 721 |
| 722 void InstructionSelector::VisitTruncateFloat64ToFloat32(Node* node) { |
| 723 ArmOperandGenerator g(this); |
| 724 Emit(kArmVcvtF32F64, g.DefineAsRegister(node), |
| 725 g.UseRegister(node->InputAt(0))); |
| 726 } |
| 727 |
| 728 |
| 713 void InstructionSelector::VisitFloat64Add(Node* node) { | 729 void InstructionSelector::VisitFloat64Add(Node* node) { |
| 714 ArmOperandGenerator g(this); | 730 ArmOperandGenerator g(this); |
| 715 Int32BinopMatcher m(node); | 731 Int32BinopMatcher m(node); |
| 716 if (m.left().IsFloat64Mul() && CanCover(node, m.left().node())) { | 732 if (m.left().IsFloat64Mul() && CanCover(node, m.left().node())) { |
| 717 Int32BinopMatcher mleft(m.left().node()); | 733 Int32BinopMatcher mleft(m.left().node()); |
| 718 Emit(kArmVmlaF64, g.DefineSameAsFirst(node), | 734 Emit(kArmVmlaF64, g.DefineSameAsFirst(node), |
| 719 g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), | 735 g.UseRegister(m.right().node()), g.UseRegister(mleft.left().node()), |
| 720 g.UseRegister(mleft.right().node())); | 736 g.UseRegister(mleft.right().node())); |
| 721 return; | 737 return; |
| 722 } | 738 } |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 934 } else { | 950 } else { |
| 935 DCHECK(cont->IsSet()); | 951 DCHECK(cont->IsSet()); |
| 936 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), | 952 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), |
| 937 g.UseRegister(m.left().node()), g.UseRegister(m.right().node())); | 953 g.UseRegister(m.left().node()), g.UseRegister(m.right().node())); |
| 938 } | 954 } |
| 939 } | 955 } |
| 940 | 956 |
| 941 } // namespace compiler | 957 } // namespace compiler |
| 942 } // namespace internal | 958 } // namespace internal |
| 943 } // namespace v8 | 959 } // namespace v8 |
| OLD | NEW |