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/arm64/macro-assembler-arm64.h" | 7 #include "src/arm64/macro-assembler-arm64.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/compiler/node-properties-inl.h" | 11 #include "src/compiler/node-properties-inl.h" |
12 #include "src/scopes.h" | 12 #include "src/scopes.h" |
13 | 13 |
14 namespace v8 { | 14 namespace v8 { |
15 namespace internal { | 15 namespace internal { |
16 namespace compiler { | 16 namespace compiler { |
17 | 17 |
18 #define __ masm()-> | 18 #define __ masm()-> |
19 | 19 |
20 | 20 |
21 // Adds Arm64-specific methods to convert InstructionOperands. | 21 // Adds Arm64-specific methods to convert InstructionOperands. |
22 class Arm64OperandConverter FINAL : public InstructionOperandConverter { | 22 class Arm64OperandConverter FINAL : public InstructionOperandConverter { |
23 public: | 23 public: |
24 Arm64OperandConverter(CodeGenerator* gen, Instruction* instr) | 24 Arm64OperandConverter(CodeGenerator* gen, Instruction* instr) |
25 : InstructionOperandConverter(gen, instr) {} | 25 : InstructionOperandConverter(gen, instr) {} |
26 | 26 |
| 27 DoubleRegister InputFloat32Register(int index) { |
| 28 return InputDoubleRegister(index).S(); |
| 29 } |
| 30 |
| 31 DoubleRegister InputFloat64Register(int index) { |
| 32 return InputDoubleRegister(index); |
| 33 } |
| 34 |
| 35 DoubleRegister OutputFloat32Register() { return OutputDoubleRegister().S(); } |
| 36 |
| 37 DoubleRegister OutputFloat64Register() { return OutputDoubleRegister(); } |
| 38 |
27 Register InputRegister32(int index) { | 39 Register InputRegister32(int index) { |
28 return ToRegister(instr_->InputAt(index)).W(); | 40 return ToRegister(instr_->InputAt(index)).W(); |
29 } | 41 } |
30 | 42 |
31 Register InputRegister64(int index) { return InputRegister(index); } | 43 Register InputRegister64(int index) { return InputRegister(index); } |
32 | 44 |
33 Operand InputImmediate(int index) { | 45 Operand InputImmediate(int index) { |
34 return ToImmediate(instr_->InputAt(index)); | 46 return ToImmediate(instr_->InputAt(index)); |
35 } | 47 } |
36 | 48 |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 *first_index += 2; | 111 *first_index += 2; |
100 return MemOperand(InputRegister(index + 0), InputInt32(index + 1)); | 112 return MemOperand(InputRegister(index + 0), InputInt32(index + 1)); |
101 case kMode_MRR: | 113 case kMode_MRR: |
102 *first_index += 2; | 114 *first_index += 2; |
103 return MemOperand(InputRegister(index + 0), InputRegister(index + 1)); | 115 return MemOperand(InputRegister(index + 0), InputRegister(index + 1)); |
104 } | 116 } |
105 UNREACHABLE(); | 117 UNREACHABLE(); |
106 return MemOperand(no_reg); | 118 return MemOperand(no_reg); |
107 } | 119 } |
108 | 120 |
109 MemOperand MemoryOperand() { | 121 MemOperand MemoryOperand(int first_index = 0) { |
110 int index = 0; | 122 return MemoryOperand(&first_index); |
111 return MemoryOperand(&index); | |
112 } | 123 } |
113 | 124 |
114 Operand ToOperand(InstructionOperand* op) { | 125 Operand ToOperand(InstructionOperand* op) { |
115 if (op->IsRegister()) { | 126 if (op->IsRegister()) { |
116 return Operand(ToRegister(op)); | 127 return Operand(ToRegister(op)); |
117 } | 128 } |
118 return ToImmediate(op); | 129 return ToImmediate(op); |
119 } | 130 } |
120 | 131 |
121 Operand ToOperand32(InstructionOperand* op) { | 132 Operand ToOperand32(InstructionOperand* op) { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 DCHECK(!op->IsDoubleRegister()); | 167 DCHECK(!op->IsDoubleRegister()); |
157 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); | 168 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); |
158 // The linkage computes where all spill slots are located. | 169 // The linkage computes where all spill slots are located. |
159 FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0); | 170 FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), 0); |
160 return MemOperand(offset.from_stack_pointer() ? masm->StackPointer() : fp, | 171 return MemOperand(offset.from_stack_pointer() ? masm->StackPointer() : fp, |
161 offset.offset()); | 172 offset.offset()); |
162 } | 173 } |
163 }; | 174 }; |
164 | 175 |
165 | 176 |
| 177 namespace { |
| 178 |
| 179 class OutOfLineLoadFloat32 FINAL : public OutOfLineCode { |
| 180 public: |
| 181 OutOfLineLoadFloat32(CodeGenerator* gen, DoubleRegister result) |
| 182 : OutOfLineCode(gen), result_(result) {} |
| 183 |
| 184 void Generate() FINAL { |
| 185 __ Fmov(result_, std::numeric_limits<float>::quiet_NaN()); |
| 186 } |
| 187 |
| 188 private: |
| 189 DoubleRegister const result_; |
| 190 }; |
| 191 |
| 192 |
| 193 class OutOfLineLoadFloat64 FINAL : public OutOfLineCode { |
| 194 public: |
| 195 OutOfLineLoadFloat64(CodeGenerator* gen, DoubleRegister result) |
| 196 : OutOfLineCode(gen), result_(result) {} |
| 197 |
| 198 void Generate() FINAL { |
| 199 __ Fmov(result_, std::numeric_limits<double>::quiet_NaN()); |
| 200 } |
| 201 |
| 202 private: |
| 203 DoubleRegister const result_; |
| 204 }; |
| 205 |
| 206 |
| 207 class OutOfLineLoadInteger FINAL : public OutOfLineCode { |
| 208 public: |
| 209 OutOfLineLoadInteger(CodeGenerator* gen, Register result) |
| 210 : OutOfLineCode(gen), result_(result) {} |
| 211 |
| 212 void Generate() FINAL { __ Mov(result_, 0); } |
| 213 |
| 214 private: |
| 215 Register const result_; |
| 216 }; |
| 217 |
| 218 } // namespace |
| 219 |
| 220 |
| 221 #define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \ |
| 222 do { \ |
| 223 auto result = i.OutputFloat##width##Register(); \ |
| 224 auto offset = i.InputRegister32(0); \ |
| 225 auto length = i.InputOperand32(1); \ |
| 226 __ Cmp(offset, length); \ |
| 227 auto ool = new (zone()) OutOfLineLoadFloat##width(this, result); \ |
| 228 __ B(hs, ool->entry()); \ |
| 229 __ Ldr(result, i.MemoryOperand(2)); \ |
| 230 __ Bind(ool->exit()); \ |
| 231 } while (0) |
| 232 |
| 233 |
| 234 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ |
| 235 do { \ |
| 236 auto result = i.OutputRegister32(); \ |
| 237 auto offset = i.InputRegister32(0); \ |
| 238 auto length = i.InputOperand32(1); \ |
| 239 __ Cmp(offset, length); \ |
| 240 auto ool = new (zone()) OutOfLineLoadInteger(this, result); \ |
| 241 __ B(hs, ool->entry()); \ |
| 242 __ asm_instr(result, i.MemoryOperand(2)); \ |
| 243 __ Bind(ool->exit()); \ |
| 244 } while (0) |
| 245 |
| 246 |
| 247 #define ASSEMBLE_CHECKED_STORE_FLOAT(width) \ |
| 248 do { \ |
| 249 auto offset = i.InputRegister32(0); \ |
| 250 auto length = i.InputOperand32(1); \ |
| 251 __ Cmp(offset, length); \ |
| 252 Label done; \ |
| 253 __ B(hs, &done); \ |
| 254 __ Str(i.InputFloat##width##Register(2), i.MemoryOperand(3)); \ |
| 255 __ Bind(&done); \ |
| 256 } while (0) |
| 257 |
| 258 |
| 259 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ |
| 260 do { \ |
| 261 auto offset = i.InputRegister32(0); \ |
| 262 auto length = i.InputOperand32(1); \ |
| 263 __ Cmp(offset, length); \ |
| 264 Label done; \ |
| 265 __ B(hs, &done); \ |
| 266 __ asm_instr(i.InputRegister32(2), i.MemoryOperand(3)); \ |
| 267 __ Bind(&done); \ |
| 268 } while (0) |
| 269 |
| 270 |
166 #define ASSEMBLE_SHIFT(asm_instr, width) \ | 271 #define ASSEMBLE_SHIFT(asm_instr, width) \ |
167 do { \ | 272 do { \ |
168 if (instr->InputAt(1)->IsRegister()) { \ | 273 if (instr->InputAt(1)->IsRegister()) { \ |
169 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ | 274 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), \ |
170 i.InputRegister##width(1)); \ | 275 i.InputRegister##width(1)); \ |
171 } else { \ | 276 } else { \ |
172 int64_t imm = i.InputOperand##width(1).immediate().value(); \ | 277 int64_t imm = i.InputOperand##width(1).immediate().value(); \ |
173 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), imm); \ | 278 __ asm_instr(i.OutputRegister##width(), i.InputRegister##width(0), imm); \ |
174 } \ | 279 } \ |
175 } while (0) | 280 } while (0) |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 temp = scope.AcquireX(); | 714 temp = scope.AcquireX(); |
610 lr_status = kLRHasBeenSaved; | 715 lr_status = kLRHasBeenSaved; |
611 __ Push(lr, temp); // Need to push a pair | 716 __ Push(lr, temp); // Need to push a pair |
612 } | 717 } |
613 __ RecordWrite(object, index, value, lr_status, mode); | 718 __ RecordWrite(object, index, value, lr_status, mode); |
614 if (csp.is(masm()->StackPointer())) { | 719 if (csp.is(masm()->StackPointer())) { |
615 __ Pop(temp, lr); | 720 __ Pop(temp, lr); |
616 } | 721 } |
617 break; | 722 break; |
618 } | 723 } |
| 724 case kCheckedLoadInt8: |
| 725 ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrsb); |
| 726 break; |
| 727 case kCheckedLoadUint8: |
| 728 ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrb); |
| 729 break; |
| 730 case kCheckedLoadInt16: |
| 731 ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrsh); |
| 732 break; |
| 733 case kCheckedLoadUint16: |
| 734 ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrh); |
| 735 break; |
| 736 case kCheckedLoadWord32: |
| 737 ASSEMBLE_CHECKED_LOAD_INTEGER(Ldr); |
| 738 break; |
| 739 case kCheckedLoadFloat32: |
| 740 ASSEMBLE_CHECKED_LOAD_FLOAT(32); |
| 741 break; |
| 742 case kCheckedLoadFloat64: |
| 743 ASSEMBLE_CHECKED_LOAD_FLOAT(64); |
| 744 break; |
| 745 case kCheckedStoreWord8: |
| 746 ASSEMBLE_CHECKED_STORE_INTEGER(Strb); |
| 747 break; |
| 748 case kCheckedStoreWord16: |
| 749 ASSEMBLE_CHECKED_STORE_INTEGER(Strh); |
| 750 break; |
| 751 case kCheckedStoreWord32: |
| 752 ASSEMBLE_CHECKED_STORE_INTEGER(Str); |
| 753 break; |
| 754 case kCheckedStoreFloat32: |
| 755 ASSEMBLE_CHECKED_STORE_FLOAT(32); |
| 756 break; |
| 757 case kCheckedStoreFloat64: |
| 758 ASSEMBLE_CHECKED_STORE_FLOAT(64); |
| 759 break; |
619 } | 760 } |
620 } | 761 } |
621 | 762 |
622 | 763 |
623 // Assemble branches after this instruction. | 764 // Assemble branches after this instruction. |
624 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { | 765 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
625 Arm64OperandConverter i(this, instr); | 766 Arm64OperandConverter i(this, instr); |
626 Label* tlabel = branch->true_label; | 767 Label* tlabel = branch->true_label; |
627 Label* flabel = branch->false_label; | 768 Label* flabel = branch->false_label; |
628 switch (branch->condition) { | 769 switch (branch->condition) { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
763 case kUnsignedGreaterThan: | 904 case kUnsignedGreaterThan: |
764 cc = hi; | 905 cc = hi; |
765 break; | 906 break; |
766 case kOverflow: | 907 case kOverflow: |
767 cc = vs; | 908 cc = vs; |
768 break; | 909 break; |
769 case kNotOverflow: | 910 case kNotOverflow: |
770 cc = vc; | 911 cc = vc; |
771 break; | 912 break; |
772 } | 913 } |
773 __ bind(&check); | 914 __ Bind(&check); |
774 __ Cset(reg, cc); | 915 __ Cset(reg, cc); |
775 __ Bind(&done); | 916 __ Bind(&done); |
776 } | 917 } |
777 | 918 |
778 | 919 |
779 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { | 920 void CodeGenerator::AssembleDeoptimizerCall(int deoptimization_id) { |
780 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( | 921 Address deopt_entry = Deoptimizer::GetDeoptimizationEntry( |
781 isolate(), deoptimization_id, Deoptimizer::LAZY); | 922 isolate(), deoptimization_id, Deoptimizer::LAZY); |
782 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); | 923 __ Call(deopt_entry, RelocInfo::RUNTIME_ENTRY); |
783 } | 924 } |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1016 } | 1157 } |
1017 } | 1158 } |
1018 MarkLazyDeoptSite(); | 1159 MarkLazyDeoptSite(); |
1019 } | 1160 } |
1020 | 1161 |
1021 #undef __ | 1162 #undef __ |
1022 | 1163 |
1023 } // namespace compiler | 1164 } // namespace compiler |
1024 } // namespace internal | 1165 } // namespace internal |
1025 } // namespace v8 | 1166 } // namespace v8 |
OLD | NEW |