1 |
cebix |
1.1 |
/* |
2 |
|
|
* UAE - The Un*x Amiga Emulator |
3 |
|
|
* |
4 |
|
|
* m68k -> i386 compiler |
5 |
|
|
* |
6 |
|
|
* (c) 1995 Bernd Schmidt |
7 |
|
|
*/ |
8 |
|
|
|
9 |
|
|
typedef uaecptr (*code_execfunc)(void); |
10 |
|
|
|
11 |
|
|
struct code_page { |
12 |
|
|
struct code_page *next; |
13 |
|
|
uae_u32 allocmask; |
14 |
|
|
}; |
15 |
|
|
|
16 |
|
|
struct hash_block { |
17 |
|
|
struct hash_block *lru_next, *lru_prev; |
18 |
|
|
struct hash_entry *he_first; |
19 |
|
|
|
20 |
|
|
struct code_page *cpage; |
21 |
|
|
int alloclen; |
22 |
|
|
uae_u32 page_allocmask; |
23 |
|
|
char *compile_start; |
24 |
|
|
|
25 |
|
|
int nrefs; |
26 |
|
|
|
27 |
|
|
int translated:1; |
28 |
|
|
int untranslatable:1; |
29 |
|
|
int allocfailed:1; |
30 |
|
|
}; |
31 |
|
|
|
32 |
|
|
struct hash_entry { |
33 |
|
|
code_execfunc execute; /* For the sake of the stubs in X86.S */ |
34 |
|
|
struct hash_entry *next,*prev; |
35 |
|
|
struct hash_entry *next_same_block, *lru_next, *lru_prev; |
36 |
|
|
struct hash_block *block; |
37 |
|
|
|
38 |
|
|
uaecptr addr; |
39 |
|
|
uae_u32 matchword; |
40 |
|
|
int ncalls:8; |
41 |
|
|
int locked:1; |
42 |
|
|
int cacheflush:1; |
43 |
|
|
}; |
44 |
|
|
|
45 |
|
|
extern int nr_bbs_start; |
46 |
|
|
extern uae_u8 nr_bbs_to_run; |
47 |
|
|
extern code_execfunc exec_me; |
48 |
|
|
|
49 |
|
|
#ifdef USE_COMPILER |
50 |
|
|
static __inline__ void run_compiled_code(void) |
51 |
|
|
{ |
52 |
|
|
|
53 |
|
|
/*if (regs.spcflags == SPCFLAG_EXEC && may_run_compiled) {*/ |
54 |
|
|
while (regs.spcflags == SPCFLAG_EXEC) { |
55 |
|
|
uaecptr newpc; |
56 |
|
|
regs.spcflags = 0; |
57 |
|
|
/* newpc = (*exec_me)();*/ |
58 |
|
|
__asm__ __volatile__ ("pushl %%ebp; call *%1; popl %%ebp" : "=a" (newpc) : "r" (exec_me) : |
59 |
|
|
"%eax", "%edx", "%ecx", "%ebx", |
60 |
|
|
"%edi", "%esi", "memory", "cc"); |
61 |
|
|
if (nr_bbs_to_run == 0) { |
62 |
|
|
struct hash_entry *h = (struct hash_entry *)newpc; |
63 |
|
|
regs.spcflags = SPCFLAG_EXEC; |
64 |
|
|
exec_me = h->execute; |
65 |
|
|
regs.pc = h->addr; |
66 |
|
|
regs.pc_p = regs.pc_oldp = get_real_address(h->addr); |
67 |
|
|
nr_bbs_to_run = nr_bbs_start; |
68 |
|
|
} else |
69 |
|
|
m68k_setpc_fast(newpc); |
70 |
|
|
do_cycles(); |
71 |
|
|
} |
72 |
|
|
/*} else */ |
73 |
|
|
regs.spcflags &= ~SPCFLAG_EXEC; |
74 |
|
|
} |
75 |
|
|
|
76 |
|
|
extern void compiler_init(void); |
77 |
|
|
extern void possible_loadseg(void); |
78 |
|
|
|
79 |
|
|
extern void m68k_do_rts(void); |
80 |
|
|
extern void m68k_do_bsr(uaecptr, uae_s32); |
81 |
|
|
extern void m68k_do_jsr(uaecptr, uaecptr); |
82 |
|
|
extern void compiler_flush_jsr_stack(void); |
83 |
|
|
|
84 |
|
|
#else |
85 |
|
|
|
86 |
|
|
#define run_compiled_code() do { ; } while (0) |
87 |
|
|
#define compiler_init() do { ; } while (0) |
88 |
|
|
#define possible_loadseg() do { ; } while (0) |
89 |
|
|
#define compiler_flush_jsr_stack() do { ; } while (0) |
90 |
|
|
|
91 |
|
|
static __inline__ void m68k_do_rts(void) |
92 |
|
|
{ |
93 |
|
|
m68k_setpc(get_long(m68k_areg(regs, 7))); |
94 |
|
|
m68k_areg(regs, 7) += 4; |
95 |
|
|
} |
96 |
|
|
|
97 |
|
|
static __inline__ void m68k_do_bsr(uaecptr oldpc, uae_s32 offset) |
98 |
|
|
{ |
99 |
|
|
m68k_areg(regs, 7) -= 4; |
100 |
|
|
put_long(m68k_areg(regs, 7), oldpc); |
101 |
|
|
m68k_incpc(offset); |
102 |
|
|
} |
103 |
|
|
|
104 |
|
|
static __inline__ void m68k_do_jsr(uaecptr oldpc, uaecptr dest) |
105 |
|
|
{ |
106 |
|
|
m68k_areg(regs, 7) -= 4; |
107 |
|
|
put_long(m68k_areg(regs, 7), oldpc); |
108 |
|
|
m68k_setpc(dest); |
109 |
|
|
} |
110 |
|
|
|
111 |
|
|
#endif |