132 |
|
} |
133 |
|
#endif |
134 |
|
|
135 |
– |
#if ! USE_PUSH_POP |
136 |
– |
static void (*m68k_do_compile_execute)(void) = NULL; |
137 |
– |
#endif |
138 |
– |
|
135 |
|
static compop_func *compfunctbl[65536]; |
136 |
|
static compop_func *nfcompfunctbl[65536]; |
137 |
|
static cpuop_func *nfcpufunctbl[65536]; |
6007 |
|
|
6008 |
|
current_compile_p=popallspace; |
6009 |
|
set_target(current_compile_p); |
6010 |
< |
#if USE_PUSH_POP |
6011 |
< |
/* If we can't use gcc inline assembly, we need to pop some |
6012 |
< |
registers before jumping back to the various get-out routines. |
6013 |
< |
This generates the code for it. |
6014 |
< |
*/ |
6010 |
> |
|
6011 |
> |
/* We need to guarantee 16-byte stack alignment on x86 at any point |
6012 |
> |
within the JIT generated code. We have multiple exit points |
6013 |
> |
possible but a single entry. A "jmp" is used so that we don't |
6014 |
> |
have to generate stack alignment in generated code that has to |
6015 |
> |
call external functions (e.g. a generic instruction handler). |
6016 |
> |
|
6017 |
> |
In summary, JIT generated code is not leaf so we have to deal |
6018 |
> |
with it here to maintain correct stack alignment. */ |
6019 |
> |
align_target(align_jumps); |
6020 |
> |
current_compile_p=get_target(); |
6021 |
> |
pushall_call_handler=get_target(); |
6022 |
> |
for (i=N_REGS;i--;) { |
6023 |
> |
if (need_to_preserve[i]) |
6024 |
> |
raw_push_l_r(i); |
6025 |
> |
} |
6026 |
> |
raw_dec_sp(stack_space); |
6027 |
> |
r=REG_PC_TMP; |
6028 |
> |
raw_mov_l_rm(r,(uintptr)®s.pc_p); |
6029 |
> |
raw_and_l_ri(r,TAGMASK); |
6030 |
> |
raw_jmp_m_indexed((uintptr)cache_tags,r,SIZEOF_VOID_P); |
6031 |
> |
|
6032 |
> |
/* now the exit points */ |
6033 |
|
align_target(align_jumps); |
6034 |
|
popall_do_nothing=get_target(); |
6035 |
|
raw_inc_sp(stack_space); |
6084 |
|
} |
6085 |
|
raw_jmp((uintptr)check_checksum); |
6086 |
|
|
6073 |
– |
align_target(align_jumps); |
6074 |
– |
current_compile_p=get_target(); |
6075 |
– |
#else |
6076 |
– |
popall_exec_nostats=(void *)exec_nostats; |
6077 |
– |
popall_execute_normal=(void *)execute_normal; |
6078 |
– |
popall_cache_miss=(void *)cache_miss; |
6079 |
– |
popall_recompile_block=(void *)recompile_block; |
6080 |
– |
popall_do_nothing=(void *)do_nothing; |
6081 |
– |
popall_check_checksum=(void *)check_checksum; |
6082 |
– |
#endif |
6083 |
– |
|
6084 |
– |
/* And now, the code to do the matching pushes and then jump |
6085 |
– |
into a handler routine */ |
6086 |
– |
pushall_call_handler=get_target(); |
6087 |
– |
#if USE_PUSH_POP |
6088 |
– |
for (i=N_REGS;i--;) { |
6089 |
– |
if (need_to_preserve[i]) |
6090 |
– |
raw_push_l_r(i); |
6091 |
– |
} |
6092 |
– |
#endif |
6093 |
– |
raw_dec_sp(stack_space); |
6094 |
– |
r=REG_PC_TMP; |
6095 |
– |
raw_mov_l_rm(r,(uintptr)®s.pc_p); |
6096 |
– |
raw_and_l_ri(r,TAGMASK); |
6097 |
– |
raw_jmp_m_indexed((uintptr)cache_tags,r,SIZEOF_VOID_P); |
6098 |
– |
|
6099 |
– |
#if ! USE_PUSH_POP |
6100 |
– |
align_target(align_jumps); |
6101 |
– |
m68k_do_compile_execute = (void (*)(void))get_target(); |
6102 |
– |
for (i=N_REGS;i--;) { |
6103 |
– |
if (need_to_preserve[i]) |
6104 |
– |
raw_push_l_r(i); |
6105 |
– |
} |
6106 |
– |
raw_dec_sp(stack_space); |
6107 |
– |
align_target(align_loops); |
6108 |
– |
uae_u32 dispatch_loop = (uintptr)get_target(); |
6109 |
– |
r=REG_PC_TMP; |
6110 |
– |
raw_mov_l_rm(r,(uintptr)®s.pc_p); |
6111 |
– |
raw_and_l_ri(r,TAGMASK); |
6112 |
– |
raw_call_m_indexed((uintptr)cache_tags,r,SIZEOF_VOID_P); |
6113 |
– |
raw_cmp_l_mi((uintptr)®s.spcflags,0); |
6114 |
– |
raw_jcc_b_oponly(NATIVE_CC_EQ); |
6115 |
– |
emit_byte(dispatch_loop-((uintptr)get_target()+1)); |
6116 |
– |
raw_call((uintptr)m68k_do_specialties); |
6117 |
– |
raw_test_l_rr(REG_RESULT,REG_RESULT); |
6118 |
– |
raw_jcc_b_oponly(NATIVE_CC_EQ); |
6119 |
– |
emit_byte(dispatch_loop-((uintptr)get_target()+1)); |
6120 |
– |
raw_cmp_b_mi((uintptr)&quit_program,0); |
6121 |
– |
raw_jcc_b_oponly(NATIVE_CC_EQ); |
6122 |
– |
emit_byte(dispatch_loop-((uintptr)get_target()+1)); |
6123 |
– |
raw_inc_sp(stack_space); |
6124 |
– |
for (i=0;i<N_REGS;i++) { |
6125 |
– |
if (need_to_preserve[i]) |
6126 |
– |
raw_pop_l_r(i); |
6127 |
– |
} |
6128 |
– |
raw_ret(); |
6129 |
– |
#endif |
6130 |
– |
|
6087 |
|
// no need to further write into popallspace |
6088 |
|
vm_protect(popallspace, POPALLSPACE_SIZE, VM_PAGE_READ | VM_PAGE_EXECUTE); |
6089 |
|
} |
7081 |
|
|
7082 |
|
typedef void (*compiled_handler)(void); |
7083 |
|
|
7084 |
< |
#if USE_PUSH_POP |
7129 |
< |
void m68k_do_compile_execute(void) |
7084 |
> |
static void m68k_do_compile_execute(void) |
7085 |
|
{ |
7086 |
|
for (;;) { |
7087 |
|
((compiled_handler)(pushall_call_handler))(); |
7092 |
|
} |
7093 |
|
} |
7094 |
|
} |
7140 |
– |
#endif |
7095 |
|
|
7096 |
|
void m68k_compile_execute (void) |
7097 |
|
{ |