aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-08-06 09:59:25 +0200
committerLars Knoll <lars.knoll@qt.io>2017-08-08 18:58:58 +0000
commitd24da7f9497834f982e5cd6e29ff53b73fbac1a3 (patch)
tree26bedbd08aad19f36b756418e8b98fe319062074 /src
parent4d8aaeddfb81f8f97eaccd4e8d18c17f82c0f596 (diff)
Add instructions for <, <=, >, >=
Change-Id: Ibdd784507083da4c2cdc49208e842cc2e9c40da5 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/compiler/qv4codegen.cpp37
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp16
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h32
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp60
4 files changed, 144 insertions, 1 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 38a8678f0f..1ad7e59203 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -952,6 +952,10 @@ Codegen::Reference Codegen::binopHelper(QSOperator::Op oper, Reference &left, Re
}
case QSOperator::Equal:
case QSOperator::NotEqual:
+ case QSOperator::Gt:
+ case QSOperator::Ge:
+ case QSOperator::Lt:
+ case QSOperator::Le:
if (_expr.accept(cx))
return jumpBinop(oper, left, right);
// else: fallthrough
@@ -976,6 +980,10 @@ static QSOperator::Op invert(QSOperator::Op oper)
switch (oper) {
case QSOperator::Equal: return QSOperator::NotEqual;
case QSOperator::NotEqual: return QSOperator::Equal;
+ case QSOperator::Gt: return QSOperator::Le;
+ case QSOperator::Ge: return QSOperator::Lt;
+ case QSOperator::Lt: return QSOperator::Ge;
+ case QSOperator::Le: return QSOperator::Gt;
default: Q_UNIMPLEMENTED(); return QSOperator::Invalid;
}
}
@@ -987,7 +995,6 @@ Codegen::Reference Codegen::jumpBinop(QSOperator::Op oper, Reference &left, Refe
const BytecodeGenerator::Label *jumpTarget = _expr.iftrue();
if (_expr.trueBlockFollowsCondition()) {
oper = invert(oper);
- std::swap(left, right);
jumpTarget = _expr.iffalse();
}
@@ -1006,6 +1013,34 @@ Codegen::Reference Codegen::jumpBinop(QSOperator::Op oper, Reference &left, Refe
bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
break;
}
+ case QSOperator::Gt: {
+ Instruction::CmpJmpGt cjump;
+ cjump.lhs = left.stackSlot();
+ cjump.rhs = right.stackSlot();
+ bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ break;
+ }
+ case QSOperator::Ge: {
+ Instruction::CmpJmpGe cjump;
+ cjump.lhs = left.stackSlot();
+ cjump.rhs = right.stackSlot();
+ bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ break;
+ }
+ case QSOperator::Lt: {
+ Instruction::CmpJmpLt cjump;
+ cjump.lhs = left.stackSlot();
+ cjump.rhs = right.stackSlot();
+ bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ break;
+ }
+ case QSOperator::Le: {
+ Instruction::CmpJmpLe cjump;
+ cjump.lhs = left.stackSlot();
+ cjump.rhs = right.stackSlot();
+ bytecodeGenerator->addJumpInstruction(cjump).link(*jumpTarget);
+ break;
+ }
default: Q_UNIMPLEMENTED(); Q_UNREACHABLE();
}
return Reference();
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index dc89436a02..119b6d9960 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -380,6 +380,22 @@ void dumpBytecode(const char *code, int len, int nFormals)
d << instr.lhs.dump(nFormals) << ", " << instr.rhs.dump(nFormals) << ", " << absoluteInstructionOffset(start, instr);
MOTH_END_INSTR(CmpJmpNe)
+ MOTH_BEGIN_INSTR(CmpJmpGt)
+ d << instr.lhs.dump(nFormals) << ", " << instr.rhs.dump(nFormals) << ", " << absoluteInstructionOffset(start, instr);
+ MOTH_END_INSTR(CmpJmpGt)
+
+ MOTH_BEGIN_INSTR(CmpJmpGe)
+ d << instr.lhs.dump(nFormals) << ", " << instr.rhs.dump(nFormals) << ", " << absoluteInstructionOffset(start, instr);
+ MOTH_END_INSTR(CmpJmpGe)
+
+ MOTH_BEGIN_INSTR(CmpJmpLt)
+ d << instr.lhs.dump(nFormals) << ", " << instr.rhs.dump(nFormals) << ", " << absoluteInstructionOffset(start, instr);
+ MOTH_END_INSTR(CmpJmpLt)
+
+ MOTH_BEGIN_INSTR(CmpJmpLe)
+ d << instr.lhs.dump(nFormals) << ", " << instr.rhs.dump(nFormals) << ", " << absoluteInstructionOffset(start, instr);
+ MOTH_END_INSTR(CmpJmpLe)
+
MOTH_BEGIN_INSTR(JumpStrictEqual)
d << instr.lhs.dump(nFormals) << " " << absoluteInstructionOffset(start, instr);
MOTH_END_INSTR(JumpStrictEqual)
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 5c2efd2c37..24a840efba 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -138,6 +138,10 @@ QT_BEGIN_NAMESPACE
F(JumpNe, jumpNe) \
F(CmpJmpEq, cmpJmpEq) \
F(CmpJmpNe, cmpJmpNe) \
+ F(CmpJmpGt, cmpJmpGt) \
+ F(CmpJmpGe, cmpJmpGe) \
+ F(CmpJmpLt, cmpJmpLt) \
+ F(CmpJmpLe, cmpJmpLe) \
F(JumpStrictEqual, jumpStrictEqual) \
F(JumpStrictNotEqual, jumpStrictNotEqual) \
F(UNot, unot) \
@@ -564,6 +568,30 @@ union Instr
StackSlot rhs;
ptrdiff_t offset;
};
+ struct instr_cmpJmpGt {
+ MOTH_INSTR_HEADER
+ StackSlot lhs;
+ StackSlot rhs;
+ ptrdiff_t offset;
+ };
+ struct instr_cmpJmpGe {
+ MOTH_INSTR_HEADER
+ StackSlot lhs;
+ StackSlot rhs;
+ ptrdiff_t offset;
+ };
+ struct instr_cmpJmpLt {
+ MOTH_INSTR_HEADER
+ StackSlot lhs;
+ StackSlot rhs;
+ ptrdiff_t offset;
+ };
+ struct instr_cmpJmpLe {
+ MOTH_INSTR_HEADER
+ StackSlot lhs;
+ StackSlot rhs;
+ ptrdiff_t offset;
+ };
struct instr_jumpStrictEqual {
MOTH_INSTR_HEADER
ptrdiff_t offset;
@@ -741,6 +769,10 @@ union Instr
instr_jumpNe jumpNe;
instr_cmpJmpEq cmpJmpEq;
instr_cmpJmpNe cmpJmpNe;
+ instr_cmpJmpGt cmpJmpGt;
+ instr_cmpJmpGe cmpJmpGe;
+ instr_cmpJmpLt cmpJmpLt;
+ instr_cmpJmpLe cmpJmpLe;
instr_jumpStrictEqual jumpStrictEqual;
instr_jumpStrictNotEqual jumpStrictNotEqual;
instr_unot unot;
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 847e4e39c7..e75b8e6911 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -815,6 +815,66 @@ QV4::ReturnedValue VME::exec(Function *function)
}
MOTH_END_INSTR(CmpJmpNe)
+ MOTH_BEGIN_INSTR(CmpJmpGt)
+ const Value lhs = STACK_VALUE(instr.lhs);
+ const Value rhs = STACK_VALUE(instr.rhs);
+ if (Q_LIKELY(lhs.isInteger() && rhs.isInteger())) {
+ if (lhs.int_32() > rhs.int_32())
+ code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
+ } if (lhs.isNumber() && rhs.isNumber()) {
+ if (lhs.asDouble() > rhs.asDouble())
+ code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
+ } else {
+ if (Runtime::method_compareGreaterThan(lhs, rhs))
+ code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
+ }
+ MOTH_END_INSTR(CmpJmpGt)
+
+ MOTH_BEGIN_INSTR(CmpJmpGe)
+ const Value lhs = STACK_VALUE(instr.lhs);
+ const Value rhs = STACK_VALUE(instr.rhs);
+ if (Q_LIKELY(lhs.isInteger() && rhs.isInteger())) {
+ if (lhs.int_32() >= rhs.int_32())
+ code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
+ } if (lhs.isNumber() && rhs.isNumber()) {
+ if (lhs.asDouble() >= rhs.asDouble())
+ code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
+ } else {
+ if (Runtime::method_compareGreaterEqual(lhs, rhs))
+ code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
+ }
+ MOTH_END_INSTR(CmpJmpGe)
+
+ MOTH_BEGIN_INSTR(CmpJmpLt)
+ const Value lhs = STACK_VALUE(instr.lhs);
+ const Value rhs = STACK_VALUE(instr.rhs);
+ if (Q_LIKELY(lhs.isInteger() && rhs.isInteger())) {
+ if (lhs.int_32() < rhs.int_32())
+ code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
+ } if (lhs.isNumber() && rhs.isNumber()) {
+ if (lhs.asDouble() < rhs.asDouble())
+ code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
+ } else {
+ if (Runtime::method_compareLessThan(lhs, rhs))
+ code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
+ }
+ MOTH_END_INSTR(CmpJmpLt)
+
+ MOTH_BEGIN_INSTR(CmpJmpLe)
+ const Value lhs = STACK_VALUE(instr.lhs);
+ const Value rhs = STACK_VALUE(instr.rhs);
+ if (Q_LIKELY(lhs.isInteger() && rhs.isInteger())) {
+ if (lhs.int_32() <= rhs.int_32())
+ code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
+ } if (lhs.isNumber() && rhs.isNumber()) {
+ if (lhs.asDouble() <= rhs.asDouble())
+ code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
+ } else {
+ if (Runtime::method_compareLessEqual(lhs, rhs))
+ code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;
+ }
+ MOTH_END_INSTR(CmpJmpLe)
+
MOTH_BEGIN_INSTR(JumpStrictEqual)
if (RuntimeHelpers::strictEqual(STACK_VALUE(instr.lhs), accumulator))
code = reinterpret_cast<const uchar *>(&instr.offset) + instr.offset;