diff --git a/src/crankshaft/ppc/lithium-codegen-ppc.cc b/src/crankshaft/ppc/lithium-codegen-ppc.cc index 10a13def75..1134ebf0ed 100644 --- a/src/crankshaft/ppc/lithium-codegen-ppc.cc +++ b/src/crankshaft/ppc/lithium-codegen-ppc.cc @@ -2390,32 +2390,13 @@ void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) { DoubleRegister value = ToDoubleRegister(instr->value()); __ fcmpu(value, kDoubleRegZero); EmitFalseBranch(instr, ne); -#if V8_TARGET_ARCH_PPC64 - __ MovDoubleToInt64(scratch, value); -#else - __ MovDoubleHighToInt(scratch, value); -#endif - __ cmpi(scratch, Operand::Zero()); + __ TestDoubleSign(value, scratch); EmitBranch(instr, lt); } else { Register value = ToRegister(instr->value()); __ CheckMap(value, scratch, Heap::kHeapNumberMapRootIndex, instr->FalseLabel(chunk()), DO_SMI_CHECK); -#if V8_TARGET_ARCH_PPC64 - __ LoadP(scratch, FieldMemOperand(value, HeapNumber::kValueOffset)); - __ li(ip, Operand(1)); - __ rotrdi(ip, ip, 1); // ip = 0x80000000_00000000 - __ cmp(scratch, ip); -#else - __ lwz(scratch, FieldMemOperand(value, HeapNumber::kExponentOffset)); - __ lwz(ip, FieldMemOperand(value, HeapNumber::kMantissaOffset)); - Label skip; - __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000))); - __ cmp(scratch, r0); - __ bne(&skip); - __ cmpi(ip, Operand::Zero()); - __ bind(&skip); -#endif + __ TestHeapNumberIsMinusZero(value, scratch, ip); EmitBranch(instr, eq); } } @@ -3703,13 +3684,8 @@ void LCodeGen::DoMathRound(LMathRound* instr) { // If the input is +0.5, the result is 1. __ bgt(&convert); // Out of [-0.5, +0.5]. if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { -#if V8_TARGET_ARCH_PPC64 - __ MovDoubleToInt64(scratch1, input); -#else - __ MovDoubleHighToInt(scratch1, input); -#endif - __ cmpi(scratch1, Operand::Zero()); - // [-0.5, -0]. + // [-0.5, -0] (negative) yields minus zero. + __ TestDoubleSign(input, scratch1); DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero); } __ fcmpu(input, dot_five); @@ -4926,17 +4902,7 @@ void LCodeGen::EmitNumberUntagD(LNumberUntagD* instr, Register input_reg, // load heap number __ lfd(result_reg, FieldMemOperand(input_reg, HeapNumber::kValueOffset)); if (deoptimize_on_minus_zero) { -#if V8_TARGET_ARCH_PPC64 - __ MovDoubleToInt64(scratch, result_reg); - // rotate left by one for simple compare. - __ rldicl(scratch, scratch, 1, 0); - __ cmpi(scratch, Operand(1)); -#else - __ MovDoubleToInt64(scratch, ip, result_reg); - __ cmpi(ip, Operand::Zero()); - __ bne(&done); - __ Cmpi(scratch, Operand(HeapNumber::kSignMask), r0); -#endif + __ TestDoubleIsMinusZero(result_reg, scratch, ip); DeoptimizeIf(eq, instr, Deoptimizer::kMinusZero); } __ b(&done); @@ -5025,10 +4991,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { __ cmpi(input_reg, Operand::Zero()); __ bne(&done); - __ lwz(scratch1, - FieldMemOperand(scratch2, HeapNumber::kValueOffset + - Register::kExponentOffset)); - __ cmpwi(scratch1, Operand::Zero()); + __ TestHeapNumberSign(scratch2, scratch1); DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero); } } @@ -5103,12 +5066,7 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) { Label done; __ cmpi(result_reg, Operand::Zero()); __ bne(&done); -#if V8_TARGET_ARCH_PPC64 - __ MovDoubleToInt64(scratch1, double_input); -#else - __ MovDoubleHighToInt(scratch1, double_input); -#endif - __ cmpi(scratch1, Operand::Zero()); + __ TestDoubleSign(double_input, scratch1); DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero); __ bind(&done); } @@ -5133,12 +5091,7 @@ void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { Label done; __ cmpi(result_reg, Operand::Zero()); __ bne(&done); -#if V8_TARGET_ARCH_PPC64 - __ MovDoubleToInt64(scratch1, double_input); -#else - __ MovDoubleHighToInt(scratch1, double_input); -#endif - __ cmpi(scratch1, Operand::Zero()); + __ TestDoubleSign(double_input, scratch1); DeoptimizeIf(lt, instr, Deoptimizer::kMinusZero); __ bind(&done); } diff --git a/src/full-codegen/ppc/full-codegen-ppc.cc b/src/full-codegen/ppc/full-codegen-ppc.cc index e168eabb5a..49df27c83f 100644 --- a/src/full-codegen/ppc/full-codegen-ppc.cc +++ b/src/full-codegen/ppc/full-codegen-ppc.cc @@ -3173,22 +3173,7 @@ void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) { &if_false, &fall_through); __ CheckMap(r3, r4, Heap::kHeapNumberMapRootIndex, if_false, DO_SMI_CHECK); -#if V8_TARGET_ARCH_PPC64 - __ LoadP(r4, FieldMemOperand(r3, HeapNumber::kValueOffset)); - __ li(r5, Operand(1)); - __ rotrdi(r5, r5, 1); // r5 = 0x80000000_00000000 - __ cmp(r4, r5); -#else - __ lwz(r5, FieldMemOperand(r3, HeapNumber::kExponentOffset)); - __ lwz(r4, FieldMemOperand(r3, HeapNumber::kMantissaOffset)); - Label skip; - __ lis(r0, Operand(SIGN_EXT_IMM16(0x8000))); - __ cmp(r5, r0); - __ bne(&skip); - __ cmpi(r4, Operand::Zero()); - __ bind(&skip); -#endif - + __ TestHeapNumberIsMinusZero(r3, r4, r5); PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); Split(eq, if_true, if_false, fall_through); diff --git a/src/ppc/builtins-ppc.cc b/src/ppc/builtins-ppc.cc index 73efb34979..855dcda632 100644 --- a/src/ppc/builtins-ppc.cc +++ b/src/ppc/builtins-ppc.cc @@ -215,17 +215,7 @@ void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { __ b(CommuteCondition(cond_done), &compare_swap); // Left and right hand side are equal, check for -0 vs. +0. -#if V8_TARGET_ARCH_PPC64 - __ MovDoubleToInt64(r7, reg); - __ rotldi(r7, r7, 1); - __ cmpi(r7, Operand(1)); -#else - __ MovDoubleToInt64(r7, r8, reg); - __ cmpi(r8, Operand::Zero()); - __ bne(&loop); - __ lis(r8, Operand(SIGN_EXT_IMM16(0x8000))); - __ cmp(r7, r8); -#endif + __ TestDoubleIsMinusZero(reg, r7, r8); __ bne(&loop); // Update accumulator. Result is on the right hand side. diff --git a/src/ppc/macro-assembler-ppc.cc b/src/ppc/macro-assembler-ppc.cc index a2043a0559..5088f58946 100644 --- a/src/ppc/macro-assembler-ppc.cc +++ b/src/ppc/macro-assembler-ppc.cc @@ -2128,6 +2128,60 @@ void MacroAssembler::TestDoubleIsInt32(DoubleRegister double_input, TryDoubleToInt32Exact(scratch1, double_input, scratch2, double_scratch); } +void MacroAssembler::TestDoubleIsMinusZero(DoubleRegister input, + Register scratch1, + Register scratch2) { +#if V8_TARGET_ARCH_PPC64 + MovDoubleToInt64(scratch1, input); + rotldi(scratch1, scratch1, 1); + cmpi(scratch1, Operand(1)); +#else + MovDoubleToInt64(scratch1, scratch2, input); + Label done; + cmpi(scratch2, Operand::Zero()); + bne(&done); + lis(scratch2, Operand(SIGN_EXT_IMM16(0x8000))); + cmp(scratch1, scratch2); + bind(&done); +#endif +} + +void MacroAssembler::TestHeapNumberIsMinusZero(Register input, + Register scratch1, + Register scratch2) { +#if V8_TARGET_ARCH_PPC64 + LoadP(scratch1, FieldMemOperand(input, HeapNumber::kValueOffset)); + rotldi(scratch1, scratch1, 1); + cmpi(scratch1, Operand(1)); +#else + lwz(scratch1, FieldMemOperand(input, HeapNumber::kExponentOffset)); + lwz(scratch2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); + Label done; + cmpi(scratch2, Operand::Zero()); + bne(&done); + lis(scratch2, Operand(SIGN_EXT_IMM16(0x8000))); + cmp(scratch1, scratch2); + bind(&done); +#endif +} + +void MacroAssembler::TestDoubleSign(DoubleRegister input, Register scratch) { +#if V8_TARGET_ARCH_PPC64 + MovDoubleToInt64(scratch, input); +#else + MovDoubleHighToInt(scratch, input); +#endif + cmpi(scratch, Operand::Zero()); +} + +void MacroAssembler::TestHeapNumberSign(Register input, Register scratch) { +#if V8_TARGET_ARCH_PPC64 + LoadP(scratch, FieldMemOperand(input, HeapNumber::kValueOffset)); +#else + lwz(scratch, FieldMemOperand(input, HeapNumber::kExponentOffset)); +#endif + cmpi(scratch, Operand::Zero()); +} void MacroAssembler::TryDoubleToInt32Exact(Register result, DoubleRegister double_input, diff --git a/src/ppc/macro-assembler-ppc.h b/src/ppc/macro-assembler-ppc.h index 171fa6b529..2ff613db78 100644 --- a/src/ppc/macro-assembler-ppc.h +++ b/src/ppc/macro-assembler-ppc.h @@ -864,6 +864,18 @@ class MacroAssembler : public Assembler { void TestDoubleIsInt32(DoubleRegister double_input, Register scratch1, Register scratch2, DoubleRegister double_scratch); + // Check if a double is equal to -0.0. + // CR_EQ in cr7 holds the result. + void TestDoubleIsMinusZero(DoubleRegister input, Register scratch1, + Register scratch2); + void TestHeapNumberIsMinusZero(Register input, Register scratch1, + Register scratch2); + + // Check the sign of a double. + // CR_LT in cr7 holds the result. + void TestDoubleSign(DoubleRegister input, Register scratch); + void TestHeapNumberSign(Register input, Register scratch); + // Try to convert a double to a signed 32-bit integer. // CR_EQ in cr7 is set and result assigned if the conversion is exact. void TryDoubleToInt32Exact(Register result, DoubleRegister double_input,