mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Implement LBitNotV (bug 725000, r=sstangl).
This commit is contained in:
parent
12446370fb
commit
3cf56bb5ef
@ -45,6 +45,7 @@
|
||||
#include "MIRGenerator.h"
|
||||
#include "shared/CodeGenerator-shared-inl.h"
|
||||
#include "jsnum.h"
|
||||
#include "jsinterpinlines.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace js::ion;
|
||||
@ -1751,6 +1752,16 @@ CodeGenerator::visitThrow(LThrow *lir)
|
||||
return callVM(ThrowInfo, lir);
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGenerator::visitBitNotV(LBitNotV *lir)
|
||||
{
|
||||
typedef bool (*pf)(JSContext *, const Value &, int *p);
|
||||
static const VMFunction info = FunctionInfo<pf>(BitNot);
|
||||
|
||||
pushArg(ToValue(lir, LBitNotV::Input));
|
||||
return callVM(info, lir);
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGenerator::visitLoadElementV(LLoadElementV *load)
|
||||
{
|
||||
|
@ -132,6 +132,7 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
bool visitCallIteratorMore(LCallIteratorMore *lir);
|
||||
bool visitCallIteratorEnd(LCallIteratorEnd *lir);
|
||||
bool visitCallSetProperty(LCallSetProperty *ins);
|
||||
bool visitBitNotV(LBitNotV *lir);
|
||||
|
||||
bool visitCheckOverRecursed(LCheckOverRecursed *lir);
|
||||
bool visitCheckOverRecursedFailure(CheckOverRecursedFailure *ool);
|
||||
|
@ -2015,6 +2015,8 @@ IonBuilder::jsop_bitnot()
|
||||
ins->infer(oracle->unaryOp(script, pc));
|
||||
|
||||
current->push(ins);
|
||||
if (ins->isEffectful() && !resumeAfter(ins))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool
|
||||
|
@ -615,10 +615,20 @@ class LCompareDAndBranch : public LInstructionHelper<0, 2, 0>
|
||||
|
||||
// Bitwise not operation, takes a 32-bit integer as input and returning
|
||||
// a 32-bit integer result as an output.
|
||||
class LBitNot : public LInstructionHelper<1, 1, 0>
|
||||
class LBitNotI : public LInstructionHelper<1, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(BitNot);
|
||||
LIR_HEADER(BitNotI);
|
||||
};
|
||||
|
||||
// Call a stub to perform a binary operation.
|
||||
class LBitNotV : public LCallInstructionHelper<1, BOX_PIECES, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(BitNotV);
|
||||
BOX_OUTPUT_ACCESSORS();
|
||||
|
||||
static const size_t Input = 0;
|
||||
};
|
||||
|
||||
// Binary bitwise operation, taking two 32-bit integers as inputs and returning
|
||||
|
@ -61,7 +61,8 @@
|
||||
_(CallGeneric) \
|
||||
_(CallNative) \
|
||||
_(StackArg) \
|
||||
_(BitNot) \
|
||||
_(BitNotI) \
|
||||
_(BitNotV) \
|
||||
_(BitOp) \
|
||||
_(ShiftOp) \
|
||||
_(Return) \
|
||||
|
@ -354,9 +354,15 @@ LIRGenerator::visitBitNot(MBitNot *ins)
|
||||
{
|
||||
MDefinition *input = ins->getOperand(0);
|
||||
|
||||
JS_ASSERT(input->type() == MIRType_Int32);
|
||||
if (input->type() == MIRType_Int32)
|
||||
return lowerForALU(new LBitNotI(), ins, input);
|
||||
|
||||
return lowerForALU(new LBitNot(), ins, input);
|
||||
LBitNotV *lir = new LBitNotV;
|
||||
if (!useBox(lir, LBitNotV::Input, input))
|
||||
return false;
|
||||
if (!defineVMReturn(lir, ins))
|
||||
return false;
|
||||
return assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1540,7 +1540,7 @@ class MBitNot
|
||||
return congruentIfOperandsEqual(ins);
|
||||
}
|
||||
AliasSet getAliasSet() const {
|
||||
if (specialization_ >= MIRType_Object)
|
||||
if (specialization_ == MIRType_None)
|
||||
return AliasSet::Store(AliasSet::Any);
|
||||
return AliasSet::None();
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ namespace ion {
|
||||
enum DataType {
|
||||
Type_Void,
|
||||
Type_Bool,
|
||||
Type_JSBool,
|
||||
Type_Int32,
|
||||
Type_Object,
|
||||
Type_Value
|
||||
};
|
||||
@ -189,7 +189,7 @@ template <> struct TypeToArgProperties<const Value &> {
|
||||
|
||||
template <class> struct OutParamToDataType { static const DataType result = Type_Void; };
|
||||
template <> struct OutParamToDataType<Value *> { static const DataType result = Type_Value; };
|
||||
template <> struct OutParamToDataType<JSBool *> { static const DataType result = Type_JSBool; };
|
||||
template <> struct OutParamToDataType<int *> { static const DataType result = Type_Int32; };
|
||||
|
||||
#define FOR_EACH_ARGS_1(Macro, Sep, Last) Macro(1) Last(1)
|
||||
#define FOR_EACH_ARGS_2(Macro, Sep, Last) FOR_EACH_ARGS_1(Macro, Sep, Sep) Macro(2) Last(2)
|
||||
@ -245,8 +245,8 @@ struct FunctionInfo<R (*)(JSContext *)> : public VMFunction {
|
||||
return 0;
|
||||
}
|
||||
FunctionInfo(pf fun)
|
||||
: VMFunction(JS_FUNC_TO_DATA_PTR(void *, fun), explicitArgs(),
|
||||
argumentProperties(), outParam(), returnType())
|
||||
: VMFunction(JS_FUNC_TO_DATA_PTR(void *, fun), explicitArgs(),
|
||||
argumentProperties(), outParam(), returnType())
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -514,7 +514,7 @@ CodeGeneratorARM::visitDivI(LDivI *ins)
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorARM::visitBitNot(LBitNot *ins)
|
||||
CodeGeneratorARM::visitBitNotI(LBitNotI *ins)
|
||||
{
|
||||
const LAllocation *input = ins->getOperand(0);
|
||||
const LDefinition *dest = ins->getDef(0);
|
||||
|
@ -102,7 +102,7 @@ class CodeGeneratorARM : public CodeGeneratorShared
|
||||
virtual bool visitAbsD(LAbsD *ins);
|
||||
virtual bool visitAddI(LAddI *ins);
|
||||
virtual bool visitSubI(LSubI *ins);
|
||||
virtual bool visitBitNot(LBitNot *ins);
|
||||
virtual bool visitBitNotI(LBitNotI *ins);
|
||||
virtual bool visitBitOp(LBitOp *ins);
|
||||
|
||||
virtual bool visitMulI(LMulI *ins);
|
||||
|
@ -587,9 +587,9 @@ IonCompartment::generateVMWrapper(JSContext *cx, const VMFunction &f)
|
||||
masm.ma_mov(sp, outReg);
|
||||
break;
|
||||
|
||||
case Type_JSBool:
|
||||
case Type_Int32:
|
||||
outReg = regs.takeAny();
|
||||
masm.reserveStack(sizeof(JSBool));
|
||||
masm.reserveStack(sizeof(int));
|
||||
masm.ma_mov(sp, outReg);
|
||||
break;
|
||||
|
||||
@ -657,9 +657,9 @@ IonCompartment::generateVMWrapper(JSContext *cx, const VMFunction &f)
|
||||
masm.freeStack(sizeof(Value));
|
||||
break;
|
||||
|
||||
case Type_JSBool:
|
||||
case Type_Int32:
|
||||
masm.load32(Address(sp, 0), ReturnReg);
|
||||
masm.freeStack(sizeof(JSBool));
|
||||
masm.freeStack(sizeof(int32));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -636,7 +636,7 @@ CodeGeneratorX86Shared::visitModI(LModI *ins)
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGeneratorX86Shared::visitBitNot(LBitNot *ins)
|
||||
CodeGeneratorX86Shared::visitBitNotI(LBitNotI *ins)
|
||||
{
|
||||
const LAllocation *input = ins->getOperand(0);
|
||||
JS_ASSERT(!input->isConstant());
|
||||
|
@ -122,7 +122,7 @@ class CodeGeneratorX86Shared : public CodeGeneratorShared
|
||||
virtual bool visitMulI(LMulI *ins);
|
||||
virtual bool visitDivI(LDivI *ins);
|
||||
virtual bool visitModI(LModI *ins);
|
||||
virtual bool visitBitNot(LBitNot *ins);
|
||||
virtual bool visitBitNotI(LBitNotI *ins);
|
||||
virtual bool visitBitOp(LBitOp *ins);
|
||||
virtual bool visitShiftOp(LShiftOp *ins);
|
||||
virtual bool visitMoveGroup(LMoveGroup *group);
|
||||
|
@ -513,9 +513,9 @@ IonCompartment::generateVMWrapper(JSContext *cx, const VMFunction &f)
|
||||
masm.movq(esp, outReg);
|
||||
break;
|
||||
|
||||
case Type_JSBool:
|
||||
case Type_Int32:
|
||||
outReg = regs.takeAny();
|
||||
masm.reserveStack(sizeof(JSBool));
|
||||
masm.reserveStack(sizeof(int));
|
||||
masm.movq(esp, outReg);
|
||||
break;
|
||||
|
||||
@ -592,10 +592,9 @@ IonCompartment::generateVMWrapper(JSContext *cx, const VMFunction &f)
|
||||
masm.freeStack(sizeof(Value));
|
||||
break;
|
||||
|
||||
case Type_JSBool:
|
||||
JS_STATIC_ASSERT(sizeof(JSBool) == 4);
|
||||
case Type_Int32:
|
||||
masm.load32(Address(esp, 0), ReturnReg);
|
||||
masm.freeStack(sizeof(JSBool));
|
||||
masm.freeStack(sizeof(int));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -531,9 +531,9 @@ IonCompartment::generateVMWrapper(JSContext *cx, const VMFunction &f)
|
||||
masm.movl(esp, outReg);
|
||||
break;
|
||||
|
||||
case Type_JSBool:
|
||||
case Type_Int32:
|
||||
outReg = regs.takeAny();
|
||||
masm.reserveStack(sizeof(JSBool));
|
||||
masm.reserveStack(sizeof(int32));
|
||||
masm.movl(esp, outReg);
|
||||
break;
|
||||
|
||||
@ -598,7 +598,7 @@ IonCompartment::generateVMWrapper(JSContext *cx, const VMFunction &f)
|
||||
masm.freeStack(sizeof(Value));
|
||||
break;
|
||||
|
||||
case Type_JSBool:
|
||||
case Type_Int32:
|
||||
masm.load32(Address(esp, 0), ReturnReg);
|
||||
masm.freeStack(sizeof(JSBool));
|
||||
break;
|
||||
|
9
js/src/jit-test/tests/ion/bug725000.js
Normal file
9
js/src/jit-test/tests/ion/bug725000.js
Normal file
@ -0,0 +1,9 @@
|
||||
function f(s) {
|
||||
var q;
|
||||
for (var i = 0; i < 10000; i++)
|
||||
q = ~s;
|
||||
return q;
|
||||
}
|
||||
var obj = { valueOf: function () { return 3; } }
|
||||
assertEq(f(obj), -4);
|
||||
|
@ -2461,9 +2461,8 @@ END_CASE(JSOP_NOT)
|
||||
BEGIN_CASE(JSOP_BITNOT)
|
||||
{
|
||||
int32_t i;
|
||||
if (!ToInt32(cx, regs.sp[-1], &i))
|
||||
if (!BitNot(cx, regs.sp[-1], &i))
|
||||
goto error;
|
||||
i = ~i;
|
||||
regs.sp[-1].setInt32(i);
|
||||
}
|
||||
END_CASE(JSOP_BITNOT)
|
||||
|
@ -817,6 +817,16 @@ GreaterThanOrEqualOperation(JSContext *cx, const Value &lhs, const Value &rhs, b
|
||||
RELATIONAL_OP(>=);
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE bool
|
||||
BitNot(JSContext *cx, const Value &in, int *out)
|
||||
{
|
||||
int i;
|
||||
if (!ToInt32(cx, in, &i))
|
||||
return false;
|
||||
*out = ~i;
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef RELATIONAL_OP
|
||||
|
||||
} /* namespace js */
|
||||
|
Loading…
Reference in New Issue
Block a user