V4 JIT: fixes after NaN boxing changes.
Change-Id: I22a1b46f488dc65513ed287dabe7d85469cc5173 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
226f8cc9fe
commit
51c31660b1
|
@ -1842,6 +1842,9 @@ void InstructionSelection::visitRet(V4IR::Ret *s)
|
|||
if (t->type == V4IR::DoubleType) {
|
||||
_as->moveDoubleTo64((Assembler::FPRegisterID) t->index,
|
||||
Assembler::ReturnValueRegister);
|
||||
_as->move(Assembler::TrustedImm64(QV4::Value::NaNEncodeMask),
|
||||
Assembler::ScratchRegister);
|
||||
_as->xor64(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
|
||||
} else if (t->type == V4IR::UInt32Type) {
|
||||
Address tmp = addressForArgument(0);
|
||||
_as->storeUInt32((Assembler::RegisterID) t->index, Pointer(tmp));
|
||||
|
@ -2056,26 +2059,10 @@ void InstructionSelection::doubleBinop(V4IR::AluOp oper, V4IR::Expr *leftSource,
|
|||
|
||||
switch (oper) {
|
||||
case V4IR::OpAdd:
|
||||
if (V4IR::Const *c = rightSource->asConst()) {
|
||||
_as->moveDouble(_as->toDoubleRegister(leftSource, targetReg), targetReg);
|
||||
Assembler::ImplicitAddress addr =
|
||||
_as->constantTable().loadValueAddress(c, Assembler::ScratchRegister);
|
||||
_as->addDouble(Address(addr.base, addr.offset), targetReg);
|
||||
break;
|
||||
}
|
||||
|
||||
_as->addDouble(_as->toDoubleRegister(leftSource), _as->toDoubleRegister(rightSource),
|
||||
targetReg);
|
||||
break;
|
||||
case V4IR::OpMul:
|
||||
if (V4IR::Const *c = rightSource->asConst()) {
|
||||
_as->moveDouble(_as->toDoubleRegister(leftSource, targetReg), targetReg);
|
||||
Assembler::ImplicitAddress addr =
|
||||
_as->constantTable().loadValueAddress(c, Assembler::ScratchRegister);
|
||||
_as->mulDouble(Address(addr.base, addr.offset), targetReg);
|
||||
break;
|
||||
}
|
||||
|
||||
_as->mulDouble(_as->toDoubleRegister(leftSource), _as->toDoubleRegister(rightSource),
|
||||
targetReg);
|
||||
break;
|
||||
|
@ -2088,15 +2075,16 @@ void InstructionSelection::doubleBinop(V4IR::AluOp oper, V4IR::Expr *leftSource,
|
|||
_as->subDouble(Assembler::FPGpr0, targetReg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (V4IR::Const *c = rightSource->asConst()) {
|
||||
} else if (rightSource->asConst() && targetReg == Assembler::FPGpr0) {
|
||||
Q_ASSERT(leftSource->asTemp());
|
||||
Q_ASSERT(leftSource->asTemp()->kind == V4IR::Temp::PhysicalRegister);
|
||||
_as->moveDouble(_as->toDoubleRegister(leftSource, targetReg), targetReg);
|
||||
Assembler::ImplicitAddress addr =
|
||||
_as->constantTable().loadValueAddress(c, Assembler::ScratchRegister);
|
||||
_as->subDouble(Address(addr.base, addr.offset), targetReg);
|
||||
Assembler::FPRegisterID reg = (Assembler::FPRegisterID) leftSource->asTemp()->index;
|
||||
_as->moveDouble(_as->toDoubleRegister(rightSource, reg), reg);
|
||||
_as->subDouble(reg, targetReg);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
_as->subDouble(_as->toDoubleRegister(leftSource), _as->toDoubleRegister(rightSource),
|
||||
targetReg);
|
||||
|
@ -2110,16 +2098,16 @@ void InstructionSelection::doubleBinop(V4IR::AluOp oper, V4IR::Expr *leftSource,
|
|||
_as->divDouble(Assembler::FPGpr0, targetReg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (V4IR::Const *c = rightSource->asConst()) {
|
||||
} else if (rightSource->asConst() && targetReg == Assembler::FPGpr0) {
|
||||
Q_ASSERT(leftSource->asTemp());
|
||||
Q_ASSERT(leftSource->asTemp()->kind == V4IR::Temp::PhysicalRegister);
|
||||
_as->moveDouble(_as->toDoubleRegister(leftSource, targetReg), targetReg);
|
||||
Assembler::ImplicitAddress addr =
|
||||
_as->constantTable().loadValueAddress(c, Assembler::ScratchRegister);
|
||||
_as->divDouble(Address(addr.base, addr.offset), targetReg);
|
||||
Assembler::FPRegisterID reg = (Assembler::FPRegisterID) leftSource->asTemp()->index;
|
||||
_as->moveDouble(_as->toDoubleRegister(rightSource, reg), reg);
|
||||
_as->divDouble(reg, targetReg);
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
_as->divDouble(_as->toDoubleRegister(leftSource), _as->toDoubleRegister(rightSource),
|
||||
targetReg);
|
||||
break;
|
||||
|
|
|
@ -77,6 +77,14 @@ struct CompilationUnit : public QV4::CompiledData::CompilationUnit
|
|||
// be larger, as for example on ARM we append the exception handling table.
|
||||
};
|
||||
|
||||
struct RelativeCall {
|
||||
JSC::MacroAssembler::Address addr;
|
||||
|
||||
explicit RelativeCall(const JSC::MacroAssembler::Address &addr)
|
||||
: addr(addr)
|
||||
{}
|
||||
};
|
||||
|
||||
class Assembler : public JSC::MacroAssembler
|
||||
{
|
||||
public:
|
||||
|
@ -432,6 +440,11 @@ public:
|
|||
call(addr);
|
||||
}
|
||||
|
||||
void callAbsolute(const char* /*functionName*/, const RelativeCall &relativeCall)
|
||||
{
|
||||
call(relativeCall.addr);
|
||||
}
|
||||
|
||||
void registerBlock(V4IR::BasicBlock*, V4IR::BasicBlock *nextBlock);
|
||||
void jumpToBlock(V4IR::BasicBlock* current, V4IR::BasicBlock *target);
|
||||
void addPatch(V4IR::BasicBlock* targetBlock, Jump targetJump);
|
||||
|
@ -886,6 +899,8 @@ public:
|
|||
loadArgumentOnStackOrRegister<3>(arg4);
|
||||
loadArgumentOnStackOrRegister<2>(arg3);
|
||||
loadArgumentOnStackOrRegister<1>(arg2);
|
||||
|
||||
prepareRelativeCall(function, this);
|
||||
loadArgumentOnStackOrRegister<0>(arg1);
|
||||
|
||||
callAbsolute(functionName, function);
|
||||
|
@ -1259,9 +1274,9 @@ public:
|
|||
|
||||
// it's not in signed int range, so load it as a double, and truncate it down
|
||||
loadDouble(addr, FPGpr0);
|
||||
static const QV4::Value magic = QV4::Value::fromDouble(double(INT_MAX) + 1);
|
||||
ImplicitAddress magicAddr = constantTable().loadValueAddress(magic, scratchReg);
|
||||
subDouble(Address(magicAddr.base, magicAddr.offset), FPGpr0);
|
||||
static const double magic = double(INT_MAX) + 1;
|
||||
move(TrustedImmPtr(&magic), scratchReg);
|
||||
subDouble(Address(scratchReg, 0), FPGpr0);
|
||||
Jump canNeverHappen = branchTruncateDoubleToUint32(FPGpr0, scratchReg);
|
||||
canNeverHappen.link(this);
|
||||
or32(TrustedImm32(1 << 31), scratchReg);
|
||||
|
@ -1309,6 +1324,13 @@ private:
|
|||
QVector<CodeLineNumerMapping> codeLineNumberMappings;
|
||||
};
|
||||
|
||||
template <typename T> inline void prepareRelativeCall(const T &, Assembler *){}
|
||||
template <> inline void prepareRelativeCall(const RelativeCall &relativeCall, Assembler *as)
|
||||
{
|
||||
as->loadPtr(Assembler::Address(Assembler::ContextRegister, qOffsetOf(QV4::ExecutionContext, lookups)),
|
||||
relativeCall.addr.base);
|
||||
}
|
||||
|
||||
class Q_QML_EXPORT InstructionSelection:
|
||||
protected V4IR::IRDecoder,
|
||||
public EvalInstructionSelection
|
||||
|
@ -1477,15 +1499,13 @@ private:
|
|||
template <typename Retval, typename Arg1, typename Arg2>
|
||||
void generateLookupCall(Retval retval, uint index, uint getterSetterOffset, Arg1 arg1, Arg2 arg2)
|
||||
{
|
||||
_as->loadPtr(Assembler::Address(Assembler::ContextRegister, qOffsetOf(QV4::ExecutionContext, lookups)),
|
||||
Assembler::ReturnValueRegister);
|
||||
|
||||
Assembler::Pointer lookupAddr(Assembler::ReturnValueRegister, index * sizeof(QV4::Lookup));
|
||||
|
||||
Assembler::Address getterSetter = lookupAddr;
|
||||
getterSetter.offset += getterSetterOffset;
|
||||
|
||||
_as->generateFunctionCallImp(retval, "lookup getter/setter", getterSetter, lookupAddr, arg1, arg2);
|
||||
_as->generateFunctionCallImp(retval, "lookup getter/setter",
|
||||
RelativeCall(getterSetter), lookupAddr, arg1, arg2);
|
||||
}
|
||||
|
||||
template <typename Arg1>
|
||||
|
|
Loading…
Reference in New Issue