summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@qt.io>2017-11-07 11:30:14 +0100
committerErik Verbruggen <erik.verbruggen@qt.io>2017-11-21 06:59:23 +0000
commit9af8a47746b69b6040fc149c1d24602a1e25b08f (patch)
treec1b90686f46eca2956526b9faf6e40149db10cc1
parent296de594828a8ab7ccbe011813378cfee3c7660f (diff)
V4: Add int32 fastpath for add/sub/mul in the JITwip/new-backend
Change-Id: I21b0e31c7c93ae51b4ab406948450e566546e246 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
-rw-r--r--src/3rdparty/masm/assembler/MacroAssemblerARM64.h9
-rw-r--r--src/qml/jit/qv4assembler.cpp115
2 files changed, 88 insertions, 36 deletions
diff --git a/src/3rdparty/masm/assembler/MacroAssemblerARM64.h b/src/3rdparty/masm/assembler/MacroAssemblerARM64.h
index d5f4acb3ca..1f94eb9032 100644
--- a/src/3rdparty/masm/assembler/MacroAssemblerARM64.h
+++ b/src/3rdparty/masm/assembler/MacroAssemblerARM64.h
@@ -718,15 +718,20 @@ public:
void or64(TrustedImm64 imm, RegisterID dest)
{
+ or64(imm, dest, dest);
+ }
+
+ void or64(TrustedImm64 imm, RegisterID src, RegisterID dest)
+ {
LogicalImmediate logicalImm = LogicalImmediate::create64(static_cast<intptr_t>(static_cast<int64_t>(imm.m_value)));
if (logicalImm.isValid()) {
- m_assembler.orr<64>(dest, dest, logicalImm);
+ m_assembler.orr<64>(dest, src, logicalImm);
return;
}
move(imm, getCachedDataTempRegisterIDAndInvalidate());
- m_assembler.orr<64>(dest, dest, dataTempRegister);
+ m_assembler.orr<64>(dest, src, dataTempRegister);
}
void rotateRight64(TrustedImm32 imm, RegisterID srcDst)
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp
index c658d64e6a..e357211074 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4assembler.cpp
@@ -92,6 +92,7 @@ struct PlatformAssembler_X86_64_SysV : JSC::MacroAssembler<JSC::MacroAssemblerX8
static const RegisterID AccumulatorRegister = RegisterID::eax;
static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
static const RegisterID ScratchRegister = RegisterID::r10;
+ static const RegisterID ScratchRegister2 = RegisterID::r9; // Note: overlaps with Arg5Reg, so do not use while setting up a call!
static const RegisterID JSStackFrameRegister = RegisterID::r12;
static const RegisterID CppStackFrameRegister = RegisterID::r13;
static const RegisterID EngineRegister = RegisterID::r14;
@@ -169,6 +170,7 @@ struct PlatformAssembler_Win64 : JSC::MacroAssembler<JSC::MacroAssemblerX86_64>
static const RegisterID AccumulatorRegister = RegisterID::eax;
static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
static const RegisterID ScratchRegister = RegisterID::r10;
+ static const RegisterID ScratchRegister2 = RegisterID::r9; // Note: overlaps with Arg3Reg, so do not use while setting up a call!
static const RegisterID JSStackFrameRegister = RegisterID::r12;
static const RegisterID CppStackFrameRegister = RegisterID::r13;
static const RegisterID EngineRegister = RegisterID::r14;
@@ -329,6 +331,7 @@ struct PlatformAssembler_ARM64 : JSC::MacroAssembler<JSC::MacroAssemblerARM64>
static const RegisterID AccumulatorRegister = JSC::ARM64Registers::x9;
static const RegisterID AccumulatorRegisterValue = AccumulatorRegister;
static const RegisterID ScratchRegister = JSC::ARM64Registers::x10;
+ static const RegisterID ScratchRegister2 = JSC::ARM64Registers::x7; // Note: overlaps with Arg7Reg, so do not use while setting up a call!
static const RegisterID JSStackFrameRegister = JSC::ARM64Registers::x19;
static const RegisterID CppStackFrameRegister = JSC::ARM64Registers::x20;
static const RegisterID EngineRegister = JSC::ARM64Registers::x21;
@@ -767,9 +770,12 @@ struct PlatformAssembler64 : PlatformAssemblerCommon
patches.push_back({ notEqual, offset });
}
- void setAccumulatorTag(QV4::Value::ValueTypeInternal tag)
+ void setAccumulatorTag(QV4::Value::ValueTypeInternal tag, RegisterID sourceReg = NoRegister)
{
- or64(TrustedImm64(int64_t(tag) << 32), AccumulatorRegister);
+ if (sourceReg == NoRegister)
+ or64(TrustedImm64(int64_t(tag) << 32), AccumulatorRegister);
+ else
+ or64(TrustedImm64(int64_t(tag) << 32), sourceReg, AccumulatorRegister);
}
void encodeDoubleIntoAccumulator(FPRegisterID src)
@@ -795,6 +801,27 @@ struct PlatformAssembler64 : PlatformAssemblerCommon
{
addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
}
+
+ Jump binopBothIntPath(Address lhsAddr, std::function<Jump(void)> fastPath)
+ {
+ urshift64(AccumulatorRegister, TrustedImm32(32), ScratchRegister);
+ Jump accNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), ScratchRegister);
+ load64(lhsAddr, ScratchRegister);
+ urshift64(ScratchRegister, TrustedImm32(32), ScratchRegister2);
+ Jump lhsNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), ScratchRegister2);
+
+ // both integer
+ Jump failure = fastPath();
+ Jump done = jump();
+
+ // all other cases
+ if (failure.isSet())
+ failure.link(this);
+ accNotInt.link(this);
+ lhsNotInt.link(this);
+
+ return done;
+ }
};
typedef PlatformAssembler64 PlatformAssembler;
@@ -1027,8 +1054,10 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
notUndefValue.link(this);
}
- void setAccumulatorTag(QV4::Value::ValueTypeInternal tag)
+ void setAccumulatorTag(QV4::Value::ValueTypeInternal tag, RegisterID sourceReg = NoRegister)
{
+ if (sourceReg != NoRegister)
+ move(sourceReg, AccumulatorRegisterValue);
move(TrustedImm32(int(tag)), AccumulatorRegisterTag);
}
@@ -1047,6 +1076,28 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
{
popValue();
}
+
+ Jump binopBothIntPath(Address lhsAddr, std::function<Jump(void)> fastPath)
+ {
+ Jump accNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), AccumulatorRegisterTag);
+ Address lhsAddrTag = lhsAddr; lhsAddrTag.offset += Value::tagOffset();
+ load32(lhsAddrTag, ScratchRegister);
+ Jump lhsNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), ScratchRegister);
+
+ // both integer
+ Address lhsAddrValue = lhsAddr; lhsAddrValue.offset += Value::valueOffset();
+ load32(lhsAddrValue, ScratchRegister);
+ Jump failure = fastPath();
+ Jump done = jump();
+
+ // all other cases
+ if (failure.isSet())
+ failure.link(this);
+ accNotInt.link(this);
+ lhsNotInt.link(this);
+
+ return done;
+ }
};
typedef PlatformAssembler32 PlatformAssembler;
@@ -1293,16 +1344,14 @@ void Assembler::unot()
void Assembler::add(int lhs)
{
-// PlatformAssembler::Address lhsAddr(PlatformAssembler::JSStackFrameRegister,
-// lhs * int(sizeof(QV4::Value)));
-// auto done = pasm()->binopFastPath(lhsAddr, [this](){
-// auto overflowed = pasm()->branchAdd32(PlatformAssembler::Overflow,
-// PlatformAssembler::AccumulatorRegister,
-// PlatformAssembler::ScratchRegister);
-// pasm()->or64(PlatformAssembler::TrustedImm64(int64_t(QV4::Value::ValueTypeInternal::Integer) << 32),
-// PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegister);
-// return overflowed;
-// });
+ auto done = pasm()->binopBothIntPath(regAddr(lhs), [this](){
+ auto overflowed = pasm()->branchAdd32(PlatformAssembler::Overflow,
+ PlatformAssembler::AccumulatorRegisterValue,
+ PlatformAssembler::ScratchRegister);
+ pasm()->setAccumulatorTag(IntegerTag,
+ PlatformAssembler::ScratchRegister);
+ return overflowed;
+ });
// slow path:
saveAccumulatorInFrame();
@@ -1314,7 +1363,7 @@ void Assembler::add(int lhs)
checkException();
// done.
-// done.link(pasm());
+ done.link(pasm());
}
void Assembler::bitAnd(int lhs)
@@ -1461,15 +1510,14 @@ void Assembler::shlConst(int rhs)
void Assembler::mul(int lhs)
{
-// PlatformAssembler::Address lhsAddr(PlatformAssembler::JSStackFrameRegister, lhs * int(sizeof(QV4::Value)));
-// auto done = pasm()->binopFastPath(lhsAddr, [this](){
-// auto overflowed = pasm()->branchMul32(PlatformAssembler::Overflow,
-// PlatformAssembler::AccumulatorRegister,
-// PlatformAssembler::ScratchRegister);
-// pasm()->or64(PlatformAssembler::TrustedImm64(int64_t(QV4::Value::ValueTypeInternal::Integer) << 32),
-// PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegister);
-// return overflowed;
-// });
+ auto done = pasm()->binopBothIntPath(regAddr(lhs), [this](){
+ auto overflowed = pasm()->branchMul32(PlatformAssembler::Overflow,
+ PlatformAssembler::AccumulatorRegisterValue,
+ PlatformAssembler::ScratchRegister);
+ pasm()->setAccumulatorTag(IntegerTag,
+ PlatformAssembler::ScratchRegister);
+ return overflowed;
+ });
// slow path:
saveAccumulatorInFrame();
@@ -1480,7 +1528,7 @@ void Assembler::mul(int lhs)
checkException();
// done.
- // done.link(pasm());
+ done.link(pasm());
}
void Assembler::div(int lhs)
@@ -1505,15 +1553,14 @@ void Assembler::mod(int lhs)
void Assembler::sub(int lhs)
{
-// PlatformAssembler::Address lhsAddr(PlatformAssembler::JSStackFrameRegister, lhs * int(sizeof(QV4::Value)));
-// auto done = pasm()->binopFastPath(lhsAddr, [this](){
-// auto overflowed = pasm()->branchSub32(PlatformAssembler::Overflow,
-// PlatformAssembler::AccumulatorRegister,
-// PlatformAssembler::ScratchRegister);
-// pasm()->or64(PlatformAssembler::TrustedImm64(int64_t(QV4::Value::ValueTypeInternal::Integer) << 32),
-// PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegister);
-// return overflowed;
-// });
+ auto done = pasm()->binopBothIntPath(regAddr(lhs), [this](){
+ auto overflowed = pasm()->branchSub32(PlatformAssembler::Overflow,
+ PlatformAssembler::AccumulatorRegisterValue,
+ PlatformAssembler::ScratchRegister);
+ pasm()->setAccumulatorTag(IntegerTag,
+ PlatformAssembler::ScratchRegister);
+ return overflowed;
+ });
// slow path:
saveAccumulatorInFrame();
@@ -1524,7 +1571,7 @@ void Assembler::sub(int lhs)
checkException();
// done.
-// done.link(pasm());
+ done.link(pasm());
}
void Assembler::cmpeqNull()