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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 case Constant::kExternalReference: | 105 case Constant::kExternalReference: |
106 case Constant::kHeapObject: | 106 case Constant::kHeapObject: |
107 break; | 107 break; |
108 } | 108 } |
109 UNREACHABLE(); | 109 UNREACHABLE(); |
110 return Immediate(-1); | 110 return Immediate(-1); |
111 } | 111 } |
112 | 112 |
113 Operand ToOperand(InstructionOperand* op, int extra = 0) { | 113 Operand ToOperand(InstructionOperand* op, int extra = 0) { |
114 RegisterOrOperand result = ToRegisterOrOperand(op, extra); | 114 RegisterOrOperand result = ToRegisterOrOperand(op, extra); |
115 ASSERT_EQ(kOperand, result.type); | 115 DCHECK_EQ(kOperand, result.type); |
116 return result.operand; | 116 return result.operand; |
117 } | 117 } |
118 | 118 |
119 RegisterOrOperand ToRegisterOrOperand(InstructionOperand* op, int extra = 0) { | 119 RegisterOrOperand ToRegisterOrOperand(InstructionOperand* op, int extra = 0) { |
120 RegisterOrOperand result; | 120 RegisterOrOperand result; |
121 if (op->IsRegister()) { | 121 if (op->IsRegister()) { |
122 ASSERT(extra == 0); | 122 DCHECK(extra == 0); |
123 result.type = kRegister; | 123 result.type = kRegister; |
124 result.reg = ToRegister(op); | 124 result.reg = ToRegister(op); |
125 return result; | 125 return result; |
126 } else if (op->IsDoubleRegister()) { | 126 } else if (op->IsDoubleRegister()) { |
127 ASSERT(extra == 0); | 127 DCHECK(extra == 0); |
128 ASSERT(extra == 0); | 128 DCHECK(extra == 0); |
129 result.type = kDoubleRegister; | 129 result.type = kDoubleRegister; |
130 result.double_reg = ToDoubleRegister(op); | 130 result.double_reg = ToDoubleRegister(op); |
131 return result; | 131 return result; |
132 } | 132 } |
133 | 133 |
134 ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot()); | 134 DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); |
135 | 135 |
136 result.type = kOperand; | 136 result.type = kOperand; |
137 // The linkage computes where all spill slots are located. | 137 // The linkage computes where all spill slots are located. |
138 FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), extra); | 138 FrameOffset offset = linkage()->GetFrameOffset(op->index(), frame(), extra); |
139 result.operand = | 139 result.operand = |
140 Operand(offset.from_stack_pointer() ? rsp : rbp, offset.offset()); | 140 Operand(offset.from_stack_pointer() ? rsp : rbp, offset.offset()); |
141 return result; | 141 return result; |
142 } | 142 } |
143 | 143 |
144 Operand MemoryOperand(int* first_input) { | 144 Operand MemoryOperand(int* first_input) { |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 bool lazy_deopt = (MiscField::decode(instr->opcode()) == 1); | 398 bool lazy_deopt = (MiscField::decode(instr->opcode()) == 1); |
399 if (lazy_deopt) { | 399 if (lazy_deopt) { |
400 RecordLazyDeoptimizationEntry(instr); | 400 RecordLazyDeoptimizationEntry(instr); |
401 } | 401 } |
402 AddNopForSmiCodeInlining(); | 402 AddNopForSmiCodeInlining(); |
403 break; | 403 break; |
404 } | 404 } |
405 case kX64CallAddress: | 405 case kX64CallAddress: |
406 if (HasImmediateInput(instr, 0)) { | 406 if (HasImmediateInput(instr, 0)) { |
407 Immediate64 imm = i.InputImmediate64(0); | 407 Immediate64 imm = i.InputImmediate64(0); |
408 ASSERT_EQ(kImm64Value, imm.type); | 408 DCHECK_EQ(kImm64Value, imm.type); |
409 __ Call(reinterpret_cast<byte*>(imm.value), RelocInfo::NONE64); | 409 __ Call(reinterpret_cast<byte*>(imm.value), RelocInfo::NONE64); |
410 } else { | 410 } else { |
411 __ call(i.InputRegister(0)); | 411 __ call(i.InputRegister(0)); |
412 } | 412 } |
413 break; | 413 break; |
414 case kPopStack: { | 414 case kPopStack: { |
415 int words = MiscField::decode(instr->opcode()); | 415 int words = MiscField::decode(instr->opcode()); |
416 __ addq(rsp, Immediate(kPointerSize * words)); | 416 __ addq(rsp, Immediate(kPointerSize * words)); |
417 break; | 417 break; |
418 } | 418 } |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 | 681 |
682 // Assembles boolean materializations after this instruction. | 682 // Assembles boolean materializations after this instruction. |
683 void CodeGenerator::AssembleArchBoolean(Instruction* instr, | 683 void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
684 FlagsCondition condition) { | 684 FlagsCondition condition) { |
685 X64OperandConverter i(this, instr); | 685 X64OperandConverter i(this, instr); |
686 Label done; | 686 Label done; |
687 | 687 |
688 // Materialize a full 64-bit 1 or 0 value. The result register is always the | 688 // Materialize a full 64-bit 1 or 0 value. The result register is always the |
689 // last output of the instruction. | 689 // last output of the instruction. |
690 Label check; | 690 Label check; |
691 ASSERT_NE(0, instr->OutputCount()); | 691 DCHECK_NE(0, instr->OutputCount()); |
692 Register reg = i.OutputRegister(instr->OutputCount() - 1); | 692 Register reg = i.OutputRegister(instr->OutputCount() - 1); |
693 Condition cc = no_condition; | 693 Condition cc = no_condition; |
694 switch (condition) { | 694 switch (condition) { |
695 case kUnorderedEqual: | 695 case kUnorderedEqual: |
696 __ j(parity_odd, &check, Label::kNear); | 696 __ j(parity_odd, &check, Label::kNear); |
697 __ movl(reg, Immediate(0)); | 697 __ movl(reg, Immediate(0)); |
698 __ jmp(&done, Label::kNear); | 698 __ jmp(&done, Label::kNear); |
699 // Fall through. | 699 // Fall through. |
700 case kEqual: | 700 case kEqual: |
701 cc = equal; | 701 cc = equal; |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
849 } | 849 } |
850 } | 850 } |
851 | 851 |
852 | 852 |
853 void CodeGenerator::AssembleMove(InstructionOperand* source, | 853 void CodeGenerator::AssembleMove(InstructionOperand* source, |
854 InstructionOperand* destination) { | 854 InstructionOperand* destination) { |
855 X64OperandConverter g(this, NULL); | 855 X64OperandConverter g(this, NULL); |
856 // Dispatch on the source and destination operand kinds. Not all | 856 // Dispatch on the source and destination operand kinds. Not all |
857 // combinations are possible. | 857 // combinations are possible. |
858 if (source->IsRegister()) { | 858 if (source->IsRegister()) { |
859 ASSERT(destination->IsRegister() || destination->IsStackSlot()); | 859 DCHECK(destination->IsRegister() || destination->IsStackSlot()); |
860 Register src = g.ToRegister(source); | 860 Register src = g.ToRegister(source); |
861 if (destination->IsRegister()) { | 861 if (destination->IsRegister()) { |
862 __ movq(g.ToRegister(destination), src); | 862 __ movq(g.ToRegister(destination), src); |
863 } else { | 863 } else { |
864 __ movq(g.ToOperand(destination), src); | 864 __ movq(g.ToOperand(destination), src); |
865 } | 865 } |
866 } else if (source->IsStackSlot()) { | 866 } else if (source->IsStackSlot()) { |
867 ASSERT(destination->IsRegister() || destination->IsStackSlot()); | 867 DCHECK(destination->IsRegister() || destination->IsStackSlot()); |
868 Operand src = g.ToOperand(source); | 868 Operand src = g.ToOperand(source); |
869 if (destination->IsRegister()) { | 869 if (destination->IsRegister()) { |
870 Register dst = g.ToRegister(destination); | 870 Register dst = g.ToRegister(destination); |
871 __ movq(dst, src); | 871 __ movq(dst, src); |
872 } else { | 872 } else { |
873 // Spill on demand to use a temporary register for memory-to-memory | 873 // Spill on demand to use a temporary register for memory-to-memory |
874 // moves. | 874 // moves. |
875 Register tmp = kScratchRegister; | 875 Register tmp = kScratchRegister; |
876 Operand dst = g.ToOperand(destination); | 876 Operand dst = g.ToOperand(destination); |
877 __ movq(tmp, src); | 877 __ movq(tmp, src); |
(...skipping 18 matching lines...) Expand all Loading... |
896 } | 896 } |
897 if (destination->IsStackSlot()) { | 897 if (destination->IsStackSlot()) { |
898 __ movq(g.ToOperand(destination), kScratchRegister); | 898 __ movq(g.ToOperand(destination), kScratchRegister); |
899 } | 899 } |
900 } else { | 900 } else { |
901 __ movq(kScratchRegister, | 901 __ movq(kScratchRegister, |
902 BitCast<uint64_t, double>(g.ToDouble(constant_source))); | 902 BitCast<uint64_t, double>(g.ToDouble(constant_source))); |
903 if (destination->IsDoubleRegister()) { | 903 if (destination->IsDoubleRegister()) { |
904 __ movq(g.ToDoubleRegister(destination), kScratchRegister); | 904 __ movq(g.ToDoubleRegister(destination), kScratchRegister); |
905 } else { | 905 } else { |
906 ASSERT(destination->IsDoubleStackSlot()); | 906 DCHECK(destination->IsDoubleStackSlot()); |
907 __ movq(g.ToOperand(destination), kScratchRegister); | 907 __ movq(g.ToOperand(destination), kScratchRegister); |
908 } | 908 } |
909 } | 909 } |
910 } else if (source->IsDoubleRegister()) { | 910 } else if (source->IsDoubleRegister()) { |
911 XMMRegister src = g.ToDoubleRegister(source); | 911 XMMRegister src = g.ToDoubleRegister(source); |
912 if (destination->IsDoubleRegister()) { | 912 if (destination->IsDoubleRegister()) { |
913 XMMRegister dst = g.ToDoubleRegister(destination); | 913 XMMRegister dst = g.ToDoubleRegister(destination); |
914 __ movsd(dst, src); | 914 __ movsd(dst, src); |
915 } else { | 915 } else { |
916 ASSERT(destination->IsDoubleStackSlot()); | 916 DCHECK(destination->IsDoubleStackSlot()); |
917 Operand dst = g.ToOperand(destination); | 917 Operand dst = g.ToOperand(destination); |
918 __ movsd(dst, src); | 918 __ movsd(dst, src); |
919 } | 919 } |
920 } else if (source->IsDoubleStackSlot()) { | 920 } else if (source->IsDoubleStackSlot()) { |
921 ASSERT(destination->IsDoubleRegister() || destination->IsDoubleStackSlot()); | 921 DCHECK(destination->IsDoubleRegister() || destination->IsDoubleStackSlot()); |
922 Operand src = g.ToOperand(source); | 922 Operand src = g.ToOperand(source); |
923 if (destination->IsDoubleRegister()) { | 923 if (destination->IsDoubleRegister()) { |
924 XMMRegister dst = g.ToDoubleRegister(destination); | 924 XMMRegister dst = g.ToDoubleRegister(destination); |
925 __ movsd(dst, src); | 925 __ movsd(dst, src); |
926 } else { | 926 } else { |
927 // We rely on having xmm0 available as a fixed scratch register. | 927 // We rely on having xmm0 available as a fixed scratch register. |
928 Operand dst = g.ToOperand(destination); | 928 Operand dst = g.ToOperand(destination); |
929 __ movsd(xmm0, src); | 929 __ movsd(xmm0, src); |
930 __ movsd(dst, xmm0); | 930 __ movsd(dst, xmm0); |
931 } | 931 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
995 return *(code->instruction_start() + start_pc) == | 995 return *(code->instruction_start() + start_pc) == |
996 v8::internal::Assembler::kNopByte; | 996 v8::internal::Assembler::kNopByte; |
997 } | 997 } |
998 | 998 |
999 #endif | 999 #endif |
1000 | 1000 |
1001 #endif | 1001 #endif |
1002 } | 1002 } |
1003 } | 1003 } |
1004 } // namespace v8::internal::compiler | 1004 } // namespace v8::internal::compiler |
OLD | NEW |