diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2014-07-22 11:56:33 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@digia.com> | 2014-08-12 12:30:34 +0200 |
commit | 4ad1b63f257ac033e3876130f39eba3325363de5 (patch) | |
tree | e617b30d8afa3ae0f132396fb70857e22cc6121f /src/qml | |
parent | f87d2a40ef2f20a11ed1353ed59ef8ced2cecb00 (diff) |
V4 JIT: generate code for int32 comparisons.
Change-Id: I5e88fb3df7b01f4f515ce4d2e451a5a6f5ba92ad
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/jit/qv4assembler.cpp | 22 | ||||
-rw-r--r-- | src/qml/jit/qv4assembler_p.h | 1 | ||||
-rw-r--r-- | src/qml/jit/qv4isel_masm.cpp | 21 | ||||
-rw-r--r-- | src/qml/jit/qv4isel_masm_p.h | 2 | ||||
-rw-r--r-- | src/qml/jit/qv4regalloc.cpp | 7 |
5 files changed, 48 insertions, 5 deletions
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp index 1e9669acd5..3f3fccb39d 100644 --- a/src/qml/jit/qv4assembler.cpp +++ b/src/qml/jit/qv4assembler.cpp @@ -365,5 +365,27 @@ Assembler::Jump Assembler::branchDouble(bool invertCondition, IR::AluOp op, return JSC::MacroAssembler::branchDouble(cond, toDoubleRegister(left, FPGpr0), toDoubleRegister(right, FPGpr1)); } +Assembler::Jump Assembler::branchInt32(bool invertCondition, IR::AluOp op, IR::Expr *left, IR::Expr *right) +{ + Assembler::RelationalCondition cond; + switch (op) { + case IR::OpGt: cond = Assembler::GreaterThan; break; + case IR::OpLt: cond = Assembler::LessThan; break; + case IR::OpGe: cond = Assembler::GreaterThanOrEqual; break; + case IR::OpLe: cond = Assembler::LessThanOrEqual; break; + case IR::OpEqual: + case IR::OpStrictEqual: cond = Assembler::Equal; break; + case IR::OpNotEqual: + case IR::OpStrictNotEqual: cond = Assembler::NotEqual; break; + default: + Q_UNREACHABLE(); + } + if (invertCondition) + cond = JSC::MacroAssembler::invert(cond); + + return JSC::MacroAssembler::branch32(cond, + toInt32Register(left, Assembler::ScratchRegister), + toInt32Register(right, Assembler::ReturnValueRegister)); +} #endif diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h index 36611b9064..9d2d6c5ca0 100644 --- a/src/qml/jit/qv4assembler_p.h +++ b/src/qml/jit/qv4assembler_p.h @@ -374,6 +374,7 @@ public: IR::BasicBlock *falseBlock); Jump genTryDoubleConversion(IR::Expr *src, Assembler::FPRegisterID dest); Assembler::Jump branchDouble(bool invertCondition, IR::AluOp op, IR::Expr *left, IR::Expr *right); + Assembler::Jump branchInt32(bool invertCondition, IR::AluOp op, IR::Expr *left, IR::Expr *right); Pointer loadAddress(RegisterID tmp, IR::Expr *t); Pointer loadTempAddress(IR::Temp *t); diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index b91b5eabc0..f5d112c072 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -1304,6 +1304,10 @@ void InstructionSelection::visitCJump(IR::CJump *s) && visitCJumpDouble(b->op, b->left, b->right, s->iftrue, s->iffalse)) return; + if (b->left->type == IR::SInt32Type && b->right->type == IR::SInt32Type + && visitCJumpSInt32(b->op, b->left, b->right, s->iftrue, s->iffalse)) + return; + if (b->op == IR::OpStrictEqual || b->op == IR::OpStrictNotEqual) { visitCJumpStrict(b, s->iftrue, s->iffalse); return; @@ -1580,6 +1584,23 @@ bool InstructionSelection::visitCJumpDouble(IR::AluOp op, IR::Expr *left, IR::Ex return true; } +bool InstructionSelection::visitCJumpSInt32(IR::AluOp op, IR::Expr *left, IR::Expr *right, + IR::BasicBlock *iftrue, IR::BasicBlock *iffalse) +{ + if (!isPregOrConst(left) || !isPregOrConst(right)) + return false; + + if (_as->nextBlock() == iftrue) { + Assembler::Jump target = _as->branchInt32(true, op, left, right); + _as->addPatch(iffalse, target); + } else { + Assembler::Jump target = _as->branchInt32(false, op, left, right); + _as->addPatch(iftrue, target); + _as->jumpToBlock(_block, iffalse); + } + return true; +} + void InstructionSelection::visitCJumpStrict(IR::Binop *binop, IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock) { diff --git a/src/qml/jit/qv4isel_masm_p.h b/src/qml/jit/qv4isel_masm_p.h index 1f1e71a284..f54b18d494 100644 --- a/src/qml/jit/qv4isel_masm_p.h +++ b/src/qml/jit/qv4isel_masm_p.h @@ -158,6 +158,8 @@ protected: bool visitCJumpDouble(IR::AluOp op, IR::Expr *left, IR::Expr *right, IR::BasicBlock *iftrue, IR::BasicBlock *iffalse); + bool visitCJumpSInt32(IR::AluOp op, IR::Expr *left, IR::Expr *right, + IR::BasicBlock *iftrue, IR::BasicBlock *iffalse); void visitCJumpStrict(IR::Binop *binop, IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock); bool visitCJumpStrictNullUndefined(IR::Type nullOrUndef, IR::Binop *binop, IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock); diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp index cccc07adde..2192b8e60b 100644 --- a/src/qml/jit/qv4regalloc.cpp +++ b/src/qml/jit/qv4regalloc.cpp @@ -631,11 +631,8 @@ protected: // IRDecoder } } else if (oper == OpBitAnd || oper == OpBitOr || oper == OpBitXor || oper == OpLShift || oper == OpRShift || oper == OpURShift) { needsCall = false; - } else if (oper == OpAdd - || oper == OpMul - || - oper == OpSub - ) { + } else if (oper == OpAdd || oper == OpMul || oper == OpSub + || (oper >= OpGt && oper <= OpStrictNotEqual)) { if (leftSource->type == SInt32Type && rightSource->type == SInt32Type) needsCall = false; } |