X-Git-Url: https://git.stderr.nl/gitweb?a=blobdiff_plain;f=interpreters%2Fgit%2Fcompiler.h;fp=interpreters%2Fgit%2Fcompiler.h;h=4ee39c61856f66058e5a5a0e26be12837744b33a;hb=147a8cbf17f2b3379277bf7d37cda9866510f16c;hp=0000000000000000000000000000000000000000;hpb=7de488aa6a1709a4d5c59b5ff59862105c1748c5;p=rodin%2Fchimara.git diff --git a/interpreters/git/compiler.h b/interpreters/git/compiler.h new file mode 100644 index 0000000..4ee39c6 --- /dev/null +++ b/interpreters/git/compiler.h @@ -0,0 +1,108 @@ +// Header for compiler.c +// $Id: compiler.h,v 1.11 2004/02/02 00:13:46 iain Exp $ + +#ifndef GIT_COMPILER_H +#define GIT_COMPILER_H + +// ------------------------------------------------------------- +// Types + +typedef enum +{ +#define LABEL(foo) label_ ## foo, +#include "labels.inc" + MAX_LABEL +} +Label; + +#ifdef USE_DIRECT_THREADING +typedef void* Opcode; // Generated opcode: pointer to a label in exec(). +#else +typedef Label Opcode; +#endif + +typedef git_uint32* Block; // Generated code block: array of labels. + +// ------------------------------------------------------------- +// Settings + +extern int gPeephole; // Peephole optimisation of generated code? +extern int gDebug; // Insert debug statements into generated code? +extern int gCacheRAM; // Keep RAM-based code in the JIT cache? + +// ------------------------------------------------------------- +// Compiling code + +extern const char* gLabelNames[]; + +extern void initCompiler (size_t cacheSize); +extern void shutdownCompiler (); + +extern void emitData (git_uint32); +extern void emitFinalCode (Label); +extern void emitConstBranch (Label op, git_uint32 address); + +extern void abortCompilation (); + +extern git_uint32 undoEmit(); +extern void nextInstructionIsReferenced (); + +extern Block peekAtEmittedStuff (int numOpcodes); + +// ------------------------------------------------------------- +// Accessing compiled code + +extern void pruneCodeCache (git_uint32 start, git_uint32 size); +extern void resetCodeCache (); +extern void compressCodeCache (); + +extern Block compile (git_uint32 pc); + +typedef struct HashNode HashNode; + +struct HashNode +{ + git_uint32 address; // Glulx address for this entry. + git_sint16 codeOffset; // Offset in 4-byte words from this hash node to the compiled code. + git_sint16 headerOffset; // Offset in 4-byte words from this hash node to the block header. + union { + int pad; // This pad assures that PatchNode and HashNode are the same size. + HashNode * next; // Next node in the same hash table slot. + } u; +}; + +typedef struct BlockHeader +{ + git_uint16 numHashNodes; // Number of lookup-able addresses in this block. + git_uint16 compiledSize; // Total size of this block, in 4-byte words. + git_uint32 glulxSize; // Size of the glulx code this block represents, in bytes. + git_uint32 runCounter; // Total number of opcodes executed in this block. +} // (used to determine which blocks stay in the cache) +BlockHeader; + +// This is the header for the block currently being executed -- +// that is, the one containing the return value of the last call +// to getCode(). +extern BlockHeader * gBlockHeader; + +// Hash table for code lookup -- inlined for speed + +extern HashNode ** gHashTable; // Hash table of glulx address -> code. +extern git_uint32 gHashSize; // Number of slots in the hash table. + +GIT_INLINE Block getCode (git_uint32 pc) +{ + HashNode * n = gHashTable [pc & (gHashSize-1)]; + while (n) + { + if (n->address == pc) + { + gBlockHeader = (BlockHeader*) ((git_uint32*)n + n->headerOffset); + return (git_uint32*)n + n->codeOffset; + } + n = n->u.next; + } + return compile (pc); +} + +#endif // GIT_COMPILER_H