aboutsummaryrefslogtreecommitdiffstats
path: root/moth
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2012-06-11 17:58:52 +0100
committerAaron Kennedy <aaron.kennedy@nokia.com>2012-06-11 17:59:36 +0100
commitb759b5f984d35d5ce95097572bd8524cfd2210fc (patch)
treeea387fcd25d2ba41b6635987742ca67ee6b2f59d /moth
parent2ebc4b30b2cefccbad0c27ba1f38d8e600533bb0 (diff)
Add skeleton moth vme
Diffstat (limited to 'moth')
-rw-r--r--moth/moth.pri2
-rw-r--r--moth/qv4instr_moth_p.h7
-rw-r--r--moth/qv4isel_moth.cpp36
-rw-r--r--moth/qv4isel_moth_p.h24
-rw-r--r--moth/qv4vme_moth.cpp100
-rw-r--r--moth/qv4vme_moth_p.h27
6 files changed, 186 insertions, 10 deletions
diff --git a/moth/moth.pri b/moth/moth.pri
index 859c4bf8f4..d91d13fca8 100644
--- a/moth/moth.pri
+++ b/moth/moth.pri
@@ -3,8 +3,10 @@ INCLUDEPATH += $$PWD
HEADERS += \
$$PWD/qv4isel_moth_p.h \
$$PWD/qv4instr_moth_p.h \
+ $$PWD/qv4vme_moth_p.h \
SOURCES += \
$$PWD/qv4isel_moth.cpp \
$$PWD/qv4instr_moth.cpp \
+ $$PWD/qv4vme_moth.cpp \
diff --git a/moth/qv4instr_moth_p.h b/moth/qv4instr_moth_p.h
index 6e95fc0a07..e582bb4ab6 100644
--- a/moth/qv4instr_moth_p.h
+++ b/moth/qv4instr_moth_p.h
@@ -4,7 +4,8 @@
#include <QtCore/qglobal.h>
#define FOR_EACH_MOTH_INSTR(F) \
- F(Nop, nop) \
+ F(Nop, common) \
+ F(Done, common) \
#if defined(Q_CC_GNU) && (!defined(Q_CC_INTEL) || __INTEL_COMPILER >= 1200)
# define MOTH_THREADED_INTERPRETER
@@ -31,11 +32,11 @@ union Instr
FOR_EACH_MOTH_INSTR(MOTH_INSTR_ENUM)
};
- struct instr_nop {
+ struct instr_common {
MOTH_INSTR_HEADER
};
- instr_nop nop;
+ instr_common common;
static int size(Type type);
};
diff --git a/moth/qv4isel_moth.cpp b/moth/qv4isel_moth.cpp
index b37d0c7e7d..628e2f0a91 100644
--- a/moth/qv4isel_moth.cpp
+++ b/moth/qv4isel_moth.cpp
@@ -1,10 +1,12 @@
#include "qv4isel_moth_p.h"
+#include "qv4vme_moth_p.h"
using namespace QQmlJS;
using namespace QQmlJS::Moth;
InstructionSelection::InstructionSelection(VM::ExecutionEngine *engine, IR::Module *module,
uchar *code)
+: _code(code), _ccode(code)
{
}
@@ -21,41 +23,61 @@ void InstructionSelection::operator()(IR::Function *function)
s->accept(this);
}
+ addInstruction(Instruction::Done());
+
qSwap(_function, function);
}
void InstructionSelection::visitExp(IR::Exp *)
{
- qWarning(__PRETTY_FUNCTION__);
+ qWarning("%s", __PRETTY_FUNCTION__);
}
void InstructionSelection::visitEnter(IR::Enter *)
{
- qWarning(__PRETTY_FUNCTION__);
+ qWarning("%s", __PRETTY_FUNCTION__);
}
void InstructionSelection::visitLeave(IR::Leave *)
{
- qWarning(__PRETTY_FUNCTION__);
+ qWarning("%s", __PRETTY_FUNCTION__);
}
void InstructionSelection::visitMove(IR::Move *)
{
- qWarning(__PRETTY_FUNCTION__);
+ qWarning("%s", __PRETTY_FUNCTION__);
}
void InstructionSelection::visitJump(IR::Jump *)
{
- qWarning(__PRETTY_FUNCTION__);
+ qWarning("%s", __PRETTY_FUNCTION__);
}
void InstructionSelection::visitCJump(IR::CJump *)
{
- qWarning(__PRETTY_FUNCTION__);
+ qWarning("%s", __PRETTY_FUNCTION__);
}
void InstructionSelection::visitRet(IR::Ret *)
{
- qWarning(__PRETTY_FUNCTION__);
+ qWarning("%s", __PRETTY_FUNCTION__);
+}
+
+int InstructionSelection::addInstructionHelper(Instr::Type type, Instr &instr)
+{
+#ifdef MOTH_THREADED_INTERPRETER
+ instr.common.code = VME::instructionJumpTable()[static_cast<int>(type)];
+#else
+ instr.common.instructionType = type;
+#endif
+
+ // XXX - int is wrong size for both of these
+ int ptrOffset = (int)(_ccode - _code);
+ int size = Instr::size(type);
+
+ ::memcpy(_ccode, reinterpret_cast<const char *>(&instr), size);
+ _ccode += size;
+
+ return ptrOffset;
}
diff --git a/moth/qv4isel_moth_p.h b/moth/qv4isel_moth_p.h
index 2d08f457bd..d8e56cac70 100644
--- a/moth/qv4isel_moth_p.h
+++ b/moth/qv4isel_moth_p.h
@@ -3,6 +3,7 @@
#include "qv4ir_p.h"
#include "qmljs_objects.h"
+#include "qv4instr_moth_p.h"
namespace QQmlJS {
namespace Moth {
@@ -25,10 +26,33 @@ protected:
virtual void visitRet(IR::Ret *);
private:
+ struct Instruction {
+#define MOTH_INSTR_DATA_TYPEDEF(I, FMT) typedef InstrData<Instr::I> I;
+ FOR_EACH_MOTH_INSTR(MOTH_INSTR_DATA_TYPEDEF)
+#undef MOTH_INSTR_DATA_TYPEDEF
+ private:
+ Instruction();
+ };
+
+ template <int Instr>
+ inline int addInstruction(const InstrData<Instr> &data);
+ int addInstructionHelper(Instr::Type type, Instr &instr);
+
IR::Function *_function;
IR::BasicBlock *_block;
+
+ uchar *_code;
+ uchar *_ccode;
};
+template<int InstrT>
+int InstructionSelection::addInstruction(const InstrData<InstrT> &data)
+{
+ Instr genericInstr;
+ InstrMeta<InstrT>::setData(genericInstr, data);
+ return addInstructionHelper(static_cast<Instr::Type>(InstrT), genericInstr);
+}
+
} // namespace Moth
} // namespace QQmlJS
diff --git a/moth/qv4vme_moth.cpp b/moth/qv4vme_moth.cpp
new file mode 100644
index 0000000000..c14a61cb9c
--- /dev/null
+++ b/moth/qv4vme_moth.cpp
@@ -0,0 +1,100 @@
+#include "qv4vme_moth_p.h"
+#include "qv4instr_moth_p.h"
+
+using namespace QQmlJS;
+using namespace QQmlJS::Moth;
+
+#define MOTH_BEGIN_INSTR_COMMON(I) { \
+ const InstrMeta<(int)Instr::I>::DataType &instr = InstrMeta<(int)Instr::I>::data(*genericInstr); \
+ code += InstrMeta<(int)Instr::I>::Size; \
+ Q_UNUSED(instr);
+
+#ifdef MOTH_THREADED_INTERPRETER
+
+# define MOTH_BEGIN_INSTR(I) op_##I: \
+ MOTH_BEGIN_INSTR_COMMON(I)
+
+# define MOTH_NEXT_INSTR(I) { \
+ genericInstr = reinterpret_cast<const Instr *>(code); \
+ goto *genericInstr->common.code; \
+ }
+
+# define MOTH_END_INSTR(I) } \
+ genericInstr = reinterpret_cast<const Instr *>(code); \
+ goto *genericInstr->common.code; \
+
+#else
+
+# define MOTH_BEGIN_INSTR(I) \
+ case Instr::I: \
+ MOTH_BEGIN_INSTR_COMMON(I)
+
+# define MOTH_NEXT_INSTR(I) { \
+ break; \
+ }
+
+# define MOTH_END_INSTR(I) } \
+ break;
+
+#endif
+
+void VME::operator()(QQmlJS::VM::Context *, const uchar *code
+#ifdef MOTH_THREADED_INTERPRETER
+ , void ***storeJumpTable
+#endif
+ )
+{
+
+#ifdef MOTH_THREADED_INTERPRETER
+ if (storeJumpTable) {
+#define MOTH_INSTR_ADDR(I, FMT) &&op_##I,
+ static void *jumpTable[] = {
+ FOR_EACH_MOTH_INSTR(MOTH_INSTR_ADDR)
+ };
+#undef MOTH_INSTR_ADDR
+ *storeJumpTable = jumpTable;
+ return;
+ }
+#endif
+
+#ifdef MOTH_THREADED_INTERPRETER
+ const Instr *genericInstr = reinterpret_cast<const Instr *>(code);
+ goto *genericInstr->common.code;
+#else
+ for (;;) {
+ const Instr *genericInstr = reinterpret_cast<const Instr *>(code);
+ switch (genericInstr->common.instructionType) {
+#endif
+
+ MOTH_BEGIN_INSTR(Nop)
+ qWarning("NOP");
+ MOTH_END_INSTR(Nop)
+
+ MOTH_BEGIN_INSTR(Done)
+ return;
+ MOTH_END_INSTR(Done)
+
+#ifdef MOTH_THREADED_INTERPRETER
+ // nothing to do
+#else
+ default:
+ qFatal("QQmlJS::Moth::VME: Internal error - unknown instruction %d", genericInstr->common.instructionType);
+ break;
+ }
+ }
+#endif
+
+}
+
+#ifdef MOTH_THREADED_INTERPRETER
+void **VME::instructionJumpTable()
+{
+ static void **jumpTable = 0;
+ if (!jumpTable) {
+ VME dummy;
+ dummy(0, 0, &jumpTable);
+ }
+ return jumpTable;
+}
+#endif
+
diff --git a/moth/qv4vme_moth_p.h b/moth/qv4vme_moth_p.h
new file mode 100644
index 0000000000..5055407ca2
--- /dev/null
+++ b/moth/qv4vme_moth_p.h
@@ -0,0 +1,27 @@
+#ifndef QV4VME_MOTH_P_H
+#define QV4VME_MOTH_P_H
+
+#include "qmljs_runtime.h"
+#include "qv4instr_moth_p.h"
+
+namespace QQmlJS {
+namespace Moth {
+
+class VME
+{
+public:
+ void operator()(QQmlJS::VM::Context *, const uchar *code
+#ifdef MOTH_THREADED_INTERPRETER
+ , void ***storeJumpTable = 0
+#endif
+ );
+
+#ifdef MOTH_THREADED_INTERPRETER
+ static void **instructionJumpTable();
+#endif
+};
+
+} // namespace Moth
+} // namespace QQmlJS
+
+#endif // QV4VME_MOTH_P_H