From d07b907bc7889308890b590d2aaf88dfc44ae616 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sun, 14 Dec 2014 16:45:23 -0800 Subject: WIP effort to update z80 core for code gen changes --- m68k_core_x86.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 6c37fad..18feea7 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -2390,10 +2390,12 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu *skip_sync = code->cur - (skip_sync+1); retn(code); - opts->read_16 = gen_mem_fun(&opts->gen, memmap, num_chunks, READ_16); - opts->read_8 = gen_mem_fun(&opts->gen, memmap, num_chunks, READ_8); - opts->write_16 = gen_mem_fun(&opts->gen, memmap, num_chunks, WRITE_16); - opts->write_8 = gen_mem_fun(&opts->gen, memmap, num_chunks, WRITE_8); + opts->gen.handle_code_write = (code_ptr)m68k_handle_code_write; + + opts->read_16 = gen_mem_fun(&opts->gen, memmap, num_chunks, READ_16, NULL); + opts->read_8 = gen_mem_fun(&opts->gen, memmap, num_chunks, READ_8, NULL); + opts->write_16 = gen_mem_fun(&opts->gen, memmap, num_chunks, WRITE_16, NULL); + opts->write_8 = gen_mem_fun(&opts->gen, memmap, num_chunks, WRITE_8, NULL); opts->read_32 = code->cur; push_r(code, opts->gen.scratch1); -- cgit v1.2.3 From 58056e06047d7777dbb2fe500fe6801fa92785f9 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Fri, 26 Dec 2014 12:37:27 -0800 Subject: Set the byte_swap flag in the M68K core so gen_mem_fun correctly inserts xor instructions for byte access functions --- m68k_core_x86.c | 1 + 1 file changed, 1 insertion(+) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 18feea7..0f89a82 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -2169,6 +2169,7 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu memset(opts, 0, sizeof(*opts)); opts->gen.address_size = SZ_D; opts->gen.address_mask = 0xFFFFFF; + opts->gen.byte_swap = 1; opts->gen.max_address = 0x1000000; opts->gen.bus_cycles = BUS; opts->gen.mem_ptr_off = offsetof(m68k_context, mem_pointers); -- cgit v1.2.3 From e8a9c14ec2e0b75eb1aef1c2a77936c6f7fd8326 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Fri, 26 Dec 2014 15:45:31 -0800 Subject: Fix a few bugs introduced in the Z80 core from the adjustments to fit with the code gen refactor --- m68k_core_x86.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 0f89a82..96e1cfa 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -2061,11 +2061,6 @@ void translate_out_of_bounds(code_info *code) call(code, (code_ptr)exit); } -void check_code_prologue(code_info *code) -{ - check_alloc_code(code, MAX_INST_LEN*4); -}; - void nop_fill_or_jmp_next(code_info *code, code_ptr old_end, code_ptr next_inst) { if (next_inst == old_end && next_inst - code->cur < 2) { -- cgit v1.2.3 From 77b305b44b0857a3e4bb6fd22ee96e4bb42323cc Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Fri, 26 Dec 2014 19:38:27 -0800 Subject: Fix a bug in ori to SR that was swapping USP and SSP inappropriately --- m68k_core_x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 96e1cfa..ef84721 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -1896,7 +1896,7 @@ void translate_m68k_andi_ori_ccr_sr(m68k_options *opts, m68kinst *inst) } else { or_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); } - if ((base_flag == X0) ^ (((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR)) > 0)) { + if (inst->op == M68K_ANDI_SR && !(inst->src.params.immed & (1 << (BIT_SUPERVISOR + 8)))) { //leave supervisor mode swap_ssp_usp(opts); } -- cgit v1.2.3 From 7103c11ebae317680cbea6b4ae2c724206d8a6d4 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sat, 27 Dec 2014 14:51:50 -0800 Subject: Decrement address register after fetching source in move with -(ax) dest to avoid bug when src is the dst addres reg --- m68k_core_x86.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index ef84721..4169389 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -604,10 +604,8 @@ void translate_m68k_move(m68k_options * opts, m68kinst * inst) break; case MODE_AREG_PREDEC: dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1)); - subi_areg(opts, dec_amount, inst->dst.params.regs.pri); case MODE_AREG_INDIRECT: case MODE_AREG_POSTINC: - areg_to_native(opts, inst->dst.params.regs.pri, opts->gen.scratch2); if (src.mode == MODE_REG_DIRECT) { if (src.base != opts->gen.scratch1) { mov_rr(code, src.base, opts->gen.scratch1, inst->extra.size); @@ -617,6 +615,10 @@ void translate_m68k_move(m68k_options * opts, m68kinst * inst) } else { mov_ir(code, src.disp, opts->gen.scratch1, inst->extra.size); } + if (inst->dst.addr_mode == MODE_AREG_PREDEC) { + subi_areg(opts, dec_amount, inst->dst.params.regs.pri); + } + areg_to_native(opts, inst->dst.params.regs.pri, opts->gen.scratch2); break; case MODE_AREG_DISPLACE: cycles(&opts->gen, BUS); -- cgit v1.2.3 From ec6bd7cf6e237ba3f24af06d2c52e629c4029207 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sat, 27 Dec 2014 15:49:15 -0800 Subject: Fix divide by zero exception return address when div instruction is bigger than 1 word --- m68k_core_x86.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 4169389..710fe58 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -1604,6 +1604,20 @@ void translate_m68k_div(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos movzx_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch2, SZ_W, SZ_D); } } + uint32_t isize = 2; + switch(inst->src.addr_mode) + { + case MODE_AREG_DISPLACE: + case MODE_AREG_INDEX_DISP8: + case MODE_ABSOLUTE_SHORT: + case MODE_PC_INDEX_DISP8: + case MODE_IMMEDIATE: + isize = 4; + break; + case MODE_ABSOLUTE: + isize = 6; + break; + } cmp_ir(code, 0, opts->gen.scratch2, SZ_D); check_alloc_code(code, 6*MAX_INST_LEN); code_ptr not_zero = code->cur + 1; @@ -1611,7 +1625,7 @@ void translate_m68k_div(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos pop_r(code, RAX); pop_r(code, RDX); mov_ir(code, VECTOR_INT_DIV_ZERO, opts->gen.scratch2, SZ_D); - mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D); + mov_ir(code, inst->address+isize, opts->gen.scratch1, SZ_D); jmp(code, opts->trap); *not_zero = code->cur - (not_zero+1); if (inst->op == M68K_DIVS) { -- cgit v1.2.3 From 08d8620cd9bfe4a2bcaaa9156f8a46a1c0b9e659 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sun, 28 Dec 2014 17:25:36 -0800 Subject: Removed bcd_add and bcd_sub from runtime.S and generated the logic inline with the rest of abcd and sbcd translation. Fixed some edge cases and undefined flag behavior in the process --- m68k_core_x86.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 6 deletions(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 710fe58..d4e0a1c 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -1404,17 +1404,69 @@ void translate_m68k_abcd_sbcd(m68k_options *opts, m68kinst *inst, host_ea *src_o mov_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch1, SZ_B); } } + uint8_t other_reg; + //WARNING: This may need adjustment if register assignments change + if (opts->gen.scratch2 > RBX) { + other_reg = RAX; + xchg_rr(code, opts->gen.scratch2, RAX, SZ_D); + } else { + other_reg = opts->gen.scratch2; + } + mov_rr(code, opts->gen.scratch1, opts->gen.scratch1 + (AH-RAX), SZ_B); + mov_rr(code, other_reg, other_reg + (AH-RAX), SZ_B); + and_ir(code, 0xF0, opts->gen.scratch1, SZ_B); + and_ir(code, 0xF0, other_reg, SZ_B); + and_ir(code, 0xF, opts->gen.scratch1 + (AH-RAX), SZ_B); + and_ir(code, 0xF, other_reg + (AH-RAX), SZ_B); + //do op on low nibble flag_to_carry(opts, FLAG_X); - jcc(code, CC_NC, code->cur + 5); if (inst->op == M68K_ABCD) { - add_ir(code, 1, opts->gen.scratch1, SZ_B); + adc_rr(code, other_reg + (AH-RAX), opts->gen.scratch1 + (AH-RAX), SZ_B); + } else { + sbb_rr(code, other_reg + (AH-RAX), opts->gen.scratch1 + (AH-RAX), SZ_B); + } + cmp_ir(code, 0xA, opts->gen.scratch1 + (AH-RAX), SZ_B); + code_ptr no_adjust = code->cur+1; + //add correction factor if necessary + jcc(code, CC_B, no_adjust); + if (inst->op == M68K_ABCD) { + add_ir(code, 6, opts->gen.scratch1 + (AH-RAX), SZ_B); + } else { + sub_ir(code, 6, opts->gen.scratch1 + (AH-RAX), SZ_B); + } + *no_adjust = code->cur - (no_adjust+1); + //add low nibble result to one of the high nibble operands + add_rr(code, opts->gen.scratch1 + (AH-RAX), opts->gen.scratch1, SZ_B); + if (inst->op == M68K_ABCD) { + add_rr(code, other_reg, opts->gen.scratch1, SZ_B); } else { - sub_ir(code, 1, opts->gen.scratch1, SZ_B); + sub_rr(code, other_reg, opts->gen.scratch1, SZ_B); } - call(code, (code_ptr) (inst->op == M68K_ABCD ? bcd_add : bcd_sub)); - reg_to_flag(opts, CH, FLAG_C); - reg_to_flag(opts, CH, FLAG_X); + if (opts->gen.scratch2 > RBX) { + mov_rr(code, opts->gen.scratch2, RAX, SZ_D); + } + set_flag(opts, 0, FLAG_C); + set_flag(opts, 0, FLAG_V); + code_ptr def_adjust = code->cur+1; + jcc(code, CC_C, def_adjust); + cmp_ir(code, 0xA0, opts->gen.scratch1, SZ_B); + no_adjust = code->cur+1; + jcc(code, CC_B, no_adjust); + *def_adjust = code->cur - (def_adjust + 1); + set_flag(opts, 1, FLAG_C); + if (inst->op == M68K_ABCD) { + add_ir(code, 0x60, opts->gen.scratch1, SZ_B); + } else { + sub_ir(code, 0x60, opts->gen.scratch1, SZ_B); + } + //V flag is set based on the result of the addition of the + //result and the correction factor + set_flag_cond(opts, CC_O, FLAG_V); + *no_adjust = code->cur - (no_adjust+1); + flag_to_flag(opts, FLAG_C, FLAG_X); + cmp_ir(code, 0, opts->gen.scratch1, SZ_B); + set_flag_cond(opts, CC_S, FLAG_N); jcc(code, CC_Z, code->cur + 4); set_flag(opts, 0, FLAG_Z); if (dst_op->base != opts->gen.scratch1) { -- cgit v1.2.3 From c61ca95add7b82aadef09aea8b4c48774e079069 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Mon, 29 Dec 2014 23:08:39 -0800 Subject: Fix handling of code writes for Z80 core. This seems to get things close to being back to where they were before the big refactor that broke the Z80 core. Some problems remain. Notably the sound driver in Sonic 2 is still quite broken. --- m68k_core_x86.c | 1 + 1 file changed, 1 insertion(+) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index d4e0a1c..7e97886 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -2237,6 +2237,7 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu opts->gen.bus_cycles = BUS; opts->gen.mem_ptr_off = offsetof(m68k_context, mem_pointers); opts->gen.ram_flags_off = offsetof(m68k_context, ram_code_flags); + opts->gen.ram_flags_shift = 11; for (int i = 0; i < 8; i++) { opts->dregs[i] = opts->aregs[i] = -1; -- cgit v1.2.3 From ec4eed4f35910aa27ca353fceea38155806ef188 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Thu, 1 Jan 2015 14:36:55 -0800 Subject: Remove some of the hard coded assumptions about the memory map from the CPU cores --- m68k_core_x86.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 7e97886..c0964bd 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -1464,7 +1464,7 @@ void translate_m68k_abcd_sbcd(m68k_options *opts, m68kinst *inst, host_ea *src_o set_flag_cond(opts, CC_O, FLAG_V); *no_adjust = code->cur - (no_adjust+1); flag_to_flag(opts, FLAG_C, FLAG_X); - + cmp_ir(code, 0, opts->gen.scratch1, SZ_B); set_flag_cond(opts, CC_S, FLAG_N); jcc(code, CC_Z, code->cur + 4); @@ -1664,7 +1664,7 @@ void translate_m68k_div(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos case MODE_ABSOLUTE_SHORT: case MODE_PC_INDEX_DISP8: case MODE_IMMEDIATE: - isize = 4; + isize = 4; break; case MODE_ABSOLUTE: isize = 6; @@ -2230,6 +2230,8 @@ void insert_breakpoint(m68k_context * context, uint32_t address, code_ptr bp_han void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks) { memset(opts, 0, sizeof(*opts)); + opts->gen.memmap = memmap; + opts->gen.memmap_chunks = num_chunks; opts->gen.address_size = SZ_D; opts->gen.address_mask = 0xFFFFFF; opts->gen.byte_swap = 1; -- cgit v1.2.3 From 574281b6ea14c8534582f088b1cbf128ba6b1d76 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Thu, 1 Jan 2015 17:31:59 -0800 Subject: Fix some issues with 68K instruction retranslation --- m68k_core_x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index c0964bd..8d9fc6a 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -2185,7 +2185,7 @@ void insert_breakpoint(m68k_context * context, uint32_t address, code_ptr bp_han mov_ir(&native, address, opts->gen.scratch1, SZ_D); if (!bp_stub) { code_info *code = &opts->gen.code; - check_alloc_code(code, 5); + check_code_prologue(code); bp_stub = code->cur; call(&native, bp_stub); -- cgit v1.2.3 From dac14d1f29445b77fee5b570e6eb73c28b1860a4 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Thu, 1 Jan 2015 19:15:05 -0800 Subject: Added 2 new functions to gen_x86.c for handling passing args according to the C abi of the host system and adapted the code in m68k_core_x86.c to use that instead of doing everything by hand --- m68k_core_x86.c | 163 ++++++++------------------------------------------------ 1 file changed, 23 insertions(+), 140 deletions(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 8d9fc6a..1914599 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -14,17 +14,6 @@ #include #include -#define CYCLES RAX -#define LIMIT RBP -#define CONTEXT RSI -#define SCRATCH1 RCX - -#ifdef X86_64 -#define SCRATCH2 RDI -#else -#define SCRATCH2 RBX -#endif - enum { FLAG_X, FLAG_N, @@ -1077,8 +1066,8 @@ void translate_shift(m68k_options * opts, m68kinst * inst, host_ea *src_op, host jmp(code, code->cur + 2); *nz_off = code->cur - (nz_off + 1); //add 2 cycles for every bit shifted - add_rr(code, RCX, CYCLES, SZ_D); - add_rr(code, RCX, CYCLES, SZ_D); + add_rr(code, RCX, opts->gen.cycles, SZ_D); + add_rr(code, RCX, opts->gen.cycles, SZ_D); if (inst->op == M68K_ASL) { //ASL has Overflow flag behavior that depends on all of the bits shifted through the MSB //Easiest way to deal with this is to shift one bit at a time @@ -1876,8 +1865,8 @@ void translate_m68k_rot(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos and_ir(code, 63, opts->gen.scratch1, SZ_D); code_ptr zero_off = code->cur + 1; jcc(code, CC_Z, code->cur + 2); - add_rr(code, opts->gen.scratch1, CYCLES, SZ_D); - add_rr(code, opts->gen.scratch1, CYCLES, SZ_D); + add_rr(code, opts->gen.scratch1, opts->gen.cycles, SZ_D); + add_rr(code, opts->gen.scratch1, opts->gen.cycles, SZ_D); cmp_ir(code, 32, opts->gen.scratch1, SZ_B); code_ptr norm_off = code->cur + 1; jcc(code, CC_L, code->cur + 2); @@ -1933,12 +1922,7 @@ void translate_m68k_illegal(m68k_options *opts, m68kinst *inst) { code_info *code = &opts->gen.code; call(code, opts->gen.save_context); -#ifdef X86_64 - mov_rr(code, opts->gen.context_reg, RDI, SZ_PTR); -#else - push_r(code, opts->gen.context_reg); -#endif - call(code, (code_ptr)print_regs_exit); + call_args(code, (code_ptr)print_regs_exit, 1, opts->gen.context_reg); } #define BIT_SUPERVISOR 5 @@ -2088,12 +2072,7 @@ void translate_m68k_reset(m68k_options *opts, m68kinst *inst) { code_info *code = &opts->gen.code; call(code, opts->gen.save_context); -#ifdef X86_64 - mov_rr(code, opts->gen.context_reg, RDI, SZ_PTR); -#else - push_r(code, opts->gen.context_reg); -#endif - call(code, (code_ptr)print_regs_exit); + call_args(code, (code_ptr)print_regs_exit, 1, opts->gen.context_reg); } void translate_m68k_rte(m68k_options *opts, m68kinst *inst) @@ -2123,10 +2102,7 @@ void translate_m68k_rte(m68k_options *opts, m68kinst *inst) void translate_out_of_bounds(code_info *code) { xor_rr(code, RDI, RDI, SZ_D); -#ifdef X86_32 - push_r(code, RDI); -#endif - call(code, (code_ptr)exit); + call_args(code, (code_ptr)exit, 1, RDI); } void nop_fill_or_jmp_next(code_info *code, code_ptr old_end, code_ptr next_inst) @@ -2156,14 +2132,7 @@ m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context) options->retrans_stub = code->cur; call(code, options->gen.save_context); push_r(code, options->gen.context_reg); -#ifdef X86_32 - push_r(code, options->gen.context_reg); - push_r(code, options->gen.scratch2); -#endif - call(code, (code_ptr)m68k_retranslate_inst); -#ifdef X86_32 - add_ir(code, 8, RSP, SZ_D); -#endif + call_args(code,(code_ptr)m68k_retranslate_inst, 2, options->gen.scratch2, options->gen.context_reg); pop_r(code, options->gen.context_reg); mov_rr(code, RAX, options->gen.scratch1, SZ_PTR); call(code, options->gen.load_context); @@ -2197,17 +2166,7 @@ void insert_breakpoint(m68k_context * context, uint32_t address, code_ptr bp_han //Save context and call breakpoint handler call(code, opts->gen.save_context); push_r(code, opts->gen.scratch1); -#ifdef X86_64 - mov_rr(code, opts->gen.context_reg, RDI, SZ_PTR); - mov_rr(code, opts->gen.scratch1, RSI, SZ_D); -#else - push_r(code, opts->gen.scratch1); - push_r(code, opts->gen.context_reg); -#endif - call(code, bp_handler); -#ifdef X86_32 - add_ir(code, 8, RSP, SZ_D); -#endif + call_args(code, bp_handler, 2, opts->gen.context_reg, opts->gen.scratch1); mov_rr(code, RAX, opts->gen.context_reg, SZ_PTR); //Restore context call(code, opts->gen.load_context); @@ -2317,8 +2276,8 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * i, opts->aregs[i], SZ_D); } } - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, current_cycle), CYCLES, SZ_D); - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, target_cycle), LIMIT, SZ_D); + mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, current_cycle), opts->gen.cycles, SZ_D); + mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, target_cycle), opts->gen.limit, SZ_D); retn(code); opts->start_context = (start_fun)code->cur; @@ -2363,17 +2322,7 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu opts->native_addr = code->cur; call(code, opts->gen.save_context); push_r(code, opts->gen.context_reg); -#ifdef X86_64 - mov_rr(code, opts->gen.context_reg, RDI, SZ_PTR); //move context to 1st arg reg - mov_rr(code, opts->gen.scratch1, RSI, SZ_D); //move address to 2nd arg reg -#else - push_r(code, opts->gen.scratch1); - push_r(code, opts->gen.context_reg); -#endif - call(code, (code_ptr)get_native_address_trans); -#ifdef X86_32 - add_ir(code, 8, RSP, SZ_D); -#endif + call_args(code, (code_ptr)get_native_address_trans, 2, opts->gen.context_reg, opts->gen.scratch1); mov_rr(code, RAX, opts->gen.scratch1, SZ_PTR); //move result to scratch reg pop_r(code, opts->gen.context_reg); call(code, opts->gen.load_context); @@ -2382,74 +2331,27 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu opts->native_addr_and_sync = code->cur; call(code, opts->gen.save_context); push_r(code, opts->gen.scratch1); -#ifdef X86_64 - mov_rr(code, opts->gen.context_reg, RDI, SZ_PTR); - xor_rr(code, RSI, RSI, SZ_D); - test_ir(code, 8, RSP, SZ_PTR); //check stack alignment - code_ptr do_adjust_rsp = code->cur + 1; - jcc(code, CC_NZ, code->cur + 2); - call(code, (code_ptr)sync_components); - code_ptr no_adjust_rsp = code->cur + 1; - jmp(code, code->cur + 2); - *do_adjust_rsp = code->cur - (do_adjust_rsp+1); - sub_ir(code, 8, RSP, SZ_PTR); - call(code, (code_ptr)sync_components); - add_ir(code, 8, RSP, SZ_PTR); - *no_adjust_rsp = code->cur - (no_adjust_rsp+1); - pop_r(code, RSI); - push_r(code, RAX); - mov_rr(code, RAX, RDI, SZ_PTR); - call(code, (code_ptr)get_native_address_trans); -#else - //TODO: Add support for pushing a constant in gen_x86 - xor_rr(code, RAX, RAX, SZ_D); - push_r(code, RAX); - push_r(code, opts->gen.context_reg); - call(code, (code_ptr)sync_components); - add_ir(code, 8, RSP, SZ_D); + + xor_rr(code, opts->gen.scratch1, opts->gen.scratch1, SZ_D); + call_args_abi(code, (code_ptr)sync_components, 2, opts->gen.context_reg, opts->gen.scratch1); pop_r(code, RSI); //restore saved address from opts->gen.scratch1 push_r(code, RAX); //save context pointer for later - push_r(code, RSI); //2nd arg -- address - push_r(code, RAX); //1st arg -- context pointer - call(code, (code_ptr)get_native_address_trans); - add_ir(code, 8, RSP, SZ_D); -#endif - + call_args(code, (code_ptr)get_native_address_trans, 2, RAX, RSI); mov_rr(code, RAX, opts->gen.scratch1, SZ_PTR); //move result to scratch reg pop_r(code, opts->gen.context_reg); call(code, opts->gen.load_context); retn(code); opts->gen.handle_cycle_limit = code->cur; - cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D); + cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), opts->gen.cycles, SZ_D); code_ptr skip_sync = code->cur + 1; jcc(code, CC_C, code->cur + 2); opts->do_sync = code->cur; push_r(code, opts->gen.scratch1); push_r(code, opts->gen.scratch2); call(code, opts->gen.save_context); -#ifdef X86_64 - mov_rr(code, opts->gen.context_reg, RDI, SZ_PTR); - xor_rr(code, RSI, RSI, SZ_D); - test_ir(code, 8, RSP, SZ_D); - code_ptr adjust_rsp = code->cur + 1; - jcc(code, CC_NZ, code->cur + 2); - call(code, (code_ptr)sync_components); - code_ptr no_adjust = code->cur + 1; - jmp(code, code->cur + 2); - *adjust_rsp = code->cur - (adjust_rsp + 1); - sub_ir(code, 8, RSP, SZ_PTR); - call(code, (code_ptr)sync_components); - add_ir(code, 8, RSP, SZ_PTR); - *no_adjust = code->cur - (no_adjust+1); -#else - //TODO: Add support for pushing a constant in gen_x86 - xor_rr(code, RAX, RAX, SZ_D); - push_r(code, RAX); - push_r(code, opts->gen.context_reg); - call(code, (code_ptr)sync_components); - add_ir(code, 8, RSP, SZ_D); -#endif + xor_rr(code, opts->gen.scratch1, opts->gen.scratch1, SZ_D); + call_args_abi(code, (code_ptr)sync_components, 2, opts->gen.context_reg, opts->gen.scratch1); mov_rr(code, RAX, opts->gen.context_reg, SZ_PTR); call(code, opts->gen.load_context); pop_r(code, opts->gen.scratch2); @@ -2559,40 +2461,21 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu retn(code); opts->gen.handle_cycle_limit_int = code->cur; - cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_cycle), CYCLES, SZ_D); + cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_cycle), opts->gen.cycles, SZ_D); code_ptr do_int = code->cur + 1; jcc(code, CC_NC, code->cur + 2); - cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D); + cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), opts->gen.cycles, SZ_D); skip_sync = code->cur + 1; jcc(code, CC_C, code->cur + 2); call(code, opts->gen.save_context); -#ifdef X86_64 - mov_rr(code, opts->gen.context_reg, RDI, SZ_PTR); - mov_rr(code, opts->gen.scratch1, RSI, SZ_D); - test_ir(code, 8, RSP, SZ_D); - adjust_rsp = code->cur + 1; - jcc(code, CC_NZ, code->cur + 2); - call(code, (code_ptr)sync_components); - no_adjust = code->cur + 1; - jmp(code, code->cur + 2); - *adjust_rsp = code->cur - (adjust_rsp + 1); - sub_ir(code, 8, RSP, SZ_PTR); - call(code, (code_ptr)sync_components); - add_ir(code, 8, RSP, SZ_PTR); - *no_adjust = code->cur - (no_adjust+1); -#else - push_r(code, opts->gen.scratch1); - push_r(code, opts->gen.context_reg); - call(code, (code_ptr)sync_components); - add_ir(code, 8, RSP, SZ_D); -#endif + call_args_abi(code, (code_ptr)sync_components, 2, opts->gen.context_reg, opts->gen.scratch1); mov_rr(code, RAX, opts->gen.context_reg, SZ_PTR); jmp(code, opts->gen.load_context); *skip_sync = code->cur - (skip_sync+1); retn(code); *do_int = code->cur - (do_int+1); //set target cycle to sync cycle - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), LIMIT, SZ_D); + mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), opts->gen.limit, SZ_D); //swap USP and SSP if not already in supervisor mode bt_irdisp(code, 5, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); code_ptr already_supervisor = code->cur + 1; -- cgit v1.2.3 From 9e0779e64b71a60ee9287ed01330baf020cfd932 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Thu, 1 Jan 2015 20:07:47 -0800 Subject: Use call_args and call_args_abi in Z80 core --- m68k_core_x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 1914599..aed617f 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -2166,7 +2166,7 @@ void insert_breakpoint(m68k_context * context, uint32_t address, code_ptr bp_han //Save context and call breakpoint handler call(code, opts->gen.save_context); push_r(code, opts->gen.scratch1); - call_args(code, bp_handler, 2, opts->gen.context_reg, opts->gen.scratch1); + call_args_abi(code, bp_handler, 2, opts->gen.context_reg, opts->gen.scratch1); mov_rr(code, RAX, opts->gen.context_reg, SZ_PTR); //Restore context call(code, opts->gen.load_context); -- cgit v1.2.3 From af8bf7f7f18861ef1235e85a72ca100e755d9859 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Fri, 2 Jan 2015 13:14:09 -0800 Subject: Added functions to gen_x86 for saving and restoring callee save registers to better abstract over ABI differences between x86 and x86-64 --- m68k_core_x86.c | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index aed617f..44f8c3e 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -2281,42 +2281,19 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu retn(code); opts->start_context = (start_fun)code->cur; + save_callee_save_regs(code); #ifdef X86_64 if (opts->gen.scratch2 != RDI) { mov_rr(code, RDI, opts->gen.scratch2, SZ_PTR); } - //save callee save registers - push_r(code, RBP); - push_r(code, R12); - push_r(code, R13); - push_r(code, R14); - push_r(code, R15); #else - //save callee save registers - push_r(code, RBP); - push_r(code, RBX); - push_r(code, RSI); - push_r(code, RDI); - mov_rdispr(code, RSP, 20, opts->gen.scratch2, SZ_D); mov_rdispr(code, RSP, 24, opts->gen.context_reg, SZ_D); #endif call(code, opts->gen.load_context); call_r(code, opts->gen.scratch2); call(code, opts->gen.save_context); -#ifdef X86_64 - //restore callee save registers - pop_r(code, R15); - pop_r(code, R14); - pop_r(code, R13); - pop_r(code, R12); - pop_r(code, RBP); -#else - pop_r(code, RDI); - pop_r(code, RSI); - pop_r(code, RBX); - pop_r(code, RBP); -#endif + restore_callee_save_regs(code); retn(code); opts->native_addr = code->cur; -- cgit v1.2.3 From 8ac1e753e1af481b2090a4c1b7395853f30b5e8f Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sat, 3 Jan 2015 16:08:23 -0800 Subject: All cycle counters are now based off the master clock. This seems to have messed up Z80 interrupt timing (music in Sonic 2 is too slow for instance), but things are generally working --- m68k_core_x86.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 44f8c3e..dea55f4 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -1012,8 +1012,8 @@ void translate_shift(m68k_options * opts, m68kinst * inst, host_ea *src_op, host //Memory shift shift_ir(code, 1, dst_op->base, SZ_W); } else { - cycles(&opts->gen, inst->extra.size == OPSIZE_LONG ? 8 : 6); if (src_op->mode == MODE_IMMED) { + cycles(&opts->gen, (inst->extra.size == OPSIZE_LONG ? 8 : 6) + 2 * src_op->disp); if (src_op->disp != 1 && inst->op == M68K_ASL) { set_flag(opts, 0, FLAG_V); for (int i = 0; i < src_op->disp; i++) { @@ -1037,6 +1037,7 @@ void translate_shift(m68k_options * opts, m68kinst * inst, host_ea *src_op, host set_flag_cond(opts, CC_O, FLAG_V); } } else { + cycles(&opts->gen, inst->extra.size == OPSIZE_LONG ? 8 : 6); if (src_op->base != RCX) { if (src_op->mode == MODE_REG_DIRECT) { mov_rr(code, src_op->base, RCX, SZ_B); @@ -1066,8 +1067,9 @@ void translate_shift(m68k_options * opts, m68kinst * inst, host_ea *src_op, host jmp(code, code->cur + 2); *nz_off = code->cur - (nz_off + 1); //add 2 cycles for every bit shifted - add_rr(code, RCX, opts->gen.cycles, SZ_D); - add_rr(code, RCX, opts->gen.cycles, SZ_D); + mov_ir(code, 2 * opts->gen.clock_divider, opts->gen.scratch2, SZ_D); + imul_rr(code, RCX, opts->gen.scratch2, SZ_D); + add_rr(code, opts->gen.scratch2, opts->gen.cycles, SZ_D); if (inst->op == M68K_ASL) { //ASL has Overflow flag behavior that depends on all of the bits shifted through the MSB //Easiest way to deal with this is to shift one bit at a time @@ -1865,8 +1867,10 @@ void translate_m68k_rot(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos and_ir(code, 63, opts->gen.scratch1, SZ_D); code_ptr zero_off = code->cur + 1; jcc(code, CC_Z, code->cur + 2); - add_rr(code, opts->gen.scratch1, opts->gen.cycles, SZ_D); - add_rr(code, opts->gen.scratch1, opts->gen.cycles, SZ_D); + //add 2 cycles for every bit shifted + mov_ir(code, 2 * opts->gen.clock_divider, opts->gen.scratch2, SZ_D); + imul_rr(code, RCX, opts->gen.scratch2, SZ_D); + add_rr(code, opts->gen.scratch2, opts->gen.cycles, SZ_D); cmp_ir(code, 32, opts->gen.scratch1, SZ_B); code_ptr norm_off = code->cur + 1; jcc(code, CC_L, code->cur + 2); @@ -2186,7 +2190,7 @@ void insert_breakpoint(m68k_context * context, uint32_t address, code_ptr bp_han } } -void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks) +void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chunks, uint32_t clock_divider) { memset(opts, 0, sizeof(*opts)); opts->gen.memmap = memmap; @@ -2196,6 +2200,7 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu opts->gen.byte_swap = 1; opts->gen.max_address = 0x1000000; opts->gen.bus_cycles = BUS; + opts->gen.clock_divider = clock_divider; opts->gen.mem_ptr_off = offsetof(m68k_context, mem_pointers); opts->gen.ram_flags_off = offsetof(m68k_context, ram_code_flags); opts->gen.ram_flags_shift = 11; @@ -2308,7 +2313,7 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu opts->native_addr_and_sync = code->cur; call(code, opts->gen.save_context); push_r(code, opts->gen.scratch1); - + xor_rr(code, opts->gen.scratch1, opts->gen.scratch1, SZ_D); call_args_abi(code, (code_ptr)sync_components, 2, opts->gen.context_reg, opts->gen.scratch1); pop_r(code, RSI); //restore saved address from opts->gen.scratch1 -- cgit v1.2.3 From 1a8489d67d209986951adb84eef3fc36dbe3b548 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Thu, 8 Jan 2015 09:36:54 -0800 Subject: Fix indentation that presumably got messed up in a merge --- m68k_core_x86.c | 544 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 272 insertions(+), 272 deletions(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index f8a323d..285a1dd 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -216,42 +216,42 @@ void dreg_to_native_sx(m68k_options *opts, uint8_t reg, uint8_t native_reg) { if (opts->dregs[reg] >= 0) { movsx_rr(&opts->gen.code, opts->dregs[reg], native_reg, SZ_W, SZ_D); - } else { + } else { movsx_rdispr(&opts->gen.code, opts->gen.context_reg, dreg_offset(reg), native_reg, SZ_W, SZ_D); - } } +} void native_to_areg(m68k_options *opts, uint8_t native_reg, uint8_t reg) { if (opts->aregs[reg] >= 0) { mov_rr(&opts->gen.code, native_reg, opts->aregs[reg], SZ_D); - } else { + } else { mov_rrdisp(&opts->gen.code, native_reg, opts->gen.context_reg, areg_offset(reg), SZ_D); - } - } + } +} void native_to_dreg(m68k_options *opts, uint8_t native_reg, uint8_t reg) { if (opts->dregs[reg] >= 0) { mov_rr(&opts->gen.code, native_reg, opts->dregs[reg], SZ_D); - } else { + } else { mov_rrdisp(&opts->gen.code, native_reg, opts->gen.context_reg, dreg_offset(reg), SZ_D); - } + } } void ldi_areg(m68k_options *opts, int32_t value, uint8_t reg) { if (opts->aregs[reg] >= 0) { mov_ir(&opts->gen.code, value, opts->aregs[reg], SZ_D); - } else { + } else { mov_irdisp(&opts->gen.code, value, opts->gen.context_reg, areg_offset(reg), SZ_D); - } + } } void ldi_native(m68k_options *opts, int32_t value, uint8_t reg) - { +{ mov_ir(&opts->gen.code, value, reg, SZ_D); - } +} void addi_native(m68k_options *opts, int32_t value, uint8_t reg) { @@ -261,90 +261,90 @@ void addi_native(m68k_options *opts, int32_t value, uint8_t reg) void subi_native(m68k_options *opts, int32_t value, uint8_t reg) { sub_ir(&opts->gen.code, value, reg, SZ_D); - } +} void push_native(m68k_options *opts, uint8_t reg) { push_r(&opts->gen.code, reg); - } +} void pop_native(m68k_options *opts, uint8_t reg) - { +{ pop_r(&opts->gen.code, reg); - } +} void sign_extend16_native(m68k_options *opts, uint8_t reg) { movsx_rr(&opts->gen.code, reg, reg, SZ_W, SZ_D); - } +} void addi_areg(m68k_options *opts, int32_t val, uint8_t reg) { if (opts->aregs[reg] >= 0) { add_ir(&opts->gen.code, val, opts->aregs[reg], SZ_D); - } else { + } else { add_irdisp(&opts->gen.code, val, opts->gen.context_reg, areg_offset(reg), SZ_D); - } + } } void subi_areg(m68k_options *opts, int32_t val, uint8_t reg) { if (opts->aregs[reg] >= 0) { sub_ir(&opts->gen.code, val, opts->aregs[reg], SZ_D); - } else { + } else { sub_irdisp(&opts->gen.code, val, opts->gen.context_reg, areg_offset(reg), SZ_D); - } - } + } +} void add_areg_native(m68k_options *opts, uint8_t reg, uint8_t native_reg) { if (opts->aregs[reg] >= 0) { add_rr(&opts->gen.code, opts->aregs[reg], native_reg, SZ_D); - } else { + } else { add_rdispr(&opts->gen.code, opts->gen.context_reg, areg_offset(reg), native_reg, SZ_D); - } + } } void add_dreg_native(m68k_options *opts, uint8_t reg, uint8_t native_reg) { if (opts->dregs[reg] >= 0) { add_rr(&opts->gen.code, opts->dregs[reg], native_reg, SZ_D); - } else { + } else { add_rdispr(&opts->gen.code, opts->gen.context_reg, dreg_offset(reg), native_reg, SZ_D); - } - } + } +} void calc_areg_displace(m68k_options *opts, m68k_op_info *op, uint8_t native_reg) - { +{ areg_to_native(opts, op->params.regs.pri, native_reg); add_ir(&opts->gen.code, op->params.regs.displacement, native_reg, SZ_D); - } +} void calc_index_disp8(m68k_options *opts, m68k_op_info *op, uint8_t native_reg) - { +{ uint8_t sec_reg = (op->params.regs.sec >> 1) & 0x7; if (op->params.regs.sec & 1) { if (op->params.regs.sec & 0x10) { add_areg_native(opts, sec_reg, native_reg); - } else { + } else { add_dreg_native(opts, sec_reg, native_reg); - } - } else { + } + } else { uint8_t other_reg = native_reg == opts->gen.scratch1 ? opts->gen.scratch2 : opts->gen.scratch1; if (op->params.regs.sec & 0x10) { areg_to_native_sx(opts, sec_reg, other_reg); - } else { + } else { dreg_to_native_sx(opts, sec_reg, other_reg); - } + } add_rr(&opts->gen.code, other_reg, native_reg, SZ_D); - } + } if (op->params.regs.displacement) { add_ir(&opts->gen.code, op->params.regs.displacement, native_reg, SZ_D); - } - } + } +} void calc_areg_index_disp8(m68k_options *opts, m68k_op_info *op, uint8_t native_reg) - { +{ areg_to_native(opts, op->params.regs.pri, native_reg); calc_index_disp8(opts, op, native_reg); } @@ -362,8 +362,8 @@ void translate_m68k_op(m68kinst * inst, host_ea * ea, m68k_options * opts, uint8 movsx_rr(code, reg, opts->gen.scratch1, SZ_W, SZ_D); ea->base = opts->gen.scratch1; } else { - ea->base = reg; - } + ea->base = reg; + } return; } switch (op->addr_mode) @@ -375,7 +375,7 @@ void translate_m68k_op(m68kinst * inst, host_ea * ea, m68k_options * opts, uint8 if (dst || native_reg(&(inst->dst), opts) >= 0 || inst->dst.addr_mode == MODE_UNUSED || !(inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG) || inst->op == M68K_EXG) { - ea->mode = MODE_REG_DISPLACE8; + ea->mode = MODE_REG_DISPLACE8; ea->base = opts->gen.context_reg; ea->disp = reg_offset(op); } else { @@ -405,10 +405,10 @@ void translate_m68k_op(m68kinst * inst, host_ea * ea, m68k_options * opts, uint8 m68k_read_size(opts, inst->extra.size); if (dst) { - if (inst->src.addr_mode == MODE_AREG_PREDEC) { + if (inst->src.addr_mode == MODE_AREG_PREDEC) { //restore src operand to opts->gen.scratch2 pop_r(code, opts->gen.scratch2); - } else { + } else { //save reg value in opts->gen.scratch2 so we can use it to save the result in memory later areg_to_native(opts, op->params.regs.pri, opts->gen.scratch2); } @@ -430,7 +430,7 @@ void translate_m68k_op(m68kinst * inst, host_ea * ea, m68k_options * opts, uint8 m68k_read_size(opts, inst->extra.size); if (dst) { pop_r(code, opts->gen.scratch2); - } + } ea->mode = MODE_REG_DIRECT; ea->base = opts->gen.scratch1; @@ -444,7 +444,7 @@ void translate_m68k_op(m68kinst * inst, host_ea * ea, m68k_options * opts, uint8 m68k_read_size(opts, inst->extra.size); if (dst) { pop_r(code, opts->gen.scratch2); - } + } ea->mode = MODE_REG_DIRECT; ea->base = opts->gen.scratch1; @@ -454,7 +454,7 @@ void translate_m68k_op(m68kinst * inst, host_ea * ea, m68k_options * opts, uint8 mov_ir(code, op->params.regs.displacement + inst->address+2, opts->gen.scratch1, SZ_D); if (dst) { push_r(code, opts->gen.scratch1); - } + } m68k_read_size(opts, inst->extra.size); if (dst) { pop_r(code, opts->gen.scratch2); @@ -469,11 +469,11 @@ void translate_m68k_op(m68kinst * inst, host_ea * ea, m68k_options * opts, uint8 calc_index_disp8(opts, op, opts->gen.scratch1); if (dst) { push_r(code, opts->gen.scratch1); - } + } m68k_read_size(opts, inst->extra.size); if (dst) { pop_r(code, opts->gen.scratch2); - } + } ea->mode = MODE_REG_DIRECT; ea->base = opts->gen.scratch1; @@ -484,7 +484,7 @@ void translate_m68k_op(m68kinst * inst, host_ea * ea, m68k_options * opts, uint8 mov_ir(code, op->params.immed, opts->gen.scratch1, SZ_D); if (dst) { push_r(code, opts->gen.scratch1); - } + } m68k_read_size(opts, inst->extra.size); if (dst) { pop_r(code, opts->gen.scratch2); @@ -708,8 +708,8 @@ void translate_m68k_move(m68k_options * opts, m68kinst * inst) if (inst->dst.addr_mode == MODE_AREG_POSTINC) { inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (inst->dst.params.regs.pri == 7 ? 2 : 1)); addi_areg(opts, inc_amount, inst->dst.params.regs.pri); - } - } + } + } //add cycles for prefetch cycles(&opts->gen, BUS); @@ -758,48 +758,48 @@ void translate_m68k_ext(m68k_options * opts, m68kinst * inst) uint8_t m68k_eval_cond(m68k_options * opts, uint8_t cc) { - uint8_t cond = CC_NZ; + uint8_t cond = CC_NZ; switch (cc) - { - case COND_HIGH: - cond = CC_Z; - case COND_LOW_SAME: + { + case COND_HIGH: + cond = CC_Z; + case COND_LOW_SAME: flag_to_reg(opts, FLAG_Z, opts->gen.scratch1); or_flag_to_reg(opts, FLAG_C, opts->gen.scratch1); - break; - case COND_CARRY_CLR: - cond = CC_Z; - case COND_CARRY_SET: + break; + case COND_CARRY_CLR: + cond = CC_Z; + case COND_CARRY_SET: check_flag(opts, FLAG_C); - break; - case COND_NOT_EQ: - cond = CC_Z; - case COND_EQ: + break; + case COND_NOT_EQ: + cond = CC_Z; + case COND_EQ: check_flag(opts, FLAG_Z); - break; - case COND_OVERF_CLR: - cond = CC_Z; - case COND_OVERF_SET: + break; + case COND_OVERF_CLR: + cond = CC_Z; + case COND_OVERF_SET: check_flag(opts, FLAG_V); - break; - case COND_PLUS: - cond = CC_Z; - case COND_MINUS: + break; + case COND_PLUS: + cond = CC_Z; + case COND_MINUS: check_flag(opts, FLAG_N); - break; - case COND_GREATER_EQ: - cond = CC_Z; - case COND_LESS: + break; + case COND_GREATER_EQ: + cond = CC_Z; + case COND_LESS: cmp_flags(opts, FLAG_N, FLAG_V); - break; - case COND_GREATER: - cond = CC_Z; - case COND_LESS_EQ: + break; + case COND_GREATER: + cond = CC_Z; + case COND_LESS_EQ: flag_to_reg(opts, FLAG_V, opts->gen.scratch1); xor_flag_to_reg(opts, FLAG_N, opts->gen.scratch1); or_flag_to_reg(opts, FLAG_Z, opts->gen.scratch1); - break; - } + break; + } return cond; } @@ -1210,8 +1210,8 @@ void op_irdisp(code_info *code, m68kinst *inst, int32_t val, uint8_t dst, int32_ case M68K_ROXR: rcr_irdisp(code, val, dst, disp, size); break; case M68K_SUB: sub_irdisp(code, val, dst, disp, size); break; case M68K_SUBX: sbb_irdisp(code, val, dst, disp, size); break; - } } +} void op_rr(code_info *code, m68kinst *inst, uint8_t src, uint8_t dst, uint8_t size) { @@ -1230,7 +1230,7 @@ void op_rr(code_info *code, m68kinst *inst, uint8_t src, uint8_t dst, uint8_t si case M68K_SUB: sub_rr(code, src, dst, size); break; case M68K_SUBX: sbb_rr(code, src, dst, size); break; } - } +} void op_rrdisp(code_info *code, m68kinst *inst, uint8_t src, uint8_t dst, int32_t disp, uint8_t size) { @@ -1248,8 +1248,8 @@ void op_rrdisp(code_info *code, m68kinst *inst, uint8_t src, uint8_t dst, int32_ case M68K_OR: or_rrdisp(code, src, dst, disp, size); break; case M68K_SUB: sub_rrdisp(code, src, dst, disp, size); break; case M68K_SUBX: sbb_rrdisp(code, src, dst, disp, size); break; - } - } + } +} void op_rdispr(code_info *code, m68kinst *inst, uint8_t src, int32_t disp, uint8_t dst, uint8_t size) { @@ -1263,8 +1263,8 @@ void op_rdispr(code_info *code, m68kinst *inst, uint8_t src, int32_t disp, uint8 case M68K_OR: or_rdispr(code, src, disp, dst, size); break; case M68K_SUB: sub_rdispr(code, src, disp, dst, size); break; case M68K_SUBX: sbb_rdispr(code, src, disp, dst, size); break; - } - } + } +} void translate_m68k_arith(m68k_options *opts, m68kinst * inst, uint32_t flag_mask, host_ea *src_op, host_ea *dst_op) { @@ -1272,23 +1272,23 @@ void translate_m68k_arith(m68k_options *opts, m68kinst * inst, uint32_t flag_mas cycles(&opts->gen, BUS); if (inst->op == M68K_ADDX || inst->op == M68K_SUBX) { flag_to_carry(opts, FLAG_X); - } + } uint8_t size = inst->dst.addr_mode == MODE_AREG ? OPSIZE_LONG : inst->extra.size; if (src_op->mode == MODE_REG_DIRECT) { if (dst_op->mode == MODE_REG_DIRECT) { op_rr(code, inst, src_op->base, dst_op->base, size); - } else { + } else { op_rrdisp(code, inst, src_op->base, dst_op->base, dst_op->disp, size); - } + } } else if (src_op->mode == MODE_REG_DISPLACE8) { op_rdispr(code, inst, src_op->base, src_op->disp, dst_op->base, size); - } else { + } else { if (dst_op->mode == MODE_REG_DIRECT) { op_ir(code, inst, src_op->disp, dst_op->base, size); - } else { + } else { op_irdisp(code, inst, src_op->disp, dst_op->base, dst_op->disp, size); - } } + } if (inst->dst.addr_mode != MODE_AREG || inst->op == M68K_CMP) { update_flags(opts, flag_mask); if (inst->op == M68K_ADDX || inst->op == M68K_SUBX) { @@ -1297,8 +1297,8 @@ void translate_m68k_arith(m68k_options *opts, m68kinst * inst, uint32_t flag_mas jcc(code, CC_Z, code->cur + 2); set_flag(opts, 0, FLAG_Z); *after_flag_set = code->cur - (after_flag_set+1); - } } + } if (inst->op != M68K_CMP) { m68k_save_result(inst, opts); } @@ -1315,11 +1315,11 @@ void translate_m68k_cmp(m68k_options * opts, m68kinst * inst) translate_m68k_op(inst, &dst_op, opts, 1); pop_r(code, opts->gen.scratch2); src_op.base = opts->gen.scratch2; - } else { + } else { translate_m68k_op(inst, &dst_op, opts, 1); if (inst->dst.addr_mode == MODE_AREG && size == OPSIZE_WORD) { size = OPSIZE_LONG; - } + } } translate_m68k_arith(opts, inst, N|Z|V|C, &src_op, &dst_op); } @@ -1360,12 +1360,12 @@ void translate_m68k_unary(m68k_options *opts, m68kinst *inst, uint32_t flag_mask cycles(&opts->gen, BUS); if (dst_op->mode == MODE_REG_DIRECT) { op_r(code, inst, dst_op->base, inst->extra.size); - } else { + } else { op_rdisp(code, inst, dst_op->base, dst_op->disp, inst->extra.size); - } + } update_flags(opts, flag_mask); m68k_save_result(inst, opts); - } +} void translate_m68k_invalid(m68k_options *opts, m68kinst *inst) { @@ -1391,16 +1391,16 @@ void translate_m68k_abcd_sbcd(m68k_options *opts, m68kinst *inst, host_ea *src_o if (dst_op->base != opts->gen.scratch1) { if (dst_op->mode == MODE_REG_DIRECT) { mov_rr(code, dst_op->base, opts->gen.scratch1, SZ_B); - } else { + } else { mov_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch1, SZ_B); - } + } } uint8_t other_reg; //WARNING: This may need adjustment if register assignments change if (opts->gen.scratch2 > RBX) { other_reg = RAX; xchg_rr(code, opts->gen.scratch2, RAX, SZ_D); - } else { + } else { other_reg = opts->gen.scratch2; } mov_rr(code, opts->gen.scratch1, opts->gen.scratch1 + (AH-RAX), SZ_B); @@ -1413,9 +1413,9 @@ void translate_m68k_abcd_sbcd(m68k_options *opts, m68kinst *inst, host_ea *src_o flag_to_carry(opts, FLAG_X); if (inst->op == M68K_ABCD) { adc_rr(code, other_reg + (AH-RAX), opts->gen.scratch1 + (AH-RAX), SZ_B); - } else { + } else { sbb_rr(code, other_reg + (AH-RAX), opts->gen.scratch1 + (AH-RAX), SZ_B); - } + } cmp_ir(code, 0xA, opts->gen.scratch1 + (AH-RAX), SZ_B); code_ptr no_adjust = code->cur+1; //add correction factor if necessary @@ -1424,7 +1424,7 @@ void translate_m68k_abcd_sbcd(m68k_options *opts, m68kinst *inst, host_ea *src_o add_ir(code, 6, opts->gen.scratch1 + (AH-RAX), SZ_B); } else { sub_ir(code, 6, opts->gen.scratch1 + (AH-RAX), SZ_B); - } + } *no_adjust = code->cur - (no_adjust+1); //add low nibble result to one of the high nibble operands add_rr(code, opts->gen.scratch1 + (AH-RAX), opts->gen.scratch1, SZ_B); @@ -1432,10 +1432,10 @@ void translate_m68k_abcd_sbcd(m68k_options *opts, m68kinst *inst, host_ea *src_o add_rr(code, other_reg, opts->gen.scratch1, SZ_B); } else { sub_rr(code, other_reg, opts->gen.scratch1, SZ_B); - } + } if (opts->gen.scratch2 > RBX) { mov_rr(code, opts->gen.scratch2, RAX, SZ_D); - } + } set_flag(opts, 0, FLAG_C); set_flag(opts, 0, FLAG_V); code_ptr def_adjust = code->cur+1; @@ -1449,7 +1449,7 @@ void translate_m68k_abcd_sbcd(m68k_options *opts, m68kinst *inst, host_ea *src_o add_ir(code, 0x60, opts->gen.scratch1, SZ_B); } else { sub_ir(code, 0x60, opts->gen.scratch1, SZ_B); - } + } //V flag is set based on the result of the addition of the //result and the correction factor set_flag_cond(opts, CC_O, FLAG_V); @@ -1466,19 +1466,19 @@ void translate_m68k_abcd_sbcd(m68k_options *opts, m68kinst *inst, host_ea *src_o } else { mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, SZ_B); } - } + } m68k_save_result(inst, opts); - } +} void translate_m68k_sl(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) { translate_shift(opts, inst, src_op, dst_op, shl_ir, shl_irdisp, shl_clr, shl_clrdisp, shr_ir, shr_irdisp); - } +} void translate_m68k_asr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) { translate_shift(opts, inst, src_op, dst_op, sar_ir, sar_irdisp, sar_clr, sar_clrdisp, NULL, NULL); - } +} void translate_m68k_lsr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) { @@ -1490,17 +1490,17 @@ void translate_m68k_bit(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos code_info *code = &opts->gen.code; cycles(&opts->gen, inst->extra.size == OPSIZE_BYTE ? 4 : ( inst->op == M68K_BTST ? 6 : (inst->op == M68K_BCLR ? 10 : 8)) - ); + ); if (src_op->mode == MODE_IMMED) { - if (inst->extra.size == OPSIZE_BYTE) { + if (inst->extra.size == OPSIZE_BYTE) { src_op->disp &= 0x7; - } + } if (dst_op->mode == MODE_REG_DIRECT) { op_ir(code, inst, src_op->disp, dst_op->base, inst->extra.size); - } else { + } else { op_irdisp(code, inst, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size); - } - } else { + } + } else { if (src_op->mode == MODE_REG_DISPLACE8 || (inst->dst.addr_mode != MODE_REG && src_op->base != opts->gen.scratch1 && src_op->base != opts->gen.scratch2)) { if (dst_op->base == opts->gen.scratch1) { push_r(code, opts->gen.scratch2); @@ -1524,38 +1524,38 @@ void translate_m68k_bit(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos if (src_op->base != opts->gen.scratch1 && src_op->base != opts->gen.scratch2) { if (src_op->mode == MODE_REG_DIRECT) { mov_rr(code, src_op->base, opts->gen.scratch1, SZ_D); - } else { + } else { mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_D); src_op->mode = MODE_REG_DIRECT; - } - src_op->base = opts->gen.scratch1; } - //b### with register destination is modulo 32 - //x86 with a memory destination isn't modulo anything - //so use an and here to force the value to be modulo 32 + src_op->base = opts->gen.scratch1; + } + //b### with register destination is modulo 32 + //x86 with a memory destination isn't modulo anything + //so use an and here to force the value to be modulo 32 and_ir(code, 31, opts->gen.scratch1, SZ_D); - } else if(inst->dst.addr_mode != MODE_REG) { - //b### with memory destination is modulo 8 - //x86-64 doesn't support 8-bit bit operations - //so we fake it by forcing the bit number to be modulo 8 + } else if(inst->dst.addr_mode != MODE_REG) { + //b### with memory destination is modulo 8 + //x86-64 doesn't support 8-bit bit operations + //so we fake it by forcing the bit number to be modulo 8 and_ir(code, 7, src_op->base, SZ_D); - size = SZ_D; - } + size = SZ_D; + } if (dst_op->mode == MODE_REG_DIRECT) { op_rr(code, inst, src_op->base, dst_op->base, size); - } else { + } else { op_rrdisp(code, inst, src_op->base, dst_op->base, dst_op->disp, size); - } + } if (src_op->base == opts->gen.scratch2) { pop_r(code, opts->gen.scratch2); - } } - //x86 sets the carry flag to the value of the bit tested - //68K sets the zero flag to the complement of the bit tested + } + //x86 sets the carry flag to the value of the bit tested + //68K sets the zero flag to the complement of the bit tested set_flag_cond(opts, CC_NC, FLAG_Z); - if (inst->op != M68K_BTST) { + if (inst->op != M68K_BTST) { m68k_save_result(inst, opts); - } + } } void translate_m68k_chk(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) @@ -1564,26 +1564,26 @@ void translate_m68k_chk(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos cycles(&opts->gen, 6); if (dst_op->mode == MODE_REG_DIRECT) { cmp_ir(code, 0, dst_op->base, inst->extra.size); - } else { + } else { cmp_irdisp(code, 0, dst_op->base, dst_op->disp, inst->extra.size); - } - uint32_t isize; - switch(inst->src.addr_mode) - { - case MODE_AREG_DISPLACE: - case MODE_AREG_INDEX_DISP8: - case MODE_ABSOLUTE_SHORT: - case MODE_PC_INDEX_DISP8: - case MODE_PC_DISPLACE: - case MODE_IMMEDIATE: - isize = 4; - break; - case MODE_ABSOLUTE: - isize = 6; - break; - default: - isize = 2; - } + } + uint32_t isize; + switch(inst->src.addr_mode) + { + case MODE_AREG_DISPLACE: + case MODE_AREG_INDEX_DISP8: + case MODE_ABSOLUTE_SHORT: + case MODE_PC_INDEX_DISP8: + case MODE_PC_DISPLACE: + case MODE_IMMEDIATE: + isize = 4; + break; + case MODE_ABSOLUTE: + isize = 6; + break; + default: + isize = 2; + } //make sure we won't start a new chunk in the middle of these branches check_alloc_code(code, MAX_INST_LEN * 11); code_ptr passed = code->cur + 1; @@ -1598,16 +1598,16 @@ void translate_m68k_chk(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos cmp_rr(code, src_op->base, dst_op->base, inst->extra.size); } else if(src_op->mode == MODE_REG_DISPLACE8) { cmp_rdispr(code, src_op->base, src_op->disp, dst_op->base, inst->extra.size); - } else { + } else { cmp_ir(code, src_op->disp, dst_op->base, inst->extra.size); - } + } } else if(dst_op->mode == MODE_REG_DISPLACE8) { if (src_op->mode == MODE_REG_DIRECT) { cmp_rrdisp(code, src_op->base, dst_op->base, dst_op->disp, inst->extra.size); - } else { + } else { cmp_irdisp(code, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size); - } } + } passed = code->cur + 1; jcc(code, CC_LE, code->cur + 2); set_flag(opts, 0, FLAG_N); @@ -1616,37 +1616,37 @@ void translate_m68k_chk(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos jmp(code, opts->trap); *passed = code->cur - (passed+1); cycles(&opts->gen, 4); - } +} void translate_m68k_div(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) - { +{ code_info *code = &opts->gen.code; check_alloc_code(code, MAX_NATIVE_SIZE); - //TODO: cycle exact division + //TODO: cycle exact division cycles(&opts->gen, inst->op == M68K_DIVS ? 158 : 140); set_flag(opts, 0, FLAG_C); push_r(code, RDX); push_r(code, RAX); if (dst_op->mode == MODE_REG_DIRECT) { mov_rr(code, dst_op->base, RAX, SZ_D); - } else { + } else { mov_rdispr(code, dst_op->base, dst_op->disp, RAX, SZ_D); - } + } if (src_op->mode == MODE_IMMED) { mov_ir(code, (src_op->disp & 0x8000) && inst->op == M68K_DIVS ? src_op->disp | 0xFFFF0000 : src_op->disp, opts->gen.scratch2, SZ_D); } else if (src_op->mode == MODE_REG_DIRECT) { - if (inst->op == M68K_DIVS) { + if (inst->op == M68K_DIVS) { movsx_rr(code, src_op->base, opts->gen.scratch2, SZ_W, SZ_D); - } else { + } else { movzx_rr(code, src_op->base, opts->gen.scratch2, SZ_W, SZ_D); - } + } } else if (src_op->mode == MODE_REG_DISPLACE8) { - if (inst->op == M68K_DIVS) { + if (inst->op == M68K_DIVS) { movsx_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch2, SZ_W, SZ_D); - } else { + } else { movzx_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch2, SZ_W, SZ_D); - } } + } uint32_t isize = 2; switch(inst->src.addr_mode) { @@ -1671,38 +1671,38 @@ void translate_m68k_div(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos mov_ir(code, inst->address+isize, opts->gen.scratch1, SZ_D); jmp(code, opts->trap); *not_zero = code->cur - (not_zero+1); - if (inst->op == M68K_DIVS) { + if (inst->op == M68K_DIVS) { cdq(code); - } else { + } else { xor_rr(code, RDX, RDX, SZ_D); - } - if (inst->op == M68K_DIVS) { + } + if (inst->op == M68K_DIVS) { idiv_r(code, opts->gen.scratch2, SZ_D); - } else { + } else { div_r(code, opts->gen.scratch2, SZ_D); - } + } code_ptr skip_sec_check, norm_off; - if (inst->op == M68K_DIVS) { + if (inst->op == M68K_DIVS) { cmp_ir(code, 0x8000, RAX, SZ_D); skip_sec_check = code->cur + 1; jcc(code, CC_GE, code->cur + 2); cmp_ir(code, -0x8000, RAX, SZ_D); norm_off = code->cur + 1; jcc(code, CC_L, code->cur + 2); - } else { + } else { cmp_ir(code, 0x10000, RAX, SZ_D); norm_off = code->cur + 1; jcc(code, CC_NC, code->cur + 2); - } + } if (dst_op->mode == MODE_REG_DIRECT) { mov_rr(code, RDX, dst_op->base, SZ_W); shl_ir(code, 16, dst_op->base, SZ_D); mov_rr(code, RAX, dst_op->base, SZ_W); - } else { + } else { mov_rrdisp(code, RDX, dst_op->base, dst_op->disp, SZ_W); shl_irdisp(code, 16, dst_op->base, dst_op->disp, SZ_D); mov_rrdisp(code, RAX, dst_op->base, dst_op->disp, SZ_W); - } + } cmp_ir(code, 0, RAX, SZ_W); pop_r(code, RAX); pop_r(code, RDX); @@ -1710,14 +1710,14 @@ void translate_m68k_div(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos code_ptr end_off = code->cur + 1; jmp(code, code->cur + 2); *norm_off = code->cur - (norm_off + 1); - if (inst->op == M68K_DIVS) { + if (inst->op == M68K_DIVS) { *skip_sec_check = code->cur - (skip_sec_check+1); - } + } pop_r(code, RAX); pop_r(code, RDX); set_flag(opts, 1, FLAG_V); *end_off = code->cur - (end_off + 1); - } +} void translate_m68k_exg(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) { @@ -1728,22 +1728,22 @@ void translate_m68k_exg(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos if (src_op->mode == MODE_REG_DIRECT) { mov_rr(code, src_op->base, dst_op->base, SZ_D); mov_rr(code, opts->gen.scratch2, src_op->base, SZ_D); - } else { + } else { mov_rdispr(code, src_op->base, src_op->disp, dst_op->base, SZ_D); mov_rrdisp(code, opts->gen.scratch2, src_op->base, src_op->disp, SZ_D); - } - } else { + } + } else { mov_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch2, SZ_D); if (src_op->mode == MODE_REG_DIRECT) { mov_rrdisp(code, src_op->base, dst_op->base, dst_op->disp, SZ_D); mov_rr(code, opts->gen.scratch2, src_op->base, SZ_D); - } else { + } else { mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_D); mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, SZ_D); mov_rrdisp(code, opts->gen.scratch2, src_op->base, src_op->disp, SZ_D); - } - } } + } +} void translate_m68k_mul(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) { @@ -1752,41 +1752,41 @@ void translate_m68k_mul(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos if (src_op->mode == MODE_IMMED) { mov_ir(code, inst->op == M68K_MULU ? (src_op->disp & 0xFFFF) : ((src_op->disp & 0x8000) ? src_op->disp | 0xFFFF0000 : src_op->disp), opts->gen.scratch1, SZ_D); } else if (src_op->mode == MODE_REG_DIRECT) { - if (inst->op == M68K_MULS) { + if (inst->op == M68K_MULS) { movsx_rr(code, src_op->base, opts->gen.scratch1, SZ_W, SZ_D); - } else { - movzx_rr(code, src_op->base, opts->gen.scratch1, SZ_W, SZ_D); - } } else { - if (inst->op == M68K_MULS) { + movzx_rr(code, src_op->base, opts->gen.scratch1, SZ_W, SZ_D); + } + } else { + if (inst->op == M68K_MULS) { movsx_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_W, SZ_D); - } else { + } else { movzx_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_W, SZ_D); - } } + } uint8_t dst_reg; if (dst_op->mode == MODE_REG_DIRECT) { dst_reg = dst_op->base; - if (inst->op == M68K_MULS) { + if (inst->op == M68K_MULS) { movsx_rr(code, dst_reg, dst_reg, SZ_W, SZ_D); - } else { - movzx_rr(code, dst_reg, dst_reg, SZ_W, SZ_D); - } } else { + movzx_rr(code, dst_reg, dst_reg, SZ_W, SZ_D); + } + } else { dst_reg = opts->gen.scratch2; - if (inst->op == M68K_MULS) { + if (inst->op == M68K_MULS) { movsx_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch2, SZ_W, SZ_D); - } else { + } else { movzx_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch2, SZ_W, SZ_D); - } } + } imul_rr(code, opts->gen.scratch1, dst_reg, SZ_D); if (dst_op->mode == MODE_REG_DISPLACE8) { mov_rrdisp(code, dst_reg, dst_op->base, dst_op->disp, SZ_D); - } + } cmp_ir(code, 0, dst_reg, SZ_D); update_flags(opts, N|Z|V0|C0); - } +} void translate_m68k_negx(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) { @@ -1806,12 +1806,12 @@ void translate_m68k_negx(m68k_options *opts, m68kinst *inst, host_ea *src_op, ho sbb_rr(code, dst_op->base, opts->gen.scratch1, inst->extra.size); mov_rr(code, opts->gen.scratch1, dst_op->base, inst->extra.size); } - } else { + } else { xor_rr(code, opts->gen.scratch1, opts->gen.scratch1, inst->extra.size); flag_to_carry(opts, FLAG_X); sbb_rdispr(code, dst_op->base, dst_op->disp, opts->gen.scratch1, inst->extra.size); mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, inst->extra.size); - } + } set_flag_cond(opts, CC_C, FLAG_C); code_ptr after_flag_set = code->cur + 1; jcc(code, CC_Z, code->cur + 2); @@ -1819,21 +1819,21 @@ void translate_m68k_negx(m68k_options *opts, m68kinst *inst, host_ea *src_op, ho *after_flag_set = code->cur - (after_flag_set+1); set_flag_cond(opts, CC_S, FLAG_N); set_flag_cond(opts, CC_O, FLAG_V); - if (opts->flag_regs[FLAG_C] >= 0) { + if (opts->flag_regs[FLAG_C] >= 0) { flag_to_flag(opts, FLAG_C, FLAG_X); - } else { + } else { set_flag_cond(opts, CC_C, FLAG_X); - } + } m68k_save_result(inst, opts); - } +} void translate_m68k_rot(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) { code_info *code = &opts->gen.code; int32_t init_flags = C|V0; - if (inst->src.addr_mode == MODE_UNUSED) { + if (inst->src.addr_mode == MODE_UNUSED) { cycles(&opts->gen, BUS); - //Memory rotate + //Memory rotate if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) { flag_to_carry(opts, FLAG_X); init_flags |= X; @@ -1843,7 +1843,7 @@ void translate_m68k_rot(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos cmp_ir(code, 0, dst_op->base, inst->extra.size); update_flags(opts, Z|N); m68k_save_result(inst, opts); - } else { + } else { if (src_op->mode == MODE_IMMED) { cycles(&opts->gen, (inst->extra.size == OPSIZE_LONG ? 8 : 6) + src_op->disp*2); if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) { @@ -1852,18 +1852,18 @@ void translate_m68k_rot(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos } if (dst_op->mode == MODE_REG_DIRECT) { op_ir(code, inst, src_op->disp, dst_op->base, inst->extra.size); - } else { + } else { op_irdisp(code, inst, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size); - } + } update_flags(opts, init_flags); - } else { + } else { if (src_op->mode == MODE_REG_DIRECT) { if (src_op->base != opts->gen.scratch1) { mov_rr(code, src_op->base, opts->gen.scratch1, SZ_B); - } + } } else { mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_B); - } + } and_ir(code, 63, opts->gen.scratch1, SZ_D); code_ptr zero_off = code->cur + 1; jcc(code, CC_Z, code->cur + 2); @@ -1877,30 +1877,30 @@ void translate_m68k_rot(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) { flag_to_carry(opts, FLAG_X); init_flags |= X; - } else { + } else { sub_ir(code, 32, opts->gen.scratch1, SZ_B); - } + } if (dst_op->mode == MODE_REG_DIRECT) { op_ir(code, inst, 31, dst_op->base, inst->extra.size); op_ir(code, inst, 1, dst_op->base, inst->extra.size); - } else { + } else { op_irdisp(code, inst, 31, dst_op->base, dst_op->disp, inst->extra.size); op_irdisp(code, inst, 1, dst_op->base, dst_op->disp, inst->extra.size); - } + } if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) { set_flag_cond(opts, CC_C, FLAG_X); sub_ir(code, 32, opts->gen.scratch1, SZ_B); *norm_off = code->cur - (norm_off+1); flag_to_carry(opts, FLAG_X); - } else { + } else { *norm_off = code->cur - (norm_off+1); - } + } if (dst_op->mode == MODE_REG_DIRECT) { op_r(code, inst, dst_op->base, inst->extra.size); - } else { + } else { op_rdisp(code, inst, dst_op->base, dst_op->disp, inst->extra.size); - } + } update_flags(opts, init_flags); code_ptr end_off = code->cur + 1; jmp(code, code->cur + 2); @@ -1908,26 +1908,26 @@ void translate_m68k_rot(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos if (inst->op == M68K_ROXR || inst->op == M68K_ROXL) { //Carry flag is set to X flag when count is 0, this is different from ROR/ROL flag_to_flag(opts, FLAG_X, FLAG_C); - } else { + } else { set_flag(opts, 0, FLAG_C); - } + } *end_off = code->cur - (end_off+1); - } + } if (dst_op->mode == MODE_REG_DIRECT) { cmp_ir(code, 0, dst_op->base, inst->extra.size); - } else { + } else { cmp_irdisp(code, 0, dst_op->base, dst_op->disp, inst->extra.size); - } - update_flags(opts, Z|N); } - } + update_flags(opts, Z|N); + } +} void translate_m68k_illegal(m68k_options *opts, m68kinst *inst) { code_info *code = &opts->gen.code; call(code, opts->gen.save_context); call_args(code, (code_ptr)print_regs_exit, 1, opts->gen.context_reg); - } +} #define BIT_SUPERVISOR 5 @@ -1943,25 +1943,25 @@ void translate_m68k_andi_ori_ccr_sr(m68k_options *opts, m68kinst *inst) if ((base_flag == X0) ^ (inst->src.params.immed & 1 << i) > 0) { flag_mask |= base_flag << ((4 - i) * 3); - } - } + } + } update_flags(opts, flag_mask); if (inst->op == M68K_ANDI_SR || inst->op == M68K_ORI_SR) { if (inst->op == M68K_ANDI_SR) { and_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); - } else { + } else { or_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); - } + } if (inst->op == M68K_ANDI_SR && !(inst->src.params.immed & (1 << (BIT_SUPERVISOR + 8)))) { //leave supervisor mode swap_ssp_usp(opts); - } + } if ((inst->op == M68K_ANDI_SR && (inst->src.params.immed & 0x700) != 0x700) || (inst->op == M68K_ORI_SR && inst->src.params.immed & 0x700)) { call(code, opts->do_sync); - } - } - } + } + } +} void translate_m68k_eori_ccr_sr(m68k_options *opts, m68kinst *inst) { @@ -1970,26 +1970,26 @@ void translate_m68k_eori_ccr_sr(m68k_options *opts, m68kinst *inst) //TODO: If ANDI to SR, trap if not in supervisor mode if (inst->src.params.immed & 0x1) { xor_flag(opts, 1, FLAG_C); - } + } if (inst->src.params.immed & 0x2) { xor_flag(opts, 1, FLAG_V); - } + } if (inst->src.params.immed & 0x4) { xor_flag(opts, 1, FLAG_Z); - } + } if (inst->src.params.immed & 0x8) { xor_flag(opts, 1, FLAG_N); - } + } if (inst->src.params.immed & 0x10) { xor_flag(opts, 1, FLAG_X); - } + } if (inst->op == M68K_ORI_SR) { xor_irdisp(code, inst->src.params.immed >> 8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); if (inst->src.params.immed & 0x700) { call(code, opts->do_sync); - } - } - } + } + } +} void set_all_flags(m68k_options *opts, uint8_t flags) { @@ -1999,7 +1999,7 @@ void set_all_flags(m68k_options *opts, uint8_t flags) flag_mask |= flags & 0x2 ? V1 : V0; flag_mask |= flags & 0x1 ? C1 : C0; update_flags(opts, flag_mask); - } +} void translate_m68k_move_ccr_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) { @@ -2012,11 +2012,11 @@ void translate_m68k_move_ccr_sr(m68k_options *opts, m68kinst *inst, host_ea *src if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { //leave supervisor mode swap_ssp_usp(opts); - } - call(code, opts->do_sync); } + call(code, opts->do_sync); + } cycles(&opts->gen, 12); - } else { + } else { if (src_op->base != opts->gen.scratch1) { if (src_op->mode == MODE_REG_DIRECT) { mov_rr(code, src_op->base, opts->gen.scratch1, SZ_W); @@ -2026,24 +2026,24 @@ void translate_m68k_move_ccr_sr(m68k_options *opts, m68kinst *inst, host_ea *src } call(code, inst->op == M68K_MOVE_SR ? opts->set_sr : opts->set_ccr); cycles(&opts->gen, 12); - } - } + } +} void translate_m68k_stop(m68k_options *opts, m68kinst *inst) { - //TODO: Trap if not in system mode - //manual says 4 cycles, but it has to be at least 8 since it's a 2-word instruction - //possibly even 12 since that's how long MOVE to SR takes + //TODO: Trap if not in system mode + //manual says 4 cycles, but it has to be at least 8 since it's a 2-word instruction + //possibly even 12 since that's how long MOVE to SR takes //On further thought prefetch + the fact that this stops the CPU may make //Motorola's accounting make sense here code_info *code = &opts->gen.code; cycles(&opts->gen, BUS*2); set_all_flags(opts, inst->src.params.immed); mov_irdisp(code, (inst->src.params.immed >> 8), opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); - if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { - //leave supervisor mode + if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { + //leave supervisor mode swap_ssp_usp(opts); - } + } code_ptr loop_top = code->cur; call(code, opts->do_sync); cmp_rr(code, opts->gen.limit, opts->gen.cycles, SZ_D); @@ -2057,7 +2057,7 @@ void translate_m68k_stop(m68k_options *opts, m68kinst *inst) *after_cycle_up = code->cur - (after_cycle_up+1); cmp_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, int_cycle), opts->gen.cycles, SZ_D); jcc(code, CC_C, loop_top); - } +} void translate_m68k_move_from_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) { @@ -2066,9 +2066,9 @@ void translate_m68k_move_from_sr(m68k_options *opts, m68kinst *inst, host_ea *sr call(code, opts->get_sr); if (dst_op->mode == MODE_REG_DIRECT) { mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_W); - } else { + } else { mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, SZ_W); - } + } m68k_save_result(inst, opts); } @@ -2114,8 +2114,8 @@ void nop_fill_or_jmp_next(code_info *code, code_ptr old_end, code_ptr next_inst) if (next_inst == old_end && next_inst - code->cur < 2) { while (code->cur < old_end) { *(code->cur++) = 0x90; //NOP - } - } else { + } + } else { jmp(code, next_inst); } } @@ -2141,7 +2141,7 @@ m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context) mov_rr(code, RAX, options->gen.scratch1, SZ_PTR); call(code, options->gen.load_context); jmp_r(code, options->gen.scratch1); - } + } jmp(&orig, options->retrans_stub); } return context; -- cgit v1.2.3 From 882b6ddf738a529c15f45f9d058dc753bc354b50 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Thu, 8 Jan 2015 19:11:56 -0800 Subject: Moved translate_m68k_rte and translate_m68k_reset to m68k_core.c --- m68k_core_x86.c | 54 +++++++++++++----------------------------------------- 1 file changed, 13 insertions(+), 41 deletions(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 285a1dd..d59b9bd 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -543,6 +543,17 @@ void m68k_save_result(m68kinst * inst, m68k_options * opts) } } +void check_user_mode_swap_ssp_usp(m68k_options *opts) +{ + code_info * code = &opts->gen.code; + //Check if we've switched to user mode and swap stack pointers if needed + bt_irdisp(code, 5, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); + code_ptr end_off = code->cur + 1; + jcc(code, CC_C, code->cur + 2); + swap_ssp_usp(opts); + *end_off = code->cur - (end_off + 1); +} + void translate_m68k_move(m68k_options * opts, m68kinst * inst) { code_info *code = &opts->gen.code; @@ -2072,37 +2083,6 @@ void translate_m68k_move_from_sr(m68k_options *opts, m68kinst *inst, host_ea *sr m68k_save_result(inst, opts); } -void translate_m68k_reset(m68k_options *opts, m68kinst *inst) -{ - code_info *code = &opts->gen.code; - call(code, opts->gen.save_context); - call_args(code, (code_ptr)print_regs_exit, 1, opts->gen.context_reg); -} - -void translate_m68k_rte(m68k_options *opts, m68kinst *inst) -{ - code_info *code = &opts->gen.code; - //TODO: Trap if not in system mode - //Read saved SR - areg_to_native(opts, 7, opts->gen.scratch1); - call(code, opts->read_16); - addi_areg(opts, 2, 7); - call(code, opts->set_sr); - //Read saved PC - areg_to_native(opts, 7, opts->gen.scratch1); - call(code, opts->read_32); - addi_areg(opts, 4, 7); - //Check if we've switched to user mode and swap stack pointers if needed - bt_irdisp(code, 5, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); - code_ptr end_off = code->cur + 1; - jcc(code, CC_C, code->cur + 2); - swap_ssp_usp(opts); - *end_off = code->cur - (end_off+1); - //Get native address, sync components, recalculate integer points and jump to returned address - call(code, opts->native_addr_and_sync); - jmp_r(code, opts->gen.scratch1); -} - void translate_out_of_bounds(code_info *code) { xor_rr(code, RDI, RDI, SZ_D); @@ -2459,11 +2439,7 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu //set target cycle to sync cycle mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, sync_cycle), opts->gen.limit, SZ_D); //swap USP and SSP if not already in supervisor mode - bt_irdisp(code, 5, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); - code_ptr already_supervisor = code->cur + 1; - jcc(code, CC_C, code->cur + 2); - swap_ssp_usp(opts); - *already_supervisor = code->cur - (already_supervisor+1); + check_user_mode_swap_ssp_usp(opts); //save PC subi_areg(opts, 4, 7); areg_to_native(opts, 7, opts->gen.scratch2); @@ -2493,11 +2469,7 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu opts->trap = code->cur; push_r(code, opts->gen.scratch2); //swap USP and SSP if not already in supervisor mode - bt_irdisp(code, 5, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); - already_supervisor = code->cur + 1; - jcc(code, CC_C, code->cur + 2); - swap_ssp_usp(opts); - *already_supervisor = code->cur - (already_supervisor+1); + check_user_mode_swap_ssp_usp(opts); //save PC subi_areg(opts, 4, 7); areg_to_native(opts, 7, opts->gen.scratch2); -- cgit v1.2.3 From 7565848dd7a5d4dd1f762aeebd31d5835fe14835 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Thu, 8 Jan 2015 21:00:21 -0800 Subject: Moved m68k_save_result to m68k_core.c --- m68k_core_x86.c | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index d59b9bd..938b071 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -521,28 +521,6 @@ void translate_m68k_op(m68kinst * inst, host_ea * ea, m68k_options * opts, uint8 } } -void m68k_save_result(m68kinst * inst, m68k_options * opts) -{ - code_info *code = &opts->gen.code; - if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG && inst->dst.addr_mode != MODE_UNUSED) { - if (inst->dst.addr_mode == MODE_AREG_PREDEC && inst->src.addr_mode == MODE_AREG_PREDEC && inst->op != M68K_MOVE) { - areg_to_native(opts, inst->dst.params.regs.pri, opts->gen.scratch2); - } - switch (inst->extra.size) - { - case OPSIZE_BYTE: - call(code, opts->write_8); - break; - case OPSIZE_WORD: - call(code, opts->write_16); - break; - case OPSIZE_LONG: - call(code, opts->write_32_lowfirst); - break; - } - } -} - void check_user_mode_swap_ssp_usp(m68k_options *opts) { code_info * code = &opts->gen.code; -- cgit v1.2.3 From d42234e4af41481a3db6f6ea5173bb1623b30d22 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Thu, 8 Jan 2015 23:20:41 -0800 Subject: A couple more indentation fixes --- m68k_core_x86.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 938b071..9787b9c 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -649,7 +649,7 @@ void translate_m68k_move(m68k_options * opts, m68kinst * inst) mov_ir(code, inst->address, opts->gen.scratch2, SZ_D); if (src.base == opts->gen.scratch1 && !(inst->dst.params.regs.sec & 1)) { push_r(code, opts->gen.scratch1); - } + } calc_index_disp8(opts, &inst->dst, opts->gen.scratch2); if (src.base == opts->gen.scratch1 && !(inst->dst.params.regs.sec & 1)) { pop_r(code, opts->gen.scratch1); @@ -691,7 +691,7 @@ void translate_m68k_move(m68k_options * opts, m68kinst * inst) if (inst->dst.addr_mode != MODE_AREG) { cmp_ir(code, 0, flags_reg, inst->extra.size); update_flags(opts, N|Z|V0|C0); -} + } if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG) { m68k_write_size(opts, inst->extra.size); if (inst->dst.addr_mode == MODE_AREG_POSTINC) { -- cgit v1.2.3 From f439d8688758710b74d4909e77ebce6444b8a448 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Wed, 14 Jan 2015 09:38:54 -0800 Subject: Removed hardcoded assumptions in M68K core about which parts of the memory map are RAM --- m68k_core_x86.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 9787b9c..167c740 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -2202,8 +2202,10 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu opts->gen.native_code_map = malloc(sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); memset(opts->gen.native_code_map, 0, sizeof(native_map_slot) * NATIVE_MAP_CHUNKS); opts->gen.deferred = NULL; - opts->gen.ram_inst_sizes = malloc(sizeof(uint8_t *) * 64); - memset(opts->gen.ram_inst_sizes, 0, sizeof(uint8_t *) * 64); + + uint32_t inst_size_size = sizeof(uint8_t *) * ram_size(&opts->gen) / 1024; + opts->gen.ram_inst_sizes = malloc(inst_size_size); + memset(opts->gen.ram_inst_sizes, 0, inst_size_size); code_info *code = &opts->gen.code; init_code_info(code); @@ -2227,9 +2229,11 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu opts->gen.load_context = code->cur; for (int i = 0; i < 5; i++) + { if (opts->flag_regs[i] >= 0) { mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, flags) + i, opts->flag_regs[i], SZ_B); } + } for (int i = 0; i < 8; i++) { if (opts->dregs[i] >= 0) { -- cgit v1.2.3 From 705e3ec64b1c659f400f96536dcb8c5c930e4bda Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Mon, 11 May 2015 20:30:13 -0700 Subject: Fixed a missed call to do_sync when updating SR in 68K core --- m68k_core_x86.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 167c740..2792bc6 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -2013,7 +2013,12 @@ void translate_m68k_move_ccr_sr(m68k_options *opts, m68kinst *inst, host_ea *src mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_W); } } - call(code, inst->op == M68K_MOVE_SR ? opts->set_sr : opts->set_ccr); + if (inst->op == M68K_MOVE_SR) { + call(code, opts->set_sr); + call(code, opts->do_sync); + } else { + call(code, opts->set_ccr); + } cycles(&opts->gen, 12); } } -- cgit v1.2.3 From 057e8fb32092e1c1c642791cf915c2522b5662e0 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Fri, 22 May 2015 23:49:32 -0700 Subject: Don't attempt to translate or map code at odd addresses. This fixes a bug that shows up when playing College Footbal USA 96 --- m68k_core_x86.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 2792bc6..62588b7 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -801,7 +801,7 @@ void translate_m68k_bcc(m68k_options * opts, m68kinst * inst) if (inst->extra.cond == COND_TRUE) { jump_m68k_abs(opts, after + disp); } else { - code_ptr dest_addr = get_native_address(opts->gen.native_code_map, after + disp); + code_ptr dest_addr = get_native_address(opts, after + disp); uint8_t cond = m68k_eval_cond(opts, inst->extra.cond); if (!dest_addr) { opts->gen.deferred = defer_address(opts->gen.deferred, after + disp, code->cur + 2); @@ -2089,7 +2089,7 @@ m68k_context * m68k_handle_code_write(uint32_t address, m68k_context * context) if (inst_start) { m68k_options * options = context->options; code_info *code = &options->gen.code; - code_ptr dst = get_native_address(context->native_code_map, inst_start); + code_ptr dst = get_native_address(context->options, inst_start); code_info orig; orig.cur = dst; orig.last = dst + 128; @@ -2475,4 +2475,11 @@ void init_m68k_opts(m68k_options * opts, memmap_chunk * memmap, uint32_t num_chu call(code, opts->native_addr_and_sync); cycles(&opts->gen, 18); jmp_r(code, opts->gen.scratch1); + + opts->odd_address = code->cur; + mov_ir(code, (int64_t)stderr, RDI, SZ_PTR); + mov_ir(code, (int64_t)"Attempt to execute code at odd address\n", RSI, SZ_PTR); + call_args_abi(code, (code_ptr)fprintf, 2, RDI, RSI, RDX); + xor_rr(code, RDI, RDI, SZ_D); + call_args(code, (code_ptr)exit, 1, RDI); } -- cgit v1.2.3 From a68ca32cfe9156b40952894ff09f1991f073486e Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Sat, 23 May 2015 20:24:27 -0700 Subject: Eliminate runtime.S/runtime_32.S. --- m68k_core_x86.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 62588b7..5c459b0 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -1363,8 +1363,12 @@ void translate_m68k_invalid(m68k_options *opts, m68kinst *inst) retn(code); return; } - mov_ir(code, inst->address, opts->gen.scratch1, SZ_D); - call(code, (code_ptr)m68k_invalid); + mov_ir(code, (int64_t)stderr, RDI, SZ_PTR); + mov_ir(code, (int64_t)"Invalid instruction at %X\n", RSI, SZ_PTR); + mov_ir(code, inst->address, RDX, SZ_D); + call_args_abi(code, (code_ptr)fprintf, 3, RDI, RSI, RDX); + mov_ir(code, 1, RDI, SZ_D); + call_args(code, (code_ptr)exit, 1, RDI); } void translate_m68k_abcd_sbcd(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) -- cgit v1.2.3 From f76857783001f197067e6a8728e76046da8b9e6f Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Mon, 25 May 2015 13:21:24 -0700 Subject: Fix div instruction when dest is d0 in 32-bit build --- m68k_core_x86.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index 5c459b0..ed0265b 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -1698,8 +1698,13 @@ void translate_m68k_div(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos } cmp_ir(code, 0, RAX, SZ_W); pop_r(code, RAX); - pop_r(code, RDX); - update_flags(opts, V0|Z|N); + if (dst_op->base == RDX) { + update_flags(opts, V0|Z|N); + add_ir(code, sizeof(void *), RSP, SZ_D); + } else { + pop_r(code, RDX); + update_flags(opts, V0|Z|N); + } code_ptr end_off = code->cur + 1; jmp(code, code->cur + 2); *norm_off = code->cur - (norm_off + 1); -- cgit v1.2.3 From b40138532a2345f01538a991ab756fa5e28aa8e0 Mon Sep 17 00:00:00 2001 From: Michael Pavone Date: Mon, 25 May 2015 15:01:38 -0700 Subject: Fix crash bug in 32-bit build for certain secnarios with bcd instructions --- m68k_core_x86.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'm68k_core_x86.c') diff --git a/m68k_core_x86.c b/m68k_core_x86.c index ed0265b..7b542da 100644 --- a/m68k_core_x86.c +++ b/m68k_core_x86.c @@ -1451,8 +1451,10 @@ void translate_m68k_abcd_sbcd(m68k_options *opts, m68kinst *inst, host_ea *src_o cmp_ir(code, 0, opts->gen.scratch1, SZ_B); set_flag_cond(opts, CC_S, FLAG_N); - jcc(code, CC_Z, code->cur + 4); + code_ptr no_setz = code->cur+1; + jcc(code, CC_Z, no_setz); set_flag(opts, 0, FLAG_Z); + *no_setz = code->cur - (no_setz + 1); if (dst_op->base != opts->gen.scratch1) { if (dst_op->mode == MODE_REG_DIRECT) { mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_B); -- cgit v1.2.3