2008-09-23 Maciej Stachowiak <mjs@apple.com>
[WebKit.git] / JavaScriptCore / VM / CTI.cpp
index fc3946b6dcf19e3abecf93557528ac043ebc580e..6859cc4c0cba01caee450b29115ba7aeb2596aa6 100644 (file)
@@ -522,6 +522,62 @@ void CTI::compileOpCall(Instruction* instruction, unsigned i, CompileOpCallType
     emitPutResult(dst);
 }
 
     emitPutResult(dst);
 }
 
+void CTI::compileOpStrictEq(Instruction* instruction, unsigned i, CompileOpStrictEqType type)
+{
+    bool negated = (type == OpNStrictEq);
+
+    unsigned dst = instruction[i + 1].u.operand;
+    unsigned src1 = instruction[i + 2].u.operand;
+    unsigned src2 = instruction[i + 3].u.operand;
+
+    emitGetArg(src1, X86::eax);
+    emitGetArg(src2, X86::edx);
+
+    m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
+    X86Assembler::JmpSrc firstNotImmediate = m_jit.emitUnlinkedJe();
+    m_jit.testl_i32r(JSImmediate::TagMask, X86::edx);
+    X86Assembler::JmpSrc secondNotImmediate = m_jit.emitUnlinkedJe();
+
+    m_jit.cmpl_rr(X86::edx, X86::eax);
+    if (negated)
+        m_jit.setne_r(X86::eax);
+    else
+        m_jit.sete_r(X86::eax);
+    m_jit.movzbl_rr(X86::eax, X86::eax);
+    emitTagAsBoolImmediate(X86::eax);
+            
+    X86Assembler::JmpSrc bothWereImmediates = m_jit.emitUnlinkedJmp();
+
+    m_jit.link(firstNotImmediate, m_jit.label());
+
+    // check that edx is immediate but not the zero immediate
+    m_jit.testl_i32r(JSImmediate::TagMask, X86::edx);
+    m_jit.setz_r(X86::ecx);
+    m_jit.movzbl_rr(X86::ecx, X86::ecx); // ecx is now 1 if edx was nonimmediate
+    m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::edx);
+    m_jit.sete_r(X86::edx);
+    m_jit.movzbl_rr(X86::edx, X86::edx); // edx is now 1 if edx was the 0 immediate
+    m_jit.orl_rr(X86::ecx, X86::edx);
+
+    m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJnz(), i));
+
+    m_jit.movl_i32r(reinterpret_cast<uint32_t>(jsBoolean(negated)), X86::eax);
+
+    X86Assembler::JmpSrc firstWasNotImmediate = m_jit.emitUnlinkedJmp();
+
+    m_jit.link(secondNotImmediate, m_jit.label());
+    // check that eax is not the zero immediate (we know it must be immediate)
+    m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::eax);
+    m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJe(), i));
+
+    m_jit.movl_i32r(reinterpret_cast<uint32_t>(jsBoolean(negated)), X86::eax);
+
+    m_jit.link(bothWereImmediates, m_jit.label());
+    m_jit.link(firstWasNotImmediate, m_jit.label());
+
+    emitPutResult(dst);
+}
+
 void CTI::emitSlowScriptCheck(unsigned opcodeIndex)
 {
     m_jit.subl_i8r(1, X86::esi);
 void CTI::emitSlowScriptCheck(unsigned opcodeIndex)
 {
     m_jit.subl_i8r(1, X86::esi);
@@ -1391,57 +1447,13 @@ void CTI::privateCompileMainPass()
         CTI_COMPILE_UNARY_OP(op_is_string)
         CTI_COMPILE_UNARY_OP(op_is_object)
         CTI_COMPILE_UNARY_OP(op_is_function)
         CTI_COMPILE_UNARY_OP(op_is_string)
         CTI_COMPILE_UNARY_OP(op_is_object)
         CTI_COMPILE_UNARY_OP(op_is_function)
-        CTI_COMPILE_BINARY_OP(op_nstricteq)
         case op_stricteq: {
         case op_stricteq: {
-            unsigned dst = instruction[i + 1].u.operand;
-            unsigned src1 = instruction[i + 2].u.operand;
-            unsigned src2 = instruction[i + 3].u.operand;
-
-            emitGetArg(src1, X86::eax);
-            emitGetArg(src2, X86::edx);
-
-            m_jit.testl_i32r(JSImmediate::TagMask, X86::eax);
-            X86Assembler::JmpSrc firstNotImmediate = m_jit.emitUnlinkedJe();
-            m_jit.testl_i32r(JSImmediate::TagMask, X86::edx);
-            X86Assembler::JmpSrc secondNotImmediate = m_jit.emitUnlinkedJe();
-
-            m_jit.cmpl_rr(X86::edx, X86::eax);
-            m_jit.sete_r(X86::eax);
-            m_jit.movzbl_rr(X86::eax, X86::eax);
-            emitTagAsBoolImmediate(X86::eax);
-            
-            X86Assembler::JmpSrc bothWereImmediates = m_jit.emitUnlinkedJmp();
-
-            m_jit.link(firstNotImmediate, m_jit.label());
-
-            // check that edx is immediate but not the zero immediate
-            
-            m_jit.testl_i32r(JSImmediate::TagMask, X86::edx);
-            m_jit.setz_r(X86::ecx);
-            m_jit.movzbl_rr(X86::ecx, X86::ecx); // ecx is now 1 if edx was nonimmediate
-            m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::edx);
-            m_jit.sete_r(X86::edx);
-            m_jit.movzbl_rr(X86::edx, X86::edx); // edx is now 1 if edx was the 0 immediate
-            m_jit.orl_rr(X86::ecx, X86::edx);
-
-            m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJnz(), i));
-
-            m_jit.movl_i32r(reinterpret_cast<uint32_t>(jsBoolean(false)), X86::eax);
-
-            X86Assembler::JmpSrc firstWasNotImmediate = m_jit.emitUnlinkedJmp();
-
-            m_jit.link(secondNotImmediate, m_jit.label());
-            // check that eax is not the zero immediate (we know it must be immediate)
-            m_jit.cmpl_i32r(reinterpret_cast<uint32_t>(JSImmediate::zeroImmediate()), X86::eax);
-            m_slowCases.append(SlowCaseEntry(m_jit.emitUnlinkedJe(), i));
-
-            m_jit.movl_i32r(reinterpret_cast<uint32_t>(jsBoolean(false)), X86::eax);
-
-            m_jit.link(bothWereImmediates, m_jit.label());
-            m_jit.link(firstWasNotImmediate, m_jit.label());
-
-            emitPutResult(dst);
-            
+            compileOpStrictEq(instruction, i, OpStrictEq);
+            i += 4;
+            break;
+        }
+        case op_nstricteq: {
+            compileOpStrictEq(instruction, i, OpNStrictEq);
             i += 4;
             break;
         }
             i += 4;
             break;
         }