V4 JIT: generate code for int32 comparisons.
authorErik Verbruggen <erik.verbruggen@digia.com>
Tue, 22 Jul 2014 09:56:33 +0000 (11:56 +0200)
committerErik Verbruggen <erik.verbruggen@digia.com>
Tue, 12 Aug 2014 10:30:34 +0000 (12:30 +0200)
Change-Id: I5e88fb3df7b01f4f515ce4d2e451a5a6f5ba92ad
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
src/qml/jit/qv4assembler.cpp
src/qml/jit/qv4assembler_p.h
src/qml/jit/qv4isel_masm.cpp
src/qml/jit/qv4isel_masm_p.h
src/qml/jit/qv4regalloc.cpp

index 1e9669a..3f3fccb 100644 (file)
@@ -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
index 36611b9..9d2d6c5 100644 (file)
@@ -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);
index b91b5ea..f5d112c 100644 (file)
@@ -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)
 {
index 1f1e71a..f54b18d 100644 (file)
@@ -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);
index cccc07a..2192b8e 100644 (file)
@@ -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;
         }