diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-08-06 09:59:25 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-08-08 18:58:58 +0000 |
commit | d24da7f9497834f982e5cd6e29ff53b73fbac1a3 (patch) | |
tree | 26bedbd08aad19f36b756418e8b98fe319062074 /src | |
parent | 4d8aaeddfb81f8f97eaccd4e8d18c17f82c0f596 (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.cpp | 37 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth.cpp | 16 | ||||
-rw-r--r-- | src/qml/compiler/qv4instr_moth_p.h | 32 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 60 |
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; |