Commit a6bdfc82 authored by barraclough@apple.com's avatar 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):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@109007 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 4cf719cc
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
......@@ -156,11 +156,6 @@ public:
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 @@ public:
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)
......
......@@ -303,11 +303,6 @@ public:
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 @@ public:
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 @@ public:
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);
}
......
......@@ -291,11 +291,6 @@ public:
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 @@ public:
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
......
......@@ -209,11 +209,6 @@ public:
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 @@ public:
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 @@ public:
m_assembler.neg(dst, dst);
}
void not32(RegisterID dst)
{
m_assembler.notlReg(dst, dst);
}
void urshift32(RegisterID shiftamount, RegisterID dest)
{
if (shiftamount == SH4Registers::r0)
......
......@@ -223,16 +223,6 @@ public:
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 @@ public:
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 @@ public:
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);
}
......
......@@ -684,10 +684,6 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator&
++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());
......
......@@ -82,7 +82,6 @@ namespace JSC {
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) \
......
......@@ -871,7 +871,15 @@ RegisterID* UnaryOpNode::emitBytecode(BytecodeGenerator& generator, RegisterID*
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)
......
......@@ -2570,24 +2570,6 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
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)
......
......@@ -242,7 +242,6 @@ void JIT::privateCompileMainPass()
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 @@ void JIT::privateCompileSlowCases()
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)
......
......@@ -780,7 +780,6 @@ namespace JSC {
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 @@ namespace JSC {
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&);
......
......@@ -448,31 +448,6 @@ void JIT::emitSlow_op_bitxor(Instruction* currentInstruction, Vector<SlowCaseEnt
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)
......
......@@ -764,15 +764,6 @@ void JIT::emit_op_eq(Instruction* currentInstruction)
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 @@ void JIT::emitSlow_op_jfalse(Instruction* currentInstruction, Vector<SlowCaseEnt
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);
......
......@@ -3036,19 +3036,6 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_rshift)
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);
......
......@@ -330,7 +330,6 @@ namespace JSC {
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);
......
......@@ -668,12 +668,6 @@ LLINT_SLOW_PATH_DECL(slow_path_bitxor)
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();
......
......@@ -97,7 +97,6 @@ LLINT_SLOW_PATH_DECL(slow_path_urshift);
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);
......
......@@ -1148,22 +1148,6 @@ _llint_op_bitor:
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
......
......@@ -417,12 +417,13 @@ namespace JSC {
}
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 @@ namespace JSC {
}
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 @@ namespace JSC {
}
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 @@ namespace JSC {
}
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)
{
}
......
......@@ -793,11 +793,20 @@ namespace JSC {
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*);
......
......@@ -32,8 +32,7 @@ namespace JSC {
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 @@ namespace JSC {
{
}
bool isReusable()
{
return m_type & TypeReusable;
}
bool isInt32()
{
return m_type & TypeInt32;
......@@ -93,19 +87,14 @@ namespace JSC {
return ResultType(TypeMaybeNumber);
}
static ResultType numberTypeCanReuse()
{
return ResultType(TypeReusable | TypeMaybeNumber);
}
static ResultType numberTypeCanReuseIsInt32()
static ResultType numberTypeIsInt32()
{
return ResultType(TypeReusable | TypeInt32 | TypeMaybeNumber);
return ResultType(TypeInt32 | TypeMaybeNumber);
}
static ResultType stringOrNumberTypeCanReuse()
static ResultType stringOrNumberType()
{
return ResultType(TypeReusable | TypeMaybeNumber | TypeMaybeString);
return ResultType(TypeMaybeNumber | TypeMaybeString);
}
static ResultType stringType()
......@@ -121,15 +110,15 @@ namespace JSC {
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:
......