Revision: 17639
Author:   [email protected]
Date:     Tue Nov 12 11:53:13 2013 UTC
Log:      Introduce %_IsMinusZero.

[email protected]
BUG=

Review URL: https://codereview.chromium.org/63423004
http://code.google.com/p/v8/source/detail?r=17639

Modified:
 /branches/bleeding_edge/src/arm/full-codegen-arm.cc
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/arm/lithium-arm.h
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/hydrogen-instructions.cc
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen-minus-zero.cc
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.h
 /branches/bleeding_edge/src/runtime.h
 /branches/bleeding_edge/src/x64/full-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.h
 /branches/bleeding_edge/test/mjsunit/compiler/minus-zero.js

=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Tue Nov 12 10:21:08 2013 UTC +++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Tue Nov 12 11:53:13 2013 UTC
@@ -3102,6 +3102,32 @@

   context()->Plug(if_true, if_false);
 }
+
+
+void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  ASSERT(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false,
+                         &if_true, &if_false, &fall_through);
+
+ __ CheckMap(r0, r1, Heap::kHeapNumberMapRootIndex, if_false, DO_SMI_CHECK);
+  __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
+  __ ldr(r1, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
+  __ cmp(r2, Operand(0x80000000));
+  __ cmp(r1, Operand(0x00000000), eq);
+
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(eq, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}


 void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Tue Nov 12 10:21:08 2013 UTC +++ /branches/bleeding_edge/src/arm/lithium-arm.cc Tue Nov 12 11:53:13 2013 UTC
@@ -1781,6 +1781,16 @@
   LOperand* value = UseRegisterAtStart(instr->value());
   return new(zone()) LCmpHoleAndBranch(value);
 }
+
+
+LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch(
+    HCompareMinusZeroAndBranch* instr) {
+  LInstruction* goto_instr = CheckElideControlInstruction(instr);
+  if (goto_instr != NULL) return goto_instr;
+  LOperand* value = UseRegister(instr->value());
+  LOperand* scratch = TempRegister();
+  return new(zone()) LCompareMinusZeroAndBranch(value, scratch);
+}


LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h Fri Nov 8 14:16:34 2013 UTC +++ /branches/bleeding_edge/src/arm/lithium-arm.h Tue Nov 12 11:53:13 2013 UTC
@@ -72,6 +72,7 @@
   V(ClampIToUint8)                              \
   V(ClampTToUint8)                              \
   V(ClassOfTestAndBranch)                       \
+  V(CompareMinusZeroAndBranch)                  \
   V(CompareNumericAndBranch)                    \
   V(CmpObjectEqAndBranch)                       \
   V(CmpHoleAndBranch)                           \
@@ -928,6 +929,22 @@
 };


+class LCompareMinusZeroAndBranch V8_FINAL : public LControlInstruction<1, 1> {
+ public:
+  LCompareMinusZeroAndBranch(LOperand* value, LOperand* temp) {
+    inputs_[0] = value;
+    temps_[0] = temp;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
+                               "cmp-minus-zero-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
+};
+
+
 class LIsObjectAndBranch V8_FINAL : public LControlInstruction<1, 1> {
  public:
   LIsObjectAndBranch(LOperand* value, LOperand* temp) {
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Nov 12 10:21:08 2013 UTC +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Nov 12 11:53:13 2013 UTC
@@ -2470,6 +2470,34 @@
   __ cmp(scratch, Operand(kHoleNanUpper32));
   EmitBranch(instr, eq);
 }
+
+
+void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
+  Representation rep = instr->hydrogen()->value()->representation();
+  ASSERT(!rep.IsInteger32());
+  Label if_false;
+  Register scratch = ToRegister(instr->temp());
+
+  if (rep.IsDouble()) {
+    DwVfpRegister value = ToDoubleRegister(instr->value());
+    __ VFPCompareAndSetFlags(value, 0.0);
+    __ b(ne, &if_false);
+    __ VmovHigh(scratch, value);
+    __ cmp(scratch, Operand(0x80000000));
+  } else {
+    Register value = ToRegister(instr->value());
+    __ CheckMap(
+ value, scratch, Heap::kHeapNumberMapRootIndex, &if_false, DO_SMI_CHECK);
+    __ ldr(scratch, FieldMemOperand(value, HeapNumber::kExponentOffset));
+    __ ldr(ip, FieldMemOperand(value, HeapNumber::kMantissaOffset));
+    __ cmp(scratch, Operand(0x80000000));
+    __ cmp(ip, Operand(0x00000000), eq);
+  }
+  EmitBranch(instr, eq);
+
+  __ bind(&if_false);
+  EmitFalseBranch(instr, al);
+}


 Condition LCodeGen::EmitIsObject(Register input,
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Fri Nov 8 17:35:58 2013 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Tue Nov 12 11:53:13 2013 UTC
@@ -2944,6 +2944,24 @@
 }


+bool HCompareMinusZeroAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
+  if (value()->representation().IsSmiOrInteger32()) {
+    // A Smi or Integer32 cannot contain minus zero.
+    *block = SecondSuccessor();
+    return true;
+  }
+  *block = NULL;
+  return false;
+}
+
+
+void HCompareMinusZeroAndBranch::InferRepresentation(
+    HInferRepresentationPhase* h_infer) {
+  ChangeRepresentation(value()->representation());
+}
+
+
+
 void HGoto::PrintDataTo(StringStream* stream) {
   stream->Add("B%d", SuccessorAt(0)->block_id());
 }
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Tue Nov 12 10:21:08 2013 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.h Tue Nov 12 11:53:13 2013 UTC
@@ -100,6 +100,7 @@
   V(CompareNumericAndBranch)                   \
   V(CompareHoleAndBranch)                      \
   V(CompareGeneric)                            \
