Reviewers: ulan, jochen,
Description:
A64: Introduce a DeoptimizeIfMinusZero() helper.
Please review this at https://codereview.chromium.org/200413002/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+45, -33 lines):
M src/a64/lithium-codegen-a64.h
M src/a64/lithium-codegen-a64.cc
M src/a64/macro-assembler-a64.h
M src/a64/macro-assembler-a64.cc
Index: src/a64/lithium-codegen-a64.cc
diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc
index
6e48ce490d94a6f3d4df80534e9a5cc10d571ed0..eb25054a63f5d046ca978729c72bc4a7c810c34f
100644
--- a/src/a64/lithium-codegen-a64.cc
+++ b/src/a64/lithium-codegen-a64.cc
@@ -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);
Index: src/a64/lithium-codegen-a64.h
diff --git a/src/a64/lithium-codegen-a64.h b/src/a64/lithium-codegen-a64.h
index
cca87726d9529534a03a5d6aa5b81ff1aa129f61..c58ca13ed6d4fd0ab2af6293a94001cae50b4dc9
100644
--- a/src/a64/lithium-codegen-a64.h
+++ b/src/a64/lithium-codegen-a64.h
@@ -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,
Index: src/a64/macro-assembler-a64.cc
diff --git a/src/a64/macro-assembler-a64.cc b/src/a64/macro-assembler-a64.cc
index
25edc06161dc533d02e718cc09d9fe4fc4312cda..3f9905dfd4c908e133144c3d6745220579e07f40
100644
--- a/src/a64/macro-assembler-a64.cc
+++ b/src/a64/macro-assembler-a64.cc
@@ -2225,14 +2225,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);
}
Index: src/a64/macro-assembler-a64.h
diff --git a/src/a64/macro-assembler-a64.h b/src/a64/macro-assembler-a64.h
index
651be99a6fb6657ac7f55a2659e71a83cbbea7c1..59412f3a64935dd76b7a246e742376996e1ea2dd
100644
--- a/src/a64/macro-assembler-a64.h
+++ b/src/a64/macro-assembler-a64.h
@@ -900,6 +900,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);
@@ -928,10 +931,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,
@@ -941,10 +946,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,
@@ -2071,10 +2078,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_;
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.