diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake index 60c7ba31e..bdc937da8 100644 --- a/cmake/dependencies.cmake +++ b/cmake/dependencies.cmake @@ -74,15 +74,27 @@ int main (void) { return 0; } set_cmake_required () list ( INSERT CMAKE_REQUIRED_FLAGS 0 -m32 ) check_c_source_compiles ( "${_code}" ARCH_X86 ) +set ( _code " +#if defined(__powerpc) || defined(__powerpc__) || defined(_M_PPC) || defined(_ARCH_PPC) +int main (void) { return 0; } +#else +#error cmake_FAIL +#endif +" ) +set_cmake_required () +list ( INSERT CMAKE_REQUIRED_FLAGS 0 -m32 ) +check_c_source_compiles ( "${_code}" ARCH_PPC32 ) if ( ARCH_AMD64 ) set ( _default "amd64" ) elseif ( ARCH_X86 ) set ( _default "x86" ) +elseif ( ARCH_PPC32 ) + set ( _default "ppc32" ) else () set ( _default "nojit" ) endif () -set ( DYNAMIPS_ARCH "${_default}" CACHE STRING "Target architecture (amd64;x86;nojit)" ) -set_property ( CACHE DYNAMIPS_ARCH PROPERTY STRINGS "amd64" "x86" "nojit" ) +set ( DYNAMIPS_ARCH "${_default}" CACHE STRING "Target architecture (amd64;x86;ppc32;nojit)" ) +set_property ( CACHE DYNAMIPS_ARCH PROPERTY STRINGS "amd64" "x86" "ppc32" "nojit" ) if ( NOT DYNAMIPS_ARCH ) set ( DYNAMIPS_ARCH "${_default}" ) endif () @@ -90,11 +102,13 @@ if ( "amd64" STREQUAL "${DYNAMIPS_ARCH}" AND ARCH_AMD64 ) list ( INSERT DYNAMIPS_FLAGS 0 -m64 ) elseif ( "x86" STREQUAL "${DYNAMIPS_ARCH}" AND ARCH_X86 ) list ( INSERT DYNAMIPS_FLAGS 0 -m32 ) +elseif ( "ppc32" STREQUAL "${DYNAMIPS_ARCH}" AND ARCH_PPC32 ) + list ( INSERT DYNAMIPS_FLAGS 0 -m32 ) elseif ( NOT "nojit" STREQUAL "${DYNAMIPS_ARCH}" ) - print_variables ( ARCH_AMD64 ARCH_X86 DYNAMIPS_ARCH ) + print_variables ( ARCH_AMD64 ARCH_X86 ARCH_PPC32 DYNAMIPS_ARCH ) message ( FATAL_ERROR "cannot build target arch DYNAMIPS_ARCH=${DYNAMIPS_ARCH}" ) endif () -print_variables ( ARCH_AMD64 ARCH_X86 DYNAMIPS_ARCH ) +print_variables ( ARCH_AMD64 ARCH_X86 ARCH_PPC32 DYNAMIPS_ARCH ) # Compiler flags foreach ( _flag diff --git a/common/ppc32_ppc32_trans.c b/common/ppc32_ppc32_trans.c new file mode 100644 index 000000000..0e1470c8e --- /dev/null +++ b/common/ppc32_ppc32_trans.c @@ -0,0 +1,2 @@ +/* not supported */ +#include "ppc32_nojit_trans.c" diff --git a/common/ppc32_ppc32_trans.h b/common/ppc32_ppc32_trans.h new file mode 100644 index 000000000..71e3e1bec --- /dev/null +++ b/common/ppc32_ppc32_trans.h @@ -0,0 +1,2 @@ +/* not supported */ +#include "ppc32_nojit_trans.h" diff --git a/stable/CMakeLists.txt b/stable/CMakeLists.txt index c907da32c..7e16896f2 100644 --- a/stable/CMakeLists.txt +++ b/stable/CMakeLists.txt @@ -269,6 +269,20 @@ maybe_rename_to_dynamips ( dynamips_x86_stable ) install_executable ( dynamips_x86_stable ) endif () +# dynamips_ppc32_stable +if ( "ppc32" STREQUAL "${DYNAMIPS_ARCH}" ) +add_compile_options( -Wa,-mregnames ) # allow powerpc register names +add_executable ( dynamips_ppc32_stable + ${_files} + "${LOCAL}/mips64_ppc32_trans.c" + "${COMMON}/ppc32_ppc32_trans.c" + ) +add_dependencies ( dynamips_ppc32_stable ${_dependencies} ) +target_link_libraries ( dynamips_ppc32_stable ${DYNAMIPS_LIBRARIES} ) +maybe_rename_to_dynamips ( dynamips_ppc32_stable ) +install_executable ( dynamips_ppc32_stable ) +endif () + # dynamips_nojit_stable if ( "nojit" STREQUAL "${DYNAMIPS_ARCH}" ) add_executable ( dynamips_nojit_stable diff --git a/stable/mips64_ppc32_trans.c b/stable/mips64_ppc32_trans.c new file mode 100644 index 000000000..7a3bf1bf6 --- /dev/null +++ b/stable/mips64_ppc32_trans.c @@ -0,0 +1,2 @@ +/* not supported */ +#include "mips64_nojit_trans.c" diff --git a/stable/mips64_ppc32_trans.h b/stable/mips64_ppc32_trans.h new file mode 100644 index 000000000..99e6e2a2b --- /dev/null +++ b/stable/mips64_ppc32_trans.h @@ -0,0 +1,2 @@ +/* not supported */ +#include "mips64_nojit_trans.h" diff --git a/unstable/CMakeLists.txt b/unstable/CMakeLists.txt index 76e7ba03d..87bea495d 100644 --- a/unstable/CMakeLists.txt +++ b/unstable/CMakeLists.txt @@ -224,6 +224,20 @@ maybe_rename_to_dynamips ( dynamips_x86_unstable ) install_executable ( dynamips_x86_unstable ) endif () +# dynamips_ppc32_unstable +if ( "ppc32" STREQUAL "${DYNAMIPS_ARCH}" ) +add_compile_options( -Wa,-mregnames ) # allow powerpc register names +add_executable ( dynamips_ppc32_unstable + ${_files} + "${LOCAL}/mips64_ppc32_trans.c" + "${COMMON}/ppc32_ppc32_trans.c" + ) +add_dependencies ( dynamips_ppc32_unstable ${_dependencies} ) +target_link_libraries ( dynamips_ppc32_unstable ${DYNAMIPS_LIBRARIES} -mregnames ) +maybe_rename_to_dynamips ( dynamips_ppc32_unstable ) +install_executable ( dynamips_ppc32_unstable ) +endif () + # dynamips_nojit_unstable if ( "nojit" STREQUAL "${DYNAMIPS_ARCH}" ) add_executable ( dynamips_nojit_unstable diff --git a/unstable/mips64_ppc32_trans.c b/unstable/mips64_ppc32_trans.c index cdc7c4d23..bb5df077a 100644 --- a/unstable/mips64_ppc32_trans.c +++ b/unstable/mips64_ppc32_trans.c @@ -26,7 +26,7 @@ #define MEMOP_OFFSET(op) (OFFSET(cpu_mips_t,mem_op_fn[(op)])) #define DECLARE_INSN(name) \ - static int mips64_emit_##name(cpu_mips_t *cpu,mips64_jit_tcb_t *b, \ + static int mips64_emit_##name(cpu_mips_t *cpu,cpu_tc_t *b, \ mips_insn_t insn) /* Set an IRQ */ @@ -49,7 +49,7 @@ void mips64_clear_irq(cpu_mips_t *cpu,m_uint8_t irq) } /* Set the Pointer Counter (PC) register */ -void mips64_set_pc(mips64_jit_tcb_t *b,m_uint64_t new_pc) +void mips64_set_pc(cpu_tc_t *b,m_uint64_t new_pc) { ppc_load(b->jit_ptr,ppc_r0,new_pc >> 32); ppc_stw(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,pc),ppc_r3); @@ -58,7 +58,7 @@ void mips64_set_pc(mips64_jit_tcb_t *b,m_uint64_t new_pc) } /* Set the Return Address (RA) register */ -void mips64_set_ra(mips64_jit_tcb_t *b,m_uint64_t ret_pc) +void mips64_set_ra(cpu_tc_t *b,m_uint64_t ret_pc) { ppc_load(b->jit_ptr,ppc_r0,ret_pc >> 32); ppc_stw(b->jit_ptr,ppc_r0,REG_OFFSET(MIPS_GPR_RA),ppc_r3); @@ -70,19 +70,22 @@ void mips64_set_ra(mips64_jit_tcb_t *b,m_uint64_t ret_pc) * Try to branch directly to the specified JIT block without returning to * main loop. */ -static void mips64_try_direct_far_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b, +static void mips64_try_direct_far_jump(cpu_mips_t *cpu,cpu_tc_t *b, m_uint64_t new_pc) { m_uint64_t new_page; m_uint32_t pc_hash,pc_offset; - u_char *test1,*test2,*test3,*test4; + u_char *test1,*test2,*test3,*test4,*test5; new_page = new_pc & MIPS_MIN_PAGE_MASK; pc_offset = ((new_pc & MIPS_MIN_PAGE_IMASK) >> 2) * sizeof(u_char *); - pc_hash = mips64_jit_get_pc_hash(new_pc) * sizeof(mips64_jit_tcb_t *); + pc_hash = mips64_jit_get_virt_hash(new_pc) * sizeof(cpu_tb_t *); + + /* Get generic CPU pointer */ + ppc_lwz(b->jit_ptr,ppc_r5,OFFSET(cpu_mips_t,gen),ppc_r3); /* Get JIT block info in r4 */ - ppc_lwz(b->jit_ptr,ppc_r4,OFFSET(cpu_mips_t,exec_blk_map),ppc_r3); + ppc_lwz(b->jit_ptr,ppc_r4,OFFSET(cpu_gen_t,tb_virt_hash),ppc_r5); /* Check if offset is too big for a 16-bit immediate value */ if (pc_hash > 0x7fff) ppc_addis(b->jit_ptr,ppc_r4,ppc_r4,ppc_ha16(pc_hash)); @@ -93,13 +96,13 @@ static void mips64_try_direct_far_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b, test1 = b->jit_ptr; ppc_bc(b->jit_ptr,PPC_BR_TRUE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0); - /* r5:r6 = start_pc, r7:r8 = new_page */ - ppc_lwz(b->jit_ptr,ppc_r5,OFFSET(mips64_jit_tcb_t,start_pc),ppc_r4); - ppc_lwz(b->jit_ptr,ppc_r6,OFFSET(mips64_jit_tcb_t,start_pc)+4,ppc_r4); + /* r5:r6 = vaddr, r7:r8 = new_page */ + ppc_lwz(b->jit_ptr,ppc_r5,OFFSET(cpu_tb_t,vaddr),ppc_r4); /* XXX assumes big endian host */ + ppc_lwz(b->jit_ptr,ppc_r6,OFFSET(cpu_tb_t,vaddr)+4,ppc_r4); ppc_load(b->jit_ptr,ppc_r7,new_page >> 32); ppc_load(b->jit_ptr,ppc_r8,new_page & 0xffffffff); - /* Check block PC (lower 32-bits first) */ + /* Check block virtual address (lower 32-bits first) */ ppc_cmpw(b->jit_ptr,ppc_cr7,ppc_r6,ppc_r8); test2 = b->jit_ptr; ppc_bc(b->jit_ptr,PPC_BR_FALSE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_EQ),0); @@ -109,11 +112,19 @@ static void mips64_try_direct_far_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b, test3 = b->jit_ptr; ppc_bc(b->jit_ptr,PPC_BR_FALSE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_EQ),0); + /* Get pointer to the Translated Code block */ + ppc_lwz(b->jit_ptr,ppc_r5,OFFSET(cpu_tb_t,tc),ppc_r4); + + ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r5,0); + test4 = b->jit_ptr; + ppc_bc(b->jit_ptr,PPC_BR_TRUE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0); + /* Jump to the code */ - ppc_lwz(b->jit_ptr,ppc_r4,OFFSET(mips64_jit_tcb_t,jit_insn_ptr),ppc_r4); + ppc_lwz(b->jit_ptr,ppc_r4,OFFSET(cpu_tc_t,jit_insn_ptr),ppc_r5); ppc_lwz(b->jit_ptr,ppc_r12,pc_offset,ppc_r4); + ppc_cmpwi(b->jit_ptr,ppc_cr7,ppc_r12,0); - test4 = b->jit_ptr; + test5 = b->jit_ptr; ppc_bc(b->jit_ptr,PPC_BR_TRUE_UNLIKELY,ppc_crbf(ppc_cr7,PPC_BR_EQ),0); ppc_mtlr(b->jit_ptr,ppc_r12); ppc_blr(b->jit_ptr); @@ -123,13 +134,14 @@ static void mips64_try_direct_far_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b, ppc_patch(test2,b->jit_ptr); ppc_patch(test3,b->jit_ptr); ppc_patch(test4,b->jit_ptr); + ppc_patch(test5,b->jit_ptr); mips64_set_pc(b,new_pc); mips64_jit_tcb_push_epilog(b); } /* Set Jump */ -static void mips64_set_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b, +static void mips64_set_jump(cpu_mips_t *cpu,cpu_tc_t *b, m_uint64_t new_pc,int local_jump) { int return_to_caller = FALSE; @@ -156,7 +168,7 @@ static void mips64_set_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b, Also notice that += 16 hack depends on insn_block_record_patch is called for unconditional branch only. */ - mips64_jit_tcb_record_patch(b,b->jit_ptr,new_pc); + mips64_jit_tcb_record_patch(cpu,b,b->jit_ptr,new_pc); b->jit_ptr += 16; /*ppc_nop(b->jit_ptr); ppc_nop(b->jit_ptr); @@ -175,7 +187,7 @@ static void mips64_set_jump(cpu_mips_t *cpu,mips64_jit_tcb_t *b, } /* Basic C call */ -static forced_inline void mips64_emit_basic_c_call(mips64_jit_tcb_t *b,void *f) +static forced_inline void mips64_emit_basic_c_call(cpu_tc_t *b,void *f) { ppc_emit_jump_code(b->jit_ptr, (u_char *)f, 1/*linked*/); /* Restore the volatile r3 */ @@ -183,14 +195,14 @@ static forced_inline void mips64_emit_basic_c_call(mips64_jit_tcb_t *b,void *f) } /* Emit a simple call to a C function without any parameter */ -static void mips64_emit_c_call(mips64_jit_tcb_t *b,void *f) +static void mips64_emit_c_call(cpu_tc_t *b,void *f) { - mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2)); + mips64_set_pc(b,b->vaddr+((b->trans_pos-1)<<2)); mips64_emit_basic_c_call(b,f); } /* Single-step operation */ -void mips64_emit_single_step(mips64_jit_tcb_t *b,mips_insn_t insn) +void mips64_emit_single_step(cpu_tc_t *b,mips_insn_t insn) { ppc_load(b->jit_ptr,ppc_r4,insn); // mips64_emit_basic_c_call(b,mips64_exec_single_step); @@ -202,10 +214,10 @@ void mips64_emit_single_step(mips64_jit_tcb_t *b,mips_insn_t insn) } /* Fast memory operation prototype */ -typedef void (*memop_fast_access)(mips64_jit_tcb_t *b,int target); +typedef void (*memop_fast_access)(cpu_tc_t *b,int target); /* Fast LB */ -static void mips64_memop_fast_lb(mips64_jit_tcb_t *b,int target) +static void mips64_memop_fast_lb(cpu_tc_t *b,int target) { ppc_lbzx(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8); ppc_extsb(b->jit_ptr,ppc_r10,ppc_r10); @@ -215,7 +227,7 @@ static void mips64_memop_fast_lb(mips64_jit_tcb_t *b,int target) } /* Fast LBU */ -static void mips64_memop_fast_lbu(mips64_jit_tcb_t *b,int target) +static void mips64_memop_fast_lbu(cpu_tc_t *b,int target) { ppc_lbzx(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8); ppc_li(b->jit_ptr,ppc_r0,0); @@ -224,7 +236,7 @@ static void mips64_memop_fast_lbu(mips64_jit_tcb_t *b,int target) } /* Fast LD */ -static void mips64_memop_fast_ld(mips64_jit_tcb_t *b,int target) +static void mips64_memop_fast_ld(cpu_tc_t *b,int target) { ppc_lwzux(b->jit_ptr,ppc_r9,ppc_r7,ppc_r8); ppc_lwz(b->jit_ptr,ppc_r10,4,ppc_r7); @@ -233,7 +245,7 @@ static void mips64_memop_fast_ld(mips64_jit_tcb_t *b,int target) } /* Fast LH */ -static void mips64_memop_fast_lh(mips64_jit_tcb_t *b,int target) +static void mips64_memop_fast_lh(cpu_tc_t *b,int target) { ppc_lhax(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8); ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31); @@ -242,7 +254,7 @@ static void mips64_memop_fast_lh(mips64_jit_tcb_t *b,int target) } /* Fast LHU */ -static void mips64_memop_fast_lhu(mips64_jit_tcb_t *b,int target) +static void mips64_memop_fast_lhu(cpu_tc_t *b,int target) { ppc_lhzx(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8); ppc_li(b->jit_ptr,ppc_r0,0); @@ -251,7 +263,7 @@ static void mips64_memop_fast_lhu(mips64_jit_tcb_t *b,int target) } /* Fast LW */ -static void mips64_memop_fast_lw(mips64_jit_tcb_t *b,int target) +static void mips64_memop_fast_lw(cpu_tc_t *b,int target) { ppc_lwzx(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8); ppc_srawi(b->jit_ptr,ppc_r0,ppc_r10,31); @@ -260,7 +272,7 @@ static void mips64_memop_fast_lw(mips64_jit_tcb_t *b,int target) } /* Fast LWU */ -static void mips64_memop_fast_lwu(mips64_jit_tcb_t *b,int target) +static void mips64_memop_fast_lwu(cpu_tc_t *b,int target) { ppc_lwzx(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8); ppc_li(b->jit_ptr,ppc_r0,0); @@ -269,14 +281,14 @@ static void mips64_memop_fast_lwu(mips64_jit_tcb_t *b,int target) } /* Fast SB */ -static void mips64_memop_fast_sb(mips64_jit_tcb_t *b,int target) +static void mips64_memop_fast_sb(cpu_tc_t *b,int target) { ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(target)+4,ppc_r3); ppc_stbx(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8); } /* Fast SD */ -static void mips64_memop_fast_sd(mips64_jit_tcb_t *b,int target) +static void mips64_memop_fast_sd(cpu_tc_t *b,int target) { ppc_lwz(b->jit_ptr,ppc_r9,REG_OFFSET(target),ppc_r3); ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(target)+4,ppc_r3); @@ -285,21 +297,21 @@ static void mips64_memop_fast_sd(mips64_jit_tcb_t *b,int target) } /* Fast SH */ -static void mips64_memop_fast_sh(mips64_jit_tcb_t *b,int target) +static void mips64_memop_fast_sh(cpu_tc_t *b,int target) { ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(target)+4,ppc_r3); ppc_sthx(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8); } /* Fast SW */ -static void mips64_memop_fast_sw(mips64_jit_tcb_t *b,int target) +static void mips64_memop_fast_sw(cpu_tc_t *b,int target) { ppc_lwz(b->jit_ptr,ppc_r10,REG_OFFSET(target)+4,ppc_r3); ppc_stwx(b->jit_ptr,ppc_r10,ppc_r7,ppc_r8); } /* Fast memory operation (64-bit) */ -static void mips64_emit_memop_fast64(mips64_jit_tcb_t *b,int write_op, +static void mips64_emit_memop_fast64(cpu_tc_t *b,int write_op, int opcode,int base,int offset, int target,int keep_ll_bit, memop_fast_access op_handler) @@ -378,7 +390,7 @@ static void mips64_emit_memop_fast64(mips64_jit_tcb_t *b,int write_op, ppc_lwz(b->jit_ptr,ppc_r12,MEMOP_OFFSET(opcode),ppc_r3); ppc_mtlr(b->jit_ptr,ppc_r12); /* Save PC for exception handling */ - mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2)); + mips64_set_pc(b,b->vaddr+((b->trans_pos-1)<<2)); /* r6 = target register */ ppc_li(b->jit_ptr,ppc_r6,target); /* Call memory function */ @@ -390,7 +402,7 @@ static void mips64_emit_memop_fast64(mips64_jit_tcb_t *b,int write_op, } /* Fast memory operation (32-bit) */ -static void mips64_emit_memop_fast32(mips64_jit_tcb_t *b,int write_op, +static void mips64_emit_memop_fast32(cpu_tc_t *b,int write_op, int opcode,int base,int offset, int target,int keep_ll_bit, memop_fast_access op_handler) @@ -456,7 +468,7 @@ static void mips64_emit_memop_fast32(mips64_jit_tcb_t *b,int write_op, ppc_lwz(b->jit_ptr,ppc_r12,MEMOP_OFFSET(opcode),ppc_r3); ppc_mtlr(b->jit_ptr,ppc_r12); /* Save PC for exception handling */ - mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2)); + mips64_set_pc(b,b->vaddr+((b->trans_pos-1)<<2)); /* r4 = sign extention of r5 */ ppc_srawi(b->jit_ptr,ppc_r4,ppc_r5,31); /* r6 = target register */ @@ -470,7 +482,7 @@ static void mips64_emit_memop_fast32(mips64_jit_tcb_t *b,int write_op, } /* Fast memory operation */ -static void mips64_emit_memop_fast(cpu_mips_t *cpu,mips64_jit_tcb_t *b, +static void mips64_emit_memop_fast(cpu_mips_t *cpu,cpu_tc_t *b, int write_op,int opcode, int base,int offset, int target,int keep_ll_bit, @@ -489,7 +501,7 @@ static void mips64_emit_memop_fast(cpu_mips_t *cpu,mips64_jit_tcb_t *b, } /* Memory operation */ -static void mips64_emit_memop(mips64_jit_tcb_t *b,int opcode,int base,int offset, +static void mips64_emit_memop(cpu_tc_t *b,int opcode,int base,int offset, int target,int keep_ll_bit) { /* lr = r12 = address of memory function */ @@ -497,7 +509,7 @@ static void mips64_emit_memop(mips64_jit_tcb_t *b,int opcode,int base,int offset ppc_mtlr(b->jit_ptr,ppc_r12); /* Save PC for exception handling */ - mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2)); + mips64_set_pc(b,b->vaddr+((b->trans_pos-1)<<2)); if (!keep_ll_bit) { ppc_li(b->jit_ptr,ppc_r0,0); ppc_stw(b->jit_ptr,ppc_r0,OFFSET(cpu_mips_t,ll_bit),ppc_r3); @@ -525,10 +537,10 @@ static void mips64_emit_memop(mips64_jit_tcb_t *b,int opcode,int base,int offset } /* Coprocessor Register transfert operation */ -static void mips64_emit_cp_xfr_op(mips64_jit_tcb_t *b,int rt,int rd,void (*f)(cpu_mips_t *cpu,u_int gp_reg,u_int cp0_reg)) +static void mips64_emit_cp_xfr_op(cpu_tc_t *b,int rt,int rd,void (*f)(cpu_mips_t *cpu,u_int gp_reg,u_int cp0_reg)) { /* update pc */ - mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2)); + mips64_set_pc(b,b->vaddr+((b->trans_pos-1)<<2)); /* r3 = CPU instance pointer */ /* r4 = gpr */ @@ -541,7 +553,7 @@ static void mips64_emit_cp_xfr_op(mips64_jit_tcb_t *b,int rt,int rd,void (*f)(cp } /* Virtual Breakpoint */ -void mips64_emit_breakpoint(mips64_jit_tcb_t *b) +void mips64_emit_breakpoint(cpu_tc_t *b) { mips64_emit_c_call(b,mips64_run_breakpoint); } @@ -556,7 +568,7 @@ static void mips64_unknown_opcode(cpu_mips_t *cpu,m_uint32_t opcode) } /* Emit unhandled instruction code */ -static int mips64_emit_unknown(cpu_mips_t *cpu,mips64_jit_tcb_t *b, +static int mips64_emit_unknown(cpu_mips_t *cpu,cpu_tc_t *b, mips_insn_t opcode) { ppc_load(b->jit_ptr,ppc_r4,opcode); @@ -577,7 +589,7 @@ static void mips64_invalid_delay_slot(cpu_mips_t *cpu) } /* Emit invalid delay slot */ -int mips64_emit_invalid_delay_slot(mips64_jit_tcb_t *b) +int mips64_emit_invalid_delay_slot(cpu_tc_t *b) { /* Restore link register */ ppc_lwz(b->jit_ptr,ppc_r0,PPC_STACK_DECREMENTER+PPC_RET_ADDR_OFFSET,ppc_r1); @@ -592,7 +604,7 @@ int mips64_emit_invalid_delay_slot(mips64_jit_tcb_t *b) * Increment count register and trigger the timer IRQ if value in compare * register is the same. */ -void mips64_inc_cp0_count_reg(mips64_jit_tcb_t *b) +void mips64_inc_cp0_count_reg(cpu_tc_t *b) { ppc_lwz(b->jit_ptr,ppc_r4,OFFSET(cpu_mips_t,cp0_virt_cnt_reg),ppc_r3); ppc_addi(b->jit_ptr,ppc_r4,ppc_r4,1); // addi takes 0 instead of r0 @@ -600,7 +612,7 @@ void mips64_inc_cp0_count_reg(mips64_jit_tcb_t *b) } /* Check if there are pending IRQ */ -void mips64_check_pending_irq(mips64_jit_tcb_t *b) +void mips64_check_pending_irq(cpu_tc_t *b) { u_char *test1; @@ -611,7 +623,7 @@ void mips64_check_pending_irq(mips64_jit_tcb_t *b) ppc_bc(b->jit_ptr,PPC_BR_TRUE,ppc_crbf(ppc_cr7,PPC_BR_EQ),0); /* Save PC */ - mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2)); + mips64_set_pc(b,b->vaddr+((b->trans_pos-1)<<2)); /* Trigger the IRQ */ mips64_emit_basic_c_call(b,mips64_trigger_irq); @@ -621,7 +633,7 @@ void mips64_check_pending_irq(mips64_jit_tcb_t *b) } /* Increment the number of executed instructions (performance debugging) */ -void mips64_inc_perf_counter(mips64_jit_tcb_t *b) +void mips64_inc_perf_counter(cpu_tc_t *b) { ppc_lwz(b->jit_ptr,ppc_r4,OFFSET(cpu_mips_t,perf_counter),ppc_r3); ppc_addi(b->jit_ptr,ppc_r4,ppc_r4,1); // addi takes 0 instead of r0 @@ -741,7 +753,7 @@ DECLARE_INSN(B) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* insert the instruction in the delay slot */ @@ -759,11 +771,11 @@ DECLARE_INSN(BAL) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* set the return address (instruction after the delay slot) */ - mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2)); + mips64_set_ra(b,b->vaddr + ((b->trans_pos + 1) << 2)); /* insert the instruction in the delay slot */ mips64_jit_fetch_and_emit(cpu,b,1); @@ -783,7 +795,7 @@ DECLARE_INSN(BEQ) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* @@ -826,7 +838,7 @@ DECLARE_INSN(BEQL) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* @@ -865,7 +877,7 @@ DECLARE_INSN(BEQZ) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* @@ -905,7 +917,7 @@ DECLARE_INSN(BNEZ) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* @@ -946,7 +958,7 @@ DECLARE_INSN(BGEZ) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* If sign bit is set, don't take the branch */ @@ -977,11 +989,11 @@ DECLARE_INSN(BGEZAL) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* set the return address (instruction after the delay slot) */ - mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2)); + mips64_set_ra(b,b->vaddr + ((b->trans_pos + 1) << 2)); /* If sign bit is set, don't take the branch */ ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3); @@ -1011,11 +1023,11 @@ DECLARE_INSN(BGEZALL) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* set the return address (instruction after the delay slot) */ - mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2)); + mips64_set_ra(b,b->vaddr + ((b->trans_pos + 1) << 2)); /* if sign bit is set, don't take the branch */ ppc_lwz(b->jit_ptr,ppc_r5,REG_OFFSET(rs),ppc_r3); @@ -1042,7 +1054,7 @@ DECLARE_INSN(BGEZL) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* If sign bit is set, don't take the branch */ @@ -1070,7 +1082,7 @@ DECLARE_INSN(BGTZ) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* @@ -1114,7 +1126,7 @@ DECLARE_INSN(BGTZL) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* @@ -1155,7 +1167,7 @@ DECLARE_INSN(BLEZ) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* @@ -1199,7 +1211,7 @@ DECLARE_INSN(BLEZL) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* @@ -1240,7 +1252,7 @@ DECLARE_INSN(BLTZ) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* @@ -1273,11 +1285,11 @@ DECLARE_INSN(BLTZAL) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* set the return address (instruction after the delay slot) */ - mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2)); + mips64_set_ra(b,b->vaddr + ((b->trans_pos + 1) << 2)); /* * test the sign bit of gpr[rs], if set, take the branch. @@ -1309,11 +1321,11 @@ DECLARE_INSN(BLTZALL) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* set the return address (instruction after the delay slot) */ - mips64_set_ra(b,b->start_pc + ((b->mips_trans_pos + 1) << 2)); + mips64_set_ra(b,b->vaddr + ((b->trans_pos + 1) << 2)); /* * test the sign bit of gpr[rs], if set, take the branch. @@ -1342,7 +1354,7 @@ DECLARE_INSN(BLTZL) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* @@ -1373,7 +1385,7 @@ DECLARE_INSN(BNE) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* @@ -1417,7 +1429,7 @@ DECLARE_INSN(BNEL) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc += sign_extend(offset << 2,18); /* @@ -1842,7 +1854,7 @@ DECLARE_INSN(ERET) /* Restore link register */ ppc_lwz(b->jit_ptr,ppc_r0,PPC_STACK_DECREMENTER+PPC_RET_ADDR_OFFSET,ppc_r1); ppc_mtlr(b->jit_ptr,ppc_r0); - mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2)); + mips64_set_pc(b,b->vaddr+((b->trans_pos-1)<<2)); /* Trick: let callee return directly to the caller */ ppc_emit_jump_code(b->jit_ptr, (u_char *)mips64_exec_eret, 0); return(0); @@ -1855,7 +1867,7 @@ DECLARE_INSN(J) m_uint64_t new_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc &= ~((1 << 28) - 1); new_pc |= instr_index << 2; @@ -1874,12 +1886,12 @@ DECLARE_INSN(JAL) m_uint64_t new_pc,ret_pc; /* compute the new pc */ - new_pc = b->start_pc + (b->mips_trans_pos << 2); + new_pc = b->vaddr + (b->trans_pos << 2); new_pc &= ~((1 << 28) - 1); new_pc |= instr_index << 2; /* set the return address (instruction after the delay slot) */ - ret_pc = b->start_pc + ((b->mips_trans_pos + 1) << 2); + ret_pc = b->vaddr + ((b->trans_pos + 1) << 2); mips64_set_ra(b,ret_pc); /* insert the instruction in the delay slot */ @@ -1898,7 +1910,7 @@ DECLARE_INSN(JALR) m_uint64_t ret_pc; /* set the return pc (instruction after the delay slot) in GPR[rd] */ - ret_pc = b->start_pc + ((b->mips_trans_pos + 1) << 2); + ret_pc = b->vaddr + ((b->trans_pos + 1) << 2); ppc_load(b->jit_ptr,ppc_r7,ret_pc >> 32); ppc_load(b->jit_ptr,ppc_r8,ret_pc & 0xffffffff); ppc_stw(b->jit_ptr,ppc_r7,REG_OFFSET(rd),ppc_r3); @@ -2800,7 +2812,7 @@ DECLARE_INSN(SYSCALL) /* Restore link register */ ppc_lwz(b->jit_ptr,ppc_r0,PPC_STACK_DECREMENTER+PPC_RET_ADDR_OFFSET,ppc_r1); ppc_mtlr(b->jit_ptr,ppc_r0); - mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2)); + mips64_set_pc(b,b->vaddr+((b->trans_pos-1)<<2)); /* Trick: let callee return directly to the caller */ ppc_emit_jump_code(b->jit_ptr, (u_char *)mips64_exec_syscall, 0); return(0); @@ -2869,7 +2881,7 @@ DECLARE_INSN(TEQI) /* TLBP */ DECLARE_INSN(TLBP) { - mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2)); + mips64_set_pc(b,b->vaddr+((b->trans_pos-1)<<2)); mips64_emit_basic_c_call(b,mips64_cp0_exec_tlbp); return(0); } @@ -2877,7 +2889,7 @@ DECLARE_INSN(TLBP) /* TLBR */ DECLARE_INSN(TLBR) { - mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2)); + mips64_set_pc(b,b->vaddr+((b->trans_pos-1)<<2)); mips64_emit_basic_c_call(b,mips64_cp0_exec_tlbr); return(0); } @@ -2885,7 +2897,7 @@ DECLARE_INSN(TLBR) /* TLBWI */ DECLARE_INSN(TLBWI) { - mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2)); + mips64_set_pc(b,b->vaddr+((b->trans_pos-1)<<2)); mips64_emit_basic_c_call(b,mips64_cp0_exec_tlbwi); return(0); } @@ -2893,7 +2905,7 @@ DECLARE_INSN(TLBWI) /* TLBWR */ DECLARE_INSN(TLBWR) { - mips64_set_pc(b,b->start_pc+((b->mips_trans_pos-1)<<2)); + mips64_set_pc(b,b->vaddr+((b->trans_pos-1)<<2)); mips64_emit_basic_c_call(b,mips64_cp0_exec_tlbwr); return(0); } diff --git a/unstable/mips64_ppc32_trans.h b/unstable/mips64_ppc32_trans.h index 65a879d5f..eaff88b07 100644 --- a/unstable/mips64_ppc32_trans.h +++ b/unstable/mips64_ppc32_trans.h @@ -72,8 +72,16 @@ static forced_inline void atomic_and(m_uint32_t *v,m_uint32_t m) /* Here's a hack, see comments in mips64_set_jump for more info */ //#define mips64_jit_tcb_set_patch ppc_patch -#define mips64_jit_tcb_set_patch(a,b) ppc_emit_jump_code(a,b,0) -#define mips64_jit_tcb_set_jump(a,b) ppc_emit_jump_code(a,b,0) +//#define mips64_jit_tcb_set_patch(a,b) ppc_emit_jump_code(a,b,0) +static inline void mips64_jit_tcb_set_patch(u_char *instp,u_char *target) +{ + ppc_emit_jump_code(instp,target,0); +} +//#define mips64_jit_tcb_set_jump(a,b) ppc_emit_jump_code(a,b,0) +static inline void mips64_jit_tcb_set_jump(u_char **instp,u_char *target) +{ + ppc_emit_jump_code(*instp,target,0); +} /* MIPS instruction array */ extern struct mips64_insn_tag mips64_insn_tags[]; @@ -81,26 +89,27 @@ extern struct mips64_insn_tag mips64_insn_tags[]; #define PPC_STACK_DECREMENTER 114 /* Push epilog for a ppc instruction block */ -static forced_inline void mips64_jit_tcb_push_epilog(mips64_jit_tcb_t *b) +static forced_inline void mips64_jit_tcb_push_epilog(cpu_tc_t *tc) { /* Restore link register */ - ppc_lwz(b->jit_ptr,ppc_r0,PPC_STACK_DECREMENTER+PPC_RET_ADDR_OFFSET,ppc_r1); - ppc_mtlr(b->jit_ptr,ppc_r0); - ppc_blr(b->jit_ptr); + ppc_lwz(tc->jit_ptr,ppc_r0,PPC_STACK_DECREMENTER+PPC_RET_ADDR_OFFSET,ppc_r1); + ppc_mtlr(tc->jit_ptr,ppc_r0); + ppc_blr(tc->jit_ptr); } /* Execute JIT code */ static forced_inline -void mips64_jit_tcb_exec(cpu_mips_t *cpu,mips64_jit_tcb_t *block) +void mips64_jit_tcb_exec(cpu_mips_t *cpu,cpu_tb_t *tb) { register insn_tblock_fptr jit_code __asm__("r12"); - m_uint32_t offset; + m_uint32_t offset,*iarray; offset = (cpu->pc & MIPS_MIN_PAGE_IMASK) >> 2; - jit_code = (insn_tblock_fptr)block->jit_insn_ptr[offset]; + jit_code = (insn_tblock_fptr)tb->tc->jit_insn_ptr[offset]; if (unlikely(!jit_code)) { - mips64_exec_single_step(cpu,vmtoh32(block->mips_code[offset])); + iarray = (m_uint32_t *)tb->target_code; + mips64_exec_single_step(cpu,vmtoh32(iarray[offset])); return; } @@ -113,8 +122,8 @@ void mips64_jit_tcb_exec(cpu_mips_t *cpu,mips64_jit_tcb_t *block) __asm__ __volatile__( "mtlr r12 \n" "mr r3, %1 \n" - "lis r0, hi16(jit_ret) \n" - "ori r0, r0, lo16(jit_ret)\n" + "lis r0, jit_ret@h \n" + "ori r0, r0, jit_ret@l \n" "stw r3, %2(r1) \n" "stw r0, %3(r1) \n" "stwu r1, %4(r1) \n"