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/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/arm/macro-assembler-arm.h" | 7 #include "src/arm/macro-assembler-arm.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
11 #include "src/scopes.h" | 11 #include "src/scopes.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 namespace compiler { | 15 namespace compiler { |
16 | 16 |
17 #define __ masm()-> | 17 #define __ masm()-> |
18 | 18 |
19 | 19 |
20 #define kScratchReg r9 | 20 #define kScratchReg r9 |
21 | 21 |
22 | 22 |
23 // Adds Arm-specific methods to convert InstructionOperands. | 23 // Adds Arm-specific methods to convert InstructionOperands. |
24 class ArmOperandConverter FINAL : public InstructionOperandConverter { | 24 class ArmOperandConverter FINAL : public InstructionOperandConverter { |
25 public: | 25 public: |
26 ArmOperandConverter(CodeGenerator* gen, Instruction* instr) | 26 ArmOperandConverter(CodeGenerator* gen, Instruction* instr) |
27 : InstructionOperandConverter(gen, instr) {} | 27 : InstructionOperandConverter(gen, instr) {} |
28 | 28 |
29 SwVfpRegister OutputFloat32Register(int index = 0) { | 29 SwVfpRegister OutputFloat32Register(size_t index = 0) { |
30 return ToFloat32Register(instr_->OutputAt(index)); | 30 return ToFloat32Register(instr_->OutputAt(index)); |
31 } | 31 } |
32 | 32 |
33 SwVfpRegister InputFloat32Register(int index) { | 33 SwVfpRegister InputFloat32Register(size_t index) { |
34 return ToFloat32Register(instr_->InputAt(index)); | 34 return ToFloat32Register(instr_->InputAt(index)); |
35 } | 35 } |
36 | 36 |
37 SwVfpRegister ToFloat32Register(InstructionOperand* op) { | 37 SwVfpRegister ToFloat32Register(InstructionOperand* op) { |
38 return ToFloat64Register(op).low(); | 38 return ToFloat64Register(op).low(); |
39 } | 39 } |
40 | 40 |
41 LowDwVfpRegister OutputFloat64Register(int index = 0) { | 41 LowDwVfpRegister OutputFloat64Register(size_t index = 0) { |
42 return ToFloat64Register(instr_->OutputAt(index)); | 42 return ToFloat64Register(instr_->OutputAt(index)); |
43 } | 43 } |
44 | 44 |
45 LowDwVfpRegister InputFloat64Register(int index) { | 45 LowDwVfpRegister InputFloat64Register(size_t index) { |
46 return ToFloat64Register(instr_->InputAt(index)); | 46 return ToFloat64Register(instr_->InputAt(index)); |
47 } | 47 } |
48 | 48 |
49 LowDwVfpRegister ToFloat64Register(InstructionOperand* op) { | 49 LowDwVfpRegister ToFloat64Register(InstructionOperand* op) { |
50 return LowDwVfpRegister::from_code(ToDoubleRegister(op).code()); | 50 return LowDwVfpRegister::from_code(ToDoubleRegister(op).code()); |
51 } | 51 } |
52 | 52 |
53 SBit OutputSBit() const { | 53 SBit OutputSBit() const { |
54 switch (instr_->flags_mode()) { | 54 switch (instr_->flags_mode()) { |
55 case kFlags_branch: | 55 case kFlags_branch: |
56 case kFlags_set: | 56 case kFlags_set: |
57 return SetCC; | 57 return SetCC; |
58 case kFlags_none: | 58 case kFlags_none: |
59 return LeaveCC; | 59 return LeaveCC; |
60 } | 60 } |
61 UNREACHABLE(); | 61 UNREACHABLE(); |
62 return LeaveCC; | 62 return LeaveCC; |
63 } | 63 } |
64 | 64 |
65 Operand InputImmediate(int index) { | 65 Operand InputImmediate(size_t index) { |
66 Constant constant = ToConstant(instr_->InputAt(index)); | 66 Constant constant = ToConstant(instr_->InputAt(index)); |
67 switch (constant.type()) { | 67 switch (constant.type()) { |
68 case Constant::kInt32: | 68 case Constant::kInt32: |
69 return Operand(constant.ToInt32()); | 69 return Operand(constant.ToInt32()); |
70 case Constant::kFloat32: | 70 case Constant::kFloat32: |
71 return Operand( | 71 return Operand( |
72 isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED)); | 72 isolate()->factory()->NewNumber(constant.ToFloat32(), TENURED)); |
73 case Constant::kFloat64: | 73 case Constant::kFloat64: |
74 return Operand( | 74 return Operand( |
75 isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED)); | 75 isolate()->factory()->NewNumber(constant.ToFloat64(), TENURED)); |
76 case Constant::kInt64: | 76 case Constant::kInt64: |
77 case Constant::kExternalReference: | 77 case Constant::kExternalReference: |
78 case Constant::kHeapObject: | 78 case Constant::kHeapObject: |
79 case Constant::kRpoNumber: | 79 case Constant::kRpoNumber: |
80 break; | 80 break; |
81 } | 81 } |
82 UNREACHABLE(); | 82 UNREACHABLE(); |
83 return Operand::Zero(); | 83 return Operand::Zero(); |
84 } | 84 } |
85 | 85 |
86 Operand InputOperand2(int first_index) { | 86 Operand InputOperand2(size_t first_index) { |
87 const int index = first_index; | 87 const size_t index = first_index; |
88 switch (AddressingModeField::decode(instr_->opcode())) { | 88 switch (AddressingModeField::decode(instr_->opcode())) { |
89 case kMode_None: | 89 case kMode_None: |
90 case kMode_Offset_RI: | 90 case kMode_Offset_RI: |
91 case kMode_Offset_RR: | 91 case kMode_Offset_RR: |
92 break; | 92 break; |
93 case kMode_Operand2_I: | 93 case kMode_Operand2_I: |
94 return InputImmediate(index + 0); | 94 return InputImmediate(index + 0); |
95 case kMode_Operand2_R: | 95 case kMode_Operand2_R: |
96 return Operand(InputRegister(index + 0)); | 96 return Operand(InputRegister(index + 0)); |
97 case kMode_Operand2_R_ASR_I: | 97 case kMode_Operand2_R_ASR_I: |
(...skipping 10 matching lines...) Expand all Loading... |
108 return Operand(InputRegister(index + 0), LSR, InputRegister(index + 1)); | 108 return Operand(InputRegister(index + 0), LSR, InputRegister(index + 1)); |
109 case kMode_Operand2_R_ROR_I: | 109 case kMode_Operand2_R_ROR_I: |
110 return Operand(InputRegister(index + 0), ROR, InputInt5(index + 1)); | 110 return Operand(InputRegister(index + 0), ROR, InputInt5(index + 1)); |
111 case kMode_Operand2_R_ROR_R: | 111 case kMode_Operand2_R_ROR_R: |
112 return Operand(InputRegister(index + 0), ROR, InputRegister(index + 1)); | 112 return Operand(InputRegister(index + 0), ROR, InputRegister(index + 1)); |
113 } | 113 } |
114 UNREACHABLE(); | 114 UNREACHABLE(); |
115 return Operand::Zero(); | 115 return Operand::Zero(); |
116 } | 116 } |
117 | 117 |
118 MemOperand InputOffset(int* first_index) { | 118 MemOperand InputOffset(size_t* first_index) { |
119 const int index = *first_index; | 119 const size_t index = *first_index; |
120 switch (AddressingModeField::decode(instr_->opcode())) { | 120 switch (AddressingModeField::decode(instr_->opcode())) { |
121 case kMode_None: | 121 case kMode_None: |
122 case kMode_Operand2_I: | 122 case kMode_Operand2_I: |
123 case kMode_Operand2_R: | 123 case kMode_Operand2_R: |
124 case kMode_Operand2_R_ASR_I: | 124 case kMode_Operand2_R_ASR_I: |
125 case kMode_Operand2_R_ASR_R: | 125 case kMode_Operand2_R_ASR_R: |
126 case kMode_Operand2_R_LSL_I: | 126 case kMode_Operand2_R_LSL_I: |
127 case kMode_Operand2_R_LSL_R: | 127 case kMode_Operand2_R_LSL_R: |
128 case kMode_Operand2_R_LSR_I: | 128 case kMode_Operand2_R_LSR_I: |
129 case kMode_Operand2_R_LSR_R: | 129 case kMode_Operand2_R_LSR_R: |
130 case kMode_Operand2_R_ROR_I: | 130 case kMode_Operand2_R_ROR_I: |
131 case kMode_Operand2_R_ROR_R: | 131 case kMode_Operand2_R_ROR_R: |
132 break; | 132 break; |
133 case kMode_Offset_RI: | 133 case kMode_Offset_RI: |
134 *first_index += 2; | 134 *first_index += 2; |
135 return MemOperand(InputRegister(index + 0), InputInt32(index + 1)); | 135 return MemOperand(InputRegister(index + 0), InputInt32(index + 1)); |
136 case kMode_Offset_RR: | 136 case kMode_Offset_RR: |
137 *first_index += 2; | 137 *first_index += 2; |
138 return MemOperand(InputRegister(index + 0), InputRegister(index + 1)); | 138 return MemOperand(InputRegister(index + 0), InputRegister(index + 1)); |
139 } | 139 } |
140 UNREACHABLE(); | 140 UNREACHABLE(); |
141 return MemOperand(r0); | 141 return MemOperand(r0); |
142 } | 142 } |
143 | 143 |
144 MemOperand InputOffset(int first_index = 0) { | 144 MemOperand InputOffset(size_t first_index = 0) { |
145 return InputOffset(&first_index); | 145 return InputOffset(&first_index); |
146 } | 146 } |
147 | 147 |
148 MemOperand ToMemOperand(InstructionOperand* op) const { | 148 MemOperand ToMemOperand(InstructionOperand* op) const { |
149 DCHECK(op != NULL); | 149 DCHECK(op != NULL); |
150 DCHECK(!op->IsRegister()); | 150 DCHECK(!op->IsRegister()); |
151 DCHECK(!op->IsDoubleRegister()); | 151 DCHECK(!op->IsDoubleRegister()); |
152 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); | 152 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); |
153 // The linkage computes where all spill slots are located. | 153 // The linkage computes where all spill slots are located. |
154 FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0); | 154 FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0); |
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
613 } | 613 } |
614 case kArmLdrb: | 614 case kArmLdrb: |
615 __ ldrb(i.OutputRegister(), i.InputOffset()); | 615 __ ldrb(i.OutputRegister(), i.InputOffset()); |
616 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 616 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
617 break; | 617 break; |
618 case kArmLdrsb: | 618 case kArmLdrsb: |
619 __ ldrsb(i.OutputRegister(), i.InputOffset()); | 619 __ ldrsb(i.OutputRegister(), i.InputOffset()); |
620 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 620 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
621 break; | 621 break; |
622 case kArmStrb: { | 622 case kArmStrb: { |
623 int index = 0; | 623 size_t index = 0; |
624 MemOperand operand = i.InputOffset(&index); | 624 MemOperand operand = i.InputOffset(&index); |
625 __ strb(i.InputRegister(index), operand); | 625 __ strb(i.InputRegister(index), operand); |
626 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 626 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
627 break; | 627 break; |
628 } | 628 } |
629 case kArmLdrh: | 629 case kArmLdrh: |
630 __ ldrh(i.OutputRegister(), i.InputOffset()); | 630 __ ldrh(i.OutputRegister(), i.InputOffset()); |
631 break; | 631 break; |
632 case kArmLdrsh: | 632 case kArmLdrsh: |
633 __ ldrsh(i.OutputRegister(), i.InputOffset()); | 633 __ ldrsh(i.OutputRegister(), i.InputOffset()); |
634 break; | 634 break; |
635 case kArmStrh: { | 635 case kArmStrh: { |
636 int index = 0; | 636 size_t index = 0; |
637 MemOperand operand = i.InputOffset(&index); | 637 MemOperand operand = i.InputOffset(&index); |
638 __ strh(i.InputRegister(index), operand); | 638 __ strh(i.InputRegister(index), operand); |
639 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 639 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
640 break; | 640 break; |
641 } | 641 } |
642 case kArmLdr: | 642 case kArmLdr: |
643 __ ldr(i.OutputRegister(), i.InputOffset()); | 643 __ ldr(i.OutputRegister(), i.InputOffset()); |
644 break; | 644 break; |
645 case kArmStr: { | 645 case kArmStr: { |
646 int index = 0; | 646 size_t index = 0; |
647 MemOperand operand = i.InputOffset(&index); | 647 MemOperand operand = i.InputOffset(&index); |
648 __ str(i.InputRegister(index), operand); | 648 __ str(i.InputRegister(index), operand); |
649 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 649 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
650 break; | 650 break; |
651 } | 651 } |
652 case kArmVldrF32: { | 652 case kArmVldrF32: { |
653 __ vldr(i.OutputFloat32Register(), i.InputOffset()); | 653 __ vldr(i.OutputFloat32Register(), i.InputOffset()); |
654 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 654 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
655 break; | 655 break; |
656 } | 656 } |
657 case kArmVstrF32: { | 657 case kArmVstrF32: { |
658 int index = 0; | 658 size_t index = 0; |
659 MemOperand operand = i.InputOffset(&index); | 659 MemOperand operand = i.InputOffset(&index); |
660 __ vstr(i.InputFloat32Register(index), operand); | 660 __ vstr(i.InputFloat32Register(index), operand); |
661 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 661 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
662 break; | 662 break; |
663 } | 663 } |
664 case kArmVldrF64: | 664 case kArmVldrF64: |
665 __ vldr(i.OutputFloat64Register(), i.InputOffset()); | 665 __ vldr(i.OutputFloat64Register(), i.InputOffset()); |
666 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 666 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
667 break; | 667 break; |
668 case kArmVstrF64: { | 668 case kArmVstrF64: { |
669 int index = 0; | 669 size_t index = 0; |
670 MemOperand operand = i.InputOffset(&index); | 670 MemOperand operand = i.InputOffset(&index); |
671 __ vstr(i.InputFloat64Register(index), operand); | 671 __ vstr(i.InputFloat64Register(index), operand); |
672 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 672 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
673 break; | 673 break; |
674 } | 674 } |
675 case kArmPush: | 675 case kArmPush: |
676 __ Push(i.InputRegister(0)); | 676 __ Push(i.InputRegister(0)); |
677 DCHECK_EQ(LeaveCC, i.OutputSBit()); | 677 DCHECK_EQ(LeaveCC, i.OutputSBit()); |
678 break; | 678 break; |
679 case kArmStoreWriteBarrier: { | 679 case kArmStoreWriteBarrier: { |
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1073 } | 1073 } |
1074 } | 1074 } |
1075 MarkLazyDeoptSite(); | 1075 MarkLazyDeoptSite(); |
1076 } | 1076 } |
1077 | 1077 |
1078 #undef __ | 1078 #undef __ |
1079 | 1079 |
1080 } // namespace compiler | 1080 } // namespace compiler |
1081 } // namespace internal | 1081 } // namespace internal |
1082 } // namespace v8 | 1082 } // namespace v8 |
OLD | NEW |