OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/compiler/code-generator-impl.h" | 7 #include "src/compiler/code-generator-impl.h" |
8 #include "src/compiler/gap-resolver.h" | 8 #include "src/compiler/gap-resolver.h" |
9 #include "src/compiler/node-matchers.h" | 9 #include "src/compiler/node-matchers.h" |
10 #include "src/compiler/node-properties-inl.h" | 10 #include "src/compiler/node-properties-inl.h" |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 return Operand(index, scale, disp); | 112 return Operand(index, scale, disp); |
113 } | 113 } |
114 case kMode_None: | 114 case kMode_None: |
115 UNREACHABLE(); | 115 UNREACHABLE(); |
116 return Operand(no_reg, 0); | 116 return Operand(no_reg, 0); |
117 } | 117 } |
118 UNREACHABLE(); | 118 UNREACHABLE(); |
119 return Operand(no_reg, 0); | 119 return Operand(no_reg, 0); |
120 } | 120 } |
121 | 121 |
122 Operand MemoryOperand() { | 122 Operand MemoryOperand(int first_input = 0) { |
123 int first_input = 0; | |
124 return MemoryOperand(&first_input); | 123 return MemoryOperand(&first_input); |
125 } | 124 } |
126 }; | 125 }; |
127 | 126 |
128 | 127 |
129 static bool HasImmediateInput(Instruction* instr, int index) { | 128 namespace { |
| 129 |
| 130 bool HasImmediateInput(Instruction* instr, int index) { |
130 return instr->InputAt(index)->IsImmediate(); | 131 return instr->InputAt(index)->IsImmediate(); |
131 } | 132 } |
132 | 133 |
133 | 134 |
| 135 class OutOfLineLoadInteger FINAL : public OutOfLineCode { |
| 136 public: |
| 137 OutOfLineLoadInteger(CodeGenerator* gen, Register result) |
| 138 : OutOfLineCode(gen), result_(result) {} |
| 139 |
| 140 void Generate() FINAL { __ xorl(result_, result_); } |
| 141 |
| 142 private: |
| 143 Register const result_; |
| 144 }; |
| 145 |
| 146 |
| 147 class OutOfLineLoadFloat FINAL : public OutOfLineCode { |
| 148 public: |
| 149 OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result) |
| 150 : OutOfLineCode(gen), result_(result) {} |
| 151 |
| 152 void Generate() FINAL { __ pcmpeqd(result_, result_); } |
| 153 |
| 154 private: |
| 155 XMMRegister const result_; |
| 156 }; |
| 157 |
| 158 } // namespace |
| 159 |
| 160 |
134 #define ASSEMBLE_UNOP(asm_instr) \ | 161 #define ASSEMBLE_UNOP(asm_instr) \ |
135 do { \ | 162 do { \ |
136 if (instr->Output()->IsRegister()) { \ | 163 if (instr->Output()->IsRegister()) { \ |
137 __ asm_instr(i.OutputRegister()); \ | 164 __ asm_instr(i.OutputRegister()); \ |
138 } else { \ | 165 } else { \ |
139 __ asm_instr(i.OutputOperand()); \ | 166 __ asm_instr(i.OutputOperand()); \ |
140 } \ | 167 } \ |
141 } while (0) | 168 } while (0) |
142 | 169 |
143 | 170 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 if (instr->InputAt(1)->IsDoubleRegister()) { \ | 240 if (instr->InputAt(1)->IsDoubleRegister()) { \ |
214 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ | 241 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ |
215 i.InputDoubleRegister(1)); \ | 242 i.InputDoubleRegister(1)); \ |
216 } else { \ | 243 } else { \ |
217 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ | 244 __ asm_instr(i.OutputDoubleRegister(), i.InputDoubleRegister(0), \ |
218 i.InputOperand(1)); \ | 245 i.InputOperand(1)); \ |
219 } \ | 246 } \ |
220 } while (0) | 247 } while (0) |
221 | 248 |
222 | 249 |
| 250 #define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr) \ |
| 251 do { \ |
| 252 auto result = i.OutputDoubleRegister(); \ |
| 253 auto offset = i.InputRegister(0); \ |
| 254 if (instr->InputAt(1)->IsRegister()) { \ |
| 255 __ cmpl(offset, i.InputRegister(1)); \ |
| 256 } else { \ |
| 257 __ cmpl(offset, i.InputImmediate(1)); \ |
| 258 } \ |
| 259 OutOfLineCode* ool = new (zone()) OutOfLineLoadFloat(this, result); \ |
| 260 __ j(above_equal, ool->entry()); \ |
| 261 __ asm_instr(result, i.MemoryOperand(2)); \ |
| 262 __ bind(ool->exit()); \ |
| 263 } while (false) |
| 264 |
| 265 |
| 266 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ |
| 267 do { \ |
| 268 auto result = i.OutputRegister(); \ |
| 269 auto offset = i.InputRegister(0); \ |
| 270 if (instr->InputAt(1)->IsRegister()) { \ |
| 271 __ cmpl(offset, i.InputRegister(1)); \ |
| 272 } else { \ |
| 273 __ cmpl(offset, i.InputImmediate(1)); \ |
| 274 } \ |
| 275 OutOfLineCode* ool = new (zone()) OutOfLineLoadInteger(this, result); \ |
| 276 __ j(above_equal, ool->entry()); \ |
| 277 __ asm_instr(result, i.MemoryOperand(2)); \ |
| 278 __ bind(ool->exit()); \ |
| 279 } while (false) |
| 280 |
| 281 |
| 282 #define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \ |
| 283 do { \ |
| 284 auto offset = i.InputRegister(0); \ |
| 285 if (instr->InputAt(1)->IsRegister()) { \ |
| 286 __ cmpl(offset, i.InputRegister(1)); \ |
| 287 } else { \ |
| 288 __ cmpl(offset, i.InputImmediate(1)); \ |
| 289 } \ |
| 290 Label done; \ |
| 291 __ j(above_equal, &done, Label::kNear); \ |
| 292 __ asm_instr(i.MemoryOperand(3), i.InputDoubleRegister(2)); \ |
| 293 __ bind(&done); \ |
| 294 } while (false) |
| 295 |
| 296 |
| 297 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ |
| 298 do { \ |
| 299 auto offset = i.InputRegister(0); \ |
| 300 if (instr->InputAt(1)->IsRegister()) { \ |
| 301 __ cmpl(offset, i.InputRegister(1)); \ |
| 302 } else { \ |
| 303 __ cmpl(offset, i.InputImmediate(1)); \ |
| 304 } \ |
| 305 Label done; \ |
| 306 __ j(above_equal, &done, Label::kNear); \ |
| 307 if (instr->InputAt(2)->IsRegister()) { \ |
| 308 __ asm_instr(i.MemoryOperand(3), i.InputRegister(2)); \ |
| 309 } else { \ |
| 310 __ asm_instr(i.MemoryOperand(3), i.InputImmediate(2)); \ |
| 311 } \ |
| 312 __ bind(&done); \ |
| 313 } while (false) |
| 314 |
| 315 |
223 // Assembles an instruction after register allocation, producing machine code. | 316 // Assembles an instruction after register allocation, producing machine code. |
224 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { | 317 void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
225 X64OperandConverter i(this, instr); | 318 X64OperandConverter i(this, instr); |
226 | 319 |
227 switch (ArchOpcodeField::decode(instr->opcode())) { | 320 switch (ArchOpcodeField::decode(instr->opcode())) { |
228 case kArchCallCodeObject: { | 321 case kArchCallCodeObject: { |
229 EnsureSpaceForLazyDeopt(); | 322 EnsureSpaceForLazyDeopt(); |
230 if (HasImmediateInput(instr, 0)) { | 323 if (HasImmediateInput(instr, 0)) { |
231 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); | 324 Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |
232 __ Call(code, RelocInfo::CODE_TARGET); | 325 __ Call(code, RelocInfo::CODE_TARGET); |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 Register index = i.InputRegister(1); | 753 Register index = i.InputRegister(1); |
661 Register value = i.InputRegister(2); | 754 Register value = i.InputRegister(2); |
662 __ movsxlq(index, index); | 755 __ movsxlq(index, index); |
663 __ movq(Operand(object, index, times_1, 0), value); | 756 __ movq(Operand(object, index, times_1, 0), value); |
664 __ leaq(index, Operand(object, index, times_1, 0)); | 757 __ leaq(index, Operand(object, index, times_1, 0)); |
665 SaveFPRegsMode mode = | 758 SaveFPRegsMode mode = |
666 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; | 759 frame()->DidAllocateDoubleRegisters() ? kSaveFPRegs : kDontSaveFPRegs; |
667 __ RecordWrite(object, index, value, mode); | 760 __ RecordWrite(object, index, value, mode); |
668 break; | 761 break; |
669 } | 762 } |
| 763 case kCheckedLoadInt8: |
| 764 ASSEMBLE_CHECKED_LOAD_INTEGER(movsxbl); |
| 765 break; |
| 766 case kCheckedLoadUint8: |
| 767 ASSEMBLE_CHECKED_LOAD_INTEGER(movzxbl); |
| 768 break; |
| 769 case kCheckedLoadInt16: |
| 770 ASSEMBLE_CHECKED_LOAD_INTEGER(movsxwl); |
| 771 break; |
| 772 case kCheckedLoadUint16: |
| 773 ASSEMBLE_CHECKED_LOAD_INTEGER(movzxwl); |
| 774 break; |
| 775 case kCheckedLoadWord32: |
| 776 ASSEMBLE_CHECKED_LOAD_INTEGER(movl); |
| 777 break; |
| 778 case kCheckedLoadFloat32: |
| 779 ASSEMBLE_CHECKED_LOAD_FLOAT(movss); |
| 780 break; |
| 781 case kCheckedLoadFloat64: |
| 782 ASSEMBLE_CHECKED_LOAD_FLOAT(movsd); |
| 783 break; |
| 784 case kCheckedStoreWord8: |
| 785 ASSEMBLE_CHECKED_STORE_INTEGER(movb); |
| 786 break; |
| 787 case kCheckedStoreWord16: |
| 788 ASSEMBLE_CHECKED_STORE_INTEGER(movw); |
| 789 break; |
| 790 case kCheckedStoreWord32: |
| 791 ASSEMBLE_CHECKED_STORE_INTEGER(movl); |
| 792 break; |
| 793 case kCheckedStoreFloat32: |
| 794 ASSEMBLE_CHECKED_STORE_FLOAT(movss); |
| 795 break; |
| 796 case kCheckedStoreFloat64: |
| 797 ASSEMBLE_CHECKED_STORE_FLOAT(movsd); |
| 798 break; |
670 } | 799 } |
671 } | 800 } |
672 | 801 |
673 | 802 |
674 // Assembles branches after this instruction. | 803 // Assembles branches after this instruction. |
675 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { | 804 void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) { |
676 X64OperandConverter i(this, instr); | 805 X64OperandConverter i(this, instr); |
677 Label::Distance flabel_distance = | 806 Label::Distance flabel_distance = |
678 branch->fallthru ? Label::kNear : Label::kFar; | 807 branch->fallthru ? Label::kNear : Label::kFar; |
679 Label* tlabel = branch->true_label; | 808 Label* tlabel = branch->true_label; |
(...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1076 } | 1205 } |
1077 } | 1206 } |
1078 MarkLazyDeoptSite(); | 1207 MarkLazyDeoptSite(); |
1079 } | 1208 } |
1080 | 1209 |
1081 #undef __ | 1210 #undef __ |
1082 | 1211 |
1083 } // namespace internal | 1212 } // namespace internal |
1084 } // namespace compiler | 1213 } // namespace compiler |
1085 } // namespace v8 | 1214 } // namespace v8 |
OLD | NEW |