|
|
1.1 root 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:
602: static __inline__ void flush_icache(int) { }
603: static __inline__ void build_comp() { }
604:
605: #endif /* !USE_JIT */
606:
607: #endif /* COMPEMU_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.