aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@me.com>2013-10-08 10:48:57 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-10 09:54:31 +0200
commitccfa06e7566f1c113a3c5c31dab3c5aeb7a4985d (patch)
treedfb2973936638a3b55a6321992031a981734c3f4 /src/qml/compiler
parenta967a9bdcc2c75a0270c2be48d845ded5332e4f0 (diff)
V4 JIT: ISel for bitwise or/xor.
Removes another 4mln calls when running v8-bench.js. Change-Id: I7fd777e4e6303f989391c4d1e361277cc24b37e8 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp70
-rw-r--r--src/qml/compiler/qv4regalloc.cpp2
2 files changed, 63 insertions, 9 deletions
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index c92b865222..2665356436 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -2306,15 +2306,69 @@ bool InstructionSelection::int32Binop(V4IR::AluOp oper, V4IR::Expr *leftSource,
Q_ASSERT(leftSource->type == V4IR::SInt32Type);
switch (oper) {
- case V4IR::OpBitAnd:
+ case V4IR::OpBitAnd: {
Q_ASSERT(rightSource->type == V4IR::SInt32Type);
- _as->move(_as->toInt32Register(leftSource, Assembler::ReturnValueRegister),
- Assembler::ReturnValueRegister);
- _as->move(_as->toInt32Register(rightSource, Assembler::ScratchRegister),
- Assembler::ScratchRegister);
- _as->and32(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
- _as->storeInt32(Assembler::ReturnValueRegister, target);
- return true;
+ if (rightSource->asTemp() && rightSource->asTemp()->kind == V4IR::Temp::PhysicalRegister
+ && target->kind == V4IR::Temp::PhysicalRegister
+ && target->index == rightSource->asTemp()->index) {
+ _as->and32(_as->toInt32Register(leftSource, Assembler::ScratchRegister),
+ (Assembler::RegisterID) target->index);
+ return true;
+ }
+ Assembler::RegisterID targetReg;
+ if (target->kind == V4IR::Temp::PhysicalRegister)
+ targetReg = (Assembler::RegisterID) target->index;
+ else
+ targetReg = Assembler::ReturnValueRegister;
+
+ _as->move(_as->toInt32Register(leftSource, targetReg), targetReg);
+ Assembler::RegisterID rReg = _as->toInt32Register(rightSource, Assembler::ScratchRegister);
+ _as->and32(rReg, targetReg);
+ if (Assembler::ReturnValueRegister == targetReg)
+ _as->storeInt32(targetReg, target);
+ } return true;
+ case V4IR::OpBitOr: {
+ Q_ASSERT(rightSource->type == V4IR::SInt32Type);
+ if (rightSource->asTemp() && rightSource->asTemp()->kind == V4IR::Temp::PhysicalRegister
+ && target->kind == V4IR::Temp::PhysicalRegister
+ && target->index == rightSource->asTemp()->index) {
+ _as->or32(_as->toInt32Register(leftSource, Assembler::ScratchRegister),
+ (Assembler::RegisterID) target->index);
+ return true;
+ }
+ Assembler::RegisterID targetReg;
+ if (target->kind == V4IR::Temp::PhysicalRegister)
+ targetReg = (Assembler::RegisterID) target->index;
+ else
+ targetReg = Assembler::ReturnValueRegister;
+
+ _as->move(_as->toInt32Register(leftSource, targetReg), targetReg);
+ Assembler::RegisterID rReg = _as->toInt32Register(rightSource, Assembler::ScratchRegister);
+ _as->or32(rReg, targetReg);
+ if (Assembler::ReturnValueRegister == targetReg)
+ _as->storeInt32(targetReg, target);
+ } return true;
+ case V4IR::OpBitXor: {
+ Q_ASSERT(rightSource->type == V4IR::SInt32Type);
+ if (rightSource->asTemp() && rightSource->asTemp()->kind == V4IR::Temp::PhysicalRegister
+ && target->kind == V4IR::Temp::PhysicalRegister
+ && target->index == rightSource->asTemp()->index) {
+ _as->xor32(_as->toInt32Register(leftSource, Assembler::ScratchRegister),
+ (Assembler::RegisterID) target->index);
+ return true;
+ }
+ Assembler::RegisterID targetReg;
+ if (target->kind == V4IR::Temp::PhysicalRegister)
+ targetReg = (Assembler::RegisterID) target->index;
+ else
+ targetReg = Assembler::ReturnValueRegister;
+
+ _as->move(_as->toInt32Register(leftSource, targetReg), targetReg);
+ Assembler::RegisterID rReg = _as->toInt32Register(rightSource, Assembler::ScratchRegister);
+ _as->xor32(rReg, targetReg);
+ if (Assembler::ReturnValueRegister == targetReg)
+ _as->storeInt32(targetReg, target);
+ } return true;
case V4IR::OpLShift:
Q_ASSERT(rightSource->type == V4IR::UInt32Type);
_as->move(_as->toInt32Register(leftSource, Assembler::ReturnValueRegister),
diff --git a/src/qml/compiler/qv4regalloc.cpp b/src/qml/compiler/qv4regalloc.cpp
index c325ea6b71..210ae686c8 100644
--- a/src/qml/compiler/qv4regalloc.cpp
+++ b/src/qml/compiler/qv4regalloc.cpp
@@ -435,7 +435,7 @@ protected: // IRDecoder
needsCall = false;
}
} else if (leftSource->type == SInt32Type && rightSource->type == SInt32Type) {
- if (oper == OpBitAnd) {
+ if (oper == OpBitAnd || oper == OpBitOr || oper == OpBitXor) {
needsCall = false;
}
} else if (leftSource->type == SInt32Type && rightSource->type == UInt32Type) {