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