aboutsummaryrefslogtreecommitdiffstats
path: root/qv4isel_p.h
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2012-05-31 17:32:49 +0200
committerRoberto Raggi <roberto.raggi@nokia.com>2012-05-31 17:32:49 +0200
commitd65f9ddff1fd9c1aac037bb1163c6fbc7e9a637c (patch)
tree6d88cc36fd94b3db95d3a9fbc05ad0351b1fd82c /qv4isel_p.h
parent8ccb1e0e683b8c047a7ccfa068392873d72ca6c4 (diff)
Generalized instruction selection.
This will simplify the instruction selection pass for different architectures.
Diffstat (limited to 'qv4isel_p.h')
-rw-r--r--qv4isel_p.h401
1 files changed, 360 insertions, 41 deletions
diff --git a/qv4isel_p.h b/qv4isel_p.h
index d53d028c50..b12f71646a 100644
--- a/qv4isel_p.h
+++ b/qv4isel_p.h
@@ -1,54 +1,373 @@
-#ifndef QV4ISEL_P_H
-#define QV4ISEL_P_H
+#ifndef QV4ISEL_H
+#define QV4ISEL_H
#include "qv4ir_p.h"
-#include "qmljs_objects.h"
-
-#include <QtCore/QHash>
namespace QQmlJS {
-namespace x86_64 {
-class InstructionSelection: protected IR::StmtVisitor
+class BaseInstructionSelection: protected IR::StmtVisitor
{
+protected:
+ struct DispatchExp: IR::ExprVisitor {
+ BaseInstructionSelection *_isel;
+ IR::Exp *_stmt;
+
+ DispatchExp(BaseInstructionSelection *isel)
+ : _isel(isel), _stmt(0) {}
+
+ void operator()(IR::Exp *s)
+ {
+ qSwap(_stmt, s);
+ _stmt->expr->accept(this);
+ qSwap(_stmt, s);
+ }
+
+ virtual void visitConst(IR::Const *) { _isel->genExpConst(_stmt); }
+ virtual void visitString(IR::String *) { _isel->genExpString(_stmt); }
+ virtual void visitName(IR::Name *) { _isel->genExpName(_stmt); }
+ virtual void visitTemp(IR::Temp *) { _isel->genExpTemp(_stmt); }
+ virtual void visitClosure(IR::Closure *) { _isel->genExpClosure(_stmt); }
+ virtual void visitUnop(IR::Unop *) { _isel->genExpUnop(_stmt); }
+ virtual void visitBinop(IR::Binop *) { _isel->genExpBinop(_stmt); }
+ virtual void visitCall(IR::Call *) { _isel->genExpCall(_stmt); }
+ virtual void visitNew(IR::New *) { _isel->genExpNew(_stmt); }
+ virtual void visitSubscript(IR::Subscript *) { _isel->genExpSubscript(_stmt); }
+ virtual void visitMember(IR::Member *) { _isel->genExpMember(_stmt); }
+ };
+
+ struct DispatchRet: IR::ExprVisitor {
+ BaseInstructionSelection *_isel;
+ IR::Ret *_stmt;
+
+ DispatchRet(BaseInstructionSelection *isel)
+ : _isel(isel), _stmt(0) {}
+
+ void operator()(IR::Ret *s)
+ {
+ qSwap(_stmt, s);
+ _stmt->expr->accept(this);
+ qSwap(_stmt, s);
+ }
+
+ virtual void visitConst(IR::Const *) { _isel->genRetConst(_stmt); }
+ virtual void visitString(IR::String *) { _isel->genRetString(_stmt); }
+ virtual void visitName(IR::Name *) { _isel->genRetName(_stmt); }
+ virtual void visitTemp(IR::Temp *) { _isel->genRetTemp(_stmt); }
+ virtual void visitClosure(IR::Closure *) { _isel->genRetClosure(_stmt); }
+ virtual void visitUnop(IR::Unop *) { _isel->genRetUnop(_stmt); }
+ virtual void visitBinop(IR::Binop *) { _isel->genRetBinop(_stmt); }
+ virtual void visitCall(IR::Call *) { _isel->genRetCall(_stmt); }
+ virtual void visitNew(IR::New *) { _isel->genRetNew(_stmt); }
+ virtual void visitSubscript(IR::Subscript *) { _isel->genRetSubscript(_stmt); }
+ virtual void visitMember(IR::Member *) { _isel->genRetMember(_stmt); }
+ };
+
+ struct DispatchMove: IR::ExprVisitor {
+ BaseInstructionSelection *_isel;
+ IR::Move *_stmt;
+
+ DispatchMove(BaseInstructionSelection *isel)
+ : _isel(isel), _stmt(0) {}
+
+ void operator()(IR::Move *stmt)
+ {
+ qSwap(_stmt, stmt);
+ _stmt->target->accept(this);
+ qSwap(_stmt, stmt);
+ }
+
+ virtual void visitConst(IR::Const *) { Q_UNREACHABLE(); }
+ virtual void visitString(IR::String *) { Q_UNREACHABLE(); }
+ virtual void visitName(IR::Name *) { _isel->moveName(_stmt); }
+ virtual void visitTemp(IR::Temp *) { _isel->moveTemp(_stmt); }
+ virtual void visitClosure(IR::Closure *) { Q_UNREACHABLE(); }
+ virtual void visitUnop(IR::Unop *) { Q_UNREACHABLE(); }
+ virtual void visitBinop(IR::Binop *) { Q_UNREACHABLE(); }
+ virtual void visitCall(IR::Call *) { Q_UNREACHABLE(); }
+ virtual void visitNew(IR::New *) { Q_UNREACHABLE(); }
+ virtual void visitSubscript(IR::Subscript *) { _isel->moveSubscript(_stmt); }
+ virtual void visitMember(IR::Member *) { _isel->moveMember(_stmt); }
+ };
+
+ struct MoveTemp: IR::ExprVisitor {
+ BaseInstructionSelection *_isel;
+ IR::Move *_stmt;
+
+ MoveTemp(BaseInstructionSelection *isel)
+ : _isel(isel), _stmt(0) {}
+
+ void operator()(IR::Move *stmt)
+ {
+ qSwap(_stmt, stmt);
+ _stmt->source->accept(this);
+ qSwap(_stmt, stmt);
+ }
+
+ virtual void visitConst(IR::Const *) { _isel->genMoveTempConst(_stmt); }
+ virtual void visitString(IR::String *) { _isel->genMoveTempString(_stmt); }
+ virtual void visitName(IR::Name *) { _isel->genMoveTempName(_stmt); }
+ virtual void visitTemp(IR::Temp *) { _isel->genMoveTempTemp(_stmt); }
+ virtual void visitClosure(IR::Closure *) { _isel->genMoveTempClosure(_stmt); }
+ virtual void visitUnop(IR::Unop *) { _isel->genMoveTempUnop(_stmt); }
+ virtual void visitBinop(IR::Binop *) { _isel->genMoveTempBinop(_stmt); }
+ virtual void visitCall(IR::Call *) { _isel->genMoveTempCall(_stmt); }
+ virtual void visitNew(IR::New *) { _isel->genMoveTempNew(_stmt); }
+ virtual void visitSubscript(IR::Subscript *) { _isel->genMoveTempSubscript(_stmt); }
+ virtual void visitMember(IR::Member *) { _isel->genMoveTempMember(_stmt); }
+ };
+
+ struct MoveName: IR::ExprVisitor {
+ BaseInstructionSelection *_isel;
+ IR::Move *_stmt;
+
+ MoveName(BaseInstructionSelection *isel)
+ : _isel(isel), _stmt(0) {}
+
+ void operator()(IR::Move *stmt)
+ {
+ qSwap(_stmt, stmt);
+ _stmt->source->accept(this);
+ qSwap(_stmt, stmt);
+ }
+
+ virtual void visitConst(IR::Const *) { _isel->genMoveNameConst(_stmt); }
+ virtual void visitString(IR::String *) { _isel->genMoveNameString(_stmt); }
+ virtual void visitName(IR::Name *) { _isel->genMoveNameName(_stmt); }
+ virtual void visitTemp(IR::Temp *) { _isel->genMoveNameTemp(_stmt); }
+ virtual void visitClosure(IR::Closure *) { _isel->genMoveNameClosure(_stmt); }
+ virtual void visitUnop(IR::Unop *) { _isel->genMoveNameUnop(_stmt); }
+ virtual void visitBinop(IR::Binop *) { _isel->genMoveNameBinop(_stmt); }
+ virtual void visitCall(IR::Call *) { _isel->genMoveNameCall(_stmt); }
+ virtual void visitNew(IR::New *) { _isel->genMoveNameNew(_stmt); }
+ virtual void visitSubscript(IR::Subscript *) { _isel->genMoveNameSubscript(_stmt); }
+ virtual void visitMember(IR::Member *) { _isel->genMoveNameMember(_stmt); }
+ };
+
+ struct MoveMember: IR::ExprVisitor {
+ BaseInstructionSelection *_isel;
+ IR::Move *_stmt;
+
+ MoveMember(BaseInstructionSelection *isel)
+ : _isel(isel), _stmt(0) {}
+
+ void operator()(IR::Move *stmt)
+ {
+ qSwap(_stmt, stmt);
+ _stmt->source->accept(this);
+ qSwap(_stmt, stmt);
+ }
+
+ virtual void visitConst(IR::Const *) { _isel->genMoveMemberConst(_stmt); }
+ virtual void visitString(IR::String *) { _isel->genMoveMemberString(_stmt); }
+ virtual void visitName(IR::Name *) { _isel->genMoveMemberName(_stmt); }
+ virtual void visitTemp(IR::Temp *) { _isel->genMoveMemberTemp(_stmt); }
+ virtual void visitClosure(IR::Closure *) { _isel->genMoveMemberClosure(_stmt); }
+ virtual void visitUnop(IR::Unop *) { _isel->genMoveMemberUnop(_stmt); }
+ virtual void visitBinop(IR::Binop *) { _isel->genMoveMemberBinop(_stmt); }
+ virtual void visitCall(IR::Call *) { _isel->genMoveMemberCall(_stmt); }
+ virtual void visitNew(IR::New *) { _isel->genMoveMemberNew(_stmt); }
+ virtual void visitSubscript(IR::Subscript *) { _isel->genMoveMemberSubscript(_stmt); }
+ virtual void visitMember(IR::Member *) { _isel->genMoveMemberMember(_stmt); }
+ };
+
+ struct MoveSubscript: IR::ExprVisitor {
+ BaseInstructionSelection *_isel;
+ IR::Move *_stmt;
+
+ MoveSubscript(BaseInstructionSelection *isel)
+ : _isel(isel), _stmt(0) {}
+
+ void operator()(IR::Move *stmt)
+ {
+ qSwap(_stmt, stmt);
+ _stmt->source->accept(this);
+ qSwap(_stmt, stmt);
+ }
+
+ virtual void visitConst(IR::Const *) { _isel->genMoveSubscriptConst(_stmt); }
+ virtual void visitString(IR::String *) { _isel->genMoveSubscriptString(_stmt); }
+ virtual void visitName(IR::Name *) { _isel->genMoveSubscriptName(_stmt); }
+ virtual void visitTemp(IR::Temp *) { _isel->genMoveSubscriptTemp(_stmt); }
+ virtual void visitClosure(IR::Closure *) { _isel->genMoveSubscriptClosure(_stmt); }
+ virtual void visitUnop(IR::Unop *) { _isel->genMoveSubscriptUnop(_stmt); }
+ virtual void visitBinop(IR::Binop *) { _isel->genMoveSubscriptBinop(_stmt); }
+ virtual void visitCall(IR::Call *) { _isel->genMoveSubscriptCall(_stmt); }
+ virtual void visitNew(IR::New *) { _isel->genMoveSubscriptNew(_stmt); }
+ virtual void visitSubscript(IR::Subscript *) { _isel->genMoveSubscriptSubscript(_stmt); }
+ virtual void visitMember(IR::Member *) { _isel->genMoveSubscriptMember(_stmt); }
+ };
+
+ struct DispatchCJump: IR::ExprVisitor {
+ BaseInstructionSelection *_isel;
+ IR::CJump *_stmt;
+
+ DispatchCJump(BaseInstructionSelection *isel)
+ : _isel(isel), _stmt(0) {}
+
+ void operator()(IR::CJump *s)
+ {
+ qSwap(_stmt, s);
+ _stmt->cond->accept(this);
+ qSwap(_stmt, s);
+ }
+
+ virtual void visitConst(IR::Const *) { _isel->genCJumpConst(_stmt); }
+ virtual void visitString(IR::String *) { _isel->genCJumpString(_stmt); }
+ virtual void visitName(IR::Name *) { _isel->genCJumpName(_stmt); }
+ virtual void visitTemp(IR::Temp *) { _isel->genCJumpTemp(_stmt); }
+ virtual void visitClosure(IR::Closure *) { _isel->genCJumpClosure(_stmt); }
+ virtual void visitUnop(IR::Unop *) { _isel->genCJumpUnop(_stmt); }
+ virtual void visitBinop(IR::Binop *) { _isel->genCJumpBinop(_stmt); }
+ virtual void visitCall(IR::Call *) { _isel->genCJumpCall(_stmt); }
+ virtual void visitNew(IR::New *) { _isel->genCJumpNew(_stmt); }
+ virtual void visitSubscript(IR::Subscript *) { _isel->genCJumpSubscript(_stmt); }
+ virtual void visitMember(IR::Member *) { _isel->genCJumpMember(_stmt); }
+ };
+
+ virtual void visitExp(IR::Exp *s)
+ {
+ dispatchExp(s);
+ }
+
+ virtual void visitEnter(IR::Enter *)
+ {
+ Q_UNREACHABLE();
+ }
+
+ virtual void visitLeave(IR::Leave *)
+ {
+ Q_UNREACHABLE();
+ }
+
+ virtual void visitMove(IR::Move *s)
+ {
+ dispatchMove(s);
+ }
+
+ virtual void visitJump(IR::Jump *s)
+ {
+ genJump(s);
+ }
+
+ virtual void visitCJump(IR::CJump *s)
+ {
+ dispatchCJump(s);
+ }
+
+ virtual void visitRet(IR::Ret *s)
+ {
+ dispatchRet(s);
+ }
+
+ DispatchExp dispatchExp;
+ DispatchRet dispatchRet;
+ DispatchCJump dispatchCJump;
+ DispatchMove dispatchMove;
+ MoveTemp moveTemp;
+ MoveName moveName;
+ MoveMember moveMember;
+ MoveSubscript moveSubscript;
+
public:
- InstructionSelection(VM::ExecutionEngine *engine, IR::Module *module, uchar *code);
- ~InstructionSelection();
+ BaseInstructionSelection()
+ : dispatchExp(this)
+ , dispatchRet(this)
+ , dispatchCJump(this)
+ , dispatchMove(this)
+ , moveTemp(this)
+ , moveName(this)
+ , moveMember(this)
+ , moveSubscript(this) {}
- void operator()(IR::Function *function);
+ void statement(IR::Stmt *s) { s->accept(this); }
-protected:
- VM::String *identifier(const QString &s);
- void loadTempAddress(int reg, IR::Temp *t);
- void callActivationProperty(IR::Call *call, IR::Temp *result);
- void callProperty(IR::Call *call, IR::Temp *result);
- void constructActivationProperty(IR::New *call, IR::Temp *result);
- void constructProperty(IR::New *ctor, IR::Temp *result);
- void callValue(IR::Call *call, IR::Temp *result);
- void constructValue(IR::New *call, IR::Temp *result);
- void checkExceptions();
-
- virtual void visitExp(IR::Exp *);
- virtual void visitEnter(IR::Enter *);
- virtual void visitLeave(IR::Leave *);
- virtual void visitMove(IR::Move *);
- virtual void visitJump(IR::Jump *);
- virtual void visitCJump(IR::CJump *);
- virtual void visitRet(IR::Ret *);
-
-private:
- VM::ExecutionEngine *_engine;
- IR::Module *_module;
- IR::Function *_function;
- IR::BasicBlock *_block;
- uchar *_buffer;
- uchar *_code;
- uchar *_codePtr;
- QHash<IR::BasicBlock *, QVector<uchar *> > _patches;
- QHash<IR::BasicBlock *, uchar *> _addrs;
+ virtual void genExpConst(IR::Exp *) { Q_UNIMPLEMENTED(); }
+ virtual void genExpString(IR::Exp *) { Q_UNIMPLEMENTED(); }
+ virtual void genExpName(IR::Exp *) { Q_UNIMPLEMENTED(); }
+ virtual void genExpTemp(IR::Exp *) { Q_UNIMPLEMENTED(); }
+ virtual void genExpClosure(IR::Exp *) { Q_UNIMPLEMENTED(); }
+ virtual void genExpUnop(IR::Exp *) { Q_UNIMPLEMENTED(); }
+ virtual void genExpBinop(IR::Exp *) { Q_UNIMPLEMENTED(); }
+ virtual void genExpCall(IR::Exp *) { Q_UNIMPLEMENTED(); }
+ virtual void genExpNew(IR::Exp *) { Q_UNIMPLEMENTED(); }
+ virtual void genExpSubscript(IR::Exp *) { Q_UNIMPLEMENTED(); }
+ virtual void genExpMember(IR::Exp *) { Q_UNIMPLEMENTED(); }
+
+ virtual void genMoveTempConst(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveTempString(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveTempName(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveTempTemp(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveTempClosure(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveTempUnop(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveTempBinop(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveTempCall(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveTempNew(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveTempSubscript(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveTempMember(IR::Move *) { Q_UNIMPLEMENTED(); }
+
+ virtual void genMoveNameConst(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveNameString(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveNameName(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveNameTemp(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveNameClosure(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveNameUnop(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveNameBinop(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveNameCall(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveNameNew(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveNameSubscript(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveNameMember(IR::Move *) { Q_UNIMPLEMENTED(); }
+
+ virtual void genMoveMemberConst(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveMemberString(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveMemberName(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveMemberTemp(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveMemberClosure(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveMemberUnop(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveMemberBinop(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveMemberCall(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveMemberNew(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveMemberSubscript(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveMemberMember(IR::Move *) { Q_UNIMPLEMENTED(); }
+
+ virtual void genMoveSubscriptConst(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveSubscriptString(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveSubscriptName(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveSubscriptTemp(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveSubscriptClosure(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveSubscriptUnop(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveSubscriptBinop(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveSubscriptCall(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveSubscriptNew(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveSubscriptSubscript(IR::Move *) { Q_UNIMPLEMENTED(); }
+ virtual void genMoveSubscriptMember(IR::Move *) { Q_UNIMPLEMENTED(); }
+
+ virtual void genJump(IR::Jump *) { Q_UNIMPLEMENTED(); }
+
+ virtual void genCJumpConst(IR::CJump *) { Q_UNIMPLEMENTED(); }
+ virtual void genCJumpString(IR::CJump *) { Q_UNIMPLEMENTED(); }
+ virtual void genCJumpName(IR::CJump *) { Q_UNIMPLEMENTED(); }
+ virtual void genCJumpTemp(IR::CJump *) { Q_UNIMPLEMENTED(); }
+ virtual void genCJumpClosure(IR::CJump *) { Q_UNIMPLEMENTED(); }
+ virtual void genCJumpUnop(IR::CJump *) { Q_UNIMPLEMENTED(); }
+ virtual void genCJumpBinop(IR::CJump *) { Q_UNIMPLEMENTED(); }
+ virtual void genCJumpCall(IR::CJump *) { Q_UNIMPLEMENTED(); }
+ virtual void genCJumpNew(IR::CJump *) { Q_UNIMPLEMENTED(); }
+ virtual void genCJumpSubscript(IR::CJump *) { Q_UNIMPLEMENTED(); }
+ virtual void genCJumpMember(IR::CJump *) { Q_UNIMPLEMENTED(); }
+
+ virtual void genRetConst(IR::Ret *) { Q_UNIMPLEMENTED(); }
+ virtual void genRetString(IR::Ret *) { Q_UNIMPLEMENTED(); }
+ virtual void genRetName(IR::Ret *) { Q_UNIMPLEMENTED(); }
+ virtual void genRetTemp(IR::Ret *) { Q_UNIMPLEMENTED(); }
+ virtual void genRetClosure(IR::Ret *) { Q_UNIMPLEMENTED(); }
+ virtual void genRetUnop(IR::Ret *) { Q_UNIMPLEMENTED(); }
+ virtual void genRetBinop(IR::Ret *) { Q_UNIMPLEMENTED(); }
+ virtual void genRetCall(IR::Ret *) { Q_UNIMPLEMENTED(); }
+ virtual void genRetNew(IR::Ret *) { Q_UNIMPLEMENTED(); }
+ virtual void genRetSubscript(IR::Ret *) { Q_UNIMPLEMENTED(); }
+ virtual void genRetMember(IR::Ret *) { Q_UNIMPLEMENTED(); }
};
-} // end of namespace x86_64
} // end of namespace QQmlJS
-#endif // QV4ISEL_P_H
+#endif // QV4ISEL_H