-
Notifications
You must be signed in to change notification settings - Fork 13
/
compiler.h
109 lines (84 loc) · 3.21 KB
/
compiler.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// 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 times this block was retrieved from the cache
} // (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);
gBlockHeader->runCounter++;
return (git_uint32*)n + n->codeOffset;
}
n = n->u.next;
}
return compile (pc);
}
#endif // GIT_COMPILER_H