+  V(CompareMinusZeroAndBranch)                 \
   V(CompareObjectEqAndBranch)                  \
   V(CompareMap)                                \
   V(Constant)                                  \
@@ -4165,6 +4166,28 @@
 };


+class HCompareMinusZeroAndBranch V8_FINAL : public HUnaryControlInstruction {
+ public:
+  DECLARE_INSTRUCTION_FACTORY_P1(HCompareMinusZeroAndBranch, HValue*);
+
+  virtual void InferRepresentation(
+      HInferRepresentationPhase* h_infer) V8_OVERRIDE;
+
+ virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE {
+    return representation();
+  }
+
+  virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE;
+
+  DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch)
+
+ private:
+  explicit HCompareMinusZeroAndBranch(HValue* value)
+      : HUnaryControlInstruction(value, NULL, NULL) {
+  }
+};
+
+
class HCompareObjectEqAndBranch : public HTemplateControlInstruction<2, 2> {
  public:
   HCompareObjectEqAndBranch(HValue* left,
=======================================
--- /branches/bleeding_edge/src/hydrogen-minus-zero.cc Thu Jul 25 11:53:38 2013 UTC +++ /branches/bleeding_edge/src/hydrogen-minus-zero.cc Tue Nov 12 11:53:13 2013 UTC
@@ -49,6 +49,14 @@
           PropagateMinusZeroChecks(change->value());
           visited_.Clear();
         }
+      } else if (current->IsCompareMinusZeroAndBranch()) {
+        HCompareMinusZeroAndBranch* check =
+            HCompareMinusZeroAndBranch::cast(current);
+        if (check->value()->representation().IsSmiOrInteger32()) {
+          ASSERT(visited_.IsEmpty());
+          PropagateMinusZeroChecks(check->value());
+          visited_.Clear();
+        }
       }
     }
   }
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Tue Nov 12 10:21:08 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc     Tue Nov 12 11:53:13 2013 UTC
@@ -9112,6 +9112,15 @@
       New<HHasInstanceTypeAndBranch>(value, JS_FUNCTION_TYPE);
   return ast_context()->ReturnControl(result, call->id());
 }
+
+
+void HOptimizedGraphBuilder::GenerateIsMinusZero(CallRuntime* call) {
+  ASSERT(call->arguments()->length() == 1);
+  CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+  HValue* value = Pop();
+ HCompareMinusZeroAndBranch* result = New<HCompareMinusZeroAndBranch>(value);
+  return ast_context()->ReturnControl(result, call->id());
+}


void HOptimizedGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) {
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Tue Nov 12 10:21:08 2013 UTC +++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Tue Nov 12 11:53:13 2013 UTC
@@ -3052,6 +3052,32 @@
 }


