A64: Introduce a DeoptimizeIfMinusZero() helper.

R=ulan@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20010 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 2cb4e78e
......@@ -1106,6 +1106,13 @@ void LCodeGen::DeoptimizeIfNotRoot(Register rt,
}
void LCodeGen::DeoptimizeIfMinusZero(DoubleRegister input,
LEnvironment* environment) {
__ TestForMinusZero(input);
DeoptimizeIf(vs, environment);
}
void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
if (!info()->IsStub()) {
// Ensure that we have enough space after the previous lazy-bailout
......@@ -2744,16 +2751,13 @@ void LCodeGen::DoDivI(LDivI* instr) {
void LCodeGen::DoDoubleToIntOrSmi(LDoubleToIntOrSmi* instr) {
DoubleRegister input = ToDoubleRegister(instr->value());
Register result = ToRegister32(instr->result());
Label done, deopt;
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
__ JumpIfMinusZero(input, &deopt);
DeoptimizeIfMinusZero(input, instr->environment());
}
__ TryConvertDoubleToInt32(result, input, double_scratch(), &done);
__ Bind(&deopt);
Deoptimize(instr->environment());
__ Bind(&done);
__ TryConvertDoubleToInt32(result, input, double_scratch());
DeoptimizeIf(ne, instr->environment());
if (instr->tag_result()) {
__ SmiTag(result.X());
......@@ -3816,11 +3820,9 @@ void LCodeGen::DoMathFloor(LMathFloor* instr) {
// and produce a valid double result in a single instruction.
DoubleRegister input = ToDoubleRegister(instr->value());
Register result = ToRegister(instr->result());
Label deopt;
Label done;
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
__ JumpIfMinusZero(input, &deopt);
DeoptimizeIfMinusZero(input, instr->environment());
}
__ Fcvtms(result, input);
......@@ -3830,12 +3832,7 @@ void LCodeGen::DoMathFloor(LMathFloor* instr) {
__ Cmp(result, Operand(result, SXTW));
// - The input was not NaN.
__ Fccmp(input, input, NoFlag, eq);
__ B(&done, eq);
__ Bind(&deopt);
Deoptimize(instr->environment());
__ Bind(&done);
DeoptimizeIf(ne, instr->environment());
}
......@@ -4526,32 +4523,35 @@ void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
__ JumpIfSmi(input, &load_smi);
Label convert_undefined, deopt;
Label convert_undefined;
// Heap number map check.
Label* not_heap_number = can_convert_undefined_to_nan ? &convert_undefined
: &deopt;
__ Ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset));
__ JumpIfNotRoot(scratch, Heap::kHeapNumberMapRootIndex, not_heap_number);
if (can_convert_undefined_to_nan) {
__ JumpIfNotRoot(scratch, Heap::kHeapNumberMapRootIndex,
&convert_undefined);
} else {
DeoptimizeIfNotRoot(scratch, Heap::kHeapNumberMapRootIndex,
instr->environment());
}
// Load heap number.
__ Ldr(result, FieldMemOperand(input, HeapNumber::kValueOffset));
if (instr->hydrogen()->deoptimize_on_minus_zero()) {
__ JumpIfMinusZero(result, &deopt);
DeoptimizeIfMinusZero(result, instr->environment());
}
__ B(&done);
if (can_convert_undefined_to_nan) {
__ Bind(&convert_undefined);
__ JumpIfNotRoot(input, Heap::kUndefinedValueRootIndex, &deopt);
DeoptimizeIfNotRoot(input, Heap::kUndefinedValueRootIndex,
instr->environment());
__ LoadRoot(scratch, Heap::kNanValueRootIndex);
__ Ldr(result, FieldMemOperand(scratch, HeapNumber::kValueOffset));
__ B(&done);
}
__ Bind(&deopt);
Deoptimize(instr->environment());
} else {
ASSERT(mode == NUMBER_CANDIDATE_IS_SMI);
// Fall through to load_smi.
......@@ -5494,7 +5494,6 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr,
Register output = ToRegister32(instr->result());
DoubleRegister dbl_scratch2 = ToDoubleRegister(temp2);
Label converted;
// Deoptimized if it's not a heap number.
DeoptimizeIfNotRoot(scratch1, Heap::kHeapNumberMapRootIndex,
......@@ -5503,10 +5502,8 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr,
// A heap number: load value and convert to int32 using non-truncating
// function. If the result is out of range, branch to deoptimize.
__ Ldr(dbl_scratch1, FieldMemOperand(input, HeapNumber::kValueOffset));
__ TryConvertDoubleToInt32(output, dbl_scratch1, dbl_scratch2, &converted);
Deoptimize(instr->environment());
__ Bind(&converted);
__ TryConvertDoubleToInt32(output, dbl_scratch1, dbl_scratch2);
DeoptimizeIf(ne, instr->environment());
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
__ Cmp(output, 0);
......
......@@ -236,6 +236,7 @@ class LCodeGen: public LCodeGenBase {
void DeoptimizeIfNotRoot(Register rt,
Heap::RootListIndex index,
LEnvironment* environment);
void DeoptimizeIfMinusZero(DoubleRegister input, LEnvironment* environment);
void ApplyCheckIf(Condition cc, LBoundsCheck* check);
MemOperand PrepareKeyedExternalArrayOperand(Register key,
......
......@@ -2239,14 +2239,19 @@ void MacroAssembler::TryConvertDoubleToInt(Register as_int,
}
void MacroAssembler::JumpIfMinusZero(DoubleRegister input,
Label* on_negative_zero) {
void MacroAssembler::TestForMinusZero(DoubleRegister input) {
UseScratchRegisterScope temps(this);
Register temp = temps.AcquireX();
// Floating point -0.0 is kMinInt as an integer, so subtracting 1 (cmp) will
// cause overflow.
Fmov(temp, input);
Cmp(temp, 1);
}
void MacroAssembler::JumpIfMinusZero(DoubleRegister input,
Label* on_negative_zero) {
TestForMinusZero(input);
B(vs, on_negative_zero);
}
......
......@@ -904,6 +904,9 @@ class MacroAssembler : public Assembler {
Label* on_not_heap_number,
Register heap_number_map = NoReg);
// Sets the vs flag if the input is -0.0.
void TestForMinusZero(DoubleRegister input);
// Jump to label if the input double register contains -0.0.
void JumpIfMinusZero(DoubleRegister input, Label* on_negative_zero);
......@@ -932,10 +935,12 @@ class MacroAssembler : public Assembler {
// Try to convert a double to a signed 32-bit int.
// This succeeds if the result compares equal to the input, so inputs of -0.0
// are converted to 0 and handled as a success.
//
// On output the Z flag is set if the conversion was successful.
void TryConvertDoubleToInt32(Register as_int,
FPRegister value,
FPRegister scratch_d,
Label* on_successful_conversion,
Label* on_successful_conversion = NULL,
Label* on_failed_conversion = NULL) {
ASSERT(as_int.Is32Bits());
TryConvertDoubleToInt(as_int, value, scratch_d, on_successful_conversion,
......@@ -945,10 +950,12 @@ class MacroAssembler : public Assembler {
// Try to convert a double to a signed 64-bit int.
// This succeeds if the result compares equal to the input, so inputs of -0.0
// are converted to 0 and handled as a success.
//
// On output the Z flag is set if the conversion was successful.
void TryConvertDoubleToInt64(Register as_int,
FPRegister value,
FPRegister scratch_d,
Label* on_successful_conversion,
Label* on_successful_conversion = NULL,
Label* on_failed_conversion = NULL) {
ASSERT(as_int.Is64Bits());
TryConvertDoubleToInt(as_int, value, scratch_d, on_successful_conversion,
......@@ -2075,10 +2082,12 @@ class MacroAssembler : public Assembler {
//
// This does not distinguish between +0 and -0, so if this distinction is
// important it must be checked separately.
//
// On output the Z flag is set if the conversion was successful.
void TryConvertDoubleToInt(Register as_int,
FPRegister value,
FPRegister scratch_d,
Label* on_successful_conversion,
Label* on_successful_conversion = NULL,
Label* on_failed_conversion = NULL);
bool generating_stub_;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment