| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
| 6 | 6 |
| 7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
| 8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
| (...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 754 Register reg = saved_regs[i]; | 754 Register reg = saved_regs[i]; |
| 755 if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { | 755 if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { |
| 756 pushq(reg); | 756 pushq(reg); |
| 757 } | 757 } |
| 758 } | 758 } |
| 759 // R12 to r15 are callee save on all platforms. | 759 // R12 to r15 are callee save on all platforms. |
| 760 if (fp_mode == kSaveFPRegs) { | 760 if (fp_mode == kSaveFPRegs) { |
| 761 subp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); | 761 subp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); |
| 762 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | 762 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { |
| 763 XMMRegister reg = XMMRegister::from_code(i); | 763 XMMRegister reg = XMMRegister::from_code(i); |
| 764 movsd(Operand(rsp, i * kDoubleSize), reg); | 764 Movsd(Operand(rsp, i * kDoubleSize), reg); |
| 765 } | 765 } |
| 766 } | 766 } |
| 767 } | 767 } |
| 768 | 768 |
| 769 | 769 |
| 770 void MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, | 770 void MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, |
| 771 Register exclusion1, | 771 Register exclusion1, |
| 772 Register exclusion2, | 772 Register exclusion2, |
| 773 Register exclusion3) { | 773 Register exclusion3) { |
| 774 if (fp_mode == kSaveFPRegs) { | 774 if (fp_mode == kSaveFPRegs) { |
| 775 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | 775 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { |
| 776 XMMRegister reg = XMMRegister::from_code(i); | 776 XMMRegister reg = XMMRegister::from_code(i); |
| 777 movsd(reg, Operand(rsp, i * kDoubleSize)); | 777 Movsd(reg, Operand(rsp, i * kDoubleSize)); |
| 778 } | 778 } |
| 779 addp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); | 779 addp(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); |
| 780 } | 780 } |
| 781 for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) { | 781 for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) { |
| 782 Register reg = saved_regs[i]; | 782 Register reg = saved_regs[i]; |
| 783 if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { | 783 if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { |
| 784 popq(reg); | 784 popq(reg); |
| 785 } | 785 } |
| 786 } | 786 } |
| 787 } | 787 } |
| (...skipping 1642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2430 Move(dst, lower); | 2430 Move(dst, lower); |
| 2431 } else { | 2431 } else { |
| 2432 movq(kScratchRegister, src); | 2432 movq(kScratchRegister, src); |
| 2433 movq(dst, kScratchRegister); | 2433 movq(dst, kScratchRegister); |
| 2434 } | 2434 } |
| 2435 } | 2435 } |
| 2436 } | 2436 } |
| 2437 } | 2437 } |
| 2438 | 2438 |
| 2439 | 2439 |
| 2440 void MacroAssembler::Movapd(XMMRegister dst, XMMRegister src) { |
| 2441 if (CpuFeatures::IsSupported(AVX)) { |
| 2442 CpuFeatureScope scope(this, AVX); |
| 2443 vmovapd(dst, src); |
| 2444 } else { |
| 2445 movapd(dst, src); |
| 2446 } |
| 2447 } |
| 2448 |
| 2449 |
| 2450 void MacroAssembler::Movsd(XMMRegister dst, XMMRegister src) { |
| 2451 if (CpuFeatures::IsSupported(AVX)) { |
| 2452 CpuFeatureScope scope(this, AVX); |
| 2453 vmovsd(dst, src); |
| 2454 } else { |
| 2455 movsd(dst, src); |
| 2456 } |
| 2457 } |
| 2458 |
| 2459 |
| 2460 void MacroAssembler::Movsd(XMMRegister dst, const Operand& src) { |
| 2461 if (CpuFeatures::IsSupported(AVX)) { |
| 2462 CpuFeatureScope scope(this, AVX); |
| 2463 vmovsd(dst, src); |
| 2464 } else { |
| 2465 movsd(dst, src); |
| 2466 } |
| 2467 } |
| 2468 |
| 2469 |
| 2470 void MacroAssembler::Movsd(const Operand& dst, XMMRegister src) { |
| 2471 if (CpuFeatures::IsSupported(AVX)) { |
| 2472 CpuFeatureScope scope(this, AVX); |
| 2473 vmovsd(dst, src); |
| 2474 } else { |
| 2475 movsd(dst, src); |
| 2476 } |
| 2477 } |
| 2478 |
| 2479 |
| 2440 void MacroAssembler::Cmp(Register dst, Handle<Object> source) { | 2480 void MacroAssembler::Cmp(Register dst, Handle<Object> source) { |
| 2441 AllowDeferredHandleDereference smi_check; | 2481 AllowDeferredHandleDereference smi_check; |
| 2442 if (source->IsSmi()) { | 2482 if (source->IsSmi()) { |
| 2443 Cmp(dst, Smi::cast(*source)); | 2483 Cmp(dst, Smi::cast(*source)); |
| 2444 } else { | 2484 } else { |
| 2445 MoveHeapObject(kScratchRegister, source); | 2485 MoveHeapObject(kScratchRegister, source); |
| 2446 cmpp(dst, kScratchRegister); | 2486 cmpp(dst, kScratchRegister); |
| 2447 } | 2487 } |
| 2448 } | 2488 } |
| 2449 | 2489 |
| (...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3038 Move(xmm_scratch, 1.0); | 3078 Move(xmm_scratch, 1.0); |
| 3039 mulsd(xmm_scratch, FieldOperand(maybe_number, HeapNumber::kValueOffset)); | 3079 mulsd(xmm_scratch, FieldOperand(maybe_number, HeapNumber::kValueOffset)); |
| 3040 jmp(&done, Label::kNear); | 3080 jmp(&done, Label::kNear); |
| 3041 | 3081 |
| 3042 bind(&smi_value); | 3082 bind(&smi_value); |
| 3043 // Value is a smi. convert to a double and store. | 3083 // Value is a smi. convert to a double and store. |
| 3044 // Preserve original value. | 3084 // Preserve original value. |
| 3045 SmiToInteger32(kScratchRegister, maybe_number); | 3085 SmiToInteger32(kScratchRegister, maybe_number); |
| 3046 Cvtlsi2sd(xmm_scratch, kScratchRegister); | 3086 Cvtlsi2sd(xmm_scratch, kScratchRegister); |
| 3047 bind(&done); | 3087 bind(&done); |
| 3048 movsd(FieldOperand(elements, index, times_8, | 3088 Movsd(FieldOperand(elements, index, times_8, |
| 3049 FixedDoubleArray::kHeaderSize - elements_offset), | 3089 FixedDoubleArray::kHeaderSize - elements_offset), |
| 3050 xmm_scratch); | 3090 xmm_scratch); |
| 3051 } | 3091 } |
| 3052 | 3092 |
| 3053 | 3093 |
| 3054 void MacroAssembler::CompareMap(Register obj, Handle<Map> map) { | 3094 void MacroAssembler::CompareMap(Register obj, Handle<Map> map) { |
| 3055 Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); | 3095 Cmp(FieldOperand(obj, HeapObject::kMapOffset), map); |
| 3056 } | 3096 } |
| 3057 | 3097 |
| 3058 | 3098 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3118 Register input_reg, | 3158 Register input_reg, |
| 3119 int offset) { | 3159 int offset) { |
| 3120 DoubleToIStub stub(isolate(), input_reg, result_reg, offset, true); | 3160 DoubleToIStub stub(isolate(), input_reg, result_reg, offset, true); |
| 3121 call(stub.GetCode(), RelocInfo::CODE_TARGET); | 3161 call(stub.GetCode(), RelocInfo::CODE_TARGET); |
| 3122 } | 3162 } |
| 3123 | 3163 |
| 3124 | 3164 |
| 3125 void MacroAssembler::TruncateHeapNumberToI(Register result_reg, | 3165 void MacroAssembler::TruncateHeapNumberToI(Register result_reg, |
| 3126 Register input_reg) { | 3166 Register input_reg) { |
| 3127 Label done; | 3167 Label done; |
| 3128 movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 3168 Movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 3129 cvttsd2siq(result_reg, xmm0); | 3169 cvttsd2siq(result_reg, xmm0); |
| 3130 cmpq(result_reg, Immediate(1)); | 3170 cmpq(result_reg, Immediate(1)); |
| 3131 j(no_overflow, &done, Label::kNear); | 3171 j(no_overflow, &done, Label::kNear); |
| 3132 | 3172 |
| 3133 // Slow case. | 3173 // Slow case. |
| 3134 if (input_reg.is(result_reg)) { | 3174 if (input_reg.is(result_reg)) { |
| 3135 subp(rsp, Immediate(kDoubleSize)); | 3175 subp(rsp, Immediate(kDoubleSize)); |
| 3136 movsd(MemOperand(rsp, 0), xmm0); | 3176 Movsd(MemOperand(rsp, 0), xmm0); |
| 3137 SlowTruncateToI(result_reg, rsp, 0); | 3177 SlowTruncateToI(result_reg, rsp, 0); |
| 3138 addp(rsp, Immediate(kDoubleSize)); | 3178 addp(rsp, Immediate(kDoubleSize)); |
| 3139 } else { | 3179 } else { |
| 3140 SlowTruncateToI(result_reg, input_reg); | 3180 SlowTruncateToI(result_reg, input_reg); |
| 3141 } | 3181 } |
| 3142 | 3182 |
| 3143 bind(&done); | 3183 bind(&done); |
| 3144 // Keep our invariant that the upper 32 bits are zero. | 3184 // Keep our invariant that the upper 32 bits are zero. |
| 3145 movl(result_reg, result_reg); | 3185 movl(result_reg, result_reg); |
| 3146 } | 3186 } |
| 3147 | 3187 |
| 3148 | 3188 |
| 3149 void MacroAssembler::TruncateDoubleToI(Register result_reg, | 3189 void MacroAssembler::TruncateDoubleToI(Register result_reg, |
| 3150 XMMRegister input_reg) { | 3190 XMMRegister input_reg) { |
| 3151 Label done; | 3191 Label done; |
| 3152 cvttsd2siq(result_reg, input_reg); | 3192 cvttsd2siq(result_reg, input_reg); |
| 3153 cmpq(result_reg, Immediate(1)); | 3193 cmpq(result_reg, Immediate(1)); |
| 3154 j(no_overflow, &done, Label::kNear); | 3194 j(no_overflow, &done, Label::kNear); |
| 3155 | 3195 |
| 3156 subp(rsp, Immediate(kDoubleSize)); | 3196 subp(rsp, Immediate(kDoubleSize)); |
| 3157 movsd(MemOperand(rsp, 0), input_reg); | 3197 Movsd(MemOperand(rsp, 0), input_reg); |
| 3158 SlowTruncateToI(result_reg, rsp, 0); | 3198 SlowTruncateToI(result_reg, rsp, 0); |
| 3159 addp(rsp, Immediate(kDoubleSize)); | 3199 addp(rsp, Immediate(kDoubleSize)); |
| 3160 | 3200 |
| 3161 bind(&done); | 3201 bind(&done); |
| 3162 // Keep our invariant that the upper 32 bits are zero. | 3202 // Keep our invariant that the upper 32 bits are zero. |
| 3163 movl(result_reg, result_reg); | 3203 movl(result_reg, result_reg); |
| 3164 } | 3204 } |
| 3165 | 3205 |
| 3166 | 3206 |
| 3167 void MacroAssembler::DoubleToI(Register result_reg, XMMRegister input_reg, | 3207 void MacroAssembler::DoubleToI(Register result_reg, XMMRegister input_reg, |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3713 // Optionally save all XMM registers. | 3753 // Optionally save all XMM registers. |
| 3714 if (save_doubles) { | 3754 if (save_doubles) { |
| 3715 int space = XMMRegister::kMaxNumRegisters * kDoubleSize + | 3755 int space = XMMRegister::kMaxNumRegisters * kDoubleSize + |
| 3716 arg_stack_space * kRegisterSize; | 3756 arg_stack_space * kRegisterSize; |
| 3717 subp(rsp, Immediate(space)); | 3757 subp(rsp, Immediate(space)); |
| 3718 int offset = -2 * kPointerSize; | 3758 int offset = -2 * kPointerSize; |
| 3719 const RegisterConfiguration* config = RegisterConfiguration::ArchDefault(); | 3759 const RegisterConfiguration* config = RegisterConfiguration::ArchDefault(); |
| 3720 for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { | 3760 for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { |
| 3721 DoubleRegister reg = | 3761 DoubleRegister reg = |
| 3722 DoubleRegister::from_code(config->GetAllocatableDoubleCode(i)); | 3762 DoubleRegister::from_code(config->GetAllocatableDoubleCode(i)); |
| 3723 movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg); | 3763 Movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg); |
| 3724 } | 3764 } |
| 3725 } else if (arg_stack_space > 0) { | 3765 } else if (arg_stack_space > 0) { |
| 3726 subp(rsp, Immediate(arg_stack_space * kRegisterSize)); | 3766 subp(rsp, Immediate(arg_stack_space * kRegisterSize)); |
| 3727 } | 3767 } |
| 3728 | 3768 |
| 3729 // Get the required frame alignment for the OS. | 3769 // Get the required frame alignment for the OS. |
| 3730 const int kFrameAlignment = base::OS::ActivationFrameAlignment(); | 3770 const int kFrameAlignment = base::OS::ActivationFrameAlignment(); |
| 3731 if (kFrameAlignment > 0) { | 3771 if (kFrameAlignment > 0) { |
| 3732 DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment)); | 3772 DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment)); |
| 3733 DCHECK(is_int8(kFrameAlignment)); | 3773 DCHECK(is_int8(kFrameAlignment)); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3759 | 3799 |
| 3760 void MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { | 3800 void MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { |
| 3761 // Registers: | 3801 // Registers: |
| 3762 // r15 : argv | 3802 // r15 : argv |
| 3763 if (save_doubles) { | 3803 if (save_doubles) { |
| 3764 int offset = -2 * kPointerSize; | 3804 int offset = -2 * kPointerSize; |
| 3765 const RegisterConfiguration* config = RegisterConfiguration::ArchDefault(); | 3805 const RegisterConfiguration* config = RegisterConfiguration::ArchDefault(); |
| 3766 for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { | 3806 for (int i = 0; i < config->num_allocatable_double_registers(); ++i) { |
| 3767 DoubleRegister reg = | 3807 DoubleRegister reg = |
| 3768 DoubleRegister::from_code(config->GetAllocatableDoubleCode(i)); | 3808 DoubleRegister::from_code(config->GetAllocatableDoubleCode(i)); |
| 3769 movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize))); | 3809 Movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize))); |
| 3770 } | 3810 } |
| 3771 } | 3811 } |
| 3772 | 3812 |
| 3773 if (pop_arguments) { | 3813 if (pop_arguments) { |
| 3774 // Get the return address from the stack and restore the frame pointer. | 3814 // Get the return address from the stack and restore the frame pointer. |
| 3775 movp(rcx, Operand(rbp, kFPOnStackSize)); | 3815 movp(rcx, Operand(rbp, kFPOnStackSize)); |
| 3776 movp(rbp, Operand(rbp, 0 * kPointerSize)); | 3816 movp(rbp, Operand(rbp, 0 * kPointerSize)); |
| 3777 | 3817 |
| 3778 // Drop everything up to and including the arguments and the receiver | 3818 // Drop everything up to and including the arguments and the receiver |
| 3779 // from the caller stack. | 3819 // from the caller stack. |
| (...skipping 1221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5001 movl(rax, dividend); | 5041 movl(rax, dividend); |
| 5002 shrl(rax, Immediate(31)); | 5042 shrl(rax, Immediate(31)); |
| 5003 addl(rdx, rax); | 5043 addl(rdx, rax); |
| 5004 } | 5044 } |
| 5005 | 5045 |
| 5006 | 5046 |
| 5007 } // namespace internal | 5047 } // namespace internal |
| 5008 } // namespace v8 | 5048 } // namespace v8 |
| 5009 | 5049 |
| 5010 #endif // V8_TARGET_ARCH_X64 | 5050 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |