| Index: src/x87/code-stubs-x87.cc
|
| diff --git a/src/ia32/code-stubs-ia32.cc b/src/x87/code-stubs-x87.cc
|
| similarity index 90%
|
| copy from src/ia32/code-stubs-ia32.cc
|
| copy to src/x87/code-stubs-x87.cc
|
| index 5547ba25e86294c7838a7885f0374535f4afb76c..2c95ad1a4837115c8e46b81f129961a424a21563 100644
|
| --- a/src/ia32/code-stubs-ia32.cc
|
| +++ b/src/x87/code-stubs-x87.cc
|
| @@ -4,7 +4,7 @@
|
|
|
| #include "v8.h"
|
|
|
| -#if V8_TARGET_ARCH_IA32
|
| +#if V8_TARGET_ARCH_X87
|
|
|
| #include "bootstrapper.h"
|
| #include "code-stubs.h"
|
| @@ -64,9 +64,9 @@ void FastCloneShallowArrayStub::InitializeInterfaceDescriptor(
|
| descriptor->register_param_count_ = 3;
|
| descriptor->register_params_ = registers;
|
| static Representation representations[] = {
|
| - Representation::Tagged(),
|
| - Representation::Smi(),
|
| - Representation::Tagged() };
|
| + Representation::Tagged(),
|
| + Representation::Smi(),
|
| + Representation::Tagged() };
|
| descriptor->register_param_representations_ = representations;
|
| descriptor->deoptimization_handler_ =
|
| Runtime::FunctionForId(
|
| @@ -479,13 +479,6 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
|
| // store the registers in any particular way, but we do have to store and
|
| // restore them.
|
| __ pushad();
|
| - if (save_doubles_ == kSaveFPRegs) {
|
| - __ sub(esp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters));
|
| - for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
|
| - XMMRegister reg = XMMRegister::from_code(i);
|
| - __ movsd(Operand(esp, i * kDoubleSize), reg);
|
| - }
|
| - }
|
| const int argument_count = 1;
|
|
|
| AllowExternalCallThatCantCauseGC scope(masm);
|
| @@ -495,13 +488,6 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
|
| __ CallCFunction(
|
| ExternalReference::store_buffer_overflow_function(isolate()),
|
| argument_count);
|
| - if (save_doubles_ == kSaveFPRegs) {
|
| - for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) {
|
| - XMMRegister reg = XMMRegister::from_code(i);
|
| - __ movsd(reg, Operand(esp, i * kDoubleSize));
|
| - }
|
| - __ add(esp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters));
|
| - }
|
| __ popad();
|
| __ ret(0);
|
| }
|
| @@ -526,12 +512,6 @@ class FloatingPointHelper : public AllStatic {
|
| static void CheckFloatOperands(MacroAssembler* masm,
|
| Label* non_float,
|
| Register scratch);
|
| -
|
| - // Test if operands are numbers (smi or HeapNumber objects), and load
|
| - // them into xmm0 and xmm1 if they are. Jump to label not_numbers if
|
| - // either operand is not a number. Operands are in edx and eax.
|
| - // Leaves operands unchanged.
|
| - static void LoadSSE2Operands(MacroAssembler* masm, Label* not_numbers);
|
| };
|
|
|
|
|
| @@ -571,11 +551,6 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
|
|
|
| bool stash_exponent_copy = !input_reg.is(esp);
|
| __ mov(scratch1, mantissa_operand);
|
| - if (CpuFeatures::IsSupported(SSE3)) {
|
| - CpuFeatureScope scope(masm, SSE3);
|
| - // Load x87 register with heap number.
|
| - __ fld_d(mantissa_operand);
|
| - }
|
| __ mov(ecx, exponent_operand);
|
| if (stash_exponent_copy) __ push(ecx);
|
|
|
| @@ -587,9 +562,6 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
|
|
|
| // Result is entirely in lower 32-bits of mantissa
|
| int delta = HeapNumber::kExponentBias + Double::kPhysicalSignificandSize;
|
| - if (CpuFeatures::IsSupported(SSE3)) {
|
| - __ fstp(0);
|
| - }
|
| __ sub(ecx, Immediate(delta));
|
| __ xor_(result_reg, result_reg);
|
| __ cmp(ecx, Immediate(31));
|
| @@ -598,38 +570,26 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
|
| __ jmp(&check_negative);
|
|
|
| __ bind(&process_64_bits);
|
| - if (CpuFeatures::IsSupported(SSE3)) {
|
| - CpuFeatureScope scope(masm, SSE3);
|
| - if (stash_exponent_copy) {
|
| - // Already a copy of the exponent on the stack, overwrite it.
|
| - STATIC_ASSERT(kDoubleSize == 2 * kPointerSize);
|
| - __ sub(esp, Immediate(kDoubleSize / 2));
|
| - } else {
|
| - // Reserve space for 64 bit answer.
|
| - __ sub(esp, Immediate(kDoubleSize)); // Nolint.
|
| - }
|
| - // Do conversion, which cannot fail because we checked the exponent.
|
| - __ fisttp_d(Operand(esp, 0));
|
| - __ mov(result_reg, Operand(esp, 0)); // Load low word of answer as result
|
| - __ add(esp, Immediate(kDoubleSize));
|
| - __ jmp(&done_no_stash);
|
| + // Result must be extracted from shifted 32-bit mantissa
|
| + __ sub(ecx, Immediate(delta));
|
| + __ neg(ecx);
|
| + if (stash_exponent_copy) {
|
| + __ mov(result_reg, MemOperand(esp, 0));
|
| } else {
|
| - // Result must be extracted from shifted 32-bit mantissa
|
| - __ sub(ecx, Immediate(delta));
|
| - __ neg(ecx);
|
| - if (stash_exponent_copy) {
|
| - __ mov(result_reg, MemOperand(esp, 0));
|
| - } else {
|
| - __ mov(result_reg, exponent_operand);
|
| - }
|
| - __ and_(result_reg,
|
| - Immediate(static_cast<uint32_t>(Double::kSignificandMask >> 32)));
|
| - __ add(result_reg,
|
| - Immediate(static_cast<uint32_t>(Double::kHiddenBit >> 32)));
|
| - __ shrd(result_reg, scratch1);
|
| - __ shr_cl(result_reg);
|
| - __ test(ecx, Immediate(32));
|
| - __ cmov(not_equal, scratch1, result_reg);
|
| + __ mov(result_reg, exponent_operand);
|
| + }
|
| + __ and_(result_reg,
|
| + Immediate(static_cast<uint32_t>(Double::kSignificandMask >> 32)));
|
| + __ add(result_reg,
|
| + Immediate(static_cast<uint32_t>(Double::kHiddenBit >> 32)));
|
| + __ shrd(result_reg, scratch1);
|
| + __ shr_cl(result_reg);
|
| + __ test(ecx, Immediate(32));
|
| + {
|
| + Label skip_mov;
|
| + __ j(equal, &skip_mov, Label::kNear);
|
| + __ mov(scratch1, result_reg);
|
| + __ bind(&skip_mov);
|
| }
|
|
|
| // If the double was negative, negate the integer result.
|
| @@ -641,7 +601,12 @@ void DoubleToIStub::Generate(MacroAssembler* masm) {
|
| } else {
|
| __ cmp(exponent_operand, Immediate(0));
|
| }
|
| - __ cmov(greater, result_reg, scratch1);
|
| + {
|
| + Label skip_mov;
|
| + __ j(less_equal, &skip_mov, Label::kNear);
|
| + __ mov(result_reg, scratch1);
|
| + __ bind(&skip_mov);
|
| + }
|
|
|
| // Restore registers
|
| __ bind(&done);
|
| @@ -677,37 +642,6 @@ void FloatingPointHelper::LoadFloatOperand(MacroAssembler* masm,
|
| }
|
|
|
|
|
| -void FloatingPointHelper::LoadSSE2Operands(MacroAssembler* masm,
|
| - Label* not_numbers) {
|
| - Label load_smi_edx, load_eax, load_smi_eax, load_float_eax, done;
|
| - // Load operand in edx into xmm0, or branch to not_numbers.
|
| - __ JumpIfSmi(edx, &load_smi_edx, Label::kNear);
|
| - Factory* factory = masm->isolate()->factory();
|
| - __ cmp(FieldOperand(edx, HeapObject::kMapOffset), factory->heap_number_map());
|
| - __ j(not_equal, not_numbers); // Argument in edx is not a number.
|
| - __ movsd(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
|
| - __ bind(&load_eax);
|
| - // Load operand in eax into xmm1, or branch to not_numbers.
|
| - __ JumpIfSmi(eax, &load_smi_eax, Label::kNear);
|
| - __ cmp(FieldOperand(eax, HeapObject::kMapOffset), factory->heap_number_map());
|
| - __ j(equal, &load_float_eax, Label::kNear);
|
| - __ jmp(not_numbers); // Argument in eax is not a number.
|
| - __ bind(&load_smi_edx);
|
| - __ SmiUntag(edx); // Untag smi before converting to float.
|
| - __ Cvtsi2sd(xmm0, edx);
|
| - __ SmiTag(edx); // Retag smi for heap number overwriting test.
|
| - __ jmp(&load_eax);
|
| - __ bind(&load_smi_eax);
|
| - __ SmiUntag(eax); // Untag smi before converting to float.
|
| - __ Cvtsi2sd(xmm1, eax);
|
| - __ SmiTag(eax); // Retag smi for heap number overwriting test.
|
| - __ jmp(&done, Label::kNear);
|
| - __ bind(&load_float_eax);
|
| - __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
|
| - __ bind(&done);
|
| -}
|
| -
|
| -
|
| void FloatingPointHelper::CheckFloatOperands(MacroAssembler* masm,
|
| Label* non_float,
|
| Register scratch) {
|
| @@ -732,269 +666,8 @@ void FloatingPointHelper::CheckFloatOperands(MacroAssembler* masm,
|
|
|
|
|
| void MathPowStub::Generate(MacroAssembler* masm) {
|
| - Factory* factory = isolate()->factory();
|
| - const Register exponent = eax;
|
| - const Register base = edx;
|
| - const Register scratch = ecx;
|
| - const XMMRegister double_result = xmm3;
|
| - const XMMRegister double_base = xmm2;
|
| - const XMMRegister double_exponent = xmm1;
|
| - const XMMRegister double_scratch = xmm4;
|
| -
|
| - Label call_runtime, done, exponent_not_smi, int_exponent;
|
| -
|
| - // Save 1 in double_result - we need this several times later on.
|
| - __ mov(scratch, Immediate(1));
|
| - __ Cvtsi2sd(double_result, scratch);
|
| -
|
| - if (exponent_type_ == ON_STACK) {
|
| - Label base_is_smi, unpack_exponent;
|
| - // The exponent and base are supplied as arguments on the stack.
|
| - // This can only happen if the stub is called from non-optimized code.
|
| - // Load input parameters from stack.
|
| - __ mov(base, Operand(esp, 2 * kPointerSize));
|
| - __ mov(exponent, Operand(esp, 1 * kPointerSize));
|
| -
|
| - __ JumpIfSmi(base, &base_is_smi, Label::kNear);
|
| - __ cmp(FieldOperand(base, HeapObject::kMapOffset),
|
| - factory->heap_number_map());
|
| - __ j(not_equal, &call_runtime);
|
| -
|
| - __ movsd(double_base, FieldOperand(base, HeapNumber::kValueOffset));
|
| - __ jmp(&unpack_exponent, Label::kNear);
|
| -
|
| - __ bind(&base_is_smi);
|
| - __ SmiUntag(base);
|
| - __ Cvtsi2sd(double_base, base);
|
| -
|
| - __ bind(&unpack_exponent);
|
| - __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
|
| - __ SmiUntag(exponent);
|
| - __ jmp(&int_exponent);
|
| -
|
| - __ bind(&exponent_not_smi);
|
| - __ cmp(FieldOperand(exponent, HeapObject::kMapOffset),
|
| - factory->heap_number_map());
|
| - __ j(not_equal, &call_runtime);
|
| - __ movsd(double_exponent,
|
| - FieldOperand(exponent, HeapNumber::kValueOffset));
|
| - } else if (exponent_type_ == TAGGED) {
|
| - __ JumpIfNotSmi(exponent, &exponent_not_smi, Label::kNear);
|
| - __ SmiUntag(exponent);
|
| - __ jmp(&int_exponent);
|
| -
|
| - __ bind(&exponent_not_smi);
|
| - __ movsd(double_exponent,
|
| - FieldOperand(exponent, HeapNumber::kValueOffset));
|
| - }
|
| -
|
| - if (exponent_type_ != INTEGER) {
|
| - Label fast_power, try_arithmetic_simplification;
|
| - __ DoubleToI(exponent, double_exponent, double_scratch,
|
| - TREAT_MINUS_ZERO_AS_ZERO, &try_arithmetic_simplification);
|
| - __ jmp(&int_exponent);
|
| -
|
| - __ bind(&try_arithmetic_simplification);
|
| - // Skip to runtime if possibly NaN (indicated by the indefinite integer).
|
| - __ cvttsd2si(exponent, Operand(double_exponent));
|
| - __ cmp(exponent, Immediate(0x1));
|
| - __ j(overflow, &call_runtime);
|
| -
|
| - if (exponent_type_ == ON_STACK) {
|
| - // Detect square root case. Crankshaft detects constant +/-0.5 at
|
| - // compile time and uses DoMathPowHalf instead. We then skip this check
|
| - // for non-constant cases of +/-0.5 as these hardly occur.
|
| - Label continue_sqrt, continue_rsqrt, not_plus_half;
|
| - // Test for 0.5.
|
| - // Load double_scratch with 0.5.
|
| - __ mov(scratch, Immediate(0x3F000000u));
|
| - __ movd(double_scratch, scratch);
|
| - __ cvtss2sd(double_scratch, double_scratch);
|
| - // Already ruled out NaNs for exponent.
|
| - __ ucomisd(double_scratch, double_exponent);
|
| - __ j(not_equal, ¬_plus_half, Label::kNear);
|
| -
|
| - // Calculates square root of base. Check for the special case of
|
| - // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13).
|
| - // According to IEEE-754, single-precision -Infinity has the highest
|
| - // 9 bits set and the lowest 23 bits cleared.
|
| - __ mov(scratch, 0xFF800000u);
|
| - __ movd(double_scratch, scratch);
|
| - __ cvtss2sd(double_scratch, double_scratch);
|
| - __ ucomisd(double_base, double_scratch);
|
| - // Comparing -Infinity with NaN results in "unordered", which sets the
|
| - // zero flag as if both were equal. However, it also sets the carry flag.
|
| - __ j(not_equal, &continue_sqrt, Label::kNear);
|
| - __ j(carry, &continue_sqrt, Label::kNear);
|
| -
|
| - // Set result to Infinity in the special case.
|
| - __ xorps(double_result, double_result);
|
| - __ subsd(double_result, double_scratch);
|
| - __ jmp(&done);
|
| -
|
| - __ bind(&continue_sqrt);
|
| - // sqrtsd returns -0 when input is -0. ECMA spec requires +0.
|
| - __ xorps(double_scratch, double_scratch);
|
| - __ addsd(double_scratch, double_base); // Convert -0 to +0.
|
| - __ sqrtsd(double_result, double_scratch);
|
| - __ jmp(&done);
|
| -
|
| - // Test for -0.5.
|
| - __ bind(¬_plus_half);
|
| - // Load double_exponent with -0.5 by substracting 1.
|
| - __ subsd(double_scratch, double_result);
|
| - // Already ruled out NaNs for exponent.
|
| - __ ucomisd(double_scratch, double_exponent);
|
| - __ j(not_equal, &fast_power, Label::kNear);
|
| -
|
| - // Calculates reciprocal of square root of base. Check for the special
|
| - // case of Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13).
|
| - // According to IEEE-754, single-precision -Infinity has the highest
|
| - // 9 bits set and the lowest 23 bits cleared.
|
| - __ mov(scratch, 0xFF800000u);
|
| - __ movd(double_scratch, scratch);
|
| - __ cvtss2sd(double_scratch, double_scratch);
|
| - __ ucomisd(double_base, double_scratch);
|
| - // Comparing -Infinity with NaN results in "unordered", which sets the
|
| - // zero flag as if both were equal. However, it also sets the carry flag.
|
| - __ j(not_equal, &continue_rsqrt, Label::kNear);
|
| - __ j(carry, &continue_rsqrt, Label::kNear);
|
| -
|
| - // Set result to 0 in the special case.
|
| - __ xorps(double_result, double_result);
|
| - __ jmp(&done);
|
| -
|
| - __ bind(&continue_rsqrt);
|
| - // sqrtsd returns -0 when input is -0. ECMA spec requires +0.
|
| - __ xorps(double_exponent, double_exponent);
|
| - __ addsd(double_exponent, double_base); // Convert -0 to +0.
|
| - __ sqrtsd(double_exponent, double_exponent);
|
| - __ divsd(double_result, double_exponent);
|
| - __ jmp(&done);
|
| - }
|
| -
|
| - // Using FPU instructions to calculate power.
|
| - Label fast_power_failed;
|
| - __ bind(&fast_power);
|
| - __ fnclex(); // Clear flags to catch exceptions later.
|
| - // Transfer (B)ase and (E)xponent onto the FPU register stack.
|
| - __ sub(esp, Immediate(kDoubleSize));
|
| - __ movsd(Operand(esp, 0), double_exponent);
|
| - __ fld_d(Operand(esp, 0)); // E
|
| - __ movsd(Operand(esp, 0), double_base);
|
| - __ fld_d(Operand(esp, 0)); // B, E
|
| -
|
| - // Exponent is in st(1) and base is in st(0)
|
| - // B ^ E = (2^(E * log2(B)) - 1) + 1 = (2^X - 1) + 1 for X = E * log2(B)
|
| - // FYL2X calculates st(1) * log2(st(0))
|
| - __ fyl2x(); // X
|
| - __ fld(0); // X, X
|
| - __ frndint(); // rnd(X), X
|
| - __ fsub(1); // rnd(X), X-rnd(X)
|
| - __ fxch(1); // X - rnd(X), rnd(X)
|
| - // F2XM1 calculates 2^st(0) - 1 for -1 < st(0) < 1
|
| - __ f2xm1(); // 2^(X-rnd(X)) - 1, rnd(X)
|
| - __ fld1(); // 1, 2^(X-rnd(X)) - 1, rnd(X)
|
| - __ faddp(1); // 2^(X-rnd(X)), rnd(X)
|
| - // FSCALE calculates st(0) * 2^st(1)
|
| - __ fscale(); // 2^X, rnd(X)
|
| - __ fstp(1); // 2^X
|
| - // Bail out to runtime in case of exceptions in the status word.
|
| - __ fnstsw_ax();
|
| - __ test_b(eax, 0x5F); // We check for all but precision exception.
|
| - __ j(not_zero, &fast_power_failed, Label::kNear);
|
| - __ fstp_d(Operand(esp, 0));
|
| - __ movsd(double_result, Operand(esp, 0));
|
| - __ add(esp, Immediate(kDoubleSize));
|
| - __ jmp(&done);
|
| -
|
| - __ bind(&fast_power_failed);
|
| - __ fninit();
|
| - __ add(esp, Immediate(kDoubleSize));
|
| - __ jmp(&call_runtime);
|
| - }
|
| -
|
| - // Calculate power with integer exponent.
|
| - __ bind(&int_exponent);
|
| - const XMMRegister double_scratch2 = double_exponent;
|
| - __ mov(scratch, exponent); // Back up exponent.
|
| - __ movsd(double_scratch, double_base); // Back up base.
|
| - __ movsd(double_scratch2, double_result); // Load double_exponent with 1.
|
| -
|
| - // Get absolute value of exponent.
|
| - Label no_neg, while_true, while_false;
|
| - __ test(scratch, scratch);
|
| - __ j(positive, &no_neg, Label::kNear);
|
| - __ neg(scratch);
|
| - __ bind(&no_neg);
|
| -
|
| - __ j(zero, &while_false, Label::kNear);
|
| - __ shr(scratch, 1);
|
| - // Above condition means CF==0 && ZF==0. This means that the
|
| - // bit that has been shifted out is 0 and the result is not 0.
|
| - __ j(above, &while_true, Label::kNear);
|
| - __ movsd(double_result, double_scratch);
|
| - __ j(zero, &while_false, Label::kNear);
|
| -
|
| - __ bind(&while_true);
|
| - __ shr(scratch, 1);
|
| - __ mulsd(double_scratch, double_scratch);
|
| - __ j(above, &while_true, Label::kNear);
|
| - __ mulsd(double_result, double_scratch);
|
| - __ j(not_zero, &while_true);
|
| -
|
| - __ bind(&while_false);
|
| - // scratch has the original value of the exponent - if the exponent is
|
| - // negative, return 1/result.
|
| - __ test(exponent, exponent);
|
| - __ j(positive, &done);
|
| - __ divsd(double_scratch2, double_result);
|
| - __ movsd(double_result, double_scratch2);
|
| - // Test whether result is zero. Bail out to check for subnormal result.
|
| - // Due to subnormals, x^-y == (1/x)^y does not hold in all cases.
|
| - __ xorps(double_scratch2, double_scratch2);
|
| - __ ucomisd(double_scratch2, double_result); // Result cannot be NaN.
|
| - // double_exponent aliased as double_scratch2 has already been overwritten
|
| - // and may not have contained the exponent value in the first place when the
|
| - // exponent is a smi. We reset it with exponent value before bailing out.
|
| - __ j(not_equal, &done);
|
| - __ Cvtsi2sd(double_exponent, exponent);
|
| -
|
| - // Returning or bailing out.
|
| - Counters* counters = isolate()->counters();
|
| - if (exponent_type_ == ON_STACK) {
|
| - // The arguments are still on the stack.
|
| - __ bind(&call_runtime);
|
| - __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1);
|
| -
|
| - // The stub is called from non-optimized code, which expects the result
|
| - // as heap number in exponent.
|
| - __ bind(&done);
|
| - __ AllocateHeapNumber(eax, scratch, base, &call_runtime);
|
| - __ movsd(FieldOperand(eax, HeapNumber::kValueOffset), double_result);
|
| - __ IncrementCounter(counters->math_pow(), 1);
|
| - __ ret(2 * kPointerSize);
|
| - } else {
|
| - __ bind(&call_runtime);
|
| - {
|
| - AllowExternalCallThatCantCauseGC scope(masm);
|
| - __ PrepareCallCFunction(4, scratch);
|
| - __ movsd(Operand(esp, 0 * kDoubleSize), double_base);
|
| - __ movsd(Operand(esp, 1 * kDoubleSize), double_exponent);
|
| - __ CallCFunction(
|
| - ExternalReference::power_double_double_function(isolate()), 4);
|
| - }
|
| - // Return value is in st(0) on ia32.
|
| - // Store it into the (fixed) result register.
|
| - __ sub(esp, Immediate(kDoubleSize));
|
| - __ fstp_d(Operand(esp, 0));
|
| - __ movsd(double_result, Operand(esp, 0));
|
| - __ add(esp, Immediate(kDoubleSize));
|
| -
|
| - __ bind(&done);
|
| - __ IncrementCounter(counters->math_pow(), 1);
|
| - __ ret(0);
|
| - }
|
| + // No SSE2 support
|
| + UNREACHABLE();
|
| }
|
|
|
|
|
| @@ -1768,15 +1441,13 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
|
| __ RecordWriteField(ebx,
|
| RegExpImpl::kLastSubjectOffset,
|
| eax,
|
| - edi,
|
| - kDontSaveFPRegs);
|
| + edi);
|
| __ mov(eax, ecx);
|
| __ mov(FieldOperand(ebx, RegExpImpl::kLastInputOffset), eax);
|
| __ RecordWriteField(ebx,
|
| RegExpImpl::kLastInputOffset,
|
| eax,
|
| - edi,
|
| - kDontSaveFPRegs);
|
| + edi);
|
|
|
| // Get the static offsets vector filled by the native regexp code.
|
| ExternalReference address_of_static_offsets_vector =
|
| @@ -2046,17 +1717,29 @@ void ICCompareStub::GenerateGeneric(MacroAssembler* masm) {
|
| Label non_number_comparison;
|
| Label unordered;
|
| __ bind(&generic_heap_number_comparison);
|
| + FloatingPointHelper::CheckFloatOperands(
|
| + masm, &non_number_comparison, ebx);
|
| + FloatingPointHelper::LoadFloatOperand(masm, eax);
|
| + FloatingPointHelper::LoadFloatOperand(masm, edx);
|
| + __ FCmp();
|
|
|
| - FloatingPointHelper::LoadSSE2Operands(masm, &non_number_comparison);
|
| - __ ucomisd(xmm0, xmm1);
|
| // Don't base result on EFLAGS when a NaN is involved.
|
| __ j(parity_even, &unordered, Label::kNear);
|
|
|
| - __ mov(eax, 0); // equal
|
| - __ mov(ecx, Immediate(Smi::FromInt(1)));
|
| - __ cmov(above, eax, ecx);
|
| - __ mov(ecx, Immediate(Smi::FromInt(-1)));
|
| - __ cmov(below, eax, ecx);
|
| + Label below_label, above_label;
|
| + // Return a result of -1, 0, or 1, based on EFLAGS.
|
| + __ j(below, &below_label, Label::kNear);
|
| + __ j(above, &above_label, Label::kNear);
|
| +
|
| + __ Move(eax, Immediate(0));
|
| + __ ret(0);
|
| +
|
| + __ bind(&below_label);
|
| + __ mov(eax, Immediate(Smi::FromInt(-1)));
|
| + __ ret(0);
|
| +
|
| + __ bind(&above_label);
|
| + __ mov(eax, Immediate(Smi::FromInt(1)));
|
| __ ret(0);
|
|
|
| // If one of the numbers was NaN, then the result is always false.
|
| @@ -2268,8 +1951,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
|
| __ push(edi);
|
| __ push(ebx);
|
| __ push(edx);
|
| - __ RecordWriteArray(ebx, edi, edx, kDontSaveFPRegs,
|
| - EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
|
| + __ RecordWriteArray(ebx, edi, edx, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
|
| __ pop(edx);
|
| __ pop(ebx);
|
| __ pop(edi);
|
| @@ -2642,19 +2324,12 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
|
|
|
|
|
| void CodeStub::GenerateFPStubs(Isolate* isolate) {
|
| - CEntryStub save_doubles(isolate, 1, kSaveFPRegs);
|
| - // Stubs might already be in the snapshot, detect that and don't regenerate,
|
| - // which would lead to code stub initialization state being messed up.
|
| - Code* save_doubles_code;
|
| - if (!save_doubles.FindCodeInCache(&save_doubles_code)) {
|
| - save_doubles_code = *(save_doubles.GetCode());
|
| - }
|
| - isolate->set_fp_stubs_generated(true);
|
| + // Do nothing.
|
| }
|
|
|
|
|
| void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
|
| - CEntryStub stub(isolate, 1, kDontSaveFPRegs);
|
| + CEntryStub stub(isolate, 1);
|
| stub.GetCode();
|
| }
|
|
|
| @@ -2670,7 +2345,7 @@ void CEntryStub::Generate(MacroAssembler* masm) {
|
| ProfileEntryHookStub::MaybeCallEntryHook(masm);
|
|
|
| // Enter the exit frame that transitions from JavaScript to C++.
|
| - __ EnterExitFrame(save_doubles_ == kSaveFPRegs);
|
| + __ EnterExitFrame();
|
|
|
| // ebx: pointer to C function (C callee-saved)
|
| // ebp: frame pointer (restored after C call)
|
| @@ -2726,7 +2401,7 @@ void CEntryStub::Generate(MacroAssembler* masm) {
|
| }
|
|
|
| // Exit the JavaScript to C++ exit frame.
|
| - __ LeaveExitFrame(save_doubles_ == kSaveFPRegs);
|
| + __ LeaveExitFrame();
|
| __ ret(0);
|
|
|
| // Handling of exception.
|
| @@ -3797,46 +3472,18 @@ void ICCompareStub::GenerateNumbers(MacroAssembler* masm) {
|
| __ JumpIfNotSmi(eax, &miss);
|
| }
|
|
|
| - // Load left and right operand.
|
| - Label done, left, left_smi, right_smi;
|
| - __ JumpIfSmi(eax, &right_smi, Label::kNear);
|
| + // Inlining the double comparison and falling back to the general compare
|
| + // stub if NaN is involved or SSE2 or CMOV is unsupported.
|
| + __ mov(ecx, edx);
|
| + __ and_(ecx, eax);
|
| + __ JumpIfSmi(ecx, &generic_stub, Label::kNear);
|
| +
|
| __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
|
| isolate()->factory()->heap_number_map());
|
| __ j(not_equal, &maybe_undefined1, Label::kNear);
|
| - __ movsd(xmm1, FieldOperand(eax, HeapNumber::kValueOffset));
|
| - __ jmp(&left, Label::kNear);
|
| - __ bind(&right_smi);
|
| - __ mov(ecx, eax); // Can't clobber eax because we can still jump away.
|
| - __ SmiUntag(ecx);
|
| - __ Cvtsi2sd(xmm1, ecx);
|
| -
|
| - __ bind(&left);
|
| - __ JumpIfSmi(edx, &left_smi, Label::kNear);
|
| __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
|
| isolate()->factory()->heap_number_map());
|
| __ j(not_equal, &maybe_undefined2, Label::kNear);
|
| - __ movsd(xmm0, FieldOperand(edx, HeapNumber::kValueOffset));
|
| - __ jmp(&done);
|
| - __ bind(&left_smi);
|
| - __ mov(ecx, edx); // Can't clobber edx because we can still jump away.
|
| - __ SmiUntag(ecx);
|
| - __ Cvtsi2sd(xmm0, ecx);
|
| -
|
| - __ bind(&done);
|
| - // Compare operands.
|
| - __ ucomisd(xmm0, xmm1);
|
| -
|
| - // Don't base result on EFLAGS when a NaN is involved.
|
| - __ j(parity_even, &unordered, Label::kNear);
|
| -
|
| - // Return a result of -1, 0, or 1, based on EFLAGS.
|
| - // Performing mov, because xor would destroy the flag register.
|
| - __ mov(eax, 0); // equal
|
| - __ mov(ecx, Immediate(Smi::FromInt(1)));
|
| - __ cmov(above, eax, ecx);
|
| - __ mov(ecx, Immediate(Smi::FromInt(-1)));
|
| - __ cmov(below, eax, ecx);
|
| - __ ret(0);
|
|
|
| __ bind(&unordered);
|
| __ bind(&generic_stub);
|
| @@ -4326,10 +3973,8 @@ void NameDictionaryLookupStub::Generate(MacroAssembler* masm) {
|
|
|
| void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(
|
| Isolate* isolate) {
|
| - StoreBufferOverflowStub stub(isolate, kDontSaveFPRegs);
|
| + StoreBufferOverflowStub stub(isolate);
|
| stub.GetCode();
|
| - StoreBufferOverflowStub stub2(isolate, kSaveFPRegs);
|
| - stub2.GetCode();
|
| }
|
|
|
|
|
| @@ -4352,7 +3997,6 @@ void RecordWriteStub::Generate(MacroAssembler* masm) {
|
| __ RememberedSetHelper(object_,
|
| address_,
|
| value_,
|
| - save_fp_regs_mode_,
|
| MacroAssembler::kReturnAtEnd);
|
| } else {
|
| __ ret(0);
|
| @@ -4399,7 +4043,6 @@ void RecordWriteStub::GenerateIncremental(MacroAssembler* masm, Mode mode) {
|
| __ RememberedSetHelper(object_,
|
| address_,
|
| value_,
|
| - save_fp_regs_mode_,
|
| MacroAssembler::kReturnAtEnd);
|
|
|
| __ bind(&dont_need_remembered_set);
|
| @@ -4416,7 +4059,7 @@ void RecordWriteStub::GenerateIncremental(MacroAssembler* masm, Mode mode) {
|
|
|
|
|
| void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
|
| - regs_.SaveCallerSaveRegisters(masm, save_fp_regs_mode_);
|
| + regs_.SaveCallerSaveRegisters(masm);
|
| int argument_count = 3;
|
| __ PrepareCallCFunction(argument_count, regs_.scratch0());
|
| __ mov(Operand(esp, 0 * kPointerSize), regs_.object());
|
| @@ -4429,7 +4072,7 @@ void RecordWriteStub::InformIncrementalMarker(MacroAssembler* masm) {
|
| ExternalReference::incremental_marking_record_write_function(isolate()),
|
| argument_count);
|
|
|
| - regs_.RestoreCallerSaveRegisters(masm, save_fp_regs_mode_);
|
| + regs_.RestoreCallerSaveRegisters(masm);
|
| }
|
|
|
|
|
| @@ -4463,7 +4106,6 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
|
| __ RememberedSetHelper(object_,
|
| address_,
|
| value_,
|
| - save_fp_regs_mode_,
|
| MacroAssembler::kReturnAtEnd);
|
| } else {
|
| __ ret(0);
|
| @@ -4511,7 +4153,6 @@ void RecordWriteStub::CheckNeedsToInformIncrementalMarker(
|
| __ RememberedSetHelper(object_,
|
| address_,
|
| value_,
|
| - save_fp_regs_mode_,
|
| MacroAssembler::kReturnAtEnd);
|
| } else {
|
| __ ret(0);
|
| @@ -4582,7 +4223,6 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
|
| __ mov(Operand(ecx, 0), eax);
|
| // Update the write barrier for the array store.
|
| __ RecordWrite(ebx, ecx, eax,
|
| - kDontSaveFPRegs,
|
| EMIT_REMEMBERED_SET,
|
| OMIT_SMI_CHECK);
|
| __ ret(0);
|
| @@ -4604,15 +4244,15 @@ void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
|
| edx,
|
| ecx,
|
| edi,
|
| - xmm0,
|
| - &slow_elements_from_double);
|
| + &slow_elements_from_double,
|
| + false);
|
| __ pop(edx);
|
| __ ret(0);
|
| }
|
|
|
|
|
| void StubFailureTrampolineStub::Generate(MacroAssembler* masm) {
|
| - CEntryStub ces(isolate(), 1, kSaveFPRegs);
|
| + CEntryStub ces(isolate(), 1);
|
| __ call(ces.GetCode(), RelocInfo::CODE_TARGET);
|
| int parameter_count_offset =
|
| StubFailureTrampolineFrame::kCallerStackParameterCountFrameOffset;
|
| @@ -5138,4 +4778,4 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
|
|
|
| } } // namespace v8::internal
|
|
|
| -#endif // V8_TARGET_ARCH_IA32
|
| +#endif // V8_TARGET_ARCH_X87
|
|
|