--- hatari/src/cpu/jit/compemu.h 2019/04/09 08:49:24 1.1 +++ hatari/src/cpu/jit/compemu.h 2019/04/09 08:56:44 1.1.1.3 @@ -1,45 +1,106 @@ +/* + * compiler/compemu.h - Public interface and definitions + * + * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS) + * + * Inspired by Christian Bauer's Basilisk II + * + * This file is part of the ARAnyM project which builds a new and powerful + * TOS/FreeMiNT compatible virtual machine running on almost any hardware. + * + * JIT compiler m68k -> IA-32 and AMD64 + * + * Original 68040 JIT compiler for UAE, copyright 2000-2002 Bernd Meyer + * Adaptation for Basilisk II and improvements, copyright 2000-2004 Gwenole Beauchesne + * Portions related to CPU detection come from linux/arch/i386/kernel/setup.c + * + * ARAnyM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * ARAnyM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with ARAnyM; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ -#include "flags_x86.h" +#ifndef COMPEMU_H +#define COMPEMU_H +#include "newcpu.h" + +#ifdef UAE #ifdef CPU_64_BIT typedef uae_u64 uintptr; #else typedef uae_u32 uintptr; #endif +/* FIXME: cpummu.cpp also checks for USE_JIT, possibly others */ +#define USE_JIT +#endif -/* Flags for Bernie during development/debugging. Should go away eventually */ -#define DISTRUST_CONSISTENT_MEM 0 -#define TAGMASK 0x000fffff +#ifdef USE_JIT + +#ifdef JIT_DEBUG +/* dump some information (m68k block, x86 block addresses) about the compiler state */ +extern void compiler_dumpstate(void); +#endif + +/* Now that we do block chaining, and also have linked lists on each tag, + TAGMASK can be much smaller and still do its job. Saves several megs + of memory! */ +#define TAGMASK 0x0000ffff #define TAGSIZE (TAGMASK+1) #define MAXRUN 1024 +#define cacheline(x) (((uintptr)x)&TAGMASK) extern uae_u8* start_pc_p; extern uae_u32 start_pc; -#define cacheline(x) (((uae_u32)x)&TAGMASK) +struct blockinfo_t; -typedef struct { +struct cpu_history { uae_u16* location; - uae_u8 cycles; uae_u8 specmem; - uae_u8 dummy2; - uae_u8 dummy3; -} cpu_history; +}; -struct blockinfo_t; +union cacheline { + cpuop_func* handler; + blockinfo_t * bi; +}; + +/* Use new spill/reload strategy when calling external functions */ +#define USE_OPTIMIZED_CALLS 0 +#if USE_OPTIMIZED_CALLS +#error implementation in progress +#endif -typedef union { - cpuop_func* handler; - struct blockinfo_t* bi; -} cacheline; +/* (gb) When on, this option can save save up to 30% compilation time + * when many lazy flushes occur (e.g. apps in MacOS 8.x). + */ +#define USE_SEPARATE_BIA 1 + +/* Use chain of checksum_info_t to compute the block checksum */ +#define USE_CHECKSUM_INFO 1 + +/* Use code inlining, aka follow-up of constant jumps */ +#define USE_INLINING 1 + +/* Inlining requires the chained checksuming information */ +#if USE_INLINING +#undef USE_CHECKSUM_INFO +#define USE_CHECKSUM_INFO 1 +#endif -extern signed long pissoff; +/* Does flush_icache_range() only check for blocks falling in the requested range? */ +#define LAZY_FLUSH_ICACHE_RANGE 0 -#define USE_OPTIMIZER 0 -#define USE_LOW_OPTIMIZER 0 -#define USE_ALIAS 1 #define USE_F_ALIAS 1 -#define USE_SOFT_FLUSH 1 #define USE_OFFSET 1 #define COMP_DEBUG 1 @@ -50,12 +111,15 @@ extern signed long pissoff; #endif #define SCALE 2 -#define MAXCYCLES (1000 * CYCLE_UNIT) -#define MAXREGOPT 65536 #define BYTES_PER_INST 10240 /* paranoid ;-) */ +#if defined(CPU_arm) +#define LONGEST_68K_INST 256 /* The number of bytes the longest possible + 68k instruction takes */ +#else #define LONGEST_68K_INST 16 /* The number of bytes the longest possible 68k instruction takes */ +#endif #define MAX_CHECKSUM_LEN 2048 /* The maximum size we calculate checksums for. Anything larger will be flushed unconditionally even with SOFT_FLUSH */ @@ -73,14 +137,16 @@ extern signed long pissoff; #define KILLTHERAT 1 /* Set to 1 to avoid some partial_rat_stalls */ -/* Whether to preserve registers across calls to JIT compiled routines */ -#if defined X86_ASSEMBLY -#define USE_PUSH_POP 0 +#if defined(CPU_arm) +#define USE_DATA_BUFFER +#define N_REGS 13 /* really 16, but 13 to 15 are SP, LR, PC */ +#else +#if defined(CPU_x86_64) +#define N_REGS 16 /* really only 15, but they are numbered 0-3,5-15 */ #else -#define USE_PUSH_POP 1 -#endif - #define N_REGS 8 /* really only 7, but they are numbered 0,1,2,3,5,6,7 */ +#endif +#endif #define N_FREGS 6 /* That leaves us two positions on the stack to play with */ /* Functions exposed to newcpu, or to what was moved from newcpu.c to @@ -89,6 +155,7 @@ extern void init_comp(void); extern void flush(int save_regs); extern void small_flush(int save_regs); extern void set_target(uae_u8* t); +extern uae_u8* get_target(void); extern void freescratch(void); extern void build_comp(void); extern void set_cache_state(int enabled); @@ -96,17 +163,29 @@ extern int get_cache_state(void); extern uae_u32 get_jitted_size(void); #ifdef JIT extern void flush_icache(uaecptr ptr, int n); +extern void flush_icache_hard(uaecptr ptr, int n); +static inline void flush_icache(int n) +{ + flush_icache(0, n); +} +static inline void flush_icache_hard(int n) +{ + flush_icache(0, n); +} #endif extern void alloc_cache(void); -extern void compile_block(cpu_history* pc_hist, int blocklen, int totcyles); extern int check_for_cache_miss(void); - -#define scaled_cycles(x) (currprefs.m68k_speed==-1?(((x)/SCALE)?(((x)/SCALE= REGALLOC */ -#define DECLARE(func) extern void func; extern void do_##func -#else -#define REGALLOC_O 2000000 -#define PEEPHOLE_O 2000000 -#define DECLARE(func) extern void func +/* What we expose to the outside */ +#define DECLARE_MIDFUNC(func) extern void func + +#if defined(CPU_arm) + +#include "compemu_midfunc_arm.h" + +#if defined(USE_JIT2) +#include "compemu_midfunc_arm2.h" +#endif #endif +#if defined(CPU_i386) || defined(CPU_x86_64) +#include "compemu_midfunc_x86.h" +#endif -/* What we expose to the outside */ -DECLARE(bt_l_ri(R4 r, IMM i)); -DECLARE(bt_l_rr(R4 r, R4 b)); -DECLARE(btc_l_ri(RW4 r, IMM i)); -DECLARE(btc_l_rr(RW4 r, R4 b)); -DECLARE(bts_l_ri(RW4 r, IMM i)); -DECLARE(bts_l_rr(RW4 r, R4 b)); -DECLARE(btr_l_ri(RW4 r, IMM i)); -DECLARE(btr_l_rr(RW4 r, R4 b)); -DECLARE(mov_l_rm(W4 d, IMM s)); -DECLARE(call_r(R4 r)); -DECLARE(sub_l_mi(IMM d, IMM s)); -DECLARE(mov_l_mi(IMM d, IMM s)); -DECLARE(mov_w_mi(IMM d, IMM s)); -DECLARE(mov_b_mi(IMM d, IMM s)); -DECLARE(rol_b_ri(RW1 r, IMM i)); -DECLARE(rol_w_ri(RW2 r, IMM i)); -DECLARE(rol_l_ri(RW4 r, IMM i)); -DECLARE(rol_l_rr(RW4 d, R1 r)); -DECLARE(rol_w_rr(RW2 d, R1 r)); -DECLARE(rol_b_rr(RW1 d, R1 r)); -DECLARE(shll_l_rr(RW4 d, R1 r)); -DECLARE(shll_w_rr(RW2 d, R1 r)); -DECLARE(shll_b_rr(RW1 d, R1 r)); -DECLARE(ror_b_ri(R1 r, IMM i)); -DECLARE(ror_w_ri(R2 r, IMM i)); -DECLARE(ror_l_ri(R4 r, IMM i)); -DECLARE(ror_l_rr(R4 d, R1 r)); -DECLARE(ror_w_rr(R2 d, R1 r)); -DECLARE(ror_b_rr(R1 d, R1 r)); -DECLARE(shrl_l_rr(RW4 d, R1 r)); -DECLARE(shrl_w_rr(RW2 d, R1 r)); -DECLARE(shrl_b_rr(RW1 d, R1 r)); -DECLARE(shra_l_rr(RW4 d, R1 r)); -DECLARE(shra_w_rr(RW2 d, R1 r)); -DECLARE(shra_b_rr(RW1 d, R1 r)); -DECLARE(shll_l_ri(RW4 r, IMM i)); -DECLARE(shll_w_ri(RW2 r, IMM i)); -DECLARE(shll_b_ri(RW1 r, IMM i)); -DECLARE(shrl_l_ri(RW4 r, IMM i)); -DECLARE(shrl_w_ri(RW2 r, IMM i)); -DECLARE(shrl_b_ri(RW1 r, IMM i)); -DECLARE(shra_l_ri(RW4 r, IMM i)); -DECLARE(shra_w_ri(RW2 r, IMM i)); -DECLARE(shra_b_ri(RW1 r, IMM i)); -DECLARE(setcc(W1 d, IMM cc)); -DECLARE(setcc_m(IMM d, IMM cc)); -DECLARE(cmov_b_rr(RW1 d, R1 s, IMM cc)); -DECLARE(cmov_w_rr(RW2 d, R2 s, IMM cc)); -DECLARE(cmov_l_rr(RW4 d, R4 s, IMM cc)); -DECLARE(cmov_l_rm(RW4 d, IMM s, IMM cc)); -DECLARE(bsf_l_rr(W4 d, R4 s)); -DECLARE(pop_m(IMM d)); -DECLARE(push_m(IMM d)); -DECLARE(pop_l(W4 d)); -DECLARE(push_l_i(IMM i)); -DECLARE(push_l(R4 s)); -DECLARE(clear_16(RW4 r)); -DECLARE(clear_8(RW4 r)); -DECLARE(sign_extend_16_rr(W4 d, R2 s)); -DECLARE(sign_extend_8_rr(W4 d, R1 s)); -DECLARE(zero_extend_16_rr(W4 d, R2 s)); -DECLARE(zero_extend_8_rr(W4 d, R1 s)); -DECLARE(imul_64_32(RW4 d, RW4 s)); -DECLARE(mul_64_32(RW4 d, RW4 s)); -DECLARE(imul_32_32(RW4 d, R4 s)); -DECLARE(mov_b_rr(W1 d, R1 s)); -DECLARE(mov_w_rr(W2 d, R2 s)); -DECLARE(mov_l_rrm_indexed(W4 d, R4 baser, R4 index)); -DECLARE(mov_w_rrm_indexed(W2 d, R4 baser, R4 index)); -DECLARE(mov_b_rrm_indexed(W1 d, R4 baser, R4 index)); -DECLARE(mov_l_mrr_indexed(R4 baser, R4 index, R4 s)); -DECLARE(mov_w_mrr_indexed(R4 baser, R4 index, R2 s)); -DECLARE(mov_b_mrr_indexed(R4 baser, R4 index, R1 s)); -DECLARE(mov_l_rm_indexed(W4 d, IMM base, R4 index)); -DECLARE(mov_l_rR(W4 d, R4 s, IMM offset)); -DECLARE(mov_w_rR(W2 d, R4 s, IMM offset)); -DECLARE(mov_b_rR(W1 d, R4 s, IMM offset)); -DECLARE(mov_l_brR(W4 d, R4 s, IMM offset)); -DECLARE(mov_w_brR(W2 d, R4 s, IMM offset)); -DECLARE(mov_b_brR(W1 d, R4 s, IMM offset)); -DECLARE(mov_l_Ri(R4 d, IMM i, IMM offset)); -DECLARE(mov_w_Ri(R4 d, IMM i, IMM offset)); -DECLARE(mov_b_Ri(R4 d, IMM i, IMM offset)); -DECLARE(mov_l_Rr(R4 d, R4 s, IMM offset)); -DECLARE(mov_w_Rr(R4 d, R2 s, IMM offset)); -DECLARE(mov_b_Rr(R4 d, R1 s, IMM offset)); -DECLARE(lea_l_brr(W4 d, R4 s, IMM offset)); -DECLARE(lea_l_brr_indexed(W4 d, R4 s, R4 index, IMM factor, IMM offset)); -DECLARE(mov_l_bRr(R4 d, R4 s, IMM offset)); -DECLARE(mov_w_bRr(R4 d, R2 s, IMM offset)); -DECLARE(mov_b_bRr(R4 d, R1 s, IMM offset)); -DECLARE(gen_bswap_32(RW4 r)); -DECLARE(gen_bswap_16(RW2 r)); -DECLARE(mov_l_rr(W4 d, R4 s)); -DECLARE(mov_l_mr(IMM d, R4 s)); -DECLARE(mov_w_mr(IMM d, R2 s)); -DECLARE(mov_w_rm(W2 d, IMM s)); -DECLARE(mov_b_mr(IMM d, R1 s)); -DECLARE(mov_b_rm(W1 d, IMM s)); -DECLARE(mov_l_ri(W4 d, IMM s)); -DECLARE(mov_w_ri(W2 d, IMM s)); -DECLARE(mov_b_ri(W1 d, IMM s)); -DECLARE(add_l_mi(IMM d, IMM s) ); -DECLARE(add_w_mi(IMM d, IMM s) ); -DECLARE(add_b_mi(IMM d, IMM s) ); -DECLARE(test_l_ri(R4 d, IMM i)); -DECLARE(test_l_rr(R4 d, R4 s)); -DECLARE(test_w_rr(R2 d, R2 s)); -DECLARE(test_b_rr(R1 d, R1 s)); -DECLARE(and_l_ri(RW4 d, IMM i)); -DECLARE(and_l(RW4 d, R4 s)); -DECLARE(and_w(RW2 d, R2 s)); -DECLARE(and_b(RW1 d, R1 s)); -DECLARE(or_l_ri(RW4 d, IMM i)); -DECLARE(or_l(RW4 d, R4 s)); -DECLARE(or_w(RW2 d, R2 s)); -DECLARE(or_b(RW1 d, R1 s)); -DECLARE(adc_l(RW4 d, R4 s)); -DECLARE(adc_w(RW2 d, R2 s)); -DECLARE(adc_b(RW1 d, R1 s)); -DECLARE(add_l(RW4 d, R4 s)); -DECLARE(add_w(RW2 d, R2 s)); -DECLARE(add_b(RW1 d, R1 s)); -DECLARE(sub_l_ri(RW4 d, IMM i)); -DECLARE(sub_w_ri(RW2 d, IMM i)); -DECLARE(sub_b_ri(RW1 d, IMM i)); -DECLARE(add_l_ri(RW4 d, IMM i)); -DECLARE(add_w_ri(RW2 d, IMM i)); -DECLARE(add_b_ri(RW1 d, IMM i)); -DECLARE(sbb_l(RW4 d, R4 s)); -DECLARE(sbb_w(RW2 d, R2 s)); -DECLARE(sbb_b(RW1 d, R1 s)); -DECLARE(sub_l(RW4 d, R4 s)); -DECLARE(sub_w(RW2 d, R2 s)); -DECLARE(sub_b(RW1 d, R1 s)); -DECLARE(cmp_l(R4 d, R4 s)); -DECLARE(cmp_l_ri(R4 r, IMM i)); -DECLARE(cmp_w(R2 d, R2 s)); -DECLARE(cmp_b(R1 d, R1 s)); -DECLARE(xor_l(RW4 d, R4 s)); -DECLARE(xor_w(RW2 d, R2 s)); -DECLARE(xor_b(RW1 d, R1 s)); -DECLARE(live_flags(void)); -DECLARE(dont_care_flags(void)); -DECLARE(duplicate_carry(void)); -DECLARE(restore_carry(void)); -DECLARE(start_needflags(void)); -DECLARE(end_needflags(void)); -DECLARE(make_flags_live(void)); -DECLARE(call_r_11(R4 r, W4 out1, R4 in1, IMM osize, IMM isize)); -DECLARE(call_r_02(R4 r, R4 in1, R4 in2, IMM isize1, IMM isize2)); -DECLARE(readmem_new(R4 address, W4 dest, IMM offset, IMM size, W4 tmp)); -DECLARE(writemem_new(R4 address, R4 source, IMM offset, IMM size, W4 tmp)); -DECLARE(forget_about(W4 r)); -DECLARE(nop(void)); - -DECLARE(f_forget_about(FW r)); -DECLARE(fmov_pi(FW r)); -DECLARE(fmov_log10_2(FW r)); -DECLARE(fmov_log2_e(FW r)); -DECLARE(fmov_loge_2(FW r)); -DECLARE(fmov_1(FW r)); -DECLARE(fmov_0(FW r)); -DECLARE(fmov_rm(FW r, MEMR m)); -DECLARE(fmov_mr(MEMW m, FR r)); -DECLARE(fmovi_rm(FW r, MEMR m)); -DECLARE(fmovi_mrb(MEMW m, FR r, double *bounds)); -DECLARE(fmovs_rm(FW r, MEMR m)); -DECLARE(fmovs_mr(MEMW m, FR r)); -DECLARE(fcuts_r(FRW r)); -DECLARE(fcut_r(FRW r)); -DECLARE(fmovl_ri(FW r, IMMS i)); -DECLARE(fmovs_ri(FW r, IMM i)); -DECLARE(fmov_ri(FW r, IMM i1, IMM i2)); -DECLARE(fmov_ext_ri(FW r, IMM i1, IMM i2, IMM i3)); -DECLARE(fmov_ext_mr(MEMW m, FR r)); -DECLARE(fmov_ext_rm(FW r, MEMR m)); -DECLARE(fmov_rr(FW d, FR s)); -DECLARE(fldcw_m_indexed(R4 index, IMM base)); -DECLARE(ftst_r(FR r)); -DECLARE(dont_care_fflags(void)); -DECLARE(fsqrt_rr(FW d, FR s)); -DECLARE(fabs_rr(FW d, FR s)); -DECLARE(frndint_rr(FW d, FR s)); -DECLARE(fgetexp_rr(FW d, FR s)); -DECLARE(fgetman_rr(FW d, FR s)); -DECLARE(fsin_rr(FW d, FR s)); -DECLARE(fcos_rr(FW d, FR s)); -DECLARE(ftan_rr(FW d, FR s)); -DECLARE(fsincos_rr(FW d, FW c, FR s)); -DECLARE(fscale_rr(FRW d, FR s)); -DECLARE(ftwotox_rr(FW d, FR s)); -DECLARE(fetox_rr(FW d, FR s)); -DECLARE(fetoxM1_rr(FW d, FR s)); -DECLARE(ftentox_rr(FW d, FR s)); -DECLARE(flog2_rr(FW d, FR s)); -DECLARE(flogN_rr(FW d, FR s)); -DECLARE(flogNP1_rr(FW d, FR s)); -DECLARE(flog10_rr(FW d, FR s)); -DECLARE(fasin_rr(FW d, FR s)); -DECLARE(facos_rr(FW d, FR s)); -DECLARE(fatan_rr(FW d, FR s)); -DECLARE(fatanh_rr(FW d, FR s)); -DECLARE(fsinh_rr(FW d, FR s)); -DECLARE(fcosh_rr(FW d, FR s)); -DECLARE(ftanh_rr(FW d, FR s)); -DECLARE(fneg_rr(FW d, FR s)); -DECLARE(fadd_rr(FRW d, FR s)); -DECLARE(fsub_rr(FRW d, FR s)); -DECLARE(fmul_rr(FRW d, FR s)); -DECLARE(frem_rr(FRW d, FR s)); -DECLARE(frem1_rr(FRW d, FR s)); -DECLARE(fdiv_rr(FRW d, FR s)); -DECLARE(fcmp_rr(FR d, FR s)); -DECLARE(fflags_into_flags(W2 tmp)); +#undef DECLARE_MIDFUNC extern int failure; #define FAIL(x) do { failure|=x; } while (0) @@ -507,12 +358,14 @@ extern void writelong_clobber(int addres extern void get_n_addr(int address, int dest, int tmp); extern void get_n_addr_jmp(int address, int dest, int tmp); extern void calc_disp_ea_020(int base, uae_u32 dp, int target, int tmp); +/* Set native Z flag only if register is zero */ +extern void set_zero(int r, int tmp); extern int kill_rodent(int r); +#define SYNC_PC_OFFSET 100 extern void sync_m68k_pc(void); extern uae_u32 get_const(int r); extern int is_const(int r); extern void register_branch(uae_u32 not_taken, uae_u32 taken, uae_u8 cond); -extern void empty_optimizer(void); #define comp_get_ibyte(o) do_get_mem_byte((uae_u8 *)(comp_pc_p + (o) + 1)) #define comp_get_iword(o) do_get_mem_word((uae_u16 *)(comp_pc_p + (o))) @@ -523,10 +376,17 @@ struct blockinfo_t; typedef struct dep_t { uae_u32* jmp_off; struct blockinfo_t* target; + struct blockinfo_t* source; struct dep_t** prev_p; struct dep_t* next; } dependency; +typedef struct checksum_info_t { + uae_u8 *start_p; + uae_u32 length; + struct checksum_info_t *next; +} checksum_info; + typedef struct blockinfo_t { uae_s32 count; cpuop_func* direct_handler_to_use; @@ -544,14 +404,18 @@ typedef struct blockinfo_t { uae_u32 c1; uae_u32 c2; +#if USE_CHECKSUM_INFO + checksum_info *csi; +#else uae_u32 len; + uae_u32 min_pcp; +#endif struct blockinfo_t* next_same_cl; struct blockinfo_t** prev_same_cl_p; struct blockinfo_t* next; struct blockinfo_t** prev_p; - uae_u32 min_pcp; uae_u8 optlevel; uae_u8 needed_flags; uae_u8 status; @@ -560,11 +424,33 @@ typedef struct blockinfo_t { dependency dep[2]; /* Holds things we depend on */ dependency* deplist; /* List of things that depend on this */ smallstate env; + +#ifdef JIT_DEBUG + /* (gb) size of the compiled block (direct handler) */ + uae_u32 direct_handler_size; +#endif } blockinfo; -#define BI_NEW 0 -#define BI_COUNTING 1 -#define BI_TARGETTED 2 +#define BI_INVALID 0 +#define BI_ACTIVE 1 +#define BI_NEED_RECOMP 2 +#define BI_NEED_CHECK 3 +#define BI_CHECKING 4 +#define BI_COMPILING 5 +#define BI_FINALIZING 6 + +void execute_normal(void); +void exec_nostats(void); +void do_nothing(void); + +#else + +static inline void flush_icache(int) { } +static inline void build_comp() { } + +#endif /* !USE_JIT */ + +#ifdef UAE typedef struct { uae_u8 type; @@ -572,14 +458,74 @@ typedef struct { uae_u32 next; } regacc; -void execute_normal(void); -void exec_nostats(void); -void do_nothing(void); +#define JIT_EXCEPTION_HANDLER +// #define JIT_ALWAYS_DISTRUST -void comp_fdbcc_opp (uae_u32 opcode, uae_u16 extra); -void comp_fscc_opp (uae_u32 opcode, uae_u16 extra); -void comp_ftrapcc_opp (uae_u32 opcode, uaecptr oldpc); -void comp_fbcc_opp (uae_u32 opcode); -void comp_fsave_opp (uae_u32 opcode); -void comp_frestore_opp (uae_u32 opcode); -void comp_fpp_opp (uae_u32 opcode, uae_u16 extra); +/* ARAnyM uses fpu_register name, used in scratch_t */ +/* FIXME: check that no ARAnyM code assumes different floating point type */ +typedef fptype fpu_register; + +extern void compile_block(cpu_history* pc_hist, int blocklen, int totcyles); + +#define MAXCYCLES (1000 * CYCLE_UNIT) +#define scaled_cycles(x) (currprefs.m68k_speed<0?(((x)/SCALE)?(((x)/SCALE (uintptr_t) 0xffffffff) { + jit_abort("JIT: 64-bit pointer (0x%llx) at %s:%d (fatal)", + address, file, line); + } + return (uae_u32) address; +} +#define uae_p32(x) (check_uae_p32((uae_u64)(x), __FILE__, __LINE__)) +#else +#define uae_p32(x) ((uae_u32)(x)) +#endif + +#endif /* COMPEMU_H */