mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 847205 - Add optimized (Double BITOP Int32) and (Int32 BITOP Double) stubs. r=bhackett
This commit is contained in:
parent
eba3c757df
commit
e7d57a8c9c
@ -2294,12 +2294,8 @@ DoBinaryArithFallback(JSContext *cx, ICBinaryArith_Fallback *stub, HandleValue l
|
||||
stub->addNewStub(doubleStub);
|
||||
return true;
|
||||
}
|
||||
case JSOP_URSH:
|
||||
// Fall-through to int32 case.
|
||||
break;
|
||||
default:
|
||||
// TODO: attach double stub for bitwise ops.
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2312,6 +2308,28 @@ DoBinaryArithFallback(JSContext *cx, ICBinaryArith_Fallback *stub, HandleValue l
|
||||
if (!int32Stub)
|
||||
return false;
|
||||
stub->addNewStub(int32Stub);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle Double <BITOP> Int32 or Int32 <BITOP> Double case.
|
||||
if ((lhs.isDouble() && rhs.isInt32()) || (lhs.isInt32() && rhs.isDouble()) && ret.isInt32()) {
|
||||
switch(op) {
|
||||
case JSOP_BITOR:
|
||||
case JSOP_BITXOR:
|
||||
case JSOP_BITAND: {
|
||||
IonSpew(IonSpew_BaselineIC, " Generating %s(%s, %s) stub", js_CodeName[op],
|
||||
lhs.isDouble() ? "Double" : "Int32",
|
||||
lhs.isDouble() ? "Int32" : "Double");
|
||||
ICBinaryArith_DoubleWithInt32::Compiler compiler(cx, op, lhs.isDouble());
|
||||
ICStub *optStub = compiler.getStub(compiler.getStubSpace(script));
|
||||
if (!optStub)
|
||||
return false;
|
||||
stub->addNewStub(optStub);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -2595,6 +2613,71 @@ ICBinaryArith_BooleanWithInt32::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ICBinaryArith_DoubleWithInt32::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
{
|
||||
JS_ASSERT(op == JSOP_BITOR || op == JSOP_BITAND || op == JSOP_BITXOR);
|
||||
|
||||
Label failure;
|
||||
Register intReg;
|
||||
Register scratchReg;
|
||||
if (lhsIsDouble_) {
|
||||
masm.branchTestDouble(Assembler::NotEqual, R0, &failure);
|
||||
masm.branchTestInt32(Assembler::NotEqual, R1, &failure);
|
||||
intReg = masm.extractInt32(R1, ExtractTemp0);
|
||||
masm.unboxDouble(R0, FloatReg0);
|
||||
scratchReg = R0.scratchReg();
|
||||
} else {
|
||||
masm.branchTestInt32(Assembler::NotEqual, R0, &failure);
|
||||
masm.branchTestDouble(Assembler::NotEqual, R1, &failure);
|
||||
intReg = masm.extractInt32(R0, ExtractTemp0);
|
||||
masm.unboxDouble(R1, FloatReg0);
|
||||
scratchReg = R1.scratchReg();
|
||||
}
|
||||
|
||||
// Truncate the double to an int32.
|
||||
{
|
||||
Label doneTruncate;
|
||||
Label truncateABICall;
|
||||
masm.branchTruncateDouble(FloatReg0, scratchReg, &truncateABICall);
|
||||
masm.jump(&doneTruncate);
|
||||
|
||||
masm.bind(&truncateABICall);
|
||||
masm.push(intReg);
|
||||
masm.setupUnalignedABICall(1, scratchReg);
|
||||
masm.passABIArg(FloatReg0);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, js::ToInt32));
|
||||
masm.storeCallResult(scratchReg);
|
||||
masm.pop(intReg);
|
||||
|
||||
masm.bind(&doneTruncate);
|
||||
}
|
||||
|
||||
Register intReg2 = scratchReg;
|
||||
// All handled ops commute, so no need to worry about ordering.
|
||||
switch(op) {
|
||||
case JSOP_BITOR:
|
||||
masm.orPtr(intReg, intReg2);
|
||||
break;
|
||||
case JSOP_BITXOR:
|
||||
masm.xorPtr(intReg, intReg2);
|
||||
break;
|
||||
case JSOP_BITAND:
|
||||
masm.andPtr(intReg, intReg2);
|
||||
break;
|
||||
default:
|
||||
JS_NOT_REACHED("Unhandled op for BinaryArith_DoubleWithInt32.");
|
||||
return false;
|
||||
}
|
||||
masm.tagValue(JSVAL_TYPE_INT32, intReg2, R0);
|
||||
EmitReturnFromIC(masm);
|
||||
|
||||
// Failure case - jump to next stub
|
||||
masm.bind(&failure);
|
||||
EmitStubGuardFailure(masm);
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// UnaryArith_Fallback
|
||||
//
|
||||
|
@ -313,6 +313,7 @@ class ICEntry
|
||||
_(BinaryArith_StringConcat) \
|
||||
_(BinaryArith_StringObjectConcat) \
|
||||
_(BinaryArith_BooleanWithInt32) \
|
||||
_(BinaryArith_DoubleWithInt32) \
|
||||
\
|
||||
_(UnaryArith_Fallback) \
|
||||
_(UnaryArith_Int32) \
|
||||
@ -2381,6 +2382,50 @@ class ICBinaryArith_BooleanWithInt32 : public ICStub
|
||||
};
|
||||
};
|
||||
|
||||
class ICBinaryArith_DoubleWithInt32 : public ICStub
|
||||
{
|
||||
friend class ICStubSpace;
|
||||
|
||||
ICBinaryArith_DoubleWithInt32(IonCode *stubCode, bool lhsIsDouble)
|
||||
: ICStub(BinaryArith_DoubleWithInt32, stubCode)
|
||||
{
|
||||
extra_ = lhsIsDouble;
|
||||
}
|
||||
|
||||
public:
|
||||
static inline ICBinaryArith_DoubleWithInt32 *New(ICStubSpace *space, IonCode *code,
|
||||
bool lhsIsDouble) {
|
||||
if (!code)
|
||||
return NULL;
|
||||
return space->allocate<ICBinaryArith_DoubleWithInt32>(code, lhsIsDouble);
|
||||
}
|
||||
|
||||
bool lhsIsDouble() const {
|
||||
return extra_;
|
||||
}
|
||||
|
||||
class Compiler : public ICMultiStubCompiler {
|
||||
protected:
|
||||
bool lhsIsDouble_;
|
||||
bool generateStubCode(MacroAssembler &masm);
|
||||
|
||||
virtual int32_t getKey() const {
|
||||
return static_cast<int32_t>(kind) | (static_cast<int32_t>(op) << 16) |
|
||||
(static_cast<int32_t>(lhsIsDouble_) << 24);
|
||||
}
|
||||
|
||||
public:
|
||||
Compiler(JSContext *cx, JSOp op, bool lhsIsDouble)
|
||||
: ICMultiStubCompiler(cx, ICStub::BinaryArith_DoubleWithInt32, op),
|
||||
lhsIsDouble_(lhsIsDouble)
|
||||
{}
|
||||
|
||||
ICStub *getStub(ICStubSpace *space) {
|
||||
return ICBinaryArith_DoubleWithInt32::New(space, getStubCode(), lhsIsDouble_);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// UnaryArith
|
||||
// JSOP_BITNOT
|
||||
// JSOP_NEG
|
||||
|
Loading…
Reference in New Issue
Block a user