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 |