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