diff options
author | Erik Verbruggen <erik.verbruggen@me.com> | 2013-10-08 10:48:57 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-10-10 09:54:31 +0200 |
commit | ccfa06e7566f1c113a3c5c31dab3c5aeb7a4985d (patch) | |
tree | dfb2973936638a3b55a6321992031a981734c3f4 /src/qml/compiler | |
parent | a967a9bdcc2c75a0270c2be48d845ded5332e4f0 (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.cpp | 70 | ||||
-rw-r--r-- | src/qml/compiler/qv4regalloc.cpp | 2 |
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) { |