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