| 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 19 matching lines...) Expand all Loading... |
| 30 Immediate InputImmediate(int index) { | 30 Immediate InputImmediate(int index) { |
| 31 return ToImmediate(instr_->InputAt(index)); | 31 return ToImmediate(instr_->InputAt(index)); |
| 32 } | 32 } |
| 33 | 33 |
| 34 Operand OutputOperand() { return ToOperand(instr_->Output()); } | 34 Operand OutputOperand() { return ToOperand(instr_->Output()); } |
| 35 | 35 |
| 36 Operand TempOperand(int index) { return ToOperand(instr_->TempAt(index)); } | 36 Operand TempOperand(int index) { return ToOperand(instr_->TempAt(index)); } |
| 37 | 37 |
| 38 Operand ToOperand(InstructionOperand* op, int extra = 0) { | 38 Operand ToOperand(InstructionOperand* op, int extra = 0) { |
| 39 if (op->IsRegister()) { | 39 if (op->IsRegister()) { |
| 40 ASSERT(extra == 0); | 40 DCHECK(extra == 0); |
| 41 return Operand(ToRegister(op)); | 41 return Operand(ToRegister(op)); |
| 42 } else if (op->IsDoubleRegister()) { | 42 } else if (op->IsDoubleRegister()) { |
| 43 ASSERT(extra == 0); | 43 DCHECK(extra == 0); |
| 44 return Operand(ToDoubleRegister(op)); | 44 return Operand(ToDoubleRegister(op)); |
| 45 } | 45 } |
| 46 ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot()); | 46 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); |
| 47 // The linkage computes where all spill slots are located. | 47 // The linkage computes where all spill slots are located. |
| 48 FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), extra); | 48 FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), extra); |
| 49 return Operand(offset.from_stack_pointer() ? esp : ebp, offset.offset()); | 49 return Operand(offset.from_stack_pointer() ? esp : ebp, offset.offset()); |
| 50 } | 50 } |
| 51 | 51 |
| 52 Operand HighOperand(InstructionOperand* op) { | 52 Operand HighOperand(InstructionOperand* op) { |
| 53 ASSERT(op->IsDoubleStackSlot()); | 53 DCHECK(op->IsDoubleStackSlot()); |
| 54 return ToOperand(op, kPointerSize); | 54 return ToOperand(op, kPointerSize); |
| 55 } | 55 } |
| 56 | 56 |
| 57 Immediate ToImmediate(InstructionOperand* operand) { | 57 Immediate ToImmediate(InstructionOperand* operand) { |
| 58 Constant constant = ToConstant(operand); | 58 Constant constant = ToConstant(operand); |
| 59 switch (constant.type()) { | 59 switch (constant.type()) { |
| 60 case Constant::kInt32: | 60 case Constant::kInt32: |
| 61 return Immediate(constant.ToInt32()); | 61 return Immediate(constant.ToInt32()); |
| 62 case Constant::kFloat64: | 62 case Constant::kFloat64: |
| 63 return Immediate( | 63 return Immediate( |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 | 478 |
| 479 // Assembles boolean materializations after an instruction. | 479 // Assembles boolean materializations after an instruction. |
| 480 void CodeGenerator::AssembleArchBoolean(Instruction* instr, | 480 void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
| 481 FlagsCondition condition) { | 481 FlagsCondition condition) { |
| 482 IA32OperandConverter i(this, instr); | 482 IA32OperandConverter i(this, instr); |
| 483 Label done; | 483 Label done; |
| 484 | 484 |
| 485 // Materialize a full 32-bit 1 or 0 value. The result register is always the | 485 // Materialize a full 32-bit 1 or 0 value. The result register is always the |
| 486 // last output of the instruction. | 486 // last output of the instruction. |
| 487 Label check; | 487 Label check; |
| 488 ASSERT_NE(0, instr->OutputCount()); | 488 DCHECK_NE(0, instr->OutputCount()); |
| 489 Register reg = i.OutputRegister(instr->OutputCount() - 1); | 489 Register reg = i.OutputRegister(instr->OutputCount() - 1); |
| 490 Condition cc = no_condition; | 490 Condition cc = no_condition; |
| 491 switch (condition) { | 491 switch (condition) { |
| 492 case kUnorderedEqual: | 492 case kUnorderedEqual: |
| 493 __ j(parity_odd, &check, Label::kNear); | 493 __ j(parity_odd, &check, Label::kNear); |
| 494 __ mov(reg, Immediate(0)); | 494 __ mov(reg, Immediate(0)); |
| 495 __ jmp(&done, Label::kNear); | 495 __ jmp(&done, Label::kNear); |
| 496 // Fall through. | 496 // Fall through. |
| 497 case kEqual: | 497 case kEqual: |
| 498 cc = equal; | 498 cc = equal; |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 788 } | 788 } |
| 789 } | 789 } |
| 790 | 790 |
| 791 | 791 |
| 792 void CodeGenerator::AssembleMove(InstructionOperand* source, | 792 void CodeGenerator::AssembleMove(InstructionOperand* source, |
| 793 InstructionOperand* destination) { | 793 InstructionOperand* destination) { |
| 794 IA32OperandConverter g(this, NULL); | 794 IA32OperandConverter g(this, NULL); |
| 795 // Dispatch on the source and destination operand kinds. Not all | 795 // Dispatch on the source and destination operand kinds. Not all |
| 796 // combinations are possible. | 796 // combinations are possible. |
| 797 if (source->IsRegister()) { | 797 if (source->IsRegister()) { |
| 798 ASSERT(destination->IsRegister() || destination->IsStackSlot()); | 798 DCHECK(destination->IsRegister() || destination->IsStackSlot()); |
| 799 Register src = g.ToRegister(source); | 799 Register src = g.ToRegister(source); |
| 800 Operand dst = g.ToOperand(destination); | 800 Operand dst = g.ToOperand(destination); |
| 801 __ mov(dst, src); | 801 __ mov(dst, src); |
| 802 } else if (source->IsStackSlot()) { | 802 } else if (source->IsStackSlot()) { |
| 803 ASSERT(destination->IsRegister() || destination->IsStackSlot()); | 803 DCHECK(destination->IsRegister() || destination->IsStackSlot()); |
| 804 Operand src = g.ToOperand(source); | 804 Operand src = g.ToOperand(source); |
| 805 if (destination->IsRegister()) { | 805 if (destination->IsRegister()) { |
| 806 Register dst = g.ToRegister(destination); | 806 Register dst = g.ToRegister(destination); |
| 807 __ mov(dst, src); | 807 __ mov(dst, src); |
| 808 } else { | 808 } else { |
| 809 Operand dst = g.ToOperand(destination); | 809 Operand dst = g.ToOperand(destination); |
| 810 __ push(src); | 810 __ push(src); |
| 811 __ pop(dst); | 811 __ pop(dst); |
| 812 } | 812 } |
| 813 } else if (source->IsConstant()) { | 813 } else if (source->IsConstant()) { |
| 814 Constant src_constant = g.ToConstant(source); | 814 Constant src_constant = g.ToConstant(source); |
| 815 if (src_constant.type() == Constant::kHeapObject) { | 815 if (src_constant.type() == Constant::kHeapObject) { |
| 816 Handle<HeapObject> src = src_constant.ToHeapObject(); | 816 Handle<HeapObject> src = src_constant.ToHeapObject(); |
| 817 if (destination->IsRegister()) { | 817 if (destination->IsRegister()) { |
| 818 Register dst = g.ToRegister(destination); | 818 Register dst = g.ToRegister(destination); |
| 819 __ LoadHeapObject(dst, src); | 819 __ LoadHeapObject(dst, src); |
| 820 } else { | 820 } else { |
| 821 ASSERT(destination->IsStackSlot()); | 821 DCHECK(destination->IsStackSlot()); |
| 822 Operand dst = g.ToOperand(destination); | 822 Operand dst = g.ToOperand(destination); |
| 823 AllowDeferredHandleDereference embedding_raw_address; | 823 AllowDeferredHandleDereference embedding_raw_address; |
| 824 if (isolate()->heap()->InNewSpace(*src)) { | 824 if (isolate()->heap()->InNewSpace(*src)) { |
| 825 __ PushHeapObject(src); | 825 __ PushHeapObject(src); |
| 826 __ pop(dst); | 826 __ pop(dst); |
| 827 } else { | 827 } else { |
| 828 __ mov(dst, src); | 828 __ mov(dst, src); |
| 829 } | 829 } |
| 830 } | 830 } |
| 831 } else if (destination->IsRegister()) { | 831 } else if (destination->IsRegister()) { |
| 832 Register dst = g.ToRegister(destination); | 832 Register dst = g.ToRegister(destination); |
| 833 __ mov(dst, g.ToImmediate(source)); | 833 __ mov(dst, g.ToImmediate(source)); |
| 834 } else if (destination->IsStackSlot()) { | 834 } else if (destination->IsStackSlot()) { |
| 835 Operand dst = g.ToOperand(destination); | 835 Operand dst = g.ToOperand(destination); |
| 836 __ mov(dst, g.ToImmediate(source)); | 836 __ mov(dst, g.ToImmediate(source)); |
| 837 } else { | 837 } else { |
| 838 double v = g.ToDouble(source); | 838 double v = g.ToDouble(source); |
| 839 uint64_t int_val = BitCast<uint64_t, double>(v); | 839 uint64_t int_val = BitCast<uint64_t, double>(v); |
| 840 int32_t lower = static_cast<int32_t>(int_val); | 840 int32_t lower = static_cast<int32_t>(int_val); |
| 841 int32_t upper = static_cast<int32_t>(int_val >> kBitsPerInt); | 841 int32_t upper = static_cast<int32_t>(int_val >> kBitsPerInt); |
| 842 if (destination->IsDoubleRegister()) { | 842 if (destination->IsDoubleRegister()) { |
| 843 XMMRegister dst = g.ToDoubleRegister(destination); | 843 XMMRegister dst = g.ToDoubleRegister(destination); |
| 844 __ Move(dst, v); | 844 __ Move(dst, v); |
| 845 } else { | 845 } else { |
| 846 ASSERT(destination->IsDoubleStackSlot()); | 846 DCHECK(destination->IsDoubleStackSlot()); |
| 847 Operand dst0 = g.ToOperand(destination); | 847 Operand dst0 = g.ToOperand(destination); |
| 848 Operand dst1 = g.HighOperand(destination); | 848 Operand dst1 = g.HighOperand(destination); |
| 849 __ mov(dst0, Immediate(lower)); | 849 __ mov(dst0, Immediate(lower)); |
| 850 __ mov(dst1, Immediate(upper)); | 850 __ mov(dst1, Immediate(upper)); |
| 851 } | 851 } |
| 852 } | 852 } |
| 853 } else if (source->IsDoubleRegister()) { | 853 } else if (source->IsDoubleRegister()) { |
| 854 XMMRegister src = g.ToDoubleRegister(source); | 854 XMMRegister src = g.ToDoubleRegister(source); |
| 855 if (destination->IsDoubleRegister()) { | 855 if (destination->IsDoubleRegister()) { |
| 856 XMMRegister dst = g.ToDoubleRegister(destination); | 856 XMMRegister dst = g.ToDoubleRegister(destination); |
| 857 __ movaps(dst, src); | 857 __ movaps(dst, src); |
| 858 } else { | 858 } else { |
| 859 ASSERT(destination->IsDoubleStackSlot()); | 859 DCHECK(destination->IsDoubleStackSlot()); |
| 860 Operand dst = g.ToOperand(destination); | 860 Operand dst = g.ToOperand(destination); |
| 861 __ movsd(dst, src); | 861 __ movsd(dst, src); |
| 862 } | 862 } |
| 863 } else if (source->IsDoubleStackSlot()) { | 863 } else if (source->IsDoubleStackSlot()) { |
| 864 ASSERT(destination->IsDoubleRegister() || destination->IsDoubleStackSlot()); | 864 DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot()); |
| 865 Operand src = g.ToOperand(source); | 865 Operand src = g.ToOperand(source); |
| 866 if (destination->IsDoubleRegister()) { | 866 if (destination->IsDoubleRegister()) { |
| 867 XMMRegister dst = g.ToDoubleRegister(destination); | 867 XMMRegister dst = g.ToDoubleRegister(destination); |
| 868 __ movsd(dst, src); | 868 __ movsd(dst, src); |
| 869 } else { | 869 } else { |
| 870 // We rely on having xmm0 available as a fixed scratch register. | 870 // We rely on having xmm0 available as a fixed scratch register. |
| 871 Operand dst = g.ToOperand(destination); | 871 Operand dst = g.ToOperand(destination); |
| 872 __ movsd(xmm0, src); | 872 __ movsd(xmm0, src); |
| 873 __ movsd(dst, xmm0); | 873 __ movsd(dst, xmm0); |
| 874 } | 874 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 947 return false; | 947 return false; |
| 948 } | 948 } |
| 949 return *(code->instruction_start() + start_pc) == | 949 return *(code->instruction_start() + start_pc) == |
| 950 v8::internal::Assembler::kNopByte; | 950 v8::internal::Assembler::kNopByte; |
| 951 } | 951 } |
| 952 | 952 |
| 953 #endif // DEBUG | 953 #endif // DEBUG |
| 954 } | 954 } |
| 955 } | 955 } |
| 956 } // namespace v8::internal::compiler | 956 } // namespace v8::internal::compiler |
| OLD | NEW |