+void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  ASSERT(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false,
+                         &if_true, &if_false, &fall_through);
+
+  Handle<Map> map = masm()->isolate()->factory()->heap_number_map();
+  __ CheckMap(eax, map, if_false, DO_SMI_CHECK);
+ __ cmp(FieldOperand(eax, HeapNumber::kExponentOffset), Immediate(0x80000000));
+  __ j(not_equal, if_false);
+ __ cmp(FieldOperand(eax, HeapNumber::kMantissaOffset), Immediate(0x00000000));
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(equal, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}
+
+
+
 void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
   ZoneList<Expression*>* args = expr->arguments();
   ASSERT(args->length() == 1);
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Nov 12 10:21:08 2013 UTC +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Nov 12 11:53:13 2013 UTC
@@ -2668,6 +2668,39 @@
   __ cmp(MemOperand(esp, -offset), Immediate(kHoleNanUpper32));
   EmitBranch(instr, equal);
 }
+
+
+void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
+  Representation rep = instr->hydrogen()->value()->representation();
+  ASSERT(!rep.IsInteger32());
+  Label if_false;
+  Register scratch = ToRegister(instr->temp());
+
+  if (rep.IsDouble()) {
+    CpuFeatureScope use_sse2(masm(), SSE2);
+    XMMRegister value = ToDoubleRegister(instr->value());
+    XMMRegister xmm_scratch = double_scratch0();
+    __ xorps(xmm_scratch, xmm_scratch);
+    __ ucomisd(xmm_scratch, value);
+    __ j(not_equal, &if_false);
+    __ movmskpd(scratch, value);
+    __ test(scratch, Immediate(1));
+    EmitBranch(instr, not_zero);
+  } else {
+    Register value = ToRegister(instr->value());
+    Handle<Map> map = masm()->isolate()->factory()->heap_number_map();
+    __ CheckMap(eax, map, &if_false, DO_SMI_CHECK);
+    __ cmp(FieldOperand(value, HeapNumber::kExponentOffset),
+           Immediate(0x80000000));
+    __ j(not_equal, &if_false);
+    __ cmp(FieldOperand(value, HeapNumber::kMantissaOffset),
+           Immediate(0x00000000));
+    EmitBranch(instr, equal);
+  }
+
+  __ bind(&if_false);
+  EmitFalseBranch(instr, no_condition);
+}


 Condition LCodeGen::EmitIsObject(Register input,
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Tue Nov 12 10:21:08 2013 UTC +++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Tue Nov 12 11:53:13 2013 UTC
@@ -1766,6 +1766,16 @@
   LOperand* value = UseRegisterAtStart(instr->value());
   return new(zone()) LCmpHoleAndBranch(value);
 }
+
+
+LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch(
+    HCompareMinusZeroAndBranch* instr) {
+  LInstruction* goto_instr = CheckElideControlInstruction(instr);
+  if (goto_instr != NULL) return goto_instr;
+  LOperand* value = UseRegister(instr->value());
+  LOperand* scratch = TempRegister();
+  return new(zone()) LCompareMinusZeroAndBranch(value, scratch);
+}


LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h Fri Nov 8 14:16:34 2013 UTC +++ /branches/bleeding_edge/src/ia32/lithium-ia32.h Tue Nov 12 11:53:13 2013 UTC
@@ -74,6 +74,7 @@
   V(ClampTToUint8NoSSE2)                        \
   V(ClassOfTestAndBranch)                       \
   V(ClobberDoubles)                             \
+  V(CompareMinusZeroAndBranch)                  \
   V(CompareNumericAndBranch)                    \
   V(CmpObjectEqAndBranch)                       \
   V(CmpHoleAndBranch)                           \
@@ -900,6 +901,22 @@
 };


