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