diff options
author | Michael Pavone <pavone@retrodev.com> | 2014-02-16 19:54:27 -0800 |
---|---|---|
committer | Michael Pavone <pavone@retrodev.com> | 2014-02-16 19:54:27 -0800 |
commit | 0e2ca307653c9d0af871a1a0d68a7f7014d02fc4 (patch) | |
tree | 593038ac359a3f89493e2327ef7eb1211141b922 | |
parent | 01325bd8f812abe9685ab69a0f112558a0f42fe5 (diff) |
Generate handle_cycle_limit at runtime so it can use the generated save/load_context functions. Since the hand written versions of save/load are no longer used they have been removed.
-rw-r--r-- | m68k_to_x86.c | 52 | ||||
-rw-r--r-- | m68k_to_x86.h | 2 | ||||
-rw-r--r-- | runtime.S | 61 |
3 files changed, 41 insertions, 74 deletions
diff --git a/m68k_to_x86.c b/m68k_to_x86.c index 916a9b1..54ec824 100644 --- a/m68k_to_x86.c +++ b/m68k_to_x86.c @@ -30,12 +30,10 @@ char disasm_buf[1024]; m68k_context * sync_components(m68k_context * context, uint32_t address); -void handle_cycle_limit(); void m68k_invalid(); void set_sr(); void set_ccr(); void get_sr(); -void do_sync(); void bcd_add(); void bcd_sub(); @@ -56,12 +54,12 @@ uint8_t * check_cycles_int(uint8_t * dst, uint32_t address, x86_68k_options * op return dst; } -uint8_t * check_cycles(uint8_t * dst) +uint8_t * check_cycles(uint8_t * dst, x86_68k_options * opts) { dst = cmp_rr(dst, CYCLES, LIMIT, SZ_D); uint8_t * jmp_off = dst+1; dst = jcc(dst, CC_NC, dst + 7); - dst = call(dst, (uint8_t *)handle_cycle_limit); + dst = call(dst, opts->handle_cycle_limit); *jmp_off = dst - (jmp_off+1); return dst; } @@ -2850,7 +2848,7 @@ uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_B); } if (inst->src.params.immed & 0x700) { - dst = call(dst, (uint8_t *)do_sync); + dst = call(dst, opts->do_sync); } } break; @@ -3166,7 +3164,7 @@ uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) if (inst->op == M68K_ORI_SR) { dst = xor_irdisp8(dst, inst->src.params.immed >> 8, CONTEXT, offsetof(m68k_context, status), SZ_B); if (inst->src.params.immed & 0x700) { - dst = call(dst, (uint8_t *)do_sync); + dst = call(dst, opts->do_sync); } } break; @@ -3225,7 +3223,7 @@ uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D); dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); } - dst = call(dst, (uint8_t *)do_sync); + dst = call(dst, opts->do_sync); } dst = cycles(dst, 12); } else { @@ -3414,7 +3412,7 @@ uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) if (inst->op == M68K_ORI_SR) { dst = or_irdisp8(dst, inst->src.params.immed >> 8, CONTEXT, offsetof(m68k_context, status), SZ_B); if (inst->src.params.immed & 0x700) { - dst = call(dst, (uint8_t *)do_sync); + dst = call(dst, opts->do_sync); } } break; @@ -3714,7 +3712,7 @@ uint8_t * translate_m68k(uint8_t * dst, m68kinst * inst, x86_68k_options * opts) dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); } uint8_t * loop_top = dst; - dst = call(dst, (uint8_t *)do_sync); + dst = call(dst, opts->do_sync); dst = cmp_rr(dst, LIMIT, CYCLES, SZ_D); uint8_t * normal_cycle_up = dst + 1; dst = jcc(dst, CC_A, dst+2); @@ -4116,7 +4114,7 @@ uint8_t * gen_mem_fun(x86_68k_options * opts, memmap_chunk * memmap, uint32_t nu { uint8_t * dst = opts->cur_code; uint8_t * start = dst; - dst = check_cycles(dst); + dst = check_cycles(dst, opts); dst = cycles(dst, BUS); dst = and_ir(dst, 0xFFFFFF, SCRATCH1, SZ_D); uint8_t *lb_jcc = NULL, *ub_jcc = NULL; @@ -4436,6 +4434,34 @@ void init_x86_68k_opts(x86_68k_options * opts, memmap_chunk * memmap, uint32_t n dst = call(dst, opts->load_context); dst = retn(dst); + opts->handle_cycle_limit = dst; + dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D); + uint8_t * skip_sync = dst+1; + dst = jcc(dst, CC_C, dst+2); + opts->do_sync = dst; + dst = push_r(dst, SCRATCH1); + dst = push_r(dst, SCRATCH2); + dst = call(dst, opts->save_context); + dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); + dst = xor_rr(dst, RSI, RSI, SZ_D); + dst = test_ir(dst, 8, RSP, SZ_D); + uint8_t *adjust_rsp = dst+1; + dst = jcc(dst, CC_NZ, dst+2); + dst = call(dst, (uint8_t *)sync_components); + uint8_t *no_adjust = dst+1; + dst = jmp(dst, dst+2); + *adjust_rsp = dst - (adjust_rsp + 1); + dst = sub_ir(dst, 8, RSP, SZ_Q); + dst = call(dst, (uint8_t *)sync_components); + dst = add_ir(dst, 8, RSP, SZ_Q); + *no_adjust = dst - (no_adjust+1); + dst = mov_rr(dst, RAX, CONTEXT, SZ_Q); + dst = call(dst, opts->load_context); + dst = pop_r(dst, SCRATCH2); + dst = pop_r(dst, SCRATCH1); + *skip_sync = dst - (skip_sync+1); + dst = retn(dst); + opts->cur_code = dst; opts->read_16 = gen_mem_fun(opts, memmap, num_chunks, READ_16); @@ -4484,16 +4510,16 @@ void init_x86_68k_opts(x86_68k_options * opts, memmap_chunk * memmap, uint32_t n uint8_t * do_int = dst+1; dst = jcc(dst, CC_NC, dst+2); dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, sync_cycle), CYCLES, SZ_D); - uint8_t * skip_sync = dst+1; + skip_sync = dst+1; dst = jcc(dst, CC_C, dst+2); dst = call(dst, opts->save_context); dst = mov_rr(dst, CONTEXT, RDI, SZ_Q); dst = mov_rr(dst, SCRATCH1, RSI, SZ_D); dst = test_ir(dst, 8, RSP, SZ_D); - uint8_t *adjust_rsp = dst+1; + adjust_rsp = dst+1; dst = jcc(dst, CC_NZ, dst+2); dst = call(dst, (uint8_t *)sync_components); - uint8_t *no_adjust = dst+1; + no_adjust = dst+1; dst = jmp(dst, dst+2); *adjust_rsp = dst - (adjust_rsp + 1); dst = sub_ir(dst, 8, RSP, SZ_Q); diff --git a/m68k_to_x86.h b/m68k_to_x86.h index 4b64c53..c3a50d7 100644 --- a/m68k_to_x86.h +++ b/m68k_to_x86.h @@ -36,7 +36,9 @@ typedef struct { uint8_t *read_32; uint8_t *write_32_lowfirst; uint8_t *write_32_highfirst; + uint8_t *handle_cycle_limit; uint8_t *handle_cycle_limit_int; + uint8_t *do_sync; uint8_t *trap; uint8_t *save_context; uint8_t *load_context; @@ -1,30 +1,4 @@ - .global handle_cycle_limit - .global do_sync -handle_cycle_limit: - cmp 84(%rsi), %eax - jb skip_sync -do_sync: - push %rcx - push %rdi - call m68k_save_context - mov %rsi, %rdi - xor %esi, %esi - test $8, %esp - jnz adjust_rsp - call sync_components - jmp done_adjust -adjust_rsp: - sub $8, %rsp - call sync_components - add $8, %rsp -done_adjust: - mov %rax, %rsi - call m68k_load_context - pop %rdi - pop %rcx -skip_sync: - ret invalid_msg: .asciz "Invalid instruction at %X\n" @@ -149,38 +123,3 @@ set_ccr: mov %cl, (%rsi) ret - .global m68k_save_context -m68k_save_context: - mov %bl, 1(%rsi) /* N Flag */ - mov %dl, 2(%rsi) /* Z flag */ - mov %bh, 3(%rsi) /* V flag */ - mov %dh, 4(%rsi) /* C flag */ - mov %r10d, 8(%rsi) /* d0 */ - mov %r11d, 12(%rsi) /* d1 */ - mov %r12d, 16(%rsi) /* d2 */ - mov %r8d, 20(%rsi) /* d3 */ - mov %r13d, 40(%rsi) /* a0 */ - mov %r14d, 44(%rsi) /* a1 */ - mov %r9d, 48(%rsi) /* a2 */ - mov %r15d, 68(%rsi) /* a7 */ - mov %eax, 80(%rsi) /* current cycle count */ - ret - - .global m68k_load_context -m68k_load_context: - mov 1(%rsi), %bl /* N Flag */ - mov 2(%rsi), %dl /* Z flag */ - mov 3(%rsi), %bh /* V flag */ - mov 4(%rsi), %dh /* C flag */ - mov 8(%rsi), %r10d /* d0 */ - mov 12(%rsi), %r11d /* d1 */ - mov 16(%rsi), %r12d /* d2 */ - mov 20(%rsi), %r8d /* d3 */ - mov 40(%rsi), %r13d /* a0 */ - mov 44(%rsi), %r14d /* a1 */ - mov 48(%rsi), %r9d /* a2 */ - mov 68(%rsi), %r15d /* a7 */ - mov 76(%rsi), %ebp /* target cycle count */ - mov 80(%rsi), %eax /* current cycle count */ - ret - |