From 20a29c9a0f7fe1112ad6fce7e297ea729a2dd113 Mon Sep 17 00:00:00 2001
From: "danno@chromium.org"
 <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Date: Mon, 5 Mar 2012 15:40:25 +0000
Subject: [PATCH] MIPS: Inline ordered relational compares of mixed
 double/undefined values.

Port r10905 (2a997cf).

Original commit message:

Allow Crankshaft to inline ordered relational comparisons (<, >, <=, >=) that have undefined arguments in addition to double value arguments (rather than calling the generic Compare stub).

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/9583038
Patch from Daniel Kalmar <kalmard@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10925 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
---
 src/mips/code-stubs-mips.cc | 25 ++++++++++++++++++++-----
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 4717847a21..a928dc0aeb 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -6785,15 +6785,15 @@ void ICCompareStub::GenerateHeapNumbers(MacroAssembler* masm) {
   ASSERT(state_ == CompareIC::HEAP_NUMBERS);
 
   Label generic_stub;
-  Label unordered;
+  Label unordered, maybe_undefined1, maybe_undefined2;
   Label miss;
   __ And(a2, a1, Operand(a0));
   __ JumpIfSmi(a2, &generic_stub);
 
   __ GetObjectType(a0, a2, a2);
-  __ Branch(&miss, ne, a2, Operand(HEAP_NUMBER_TYPE));
+  __ Branch(&maybe_undefined1, ne, a2, Operand(HEAP_NUMBER_TYPE));
   __ GetObjectType(a1, a2, a2);
-  __ Branch(&miss, ne, a2, Operand(HEAP_NUMBER_TYPE));
+  __ Branch(&maybe_undefined2, ne, a2, Operand(HEAP_NUMBER_TYPE));
 
   // Inlining the double comparison and falling back to the general compare
   // stub if NaN is involved or FPU is unsupported.
@@ -6825,14 +6825,29 @@ void ICCompareStub::GenerateHeapNumbers(MacroAssembler* masm) {
     __ bind(&fpu_lt);
     __ Ret(USE_DELAY_SLOT);
     __ li(v0, Operand(LESS));  // In delay slot.
-
-    __ bind(&unordered);
   }
 
+  __ bind(&unordered);
+
   CompareStub stub(GetCondition(), strict(), NO_COMPARE_FLAGS, a1, a0);
   __ bind(&generic_stub);
   __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
 
+  __ bind(&maybe_undefined1);
+  if (Token::IsOrderedRelationalCompareOp(op_)) {
+    __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
+    __ Branch(&miss, ne, a0, Operand(at));
+    __ GetObjectType(a1, a2, a2);
+    __ Branch(&maybe_undefined2, ne, a2, Operand(HEAP_NUMBER_TYPE));
+    __ jmp(&unordered);
+  }
+
+  __ bind(&maybe_undefined2);
+  if (Token::IsOrderedRelationalCompareOp(op_)) {
+    __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
+    __ Branch(&unordered, eq, a1, Operand(at));
+  }
+
   __ bind(&miss);
   GenerateMiss(masm);
 }