aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jit/qv4assembler.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-11-27 21:41:30 +0100
committerLars Knoll <lars.knoll@qt.io>2018-01-02 16:53:09 +0000
commit142151cfef47420c08fb28f66d8f1d9810ad35d5 (patch)
tree990804ef682413ade9bf5fdb4df8a36ea07810d9 /src/qml/jit/qv4assembler.cpp
parenta1e5ec589e2ff25f1a3f96eeace1e1e9414044e3 (diff)
Optimize bitAnd, bitOr and bitXor
Change-Id: I8e9ea1c26a1bd9c4320d61c2a8d89175a65fe945 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'src/qml/jit/qv4assembler.cpp')
-rw-r--r--src/qml/jit/qv4assembler.cpp97
1 files changed, 83 insertions, 14 deletions
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp
index d2750c5404..d12553b423 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4assembler.cpp
@@ -730,10 +730,35 @@ struct PlatformAssembler64 : PlatformAssemblerCommon
isNumber.link(this);
}
+ void toInt32LhsAcc(Address lhs, RegisterID lhsTarget)
+ {
+ load64(lhs, lhsTarget);
+ urshift64(lhsTarget, TrustedImm32(Value::QuickType_Shift), ScratchRegister2);
+ auto lhsIsInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);
+
+ pushAligned(AccumulatorRegister);
+ move(lhsTarget, registerForArg(0));
+ callHelper(toInt32Helper);
+ move(ReturnValueRegister, lhsTarget);
+ popAligned(AccumulatorRegister);
+
+ lhsIsInt.link(this);
+ urshift64(AccumulatorRegister, TrustedImm32(Value::QuickType_Shift), ScratchRegister2);
+ auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);
+
+ pushAligned(lhsTarget);
+ move(AccumulatorRegister, registerForArg(0));
+ callHelper(toInt32Helper);
+ move(ReturnValueRegister, AccumulatorRegister);
+ popAligned(lhsTarget);
+
+ isInt.link(this);
+ }
+
void toInt32()
{
- urshift64(AccumulatorRegister, TrustedImm32(Value::QuickType_Shift), ScratchRegister);
- auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister);
+ urshift64(AccumulatorRegister, TrustedImm32(Value::QuickType_Shift), ScratchRegister2);
+ auto isInt = branch32(Equal, TrustedImm32(Value::QT_Int), ScratchRegister2);
move(AccumulatorRegister, registerForArg(0));
callRuntime("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper),
@@ -965,6 +990,59 @@ struct PlatformAssembler32 : PlatformAssemblerCommon
isNumber.link(this);
}
+ void toInt32LhsAcc(Address lhs, RegisterID lhsTarget)
+ {
+ bool accumulatorNeedsSaving = AccumulatorRegisterValue == ReturnValueRegisterValue
+ || AccumulatorRegisterTag == ReturnValueRegisterTag;
+ lhs.offset += 4;
+ load32(lhs, lhsTarget);
+ lhs.offset -= 4;
+ auto lhsIsNotInt = branch32(NotEqual, TrustedImm32(int(IntegerTag)), lhsTarget);
+ load32(lhs, lhsTarget);
+ auto lhsIsInt = jump();
+
+ lhsIsNotInt.link(this);
+ if (accumulatorNeedsSaving) {
+ push(AccumulatorRegisterTag);
+ push(AccumulatorRegisterValue);
+ }
+ if (ArgInRegCount < 2) {
+ push(lhsTarget);
+ load32(lhs, lhsTarget);
+ push(lhsTarget);
+ } else {
+ move(lhsTarget, registerForArg(1));
+ load32(lhs, registerForArg(0));
+ }
+ callHelper(toInt32Helper);
+ move(ReturnValueRegisterValue, lhsTarget);
+ if (ArgInRegCount < 2)
+ addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
+ if (accumulatorNeedsSaving) {
+ pop(AccumulatorRegisterValue);
+ pop(AccumulatorRegisterTag);
+ }
+ lhsIsInt.link(this);
+
+ auto rhsIsInt = branch32(Equal, TrustedImm32(int(IntegerTag)), AccumulatorRegisterTag);
+
+ pushAligned(lhsTarget);
+ if (ArgInRegCount < 2) {
+ push(AccumulatorRegisterTag);
+ push(AccumulatorRegisterValue);
+ } else {
+ move(AccumulatorRegisterValue, registerForArg(0));
+ move(AccumulatorRegisterTag, registerForArg(1));
+ }
+ callRuntime("toInt32Helper", reinterpret_cast<void *>(&toInt32Helper),
+ Assembler::ResultInAccumulator);
+ if (ArgInRegCount < 2)
+ addPtr(TrustedImm32(2 * PointerSize), StackPointerRegister);
+ popAligned(lhsTarget);
+
+ rhsIsInt.link(this);
+ }
+
void toInt32()
{
urshift32(AccumulatorRegisterTag, TrustedImm32(Value::QuickType_Shift - 32), ScratchRegister);
@@ -1476,10 +1554,7 @@ void Assembler::add(int lhs)
void Assembler::bitAnd(int lhs)
{
PlatformAssembler::Address lhsAddr = regAddr(lhs);
- pasm()->regToInt32(lhsAddr, PlatformAssembler::ScratchRegister);
- pasm()->pushAligned(PlatformAssembler::ScratchRegister);
- pasm()->toInt32();
- pasm()->popAligned(PlatformAssembler::ScratchRegister);
+ pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
pasm()->and32(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
pasm()->setAccumulatorTag(IntegerTag);
}
@@ -1487,10 +1562,7 @@ void Assembler::bitAnd(int lhs)
void Assembler::bitOr(int lhs)
{
PlatformAssembler::Address lhsAddr = regAddr(lhs);
- pasm()->regToInt32(lhsAddr, PlatformAssembler::ScratchRegister);
- pasm()->pushAligned(PlatformAssembler::ScratchRegister);
- pasm()->toInt32();
- pasm()->popAligned(PlatformAssembler::ScratchRegister);
+ pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
pasm()->or32(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
pasm()->setAccumulatorTag(IntegerTag);
}
@@ -1498,10 +1570,7 @@ void Assembler::bitOr(int lhs)
void Assembler::bitXor(int lhs)
{
PlatformAssembler::Address lhsAddr = regAddr(lhs);
- pasm()->regToInt32(lhsAddr, PlatformAssembler::ScratchRegister);
- pasm()->pushAligned(PlatformAssembler::ScratchRegister);
- pasm()->toInt32();
- pasm()->popAligned(PlatformAssembler::ScratchRegister);
+ pasm()->toInt32LhsAcc(lhsAddr, PlatformAssembler::ScratchRegister);
pasm()->xor32(PlatformAssembler::ScratchRegister, PlatformAssembler::AccumulatorRegisterValue);
pasm()->setAccumulatorTag(IntegerTag);
}