PPC: Refactor checks for minus zero.

R=joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=

Review URL: https://codereview.chromium.org/1650593002

Cr-Commit-Position: refs/heads/master@{#33620}
This commit is contained in:
mbrandy 2016-01-29 12:40:28 -08:00 committed by Commit bot
parent ceb2d18d82
commit 21bb9c6a39
5 changed files with 76 additions and 82 deletions

View File

@ -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);
}

View File

@ -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);

View File

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

View File

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

View File

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