18 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 |
*/ |
*/ |
20 |
|
|
21 |
|
/* allow to see translation results - the slowdown should be negligible, so we leave it */ |
22 |
|
#define DEBUG_DISAS |
23 |
|
|
24 |
|
/* is_jmp field values */ |
25 |
|
#define DISAS_NEXT 0 /* next instruction can be analyzed */ |
26 |
|
#define DISAS_JUMP 1 /* only pc was modified dynamically */ |
27 |
|
#define DISAS_UPDATE 2 /* cpu state was modified dynamically */ |
28 |
|
#define DISAS_TB_JUMP 3 /* only pc was modified statically */ |
29 |
|
|
30 |
|
struct TranslationBlock; |
31 |
|
|
32 |
|
/* XXX: make safe guess about sizes */ |
33 |
|
#define MAX_OP_PER_INSTR 32 |
34 |
|
#define OPC_BUF_SIZE 512 |
35 |
|
#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR) |
36 |
|
|
37 |
|
#define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * 3) |
38 |
|
|
39 |
|
extern uint16_t gen_opc_buf[OPC_BUF_SIZE]; |
40 |
|
extern uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE]; |
41 |
|
extern uint32_t gen_opc_pc[OPC_BUF_SIZE]; |
42 |
|
extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; |
43 |
|
|
44 |
|
#if defined(TARGET_I386) |
45 |
|
|
46 |
#define GEN_FLAG_CODE32_SHIFT 0 |
#define GEN_FLAG_CODE32_SHIFT 0 |
47 |
#define GEN_FLAG_ADDSEG_SHIFT 1 |
#define GEN_FLAG_ADDSEG_SHIFT 1 |
48 |
#define GEN_FLAG_SS32_SHIFT 2 |
#define GEN_FLAG_SS32_SHIFT 2 |
52 |
#define GEN_FLAG_CPL_SHIFT 9 |
#define GEN_FLAG_CPL_SHIFT 9 |
53 |
#define GEN_FLAG_IOPL_SHIFT 12 /* same position as eflags */ |
#define GEN_FLAG_IOPL_SHIFT 12 /* same position as eflags */ |
54 |
|
|
55 |
struct TranslationBlock; |
#endif |
56 |
int cpu_x86_gen_code(struct TranslationBlock *tb, |
|
57 |
int max_code_size, int *gen_code_size_ptr); |
extern FILE *logfile; |
58 |
int cpu_x86_search_pc(struct TranslationBlock *tb, |
extern int loglevel; |
59 |
uint32_t *found_pc, unsigned long searched_pc); |
|
60 |
void cpu_x86_tblocks_init(void); |
int gen_intermediate_code(struct TranslationBlock *tb, int search_pc); |
61 |
void page_init(void); |
void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf); |
62 |
|
int cpu_gen_code(struct TranslationBlock *tb, |
63 |
|
int max_code_size, int *gen_code_size_ptr); |
64 |
|
int cpu_search_pc(struct TranslationBlock *tb, |
65 |
|
uint32_t *found_pc, unsigned long searched_pc); |
66 |
|
void cpu_exec_init(void); |
67 |
int page_unprotect(unsigned long address); |
int page_unprotect(unsigned long address); |
68 |
|
|
69 |
#define CODE_GEN_MAX_SIZE 65536 |
#define CODE_GEN_MAX_SIZE 65536 |
197 |
#define offsetof(type, field) ((size_t) &((type *)0)->field) |
#define offsetof(type, field) ((size_t) &((type *)0)->field) |
198 |
#endif |
#endif |
199 |
|
|
200 |
|
#if defined(__powerpc__) |
201 |
|
|
202 |
|
/* on PowerPC we patch the jump instruction directly */ |
203 |
|
#define JUMP_TB(tbparam, n, eip)\ |
204 |
|
do {\ |
205 |
|
static void __attribute__((unused)) *__op_label ## n = &&label ## n;\ |
206 |
|
asm volatile ("b %0" : : "i" (&__op_jmp ## n));\ |
207 |
|
label ## n:\ |
208 |
|
T0 = (long)(tbparam) + (n);\ |
209 |
|
EIP = eip;\ |
210 |
|
} while (0) |
211 |
|
|
212 |
|
#else |
213 |
|
|
214 |
|
/* jump to next block operations (more portable code, does not need |
215 |
|
cache flushing, but slower because of indirect jump) */ |
216 |
|
#define JUMP_TB(tbparam, n, eip)\ |
217 |
|
do {\ |
218 |
|
static void __attribute__((unused)) *__op_label ## n = &&label ## n;\ |
219 |
|
goto *(void *)(((TranslationBlock *)tbparam)->tb_next[n]);\ |
220 |
|
label ## n:\ |
221 |
|
T0 = (long)(tbparam) + (n);\ |
222 |
|
EIP = eip;\ |
223 |
|
} while (0) |
224 |
|
|
225 |
|
#endif |
226 |
|
|
227 |
#ifdef __powerpc__ |
#ifdef __powerpc__ |
228 |
static inline int testandset (int *p) |
static inline int testandset (int *p) |
229 |
{ |
{ |