aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@me.com>2013-09-09 15:36:09 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-20 12:42:33 +0200
commit857b135d77221769dadec54daa6540f431245c7a (patch)
treef9a2d434c20e4a484c2bcb1bb40d48831c3dd31e /src/qml/compiler
parentd33fe17cd1fddd8dee0a26dc46f5062c34f11216 (diff)
V4 JIT: generate inline code for more binops.
Bitwise-and, shift left, and shift-right. Change-Id: Ifa949c60261054218797302673822f480f47bd6e Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp45
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h2
-rw-r--r--src/qml/compiler/qv4regalloc.cpp8
3 files changed, 55 insertions, 0 deletions
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index c0245dd7fb..ec42e4078a 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -1322,6 +1322,11 @@ void InstructionSelection::binop(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR:
doubleBinop(oper, leftSource, rightSource, target);
return;
}
+ if (leftSource->type == V4IR::SInt32Type &&
+ (rightSource->type == V4IR::SInt32Type || rightSource->type == V4IR::UInt32Type)) {
+ if (int32Binop(oper, leftSource, rightSource, target))
+ return;
+ }
Assembler::Jump done = genInlineBinop(oper, leftSource, rightSource, target);
@@ -2142,3 +2147,43 @@ bool InstructionSelection::visitCJumpDouble(V4IR::AluOp op, V4IR::Expr *left, V4
_as->jumpToBlock(_block, iffalse);
return true;
}
+
+bool InstructionSelection::int32Binop(V4IR::AluOp oper, V4IR::Expr *leftSource,
+ V4IR::Expr *rightSource, V4IR::Temp *target)
+{
+ Q_ASSERT(leftSource->type == V4IR::SInt32Type);
+
+ switch (oper) {
+ 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;
+ case V4IR::OpLShift:
+ Q_ASSERT(rightSource->type == V4IR::UInt32Type);
+ _as->move(_as->toInt32Register(leftSource, Assembler::ReturnValueRegister),
+ Assembler::ReturnValueRegister);
+ _as->move(_as->toUInt32Register(rightSource, Assembler::ScratchRegister),
+ Assembler::ScratchRegister);
+ _as->and32(Assembler::TrustedImm32(0x1f), Assembler::ScratchRegister); // TODO: for constants, do this in the IR
+ _as->lshift32(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
+ _as->storeInt32(Assembler::ReturnValueRegister, target);
+ return true;
+ case V4IR::OpRShift:
+ Q_ASSERT(rightSource->type == V4IR::UInt32Type);
+ _as->move(_as->toInt32Register(leftSource, Assembler::ReturnValueRegister),
+ Assembler::ReturnValueRegister);
+ _as->move(_as->toUInt32Register(rightSource, Assembler::ScratchRegister),
+ Assembler::ScratchRegister);
+ _as->and32(Assembler::TrustedImm32(0x1f), Assembler::ScratchRegister); // TODO: for constants, do this in the IR
+ _as->rshift32(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
+ _as->storeInt32(Assembler::ReturnValueRegister, target);
+ return true;
+ default:
+ return false;
+ }
+}
diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h
index af9ca08a4b..f84177d371 100644
--- a/src/qml/compiler/qv4isel_masm_p.h
+++ b/src/qml/compiler/qv4isel_masm_p.h
@@ -1387,6 +1387,8 @@ protected:
Assembler::Jump branchDouble(V4IR::AluOp op, V4IR::Expr *left, V4IR::Expr *right);
bool visitCJumpDouble(V4IR::AluOp op, V4IR::Expr *left, V4IR::Expr *right,
V4IR::BasicBlock *iftrue, V4IR::BasicBlock *iffalse);
+ bool int32Binop(V4IR::AluOp oper, V4IR::Expr *leftSource, V4IR::Expr *rightSource,
+ V4IR::Temp *target);
private:
void convertTypeSlowPath(V4IR::Temp *source, V4IR::Temp *target);
diff --git a/src/qml/compiler/qv4regalloc.cpp b/src/qml/compiler/qv4regalloc.cpp
index 8a879aa40c..926526c5fd 100644
--- a/src/qml/compiler/qv4regalloc.cpp
+++ b/src/qml/compiler/qv4regalloc.cpp
@@ -426,6 +426,14 @@ protected: // IRDecoder
|| (oper >= OpGt && oper <= OpStrictNotEqual)) {
needsCall = false;
}
+ } else if (leftSource->type == SInt32Type && rightSource->type == SInt32Type) {
+ if (oper == OpBitAnd) {
+ needsCall = false;
+ }
+ } else if (leftSource->type == SInt32Type && rightSource->type == UInt32Type) {
+ if (oper == OpLShift || oper == OpRShift) {
+ needsCall = false;
+ }
}
#if 0 // TODO: change masm to generate code