+class LCompareMinusZeroAndBranch V8_FINAL : public LControlInstruction<1, 1> {
+ public:
+  LCompareMinusZeroAndBranch(LOperand* value, LOperand* temp) {
+    inputs_[0] = value;
+    temps_[0] = temp;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+  LOperand* temp() { return temps_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
+                               "cmp-minus-zero-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
+};
+
+
 class LIsObjectAndBranch V8_FINAL : public LControlInstruction<1, 1> {
  public:
   LIsObjectAndBranch(LOperand* value, LOperand* temp) {
=======================================
--- /branches/bleeding_edge/src/runtime.h       Fri Nov  8 13:44:27 2013 UTC
+++ /branches/bleeding_edge/src/runtime.h       Tue Nov 12 11:53:13 2013 UTC
@@ -630,6 +630,7 @@
F(MathTan, 1, 1) \ F(MathSqrt, 1, 1) \ F(MathLog, 1, 1) \ + F(IsMinusZero, 1, 1) \ F(IsRegExpEquivalent, 2, 1) \ F(HasCachedArrayIndex, 1, 1) \ F(GetCachedArrayIndex, 1, 1) \
=======================================
--- /branches/bleeding_edge/src/x64/full-codegen-x64.cc Tue Nov 12 10:21:08 2013 UTC +++ /branches/bleeding_edge/src/x64/full-codegen-x64.cc Tue Nov 12 11:53:13 2013 UTC
@@ -3024,6 +3024,33 @@

   context()->Plug(if_true, if_false);
 }
+
+
+void FullCodeGenerator::EmitIsMinusZero(CallRuntime* expr) {
+  ZoneList<Expression*>* args = expr->arguments();
+  ASSERT(args->length() == 1);
+
+  VisitForAccumulatorValue(args->at(0));
+
+  Label materialize_true, materialize_false;
+  Label* if_true = NULL;
+  Label* if_false = NULL;
+  Label* fall_through = NULL;
+  context()->PrepareTest(&materialize_true, &materialize_false,
+                         &if_true, &if_false, &fall_through);
+
+  Handle<Map> map = masm()->isolate()->factory()->heap_number_map();
+  __ CheckMap(rax, map, if_false, DO_SMI_CHECK);
+  __ cmpl(FieldOperand(rax, HeapNumber::kExponentOffset),
+          Immediate(0x80000000));
+  __ j(not_equal, if_false);
+  __ cmpl(FieldOperand(rax, HeapNumber::kMantissaOffset),
+          Immediate(0x00000000));
+  PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
+  Split(equal, if_true, if_false, fall_through);
+
+  context()->Plug(if_true, if_false);
+}


 void FullCodeGenerator::EmitIsArray(CallRuntime* expr) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Nov 12 10:21:08 2013 UTC +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Nov 12 11:53:13 2013 UTC
@@ -2244,6 +2244,37 @@
   __ cmpl(MemOperand(rsp, -offset), Immediate(kHoleNanUpper32));
   EmitBranch(instr, equal);
 }
+
+
+void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) {
+  Representation rep = instr->hydrogen()->value()->representation();
+  ASSERT(!rep.IsInteger32());
+  Label if_false;
+
+  if (rep.IsDouble()) {
+    XMMRegister value = ToDoubleRegister(instr->value());
+    XMMRegister xmm_scratch = double_scratch0();
+    __ xorps(xmm_scratch, xmm_scratch);
+    __ ucomisd(xmm_scratch, value);
+    __ j(not_equal, &if_false);
+    __ movmskpd(kScratchRegister, value);
+    __ testl(kScratchRegister, Immediate(1));
+    EmitBranch(instr, not_zero);
+  } else {
+    Register value = ToRegister(instr->value());
+    Handle<Map> map = masm()->isolate()->factory()->heap_number_map();
+    __ CheckMap(rax, map, &if_false, DO_SMI_CHECK);
+    __ cmpl(FieldOperand(value, HeapNumber::kExponentOffset),
+            Immediate(0x80000000));
+    __ j(not_equal, &if_false);
+    __ cmpl(FieldOperand(value, HeapNumber::kMantissaOffset),
+            Immediate(0x00000000));
+    EmitBranch(instr, equal);
+  }
+
+  __ bind(&if_false);
+  EmitFalseBranch(instr, always);
+}


 Condition LCodeGen::EmitIsObject(Register input,
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Tue Nov 12 10:21:08 2013 UTC +++ /branches/bleeding_edge/src/x64/lithium-x64.cc Tue Nov 12 11:53:13 2013 UTC
@@ -1670,6 +1670,15 @@
   LOperand* value = UseRegisterAtStart(instr->value());
   return new(zone()) LCmpHoleAndBranch(value);
 }
+
+
+LInstruction* LChunkBuilder::DoCompareMinusZeroAndBranch(
+    HCompareMinusZeroAndBranch* instr) {
+  LInstruction* goto_instr = CheckElideControlInstruction(instr);
+  if (goto_instr != NULL) return goto_instr;
+  LOperand* value = UseRegister(instr->value());
+  return new(zone()) LCompareMinusZeroAndBranch(value);
+}


LInstruction* LChunkBuilder::DoIsObjectAndBranch(HIsObjectAndBranch* instr) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h Fri Nov 8 14:16:34 2013 UTC +++ /branches/bleeding_edge/src/x64/lithium-x64.h Tue Nov 12 11:53:13 2013 UTC
@@ -72,6 +72,7 @@
   V(ClampIToUint8)                              \
   V(ClampTToUint8)                              \
   V(ClassOfTestAndBranch)                       \
+  V(CompareMinusZeroAndBranch)                  \
   V(CompareNumericAndBranch)                    \
   V(CmpObjectEqAndBranch)                       \
   V(CmpHoleAndBranch)                           \
@@ -874,6 +875,21 @@
 };


