1 |
gbeauche |
1.5 |
/* |
2 |
|
|
* compiler/compemu.h - Public interface and definitions |
3 |
|
|
* |
4 |
|
|
* Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer |
5 |
|
|
* |
6 |
cebix |
1.9 |
* Adaptation for Basilisk II and improvements, copyright 2000-2004 |
7 |
gbeauche |
1.5 |
* Gwenole Beauchesne |
8 |
|
|
* |
9 |
cebix |
1.9 |
* Basilisk II (C) 1997-2004 Christian Bauer |
10 |
gbeauche |
1.5 |
* |
11 |
|
|
* This program is free software; you can redistribute it and/or modify |
12 |
|
|
* it under the terms of the GNU General Public License as published by |
13 |
|
|
* the Free Software Foundation; either version 2 of the License, or |
14 |
|
|
* (at your option) any later version. |
15 |
|
|
* |
16 |
|
|
* This program is distributed in the hope that it will be useful, |
17 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 |
|
|
* GNU General Public License for more details. |
20 |
|
|
* |
21 |
|
|
* You should have received a copy of the GNU General Public License |
22 |
|
|
* along with this program; if not, write to the Free Software |
23 |
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 |
|
|
*/ |
25 |
|
|
|
26 |
gbeauche |
1.1 |
#ifndef COMPEMU_H |
27 |
|
|
#define COMPEMU_H |
28 |
|
|
|
29 |
|
|
#include "newcpu.h" |
30 |
|
|
|
31 |
|
|
#if USE_JIT |
32 |
|
|
|
33 |
|
|
#if JIT_DEBUG |
34 |
|
|
/* dump some information (m68k block, x86 block addresses) about the compiler state */ |
35 |
|
|
extern void compiler_dumpstate(void); |
36 |
|
|
#endif |
37 |
|
|
|
38 |
|
|
/* Now that we do block chaining, and also have linked lists on each tag, |
39 |
|
|
TAGMASK can be much smaller and still do its job. Saves several megs |
40 |
|
|
of memory! */ |
41 |
|
|
#define TAGMASK 0x0000ffff |
42 |
|
|
#define TAGSIZE (TAGMASK+1) |
43 |
|
|
#define MAXRUN 1024 |
44 |
|
|
#define cacheline(x) (((uae_u32)x)&TAGMASK) |
45 |
|
|
|
46 |
|
|
extern uae_u8* start_pc_p; |
47 |
|
|
extern uae_u32 start_pc; |
48 |
|
|
|
49 |
|
|
struct blockinfo_t; |
50 |
|
|
|
51 |
|
|
struct cpu_history { |
52 |
|
|
uae_u16 * location; |
53 |
|
|
}; |
54 |
|
|
|
55 |
|
|
union cacheline { |
56 |
|
|
cpuop_func * handler; |
57 |
|
|
blockinfo_t * bi; |
58 |
|
|
}; |
59 |
|
|
|
60 |
gbeauche |
1.7 |
/* Use new spill/reload strategy when calling external functions */ |
61 |
|
|
#define USE_OPTIMIZED_CALLS 0 |
62 |
|
|
#if USE_OPTIMIZED_CALLS |
63 |
|
|
#error implementation in progress |
64 |
|
|
#endif |
65 |
|
|
|
66 |
gbeauche |
1.1 |
/* (gb) When on, this option can save save up to 30% compilation time |
67 |
|
|
* when many lazy flushes occur (e.g. apps in MacOS 8.x). |
68 |
|
|
*/ |
69 |
|
|
#define USE_SEPARATE_BIA 1 |
70 |
|
|
|
71 |
gbeauche |
1.2 |
/* Use chain of checksum_info_t to compute the block checksum */ |
72 |
gbeauche |
1.4 |
#define USE_CHECKSUM_INFO 1 |
73 |
gbeauche |
1.2 |
|
74 |
gbeauche |
1.3 |
/* Use code inlining, aka follow-up of constant jumps */ |
75 |
gbeauche |
1.4 |
#define USE_INLINING 1 |
76 |
|
|
|
77 |
|
|
/* Inlining requires the chained checksuming information */ |
78 |
|
|
#if USE_INLINING |
79 |
|
|
#undef USE_CHECKSUM_INFO |
80 |
|
|
#define USE_CHECKSUM_INFO 1 |
81 |
|
|
#endif |
82 |
gbeauche |
1.3 |
|
83 |
gbeauche |
1.8 |
/* Does flush_icache_range() only check for blocks falling in the requested range? */ |
84 |
|
|
#define LAZY_FLUSH_ICACHE_RANGE 0 |
85 |
|
|
|
86 |
gbeauche |
1.1 |
#define USE_F_ALIAS 1 |
87 |
|
|
#define USE_OFFSET 1 |
88 |
|
|
#define COMP_DEBUG 1 |
89 |
|
|
|
90 |
|
|
#if COMP_DEBUG |
91 |
|
|
#define Dif(x) if (x) |
92 |
|
|
#else |
93 |
|
|
#define Dif(x) if (0) |
94 |
|
|
#endif |
95 |
|
|
|
96 |
|
|
#define SCALE 2 |
97 |
|
|
|
98 |
|
|
#define BYTES_PER_INST 10240 /* paranoid ;-) */ |
99 |
|
|
#define LONGEST_68K_INST 16 /* The number of bytes the longest possible |
100 |
|
|
68k instruction takes */ |
101 |
|
|
#define MAX_CHECKSUM_LEN 2048 /* The maximum size we calculate checksums |
102 |
|
|
for. Anything larger will be flushed |
103 |
|
|
unconditionally even with SOFT_FLUSH */ |
104 |
|
|
#define MAX_HOLD_BI 3 /* One for the current block, and up to two |
105 |
|
|
for jump targets */ |
106 |
|
|
|
107 |
|
|
#define INDIVIDUAL_INST 0 |
108 |
|
|
#if 1 |
109 |
|
|
// gb-- my format from readcpu.cpp is not the same |
110 |
|
|
#define FLAG_X 0x0010 |
111 |
|
|
#define FLAG_N 0x0008 |
112 |
|
|
#define FLAG_Z 0x0004 |
113 |
|
|
#define FLAG_V 0x0002 |
114 |
|
|
#define FLAG_C 0x0001 |
115 |
|
|
#else |
116 |
|
|
#define FLAG_C 0x0010 |
117 |
|
|
#define FLAG_V 0x0008 |
118 |
|
|
#define FLAG_Z 0x0004 |
119 |
|
|
#define FLAG_N 0x0002 |
120 |
|
|
#define FLAG_X 0x0001 |
121 |
|
|
#endif |
122 |
|
|
#define FLAG_CZNV (FLAG_C | FLAG_Z | FLAG_N | FLAG_V) |
123 |
|
|
#define FLAG_ZNV (FLAG_Z | FLAG_N | FLAG_V) |
124 |
|
|
|
125 |
|
|
#define KILLTHERAT 1 /* Set to 1 to avoid some partial_rat_stalls */ |
126 |
|
|
|
127 |
|
|
/* Whether to preserve registers across calls to JIT compiled routines */ |
128 |
|
|
#ifdef X86_ASSEMBLY |
129 |
|
|
#define USE_PUSH_POP 0 |
130 |
|
|
#else |
131 |
|
|
#define USE_PUSH_POP 1 |
132 |
|
|
#endif |
133 |
|
|
|
134 |
|
|
#define N_REGS 8 /* really only 7, but they are numbered 0,1,2,3,5,6,7 */ |
135 |
|
|
#define N_FREGS 6 /* That leaves us two positions on the stack to play with */ |
136 |
|
|
|
137 |
|
|
/* Functions exposed to newcpu, or to what was moved from newcpu.c to |
138 |
|
|
* compemu_support.c */ |
139 |
|
|
extern void compiler_init(void); |
140 |
|
|
extern void compiler_exit(void); |
141 |
|
|
extern bool compiler_use_jit(void); |
142 |
|
|
extern void init_comp(void); |
143 |
|
|
extern void flush(int save_regs); |
144 |
|
|
extern void small_flush(int save_regs); |
145 |
|
|
extern void set_target(uae_u8* t); |
146 |
|
|
extern uae_u8* get_target(void); |
147 |
|
|
extern void freescratch(void); |
148 |
|
|
extern void build_comp(void); |
149 |
|
|
extern void set_cache_state(int enabled); |
150 |
|
|
extern int get_cache_state(void); |
151 |
|
|
extern uae_u32 get_jitted_size(void); |
152 |
|
|
extern void (*flush_icache)(int n); |
153 |
|
|
extern void alloc_cache(void); |
154 |
|
|
extern int check_for_cache_miss(void); |
155 |
|
|
|
156 |
|
|
/* JIT FPU compilation */ |
157 |
|
|
extern void comp_fpp_opp (uae_u32 opcode, uae_u16 extra); |
158 |
|
|
extern void comp_fbcc_opp (uae_u32 opcode); |
159 |
|
|
extern void comp_fscc_opp (uae_u32 opcode, uae_u16 extra); |
160 |
|
|
|
161 |
|
|
extern uae_u32 needed_flags; |
162 |
|
|
extern cacheline cache_tags[]; |
163 |
|
|
extern uae_u8* comp_pc_p; |
164 |
|
|
extern void* pushall_call_handler; |
165 |
|
|
|
166 |
|
|
#define VREGS 32 |
167 |
|
|
#define VFREGS 16 |
168 |
|
|
|
169 |
|
|
#define INMEM 1 |
170 |
|
|
#define CLEAN 2 |
171 |
|
|
#define DIRTY 3 |
172 |
|
|
#define UNDEF 4 |
173 |
|
|
#define ISCONST 5 |
174 |
|
|
|
175 |
|
|
typedef struct { |
176 |
|
|
uae_u32* mem; |
177 |
|
|
uae_u32 val; |
178 |
|
|
uae_u8 is_swapped; |
179 |
|
|
uae_u8 status; |
180 |
|
|
uae_s8 realreg; /* gb-- realreg can hold -1 */ |
181 |
|
|
uae_u8 realind; /* The index in the holds[] array */ |
182 |
|
|
uae_u8 needflush; |
183 |
|
|
uae_u8 validsize; |
184 |
|
|
uae_u8 dirtysize; |
185 |
|
|
uae_u8 dummy; |
186 |
|
|
} reg_status; |
187 |
|
|
|
188 |
|
|
typedef struct { |
189 |
|
|
uae_u32* mem; |
190 |
|
|
double val; |
191 |
|
|
uae_u8 status; |
192 |
|
|
uae_s8 realreg; /* gb-- realreg can hold -1 */ |
193 |
|
|
uae_u8 realind; |
194 |
|
|
uae_u8 needflush; |
195 |
|
|
} freg_status; |
196 |
|
|
|
197 |
|
|
#define PC_P 16 |
198 |
|
|
#define FLAGX 17 |
199 |
|
|
#define FLAGTMP 18 |
200 |
|
|
#define NEXT_HANDLER 19 |
201 |
|
|
#define S1 20 |
202 |
|
|
#define S2 21 |
203 |
|
|
#define S3 22 |
204 |
|
|
#define S4 23 |
205 |
|
|
#define S5 24 |
206 |
|
|
#define S6 25 |
207 |
|
|
#define S7 26 |
208 |
|
|
#define S8 27 |
209 |
|
|
#define S9 28 |
210 |
|
|
#define S10 29 |
211 |
|
|
#define S11 30 |
212 |
|
|
#define S12 31 |
213 |
|
|
|
214 |
|
|
#define FP_RESULT 8 |
215 |
|
|
#define FS1 9 |
216 |
|
|
#define FS2 10 |
217 |
|
|
#define FS3 11 |
218 |
|
|
|
219 |
|
|
typedef struct { |
220 |
|
|
uae_u32 touched; |
221 |
|
|
uae_s8 holds[VREGS]; |
222 |
|
|
uae_u8 nholds; |
223 |
|
|
uae_u8 canbyte; |
224 |
|
|
uae_u8 canword; |
225 |
|
|
uae_u8 locked; |
226 |
|
|
} n_status; |
227 |
|
|
|
228 |
|
|
typedef struct { |
229 |
|
|
uae_u32 touched; |
230 |
|
|
uae_s8 holds[VFREGS]; |
231 |
|
|
uae_u8 nholds; |
232 |
|
|
uae_u8 locked; |
233 |
|
|
} fn_status; |
234 |
|
|
|
235 |
|
|
/* For flag handling */ |
236 |
|
|
#define NADA 1 |
237 |
|
|
#define TRASH 2 |
238 |
|
|
#define VALID 3 |
239 |
|
|
|
240 |
|
|
/* needflush values */ |
241 |
|
|
#define NF_SCRATCH 0 |
242 |
|
|
#define NF_TOMEM 1 |
243 |
|
|
#define NF_HANDLER 2 |
244 |
|
|
|
245 |
|
|
typedef struct { |
246 |
|
|
/* Integer part */ |
247 |
|
|
reg_status state[VREGS]; |
248 |
|
|
n_status nat[N_REGS]; |
249 |
|
|
uae_u32 flags_on_stack; |
250 |
|
|
uae_u32 flags_in_flags; |
251 |
|
|
uae_u32 flags_are_important; |
252 |
|
|
/* FPU part */ |
253 |
|
|
freg_status fate[VFREGS]; |
254 |
|
|
fn_status fat[N_FREGS]; |
255 |
|
|
|
256 |
|
|
/* x86 FPU part */ |
257 |
|
|
uae_s8 spos[N_FREGS]; |
258 |
|
|
uae_s8 onstack[6]; |
259 |
|
|
uae_s8 tos; |
260 |
|
|
} bigstate; |
261 |
|
|
|
262 |
|
|
typedef struct { |
263 |
|
|
/* Integer part */ |
264 |
|
|
char virt[VREGS]; |
265 |
|
|
char nat[N_REGS]; |
266 |
|
|
} smallstate; |
267 |
|
|
|
268 |
|
|
extern bigstate live; |
269 |
|
|
extern int touchcnt; |
270 |
|
|
|
271 |
|
|
|
272 |
|
|
#define IMM uae_s32 |
273 |
|
|
#define R1 uae_u32 |
274 |
|
|
#define R2 uae_u32 |
275 |
|
|
#define R4 uae_u32 |
276 |
|
|
#define W1 uae_u32 |
277 |
|
|
#define W2 uae_u32 |
278 |
|
|
#define W4 uae_u32 |
279 |
|
|
#define RW1 uae_u32 |
280 |
|
|
#define RW2 uae_u32 |
281 |
|
|
#define RW4 uae_u32 |
282 |
|
|
#define MEMR uae_u32 |
283 |
|
|
#define MEMW uae_u32 |
284 |
|
|
#define MEMRW uae_u32 |
285 |
|
|
|
286 |
|
|
#define FW uae_u32 |
287 |
|
|
#define FR uae_u32 |
288 |
|
|
#define FRW uae_u32 |
289 |
|
|
|
290 |
|
|
#define MIDFUNC(nargs,func,args) void func args |
291 |
|
|
#define MENDFUNC(nargs,func,args) |
292 |
|
|
#define COMPCALL(func) func |
293 |
|
|
|
294 |
|
|
#define LOWFUNC(flags,mem,nargs,func,args) static __inline__ void func args |
295 |
|
|
#define LENDFUNC(flags,mem,nargs,func,args) |
296 |
|
|
|
297 |
|
|
/* What we expose to the outside */ |
298 |
|
|
#define DECLARE_MIDFUNC(func) extern void func |
299 |
|
|
DECLARE_MIDFUNC(bt_l_ri(R4 r, IMM i)); |
300 |
|
|
DECLARE_MIDFUNC(bt_l_rr(R4 r, R4 b)); |
301 |
|
|
DECLARE_MIDFUNC(btc_l_ri(RW4 r, IMM i)); |
302 |
|
|
DECLARE_MIDFUNC(btc_l_rr(RW4 r, R4 b)); |
303 |
|
|
DECLARE_MIDFUNC(bts_l_ri(RW4 r, IMM i)); |
304 |
|
|
DECLARE_MIDFUNC(bts_l_rr(RW4 r, R4 b)); |
305 |
|
|
DECLARE_MIDFUNC(btr_l_ri(RW4 r, IMM i)); |
306 |
|
|
DECLARE_MIDFUNC(btr_l_rr(RW4 r, R4 b)); |
307 |
|
|
DECLARE_MIDFUNC(mov_l_rm(W4 d, IMM s)); |
308 |
|
|
DECLARE_MIDFUNC(call_r(R4 r)); |
309 |
|
|
DECLARE_MIDFUNC(sub_l_mi(IMM d, IMM s)); |
310 |
|
|
DECLARE_MIDFUNC(mov_l_mi(IMM d, IMM s)); |
311 |
|
|
DECLARE_MIDFUNC(mov_w_mi(IMM d, IMM s)); |
312 |
|
|
DECLARE_MIDFUNC(mov_b_mi(IMM d, IMM s)); |
313 |
|
|
DECLARE_MIDFUNC(rol_b_ri(RW1 r, IMM i)); |
314 |
|
|
DECLARE_MIDFUNC(rol_w_ri(RW2 r, IMM i)); |
315 |
|
|
DECLARE_MIDFUNC(rol_l_ri(RW4 r, IMM i)); |
316 |
|
|
DECLARE_MIDFUNC(rol_l_rr(RW4 d, R1 r)); |
317 |
|
|
DECLARE_MIDFUNC(rol_w_rr(RW2 d, R1 r)); |
318 |
|
|
DECLARE_MIDFUNC(rol_b_rr(RW1 d, R1 r)); |
319 |
|
|
DECLARE_MIDFUNC(shll_l_rr(RW4 d, R1 r)); |
320 |
|
|
DECLARE_MIDFUNC(shll_w_rr(RW2 d, R1 r)); |
321 |
|
|
DECLARE_MIDFUNC(shll_b_rr(RW1 d, R1 r)); |
322 |
|
|
DECLARE_MIDFUNC(ror_b_ri(R1 r, IMM i)); |
323 |
|
|
DECLARE_MIDFUNC(ror_w_ri(R2 r, IMM i)); |
324 |
|
|
DECLARE_MIDFUNC(ror_l_ri(R4 r, IMM i)); |
325 |
|
|
DECLARE_MIDFUNC(ror_l_rr(R4 d, R1 r)); |
326 |
|
|
DECLARE_MIDFUNC(ror_w_rr(R2 d, R1 r)); |
327 |
|
|
DECLARE_MIDFUNC(ror_b_rr(R1 d, R1 r)); |
328 |
|
|
DECLARE_MIDFUNC(shrl_l_rr(RW4 d, R1 r)); |
329 |
|
|
DECLARE_MIDFUNC(shrl_w_rr(RW2 d, R1 r)); |
330 |
|
|
DECLARE_MIDFUNC(shrl_b_rr(RW1 d, R1 r)); |
331 |
|
|
DECLARE_MIDFUNC(shra_l_rr(RW4 d, R1 r)); |
332 |
|
|
DECLARE_MIDFUNC(shra_w_rr(RW2 d, R1 r)); |
333 |
|
|
DECLARE_MIDFUNC(shra_b_rr(RW1 d, R1 r)); |
334 |
|
|
DECLARE_MIDFUNC(shll_l_ri(RW4 r, IMM i)); |
335 |
|
|
DECLARE_MIDFUNC(shll_w_ri(RW2 r, IMM i)); |
336 |
|
|
DECLARE_MIDFUNC(shll_b_ri(RW1 r, IMM i)); |
337 |
|
|
DECLARE_MIDFUNC(shrl_l_ri(RW4 r, IMM i)); |
338 |
|
|
DECLARE_MIDFUNC(shrl_w_ri(RW2 r, IMM i)); |
339 |
|
|
DECLARE_MIDFUNC(shrl_b_ri(RW1 r, IMM i)); |
340 |
|
|
DECLARE_MIDFUNC(shra_l_ri(RW4 r, IMM i)); |
341 |
|
|
DECLARE_MIDFUNC(shra_w_ri(RW2 r, IMM i)); |
342 |
|
|
DECLARE_MIDFUNC(shra_b_ri(RW1 r, IMM i)); |
343 |
|
|
DECLARE_MIDFUNC(setcc(W1 d, IMM cc)); |
344 |
|
|
DECLARE_MIDFUNC(setcc_m(IMM d, IMM cc)); |
345 |
|
|
DECLARE_MIDFUNC(cmov_l_rr(RW4 d, R4 s, IMM cc)); |
346 |
|
|
DECLARE_MIDFUNC(cmov_l_rm(RW4 d, IMM s, IMM cc)); |
347 |
gbeauche |
1.6 |
/* Set native Z flag only if register is zero */ |
348 |
|
|
DECLARE_MIDFUNC(setzflg_l(RW4 r)); |
349 |
gbeauche |
1.1 |
DECLARE_MIDFUNC(pop_m(IMM d)); |
350 |
|
|
DECLARE_MIDFUNC(push_m(IMM d)); |
351 |
|
|
DECLARE_MIDFUNC(pop_l(W4 d)); |
352 |
|
|
DECLARE_MIDFUNC(push_l_i(IMM i)); |
353 |
|
|
DECLARE_MIDFUNC(push_l(R4 s)); |
354 |
|
|
DECLARE_MIDFUNC(clear_16(RW4 r)); |
355 |
|
|
DECLARE_MIDFUNC(clear_8(RW4 r)); |
356 |
|
|
DECLARE_MIDFUNC(sign_extend_16_rr(W4 d, R2 s)); |
357 |
|
|
DECLARE_MIDFUNC(sign_extend_8_rr(W4 d, R1 s)); |
358 |
|
|
DECLARE_MIDFUNC(zero_extend_16_rr(W4 d, R2 s)); |
359 |
|
|
DECLARE_MIDFUNC(zero_extend_8_rr(W4 d, R1 s)); |
360 |
|
|
DECLARE_MIDFUNC(imul_64_32(RW4 d, RW4 s)); |
361 |
|
|
DECLARE_MIDFUNC(mul_64_32(RW4 d, RW4 s)); |
362 |
|
|
DECLARE_MIDFUNC(imul_32_32(RW4 d, R4 s)); |
363 |
|
|
DECLARE_MIDFUNC(mul_32_32(RW4 d, R4 s)); |
364 |
|
|
DECLARE_MIDFUNC(mov_b_rr(W1 d, R1 s)); |
365 |
|
|
DECLARE_MIDFUNC(mov_w_rr(W2 d, R2 s)); |
366 |
|
|
DECLARE_MIDFUNC(mov_l_rrm_indexed(W4 d,R4 baser, R4 index, IMM factor)); |
367 |
|
|
DECLARE_MIDFUNC(mov_w_rrm_indexed(W2 d, R4 baser, R4 index, IMM factor)); |
368 |
|
|
DECLARE_MIDFUNC(mov_b_rrm_indexed(W1 d, R4 baser, R4 index, IMM factor)); |
369 |
|
|
DECLARE_MIDFUNC(mov_l_mrr_indexed(R4 baser, R4 index, IMM factor, R4 s)); |
370 |
|
|
DECLARE_MIDFUNC(mov_w_mrr_indexed(R4 baser, R4 index, IMM factor, R2 s)); |
371 |
|
|
DECLARE_MIDFUNC(mov_b_mrr_indexed(R4 baser, R4 index, IMM factor, R1 s)); |
372 |
|
|
DECLARE_MIDFUNC(mov_l_bmrr_indexed(IMM base, R4 baser, R4 index, IMM factor, R4 s)); |
373 |
|
|
DECLARE_MIDFUNC(mov_w_bmrr_indexed(IMM base, R4 baser, R4 index, IMM factor, R2 s)); |
374 |
|
|
DECLARE_MIDFUNC(mov_b_bmrr_indexed(IMM base, R4 baser, R4 index, IMM factor, R1 s)); |
375 |
|
|
DECLARE_MIDFUNC(mov_l_brrm_indexed(W4 d, IMM base, R4 baser, R4 index, IMM factor)); |
376 |
|
|
DECLARE_MIDFUNC(mov_w_brrm_indexed(W2 d, IMM base, R4 baser, R4 index, IMM factor)); |
377 |
|
|
DECLARE_MIDFUNC(mov_b_brrm_indexed(W1 d, IMM base, R4 baser, R4 index, IMM factor)); |
378 |
|
|
DECLARE_MIDFUNC(mov_l_rm_indexed(W4 d, IMM base, R4 index, IMM factor)); |
379 |
|
|
DECLARE_MIDFUNC(mov_l_rR(W4 d, R4 s, IMM offset)); |
380 |
|
|
DECLARE_MIDFUNC(mov_w_rR(W2 d, R4 s, IMM offset)); |
381 |
|
|
DECLARE_MIDFUNC(mov_b_rR(W1 d, R4 s, IMM offset)); |
382 |
|
|
DECLARE_MIDFUNC(mov_l_brR(W4 d, R4 s, IMM offset)); |
383 |
|
|
DECLARE_MIDFUNC(mov_w_brR(W2 d, R4 s, IMM offset)); |
384 |
|
|
DECLARE_MIDFUNC(mov_b_brR(W1 d, R4 s, IMM offset)); |
385 |
|
|
DECLARE_MIDFUNC(mov_l_Ri(R4 d, IMM i, IMM offset)); |
386 |
|
|
DECLARE_MIDFUNC(mov_w_Ri(R4 d, IMM i, IMM offset)); |
387 |
|
|
DECLARE_MIDFUNC(mov_b_Ri(R4 d, IMM i, IMM offset)); |
388 |
|
|
DECLARE_MIDFUNC(mov_l_Rr(R4 d, R4 s, IMM offset)); |
389 |
|
|
DECLARE_MIDFUNC(mov_w_Rr(R4 d, R2 s, IMM offset)); |
390 |
|
|
DECLARE_MIDFUNC(mov_b_Rr(R4 d, R1 s, IMM offset)); |
391 |
|
|
DECLARE_MIDFUNC(lea_l_brr(W4 d, R4 s, IMM offset)); |
392 |
|
|
DECLARE_MIDFUNC(lea_l_brr_indexed(W4 d, R4 s, R4 index, IMM factor, IMM offset)); |
393 |
|
|
DECLARE_MIDFUNC(lea_l_rr_indexed(W4 d, R4 s, R4 index, IMM factor)); |
394 |
|
|
DECLARE_MIDFUNC(mov_l_bRr(R4 d, R4 s, IMM offset)); |
395 |
|
|
DECLARE_MIDFUNC(mov_w_bRr(R4 d, R2 s, IMM offset)); |
396 |
|
|
DECLARE_MIDFUNC(mov_b_bRr(R4 d, R1 s, IMM offset)); |
397 |
|
|
DECLARE_MIDFUNC(bswap_32(RW4 r)); |
398 |
|
|
DECLARE_MIDFUNC(bswap_16(RW2 r)); |
399 |
|
|
DECLARE_MIDFUNC(mov_l_rr(W4 d, R4 s)); |
400 |
|
|
DECLARE_MIDFUNC(mov_l_mr(IMM d, R4 s)); |
401 |
|
|
DECLARE_MIDFUNC(mov_w_mr(IMM d, R2 s)); |
402 |
|
|
DECLARE_MIDFUNC(mov_w_rm(W2 d, IMM s)); |
403 |
|
|
DECLARE_MIDFUNC(mov_b_mr(IMM d, R1 s)); |
404 |
|
|
DECLARE_MIDFUNC(mov_b_rm(W1 d, IMM s)); |
405 |
|
|
DECLARE_MIDFUNC(mov_l_ri(W4 d, IMM s)); |
406 |
|
|
DECLARE_MIDFUNC(mov_w_ri(W2 d, IMM s)); |
407 |
|
|
DECLARE_MIDFUNC(mov_b_ri(W1 d, IMM s)); |
408 |
|
|
DECLARE_MIDFUNC(add_l_mi(IMM d, IMM s) ); |
409 |
|
|
DECLARE_MIDFUNC(add_w_mi(IMM d, IMM s) ); |
410 |
|
|
DECLARE_MIDFUNC(add_b_mi(IMM d, IMM s) ); |
411 |
|
|
DECLARE_MIDFUNC(test_l_ri(R4 d, IMM i)); |
412 |
|
|
DECLARE_MIDFUNC(test_l_rr(R4 d, R4 s)); |
413 |
|
|
DECLARE_MIDFUNC(test_w_rr(R2 d, R2 s)); |
414 |
|
|
DECLARE_MIDFUNC(test_b_rr(R1 d, R1 s)); |
415 |
|
|
DECLARE_MIDFUNC(and_l_ri(RW4 d, IMM i)); |
416 |
|
|
DECLARE_MIDFUNC(and_l(RW4 d, R4 s)); |
417 |
|
|
DECLARE_MIDFUNC(and_w(RW2 d, R2 s)); |
418 |
|
|
DECLARE_MIDFUNC(and_b(RW1 d, R1 s)); |
419 |
|
|
DECLARE_MIDFUNC(or_l_rm(RW4 d, IMM s)); |
420 |
|
|
DECLARE_MIDFUNC(or_l_ri(RW4 d, IMM i)); |
421 |
|
|
DECLARE_MIDFUNC(or_l(RW4 d, R4 s)); |
422 |
|
|
DECLARE_MIDFUNC(or_w(RW2 d, R2 s)); |
423 |
|
|
DECLARE_MIDFUNC(or_b(RW1 d, R1 s)); |
424 |
|
|
DECLARE_MIDFUNC(adc_l(RW4 d, R4 s)); |
425 |
|
|
DECLARE_MIDFUNC(adc_w(RW2 d, R2 s)); |
426 |
|
|
DECLARE_MIDFUNC(adc_b(RW1 d, R1 s)); |
427 |
|
|
DECLARE_MIDFUNC(add_l(RW4 d, R4 s)); |
428 |
|
|
DECLARE_MIDFUNC(add_w(RW2 d, R2 s)); |
429 |
|
|
DECLARE_MIDFUNC(add_b(RW1 d, R1 s)); |
430 |
|
|
DECLARE_MIDFUNC(sub_l_ri(RW4 d, IMM i)); |
431 |
|
|
DECLARE_MIDFUNC(sub_w_ri(RW2 d, IMM i)); |
432 |
|
|
DECLARE_MIDFUNC(sub_b_ri(RW1 d, IMM i)); |
433 |
|
|
DECLARE_MIDFUNC(add_l_ri(RW4 d, IMM i)); |
434 |
|
|
DECLARE_MIDFUNC(add_w_ri(RW2 d, IMM i)); |
435 |
|
|
DECLARE_MIDFUNC(add_b_ri(RW1 d, IMM i)); |
436 |
|
|
DECLARE_MIDFUNC(sbb_l(RW4 d, R4 s)); |
437 |
|
|
DECLARE_MIDFUNC(sbb_w(RW2 d, R2 s)); |
438 |
|
|
DECLARE_MIDFUNC(sbb_b(RW1 d, R1 s)); |
439 |
|
|
DECLARE_MIDFUNC(sub_l(RW4 d, R4 s)); |
440 |
|
|
DECLARE_MIDFUNC(sub_w(RW2 d, R2 s)); |
441 |
|
|
DECLARE_MIDFUNC(sub_b(RW1 d, R1 s)); |
442 |
|
|
DECLARE_MIDFUNC(cmp_l(R4 d, R4 s)); |
443 |
|
|
DECLARE_MIDFUNC(cmp_l_ri(R4 r, IMM i)); |
444 |
|
|
DECLARE_MIDFUNC(cmp_w(R2 d, R2 s)); |
445 |
|
|
DECLARE_MIDFUNC(cmp_b(R1 d, R1 s)); |
446 |
|
|
DECLARE_MIDFUNC(xor_l(RW4 d, R4 s)); |
447 |
|
|
DECLARE_MIDFUNC(xor_w(RW2 d, R2 s)); |
448 |
|
|
DECLARE_MIDFUNC(xor_b(RW1 d, R1 s)); |
449 |
|
|
DECLARE_MIDFUNC(live_flags(void)); |
450 |
|
|
DECLARE_MIDFUNC(dont_care_flags(void)); |
451 |
|
|
DECLARE_MIDFUNC(duplicate_carry(void)); |
452 |
|
|
DECLARE_MIDFUNC(restore_carry(void)); |
453 |
|
|
DECLARE_MIDFUNC(start_needflags(void)); |
454 |
|
|
DECLARE_MIDFUNC(end_needflags(void)); |
455 |
|
|
DECLARE_MIDFUNC(make_flags_live(void)); |
456 |
|
|
DECLARE_MIDFUNC(call_r_11(R4 r, W4 out1, R4 in1, IMM osize, IMM isize)); |
457 |
|
|
DECLARE_MIDFUNC(call_r_02(R4 r, R4 in1, R4 in2, IMM isize1, IMM isize2)); |
458 |
|
|
DECLARE_MIDFUNC(forget_about(W4 r)); |
459 |
|
|
DECLARE_MIDFUNC(nop(void)); |
460 |
|
|
|
461 |
|
|
DECLARE_MIDFUNC(f_forget_about(FW r)); |
462 |
|
|
DECLARE_MIDFUNC(fmov_pi(FW r)); |
463 |
|
|
DECLARE_MIDFUNC(fmov_log10_2(FW r)); |
464 |
|
|
DECLARE_MIDFUNC(fmov_log2_e(FW r)); |
465 |
|
|
DECLARE_MIDFUNC(fmov_loge_2(FW r)); |
466 |
|
|
DECLARE_MIDFUNC(fmov_1(FW r)); |
467 |
|
|
DECLARE_MIDFUNC(fmov_0(FW r)); |
468 |
|
|
DECLARE_MIDFUNC(fmov_rm(FW r, MEMR m)); |
469 |
|
|
DECLARE_MIDFUNC(fmovi_rm(FW r, MEMR m)); |
470 |
|
|
DECLARE_MIDFUNC(fmovi_mr(MEMW m, FR r)); |
471 |
|
|
DECLARE_MIDFUNC(fmovs_rm(FW r, MEMR m)); |
472 |
|
|
DECLARE_MIDFUNC(fmovs_mr(MEMW m, FR r)); |
473 |
|
|
DECLARE_MIDFUNC(fmov_mr(MEMW m, FR r)); |
474 |
|
|
DECLARE_MIDFUNC(fmov_ext_mr(MEMW m, FR r)); |
475 |
|
|
DECLARE_MIDFUNC(fmov_ext_rm(FW r, MEMR m)); |
476 |
|
|
DECLARE_MIDFUNC(fmov_rr(FW d, FR s)); |
477 |
|
|
DECLARE_MIDFUNC(fldcw_m_indexed(R4 index, IMM base)); |
478 |
|
|
DECLARE_MIDFUNC(ftst_r(FR r)); |
479 |
|
|
DECLARE_MIDFUNC(dont_care_fflags(void)); |
480 |
|
|
DECLARE_MIDFUNC(fsqrt_rr(FW d, FR s)); |
481 |
|
|
DECLARE_MIDFUNC(fabs_rr(FW d, FR s)); |
482 |
|
|
DECLARE_MIDFUNC(frndint_rr(FW d, FR s)); |
483 |
|
|
DECLARE_MIDFUNC(fsin_rr(FW d, FR s)); |
484 |
|
|
DECLARE_MIDFUNC(fcos_rr(FW d, FR s)); |
485 |
|
|
DECLARE_MIDFUNC(ftwotox_rr(FW d, FR s)); |
486 |
|
|
DECLARE_MIDFUNC(fetox_rr(FW d, FR s)); |
487 |
|
|
DECLARE_MIDFUNC(flog2_rr(FW d, FR s)); |
488 |
|
|
DECLARE_MIDFUNC(fneg_rr(FW d, FR s)); |
489 |
|
|
DECLARE_MIDFUNC(fadd_rr(FRW d, FR s)); |
490 |
|
|
DECLARE_MIDFUNC(fsub_rr(FRW d, FR s)); |
491 |
|
|
DECLARE_MIDFUNC(fmul_rr(FRW d, FR s)); |
492 |
|
|
DECLARE_MIDFUNC(frem_rr(FRW d, FR s)); |
493 |
|
|
DECLARE_MIDFUNC(frem1_rr(FRW d, FR s)); |
494 |
|
|
DECLARE_MIDFUNC(fdiv_rr(FRW d, FR s)); |
495 |
|
|
DECLARE_MIDFUNC(fcmp_rr(FR d, FR s)); |
496 |
|
|
DECLARE_MIDFUNC(fflags_into_flags(W2 tmp)); |
497 |
|
|
#undef DECLARE_MIDFUNC |
498 |
|
|
|
499 |
|
|
extern int failure; |
500 |
|
|
#define FAIL(x) do { failure|=x; } while (0) |
501 |
|
|
|
502 |
|
|
/* Convenience functions exposed to gencomp */ |
503 |
|
|
extern uae_u32 m68k_pc_offset; |
504 |
|
|
extern void readbyte(int address, int dest, int tmp); |
505 |
|
|
extern void readword(int address, int dest, int tmp); |
506 |
|
|
extern void readlong(int address, int dest, int tmp); |
507 |
|
|
extern void writebyte(int address, int source, int tmp); |
508 |
|
|
extern void writeword(int address, int source, int tmp); |
509 |
|
|
extern void writelong(int address, int source, int tmp); |
510 |
|
|
extern void writeword_clobber(int address, int source, int tmp); |
511 |
|
|
extern void writelong_clobber(int address, int source, int tmp); |
512 |
|
|
extern void get_n_addr(int address, int dest, int tmp); |
513 |
|
|
extern void get_n_addr_jmp(int address, int dest, int tmp); |
514 |
|
|
extern void calc_disp_ea_020(int base, uae_u32 dp, int target, int tmp); |
515 |
|
|
extern int kill_rodent(int r); |
516 |
|
|
extern void sync_m68k_pc(void); |
517 |
|
|
extern uae_u32 get_const(int r); |
518 |
|
|
extern int is_const(int r); |
519 |
|
|
extern void register_branch(uae_u32 not_taken, uae_u32 taken, uae_u8 cond); |
520 |
|
|
|
521 |
|
|
#define comp_get_ibyte(o) do_get_mem_byte((uae_u8 *)(comp_pc_p + (o) + 1)) |
522 |
|
|
#define comp_get_iword(o) do_get_mem_word((uae_u16 *)(comp_pc_p + (o))) |
523 |
|
|
#define comp_get_ilong(o) do_get_mem_long((uae_u32 *)(comp_pc_p + (o))) |
524 |
|
|
|
525 |
|
|
struct blockinfo_t; |
526 |
|
|
|
527 |
|
|
typedef struct dep_t { |
528 |
|
|
uintptr* jmp_off; |
529 |
|
|
struct blockinfo_t* target; |
530 |
|
|
struct blockinfo_t* source; |
531 |
|
|
struct dep_t** prev_p; |
532 |
|
|
struct dep_t* next; |
533 |
|
|
} dependency; |
534 |
|
|
|
535 |
gbeauche |
1.2 |
typedef struct checksum_info_t { |
536 |
|
|
uae_u8 *start_p; |
537 |
|
|
uae_u32 length; |
538 |
|
|
struct checksum_info_t *next; |
539 |
|
|
} checksum_info; |
540 |
|
|
|
541 |
gbeauche |
1.1 |
typedef struct blockinfo_t { |
542 |
|
|
uae_s32 count; |
543 |
|
|
cpuop_func* direct_handler_to_use; |
544 |
|
|
cpuop_func* handler_to_use; |
545 |
|
|
/* The direct handler does not check for the correct address */ |
546 |
|
|
|
547 |
|
|
cpuop_func* handler; |
548 |
|
|
cpuop_func* direct_handler; |
549 |
|
|
|
550 |
|
|
cpuop_func* direct_pen; |
551 |
|
|
cpuop_func* direct_pcc; |
552 |
|
|
|
553 |
|
|
uae_u8* pc_p; |
554 |
|
|
|
555 |
gbeauche |
1.3 |
uae_u32 c1; |
556 |
|
|
uae_u32 c2; |
557 |
gbeauche |
1.2 |
#if USE_CHECKSUM_INFO |
558 |
|
|
checksum_info *csi; |
559 |
|
|
#else |
560 |
gbeauche |
1.1 |
uae_u32 len; |
561 |
gbeauche |
1.2 |
uae_u32 min_pcp; |
562 |
|
|
#endif |
563 |
gbeauche |
1.1 |
|
564 |
|
|
struct blockinfo_t* next_same_cl; |
565 |
|
|
struct blockinfo_t** prev_same_cl_p; |
566 |
|
|
struct blockinfo_t* next; |
567 |
|
|
struct blockinfo_t** prev_p; |
568 |
|
|
|
569 |
|
|
uae_u8 optlevel; |
570 |
|
|
uae_u8 needed_flags; |
571 |
|
|
uae_u8 status; |
572 |
|
|
uae_u8 havestate; |
573 |
|
|
|
574 |
|
|
dependency dep[2]; /* Holds things we depend on */ |
575 |
|
|
dependency* deplist; /* List of things that depend on this */ |
576 |
|
|
smallstate env; |
577 |
|
|
|
578 |
|
|
#if JIT_DEBUG |
579 |
|
|
/* (gb) size of the compiled block (direct handler) */ |
580 |
|
|
uae_u32 direct_handler_size; |
581 |
|
|
#endif |
582 |
|
|
} blockinfo; |
583 |
|
|
|
584 |
|
|
#define BI_INVALID 0 |
585 |
|
|
#define BI_ACTIVE 1 |
586 |
|
|
#define BI_NEED_RECOMP 2 |
587 |
|
|
#define BI_NEED_CHECK 3 |
588 |
|
|
#define BI_CHECKING 4 |
589 |
|
|
#define BI_COMPILING 5 |
590 |
|
|
#define BI_FINALIZING 6 |
591 |
|
|
|
592 |
|
|
void execute_normal(void); |
593 |
|
|
void exec_nostats(void); |
594 |
|
|
void do_nothing(void); |
595 |
|
|
|
596 |
|
|
#else |
597 |
|
|
|
598 |
|
|
static __inline__ void flush_icache(int) { } |
599 |
|
|
static __inline__ void build_comp() { } |
600 |
|
|
|
601 |
|
|
#endif /* !USE_JIT */ |
602 |
|
|
|
603 |
|
|
#endif /* COMPEMU_H */ |