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 |