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
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);
&& 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;
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)
{
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);
}
} 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;
}