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.

Reply via email to