+class LCompareMinusZeroAndBranch V8_FINAL : public LControlInstruction<1, 0> {
+ public:
+  explicit LCompareMinusZeroAndBranch(LOperand* value) {
+    inputs_[0] = value;
+  }
+
+  LOperand* value() { return inputs_[0]; }
+
+  DECLARE_CONCRETE_INSTRUCTION(CompareMinusZeroAndBranch,
+                               "cmp-minus-zero-and-branch")
+  DECLARE_HYDROGEN_ACCESSOR(CompareMinusZeroAndBranch)
+};
+
+
+
 class LIsObjectAndBranch V8_FINAL : public LControlInstruction<1, 0> {
  public:
   explicit LIsObjectAndBranch(LOperand* value) {
=======================================
--- /branches/bleeding_edge/test/mjsunit/compiler/minus-zero.js Mon Jul 8 11:15:24 2013 UTC +++ /branches/bleeding_edge/test/mjsunit/compiler/minus-zero.js Tue Nov 12 11:53:13 2013 UTC
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

-// Flags: --allow-natives-syntax
+// Flags: --allow-natives-syntax --no-fold-constants

 function add(x, y) {
   return x + y;
@@ -35,3 +35,59 @@
 assertEquals(0, add(0, 0));
 %OptimizeFunctionOnNextCall(add);
 assertEquals(-0, add(-0, -0));
+
+
+function test(x, y) {
+  assertTrue(%_IsMinusZero(-0));
+  assertTrue(%_IsMinusZero(1/(-Infinity)));
+  assertTrue(%_IsMinusZero(x));
+
+  assertFalse(%_IsMinusZero(0));
+  assertFalse(%_IsMinusZero(1/Infinity));
+  assertFalse(%_IsMinusZero(0.1));
+  assertFalse(%_IsMinusZero(-0.2));
+  assertFalse(%_IsMinusZero({}));
+  assertFalse(%_IsMinusZero(""));
+  assertFalse(%_IsMinusZero("-0"));
+  assertFalse(%_IsMinusZero(function() {}));
+  assertFalse(%_IsMinusZero(y));
+}
+
+test(-0, 1.2);
+test(-0, 1.2);
+%OptimizeFunctionOnNextCall(test);
+test(-0, 1.2);
+assertOptimized(test);
+
+
+function testsin() {
+  assertTrue(%_IsMinusZero(Math.sin(-0)));
+}
+
+testsin();
+testsin();
+%OptimizeFunctionOnNextCall(testsin);
+testsin();
+
+
+function testfloor() {
+  assertTrue(%_IsMinusZero(Math.floor(-0)));
+  assertFalse(%_IsMinusZero(Math.floor(2)));
+}
+
+testfloor();
+testfloor();
+%OptimizeFunctionOnNextCall(testfloor);
+testfloor();
+
+
+var double_one = Math.cos(0);
+
+function add(a, b) {
+  return a + b;
+}
+
+assertEquals(1, 1/add(double_one, 0));
+assertEquals(1, 1/add(0, double_one));
+%OptimizeFunctionOnNextCall(add);
+assertEquals(1/(-0 + -0), 1/add(-0, -0));

--
--
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/groups/opt_out.

Reply via email to