Implement support for op_negate and op_bitnot in the DFG JIT
https://bugs.webkit.org/show_bug.cgi?id=79617

Reviewed by Sam Weinig.

Remove op_bitnop - this is redundant, ~x === x^-1.
This is a fractional (<1%) progression.

Remove not32(X) from the MacroAssemblers - make this an optimization to add32(-1, X).
Remove CanReuse from the result type - this was unused.
Remove op_bitnot.

* assembler/MacroAssemblerARM.h:
(MacroAssemblerARM):
(JSC::MacroAssemblerARM::xor32):
* assembler/MacroAssemblerARMv7.h:
(MacroAssemblerARMv7):
(JSC::MacroAssemblerARMv7::xor32):
* assembler/MacroAssemblerMIPS.h:
(MacroAssemblerMIPS):
(JSC::MacroAssemblerMIPS::xor32):
* assembler/MacroAssemblerSH4.h:
(MacroAssemblerSH4):
(JSC::MacroAssemblerSH4::xor32):
* assembler/MacroAssemblerX86Common.h:
(MacroAssemblerX86Common):
(JSC::MacroAssemblerX86Common::xor32):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dump):
* bytecode/Opcode.h:
(JSC):
(JSC::padOpcodeName):
* bytecompiler/NodesCodegen.cpp:
(JSC):
(JSC::BitwiseNotNode::emitBytecode):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::privateExecute):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
(JSC::JIT::privateCompileSlowCases):
* jit/JIT.h:
(JIT):
* jit/JITArithmetic32_64.cpp:
(JSC):
* jit/JITOpcodes.cpp:
(JSC):
* jit/JITStubs.cpp:
(JSC):
* jit/JITStubs.h:
* llint/LLIntSlowPaths.cpp:
(LLInt):
* llint/LLIntSlowPaths.h:
(LLInt):
* llint/LowLevelInterpreter32_64.asm:
* parser/NodeConstructors.h:
(JSC::NegateNode::NegateNode):
(JSC::BitwiseNotNode::BitwiseNotNode):
(JSC::MultNode::MultNode):
(JSC::DivNode::DivNode):
(JSC::ModNode::ModNode):
(JSC::SubNode::SubNode):
(JSC::UnsignedRightShiftNode::UnsignedRightShiftNode):
* parser/Nodes.h:
(BitwiseNotNode):
(JSC::BitwiseNotNode::expr):
(JSC):
* parser/ResultType.h:
(ResultType):
(JSC::ResultType::numberTypeIsInt32):
(JSC::ResultType::stringOrNumberType):
(JSC::ResultType::forAdd):
(JSC::ResultType::forBitOp):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@109007 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog
index a9a16b9..b2af843 100644
--- a/Source/JavaScriptCore/ChangeLog
+++ b/Source/JavaScriptCore/ChangeLog
@@ -1,3 +1,78 @@
+2012-02-27  Gavin Barraclough  <barraclough@apple.com>
+
+        Implement support for op_negate and op_bitnot in the DFG JIT
+        https://bugs.webkit.org/show_bug.cgi?id=79617
+
+        Reviewed by Sam Weinig.
+
+        Remove op_bitnop - this is redundant, ~x === x^-1.
+        This is a fractional (<1%) progression.
+
+        Remove not32(X) from the MacroAssemblers - make this an optimization to add32(-1, X).
+        Remove CanReuse from the result type - this was unused.
+        Remove op_bitnot.
+
+        * assembler/MacroAssemblerARM.h:
+        (MacroAssemblerARM):
+        (JSC::MacroAssemblerARM::xor32):
+        * assembler/MacroAssemblerARMv7.h:
+        (MacroAssemblerARMv7):
+        (JSC::MacroAssemblerARMv7::xor32):
+        * assembler/MacroAssemblerMIPS.h:
+        (MacroAssemblerMIPS):
+        (JSC::MacroAssemblerMIPS::xor32):
+        * assembler/MacroAssemblerSH4.h:
+        (MacroAssemblerSH4):
+        (JSC::MacroAssemblerSH4::xor32):
+        * assembler/MacroAssemblerX86Common.h:
+        (MacroAssemblerX86Common):
+        (JSC::MacroAssemblerX86Common::xor32):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dump):
+        * bytecode/Opcode.h:
+        (JSC):
+        (JSC::padOpcodeName):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC):
+        (JSC::BitwiseNotNode::emitBytecode):
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::privateExecute):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        (JSC::JIT::privateCompileSlowCases):
+        * jit/JIT.h:
+        (JIT):
+        * jit/JITArithmetic32_64.cpp:
+        (JSC):
+        * jit/JITOpcodes.cpp:
+        (JSC):
+        * jit/JITStubs.cpp:
+        (JSC):
+        * jit/JITStubs.h:
+        * llint/LLIntSlowPaths.cpp:
+        (LLInt):
+        * llint/LLIntSlowPaths.h:
+        (LLInt):
+        * llint/LowLevelInterpreter32_64.asm:
+        * parser/NodeConstructors.h:
+        (JSC::NegateNode::NegateNode):
+        (JSC::BitwiseNotNode::BitwiseNotNode):
+        (JSC::MultNode::MultNode):
+        (JSC::DivNode::DivNode):
+        (JSC::ModNode::ModNode):
+        (JSC::SubNode::SubNode):
+        (JSC::UnsignedRightShiftNode::UnsignedRightShiftNode):
+        * parser/Nodes.h:
+        (BitwiseNotNode):
+        (JSC::BitwiseNotNode::expr):
+        (JSC):
+        * parser/ResultType.h:
+        (ResultType):
+        (JSC::ResultType::numberTypeIsInt32):
+        (JSC::ResultType::stringOrNumberType):
+        (JSC::ResultType::forAdd):
+        (JSC::ResultType::forBitOp):
+
 2012-02-27  Michael Saboff  <msaboff@apple.com>
 
         Error check regexp min quantifier
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
index 5117389..de2132a 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARM.h
@@ -156,11 +156,6 @@
         m_assembler.rsbs_r(srcDest, srcDest, ARMAssembler::getOp2(0));
     }
 
-    void not32(RegisterID dest)
-    {
-        m_assembler.mvns_r(dest, dest);
-    }
-
     void or32(RegisterID src, RegisterID dest)
     {
         m_assembler.orrs_r(dest, dest, src);
@@ -239,7 +234,10 @@
 
     void xor32(TrustedImm32 imm, RegisterID dest)
     {
-        m_assembler.eors_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
+        if (imm.m_value == -1)
+            m_assembler.mvns_r(dest, dest);
+        else
+            m_assembler.eors_r(dest, dest, m_assembler.getImm(imm.m_value, ARMRegisters::S0));
     }
 
     void countLeadingZeros32(RegisterID src, RegisterID dest)
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
index d883abf..6925bee 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerARMv7.h
@@ -303,11 +303,6 @@
         m_assembler.neg(srcDest, srcDest);
     }
 
-    void not32(RegisterID srcDest)
-    {
-        m_assembler.mvn(srcDest, srcDest);
-    }
-
     void or32(RegisterID src, RegisterID dest)
     {
         m_assembler.orr(dest, dest, src);
@@ -447,6 +442,11 @@
 
     void xor32(TrustedImm32 imm, RegisterID src, RegisterID dest)
     {
+        if (imm.m_value == -1) {
+            m_assembler.mvn(dest, src);
+            return;
+        }
+
         ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
         if (armImm.isValid())
             m_assembler.eor(dest, src, armImm);
@@ -463,7 +463,10 @@
 
     void xor32(TrustedImm32 imm, RegisterID dest)
     {
-        xor32(imm, dest, dest);
+        if (imm.m_value == -1)
+            m_assembler.mvn(dest, dest);
+        else
+            xor32(imm, dest, dest);
     }
     
 
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
index f1aa6d4..81935fb 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
@@ -291,11 +291,6 @@
         m_assembler.subu(srcDest, MIPSRegisters::zero, srcDest);
     }
 
-    void not32(RegisterID srcDest)
-    {
-        m_assembler.nor(srcDest, srcDest, MIPSRegisters::zero);
-    }
-
     void or32(RegisterID src, RegisterID dest)
     {
         m_assembler.orInsn(dest, dest, src);
@@ -458,6 +453,11 @@
 
     void xor32(TrustedImm32 imm, RegisterID dest)
     {
+        if (imm.m_value == -1) {
+            m_assembler.nor(dest, dest, MIPSRegisters::zero);
+            return;
+        }
+
         /*
             li  immTemp, imm
             xor dest, dest, immTemp
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h b/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
index a84f337..9a1ffc3 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h
@@ -209,11 +209,6 @@
         releaseScratch(scr);
     }
 
-    void not32(RegisterID src, RegisterID dest)
-    {
-        m_assembler.notlReg(src, dest);
-    }
-
     void or32(RegisterID src, RegisterID dest)
     {
         m_assembler.orlRegReg(src, dest);
@@ -380,6 +375,11 @@
 
     void xor32(TrustedImm32 imm, RegisterID srcDest)
     {
+        if (imm.m_value == -1) {
+            m_assembler.notlReg(srcDest, srcDest);
+            return;
+        }
+
         if ((srcDest != SH4Registers::r0) || (imm.m_value > 255) || (imm.m_value < 0)) {
             RegisterID scr = claimScratch();
             m_assembler.loadConstant((imm.m_value), scr);
@@ -1681,11 +1681,6 @@
         m_assembler.neg(dst, dst);
     }
 
-    void not32(RegisterID dst)
-    {
-        m_assembler.notlReg(dst, dst);
-    }
-
     void urshift32(RegisterID shiftamount, RegisterID dest)
     {
         if (shiftamount == SH4Registers::r0)
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
index e6c3959..802b0e0 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h
@@ -223,16 +223,6 @@
         m_assembler.negl_m(srcDest.offset, srcDest.base);
     }
 
-    void not32(RegisterID srcDest)
-    {
-        m_assembler.notl_r(srcDest);
-    }
-
-    void not32(Address srcDest)
-    {
-        m_assembler.notl_m(srcDest.offset, srcDest.base);
-    }
-    
     void or32(RegisterID src, RegisterID dest)
     {
         m_assembler.orl_rr(src, dest);
@@ -375,7 +365,6 @@
         m_assembler.subl_rm(src, dest.offset, dest.base);
     }
 
-
     void xor32(RegisterID src, RegisterID dest)
     {
         m_assembler.xorl_rr(src, dest);
@@ -383,11 +372,17 @@
 
     void xor32(TrustedImm32 imm, Address dest)
     {
-        m_assembler.xorl_im(imm.m_value, dest.offset, dest.base);
+        if (imm.m_value == -1)
+            m_assembler.notl_m(dest.offset, dest.base);
+        else
+            m_assembler.xorl_im(imm.m_value, dest.offset, dest.base);
     }
 
     void xor32(TrustedImm32 imm, RegisterID dest)
     {
+        if (imm.m_value == -1)
+        m_assembler.notl_r(dest);
+        else
         m_assembler.xorl_ir(imm.m_value, dest);
     }
 
diff --git a/Source/JavaScriptCore/bytecode/CodeBlock.cpp b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
index 30f1305..94c62f8 100644
--- a/Source/JavaScriptCore/bytecode/CodeBlock.cpp
+++ b/Source/JavaScriptCore/bytecode/CodeBlock.cpp
@@ -684,10 +684,6 @@
             ++it;
             break;
         }
-        case op_bitnot: {
-            printUnaryOp(exec, location, it, "bitnot");
-            break;
-        }
         case op_check_has_instance: {
             int base = (++it)->u.operand;
             dataLog("[%4d] check_has_instance\t\t %s\n", location, registerName(exec, base).data());
diff --git a/Source/JavaScriptCore/bytecode/Opcode.h b/Source/JavaScriptCore/bytecode/Opcode.h
index a47fa5e..45598f8 100644
--- a/Source/JavaScriptCore/bytecode/Opcode.h
+++ b/Source/JavaScriptCore/bytecode/Opcode.h
@@ -82,7 +82,6 @@
         macro(op_bitand, 5) \
         macro(op_bitxor, 5) \
         macro(op_bitor, 5) \
-        macro(op_bitnot, 3) \
         \
         macro(op_check_has_instance, 2) \
         macro(op_instanceof, 5) \
diff --git a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
index 2d41819..73c2caa 100644
--- a/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
+++ b/Source/JavaScriptCore/bytecompiler/NodesCodegen.cpp
@@ -871,7 +871,15 @@
     return generator.emitUnaryOp(opcodeID(), generator.finalDestination(dst), src);
 }
 
-
+// ------------------------------ BitwiseNotNode -----------------------------------
+ 
+RegisterID* BitwiseNotNode::emitBytecode(BytecodeGenerator& generator, RegisterID* dst)
+{
+    RefPtr<RegisterID> src2 = generator.emitLoad(generator.newTemporary(), jsNumber(-1));
+    RegisterID* src1 = generator.emitNode(m_expr);
+    return generator.emitBinaryOp(op_bitxor, generator.finalDestination(dst, src1), src1, src2.get(), OperandTypes(m_expr->resultDescriptor(), ResultType::numberTypeIsInt32()));
+}
+ 
 // ------------------------------ LogicalNotNode -----------------------------------
 
 void LogicalNotNode::emitBytecodeInConditionContext(BytecodeGenerator& generator, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue)
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index c9ecff1..30fcaca 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -2570,24 +2570,6 @@
         vPC += OPCODE_LENGTH(op_bitor);
         NEXT_INSTRUCTION();
     }
-    DEFINE_OPCODE(op_bitnot) {
-        /* bitnot dst(r) src(r)
-
-           Computes bitwise NOT of register src1 (converted to int32),
-           and puts the result in register dst.
-        */
-        int dst = vPC[1].u.operand;
-        JSValue src = callFrame->r(vPC[2].u.operand).jsValue();
-        if (src.isInt32())
-            callFrame->uncheckedR(dst) = jsNumber(~src.asInt32());
-        else {
-            JSValue result = jsNumber(~src.toInt32(callFrame));
-            CHECK_FOR_EXCEPTION();
-            callFrame->uncheckedR(dst) = result;
-        }
-        vPC += OPCODE_LENGTH(op_bitnot);
-        NEXT_INSTRUCTION();
-    }
     DEFINE_OPCODE(op_not) {
         /* not dst(r) src(r)
 
diff --git a/Source/JavaScriptCore/jit/JIT.cpp b/Source/JavaScriptCore/jit/JIT.cpp
index 9a6481a..e8dcd26 100644
--- a/Source/JavaScriptCore/jit/JIT.cpp
+++ b/Source/JavaScriptCore/jit/JIT.cpp
@@ -242,7 +242,6 @@
 
         DEFINE_OP(op_add)
         DEFINE_OP(op_bitand)
-        DEFINE_OP(op_bitnot)
         DEFINE_OP(op_bitor)
         DEFINE_OP(op_bitxor)
         DEFINE_OP(op_call)
@@ -437,7 +436,6 @@
         switch (m_interpreter->getOpcodeID(currentInstruction->u.opcode)) {
         DEFINE_SLOWCASE_OP(op_add)
         DEFINE_SLOWCASE_OP(op_bitand)
-        DEFINE_SLOWCASE_OP(op_bitnot)
         DEFINE_SLOWCASE_OP(op_bitor)
         DEFINE_SLOWCASE_OP(op_bitxor)
         DEFINE_SLOWCASE_OP(op_call)
diff --git a/Source/JavaScriptCore/jit/JIT.h b/Source/JavaScriptCore/jit/JIT.h
index 7ed1d96..37a50be 100644
--- a/Source/JavaScriptCore/jit/JIT.h
+++ b/Source/JavaScriptCore/jit/JIT.h
@@ -780,7 +780,6 @@
 
         void emit_op_add(Instruction*);
         void emit_op_bitand(Instruction*);
-        void emit_op_bitnot(Instruction*);
         void emit_op_bitor(Instruction*);
         void emit_op_bitxor(Instruction*);
         void emit_op_call(Instruction*);
@@ -900,7 +899,6 @@
 
         void emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_bitand(Instruction*, Vector<SlowCaseEntry>::iterator&);
-        void emitSlow_op_bitnot(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_bitor(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_bitxor(Instruction*, Vector<SlowCaseEntry>::iterator&);
         void emitSlow_op_call(Instruction*, Vector<SlowCaseEntry>::iterator&);
diff --git a/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp b/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp
index 4916261..244a16f 100644
--- a/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp
+++ b/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp
@@ -448,31 +448,6 @@
     stubCall.call(dst);
 }
 
-// BitNot (~)
-
-void JIT::emit_op_bitnot(Instruction* currentInstruction)
-{
-    unsigned dst = currentInstruction[1].u.operand;
-    unsigned src = currentInstruction[2].u.operand;
-
-    emitLoad(src, regT1, regT0);
-    addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
-
-    not32(regT0);
-    emitStoreAndMapInt32(dst, regT1, regT0, dst == src, OPCODE_LENGTH(op_bitnot));
-}
-
-void JIT::emitSlow_op_bitnot(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    unsigned dst = currentInstruction[1].u.operand;
-
-    linkSlowCase(iter); // int32 check
-
-    JITStubCall stubCall(this, cti_op_bitnot);
-    stubCall.addArgument(regT1, regT0);
-    stubCall.call(dst);
-}
-
 // PostInc (i++)
 
 void JIT::emit_op_post_inc(Instruction* currentInstruction)
diff --git a/Source/JavaScriptCore/jit/JITOpcodes.cpp b/Source/JavaScriptCore/jit/JITOpcodes.cpp
index f6ad615..8d6f053 100644
--- a/Source/JavaScriptCore/jit/JITOpcodes.cpp
+++ b/Source/JavaScriptCore/jit/JITOpcodes.cpp
@@ -764,15 +764,6 @@
     emitPutVirtualRegister(currentInstruction[1].u.operand);
 }
 
-void JIT::emit_op_bitnot(Instruction* currentInstruction)
-{
-    emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
-    emitJumpSlowCaseIfNotImmediateInteger(regT0);
-    not32(regT0);
-    emitFastArithIntToImmNoCheck(regT0, regT0);
-    emitPutVirtualRegister(currentInstruction[1].u.operand);
-}
-
 void JIT::emit_op_resolve_with_base(Instruction* currentInstruction)
 {
     JITStubCall stubCall(this, cti_op_resolve_with_base);
@@ -1319,14 +1310,6 @@
     emitJumpSlowToHot(branchTest32(Zero, regT0), currentInstruction[2].u.operand); // inverted!
 }
 
-void JIT::emitSlow_op_bitnot(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
-{
-    linkSlowCase(iter);
-    JITStubCall stubCall(this, cti_op_bitnot);
-    stubCall.addArgument(regT0);
-    stubCall.call(currentInstruction[1].u.operand);
-}
-
 void JIT::emitSlow_op_jtrue(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
 {
     linkSlowCase(iter);
diff --git a/Source/JavaScriptCore/jit/JITStubs.cpp b/Source/JavaScriptCore/jit/JITStubs.cpp
index a0a8165..eb33ed9 100644
--- a/Source/JavaScriptCore/jit/JITStubs.cpp
+++ b/Source/JavaScriptCore/jit/JITStubs.cpp
@@ -3036,19 +3036,6 @@
     return JSValue::encode(result);
 }
 
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitnot)
-{
-    STUB_INIT_STACK_FRAME(stackFrame);
-
-    JSValue src = stackFrame.args[0].jsValue();
-
-    ASSERT(!src.isInt32());
-    CallFrame* callFrame = stackFrame.callFrame;
-    JSValue result = jsNumber(~src.toInt32(callFrame));
-    CHECK_FOR_EXCEPTION_AT_END();
-    return JSValue::encode(result);
-}
-
 DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_with_base)
 {
     STUB_INIT_STACK_FRAME(stackFrame);
diff --git a/Source/JavaScriptCore/jit/JITStubs.h b/Source/JavaScriptCore/jit/JITStubs.h
index 890d997..7c15e94 100644
--- a/Source/JavaScriptCore/jit/JITStubs.h
+++ b/Source/JavaScriptCore/jit/JITStubs.h
@@ -330,7 +330,6 @@
 extern "C" {
     EncodedJSValue JIT_STUB cti_op_add(STUB_ARGS_DECLARATION);
     EncodedJSValue JIT_STUB cti_op_bitand(STUB_ARGS_DECLARATION);
-    EncodedJSValue JIT_STUB cti_op_bitnot(STUB_ARGS_DECLARATION);
     EncodedJSValue JIT_STUB cti_op_bitor(STUB_ARGS_DECLARATION);
     EncodedJSValue JIT_STUB cti_op_bitxor(STUB_ARGS_DECLARATION);
     EncodedJSValue JIT_STUB cti_op_call_NotJSFunction(STUB_ARGS_DECLARATION);
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
index 3a6fcc0..c36ba8d 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
@@ -668,12 +668,6 @@
     LLINT_RETURN(jsNumber(LLINT_OP_C(2).jsValue().toInt32(exec) ^ LLINT_OP_C(3).jsValue().toInt32(exec)));
 }
 
-LLINT_SLOW_PATH_DECL(slow_path_bitnot)
-{
-    LLINT_BEGIN();
-    LLINT_RETURN(jsNumber(~LLINT_OP_C(2).jsValue().toInt32(exec)));
-}
-
 LLINT_SLOW_PATH_DECL(slow_path_check_has_instance)
 {
     LLINT_BEGIN();
diff --git a/Source/JavaScriptCore/llint/LLIntSlowPaths.h b/Source/JavaScriptCore/llint/LLIntSlowPaths.h
index fe684d3..702e55d 100644
--- a/Source/JavaScriptCore/llint/LLIntSlowPaths.h
+++ b/Source/JavaScriptCore/llint/LLIntSlowPaths.h
@@ -97,7 +97,6 @@
 LLINT_SLOW_PATH_DECL(slow_path_bitand);
 LLINT_SLOW_PATH_DECL(slow_path_bitor);
 LLINT_SLOW_PATH_DECL(slow_path_bitxor);
-LLINT_SLOW_PATH_DECL(slow_path_bitnot);
 LLINT_SLOW_PATH_DECL(slow_path_check_has_instance);
 LLINT_SLOW_PATH_DECL(slow_path_instanceof);
 LLINT_SLOW_PATH_DECL(slow_path_typeof);
diff --git a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
index 2c3aa7d..a4fbfbf 100644
--- a/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
+++ b/Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
@@ -1148,22 +1148,6 @@
         5)
 
 
-_llint_op_bitnot:
-    traceExecution()
-    loadi 8[PC], t1
-    loadi 4[PC], t0
-    loadConstantOrVariable(t1, t2, t3)
-    bineq t2, Int32Tag, .opBitnotSlow
-    noti t3
-    storei t2, TagOffset[cfr, t0, 8]
-    storei t3, PayloadOffset[cfr, t0, 8]
-    dispatch(3)
-
-.opBitnotSlow:
-    callSlowPath(_llint_slow_path_bitnot)
-    dispatch(3)
-
-
 _llint_op_check_has_instance:
     traceExecution()
     loadi 4[PC], t1
diff --git a/Source/JavaScriptCore/parser/NodeConstructors.h b/Source/JavaScriptCore/parser/NodeConstructors.h
index eea3f57..e496d23 100644
--- a/Source/JavaScriptCore/parser/NodeConstructors.h
+++ b/Source/JavaScriptCore/parser/NodeConstructors.h
@@ -417,12 +417,13 @@
     }
 
     inline NegateNode::NegateNode(int lineNumber, ExpressionNode* expr)
-        : UnaryOpNode(lineNumber, ResultType::numberTypeCanReuse(), expr, op_negate)
+        : UnaryOpNode(lineNumber, ResultType::numberType(), expr, op_negate)
     {
     }
 
     inline BitwiseNotNode::BitwiseNotNode(int lineNumber, ExpressionNode* expr)
-        : UnaryOpNode(lineNumber, ResultType::forBitOp(), expr, op_bitnot)
+        : ExpressionNode(lineNumber, ResultType::forBitOp())
+        , m_expr(expr)
     {
     }
 
@@ -450,18 +451,18 @@
     }
 
     inline MultNode::MultNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
-        : BinaryOpNode(lineNumber, ResultType::numberTypeCanReuse(), expr1, expr2, op_mul, rightHasAssignments)
+        : BinaryOpNode(lineNumber, ResultType::numberType(), expr1, expr2, op_mul, rightHasAssignments)
     {
     }
 
     inline DivNode::DivNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
-        : BinaryOpNode(lineNumber, ResultType::numberTypeCanReuse(), expr1, expr2, op_div, rightHasAssignments)
+        : BinaryOpNode(lineNumber, ResultType::numberType(), expr1, expr2, op_div, rightHasAssignments)
     {
     }
 
 
     inline ModNode::ModNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
-        : BinaryOpNode(lineNumber, ResultType::numberTypeCanReuse(), expr1, expr2, op_mod, rightHasAssignments)
+        : BinaryOpNode(lineNumber, ResultType::numberType(), expr1, expr2, op_mod, rightHasAssignments)
     {
     }
 
@@ -471,7 +472,7 @@
     }
 
     inline SubNode::SubNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
-        : BinaryOpNode(lineNumber, ResultType::numberTypeCanReuse(), expr1, expr2, op_sub, rightHasAssignments)
+        : BinaryOpNode(lineNumber, ResultType::numberType(), expr1, expr2, op_sub, rightHasAssignments)
     {
     }
 
@@ -486,7 +487,7 @@
     }
 
     inline UnsignedRightShiftNode::UnsignedRightShiftNode(int lineNumber, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
-        : BinaryOpNode(lineNumber, ResultType::numberTypeCanReuse(), expr1, expr2, op_urshift, rightHasAssignments)
+        : BinaryOpNode(lineNumber, ResultType::numberType(), expr1, expr2, op_urshift, rightHasAssignments)
     {
     }
 
diff --git a/Source/JavaScriptCore/parser/Nodes.h b/Source/JavaScriptCore/parser/Nodes.h
index 0373766..ea739d5 100644
--- a/Source/JavaScriptCore/parser/Nodes.h
+++ b/Source/JavaScriptCore/parser/Nodes.h
@@ -793,11 +793,20 @@
         NegateNode(int, ExpressionNode*);
     };
 
-    class BitwiseNotNode : public UnaryOpNode {
+    class BitwiseNotNode : public ExpressionNode {
     public:
         BitwiseNotNode(int, ExpressionNode*);
-    };
 
+    protected:
+        ExpressionNode* expr() { return m_expr; }
+        const ExpressionNode* expr() const { return m_expr; }
+
+    private:
+        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
+
+        ExpressionNode* m_expr;
+    };
+ 
     class LogicalNotNode : public UnaryOpNode {
     public:
         LogicalNotNode(int, ExpressionNode*);
diff --git a/Source/JavaScriptCore/parser/ResultType.h b/Source/JavaScriptCore/parser/ResultType.h
index 27b8112..8f30e5b 100644
--- a/Source/JavaScriptCore/parser/ResultType.h
+++ b/Source/JavaScriptCore/parser/ResultType.h
@@ -32,8 +32,7 @@
         friend struct OperandTypes;
 
         typedef char Type;
-        static const Type TypeReusable = 1;
-        static const Type TypeInt32    = 2;
+        static const Type TypeInt32 = 1;
         
         static const Type TypeMaybeNumber = 0x04;
         static const Type TypeMaybeString = 0x08;
@@ -48,11 +47,6 @@
         {
         }
         
-        bool isReusable()
-        {
-            return m_type & TypeReusable;
-        }
-
         bool isInt32()
         {
             return m_type & TypeInt32;
@@ -93,19 +87,14 @@
             return ResultType(TypeMaybeNumber);
         }
         
-        static ResultType numberTypeCanReuse()
+        static ResultType numberTypeIsInt32()
         {
-            return ResultType(TypeReusable | TypeMaybeNumber);
+            return ResultType(TypeInt32 | TypeMaybeNumber);
         }
         
-        static ResultType numberTypeCanReuseIsInt32()
+        static ResultType stringOrNumberType()
         {
-            return ResultType(TypeReusable | TypeInt32 | TypeMaybeNumber);
-        }
-        
-        static ResultType stringOrNumberTypeCanReuse()
-        {
-            return ResultType(TypeReusable | TypeMaybeNumber | TypeMaybeString);
+            return ResultType(TypeMaybeNumber | TypeMaybeString);
         }
         
         static ResultType stringType()
@@ -121,15 +110,15 @@
         static ResultType forAdd(ResultType op1, ResultType op2)
         {
             if (op1.definitelyIsNumber() && op2.definitelyIsNumber())
-                return numberTypeCanReuse();
+                return numberType();
             if (op1.definitelyIsString() || op2.definitelyIsString())
                 return stringType();
-            return stringOrNumberTypeCanReuse();
+            return stringOrNumberType();
         }
         
         static ResultType forBitOp()
         {
-            return numberTypeCanReuseIsInt32();
+            return numberTypeIsInt32();
         }
 
     private: