# HG changeset patch # User Michael Pavone # Date 1392784330 28800 # Node ID 3090d016c9e9600166c6d43d3c4dd5fb7e904bb5 # Parent 90aca661542b79d1a15b4e89f74c9338913b6a03 Generate get_sr, set_sr and set_ccr at runtime so they can respect the flag_regs setting diff -r 90aca661542b -r 3090d016c9e9 m68k_to_x86.c --- a/m68k_to_x86.c Mon Feb 17 19:58:37 2014 -0800 +++ b/m68k_to_x86.c Tue Feb 18 20:32:10 2014 -0800 @@ -40,9 +40,6 @@ m68k_context * sync_components(m68k_context * context, uint32_t address); void m68k_invalid(); -void set_sr(); -void set_ccr(); -void get_sr(); void bcd_add(); void bcd_sub(); @@ -3379,7 +3376,7 @@ break; case M68K_MOVE_FROM_SR: //TODO: Trap if not in system mode - dst = call(dst, (uint8_t *)get_sr); + dst = call(dst, opts->get_sr); if (dst_op.mode == MODE_REG_DIRECT) { dst = mov_rr(dst, SCRATCH1, dst_op.base, SZ_W); } else { @@ -3415,7 +3412,7 @@ dst = mov_rdisp8r(dst, src_op.base, src_op.disp, SCRATCH1, SZ_W); } } - dst = call(dst, (uint8_t *)(inst->op == M68K_MOVE_SR ? set_sr : set_ccr)); + dst = call(dst, inst->op == M68K_MOVE_SR ? opts->set_sr : opts->set_ccr); dst = cycles(dst, 12); } @@ -3834,7 +3831,7 @@ dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); dst = call(dst, opts->read_16); dst = add_ir(dst, 2, opts->aregs[7], SZ_D); - dst = call(dst, (uint8_t *)set_sr); + dst = call(dst, opts->set_sr); //Read saved PC dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); dst = call(dst, opts->read_32); @@ -3856,7 +3853,7 @@ dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); dst = call(dst, opts->read_16); dst = add_ir(dst, 2, opts->aregs[7], SZ_D); - dst = call(dst, (uint8_t *)set_ccr); + dst = call(dst, opts->set_ccr); //Read saved PC dst = mov_rr(dst, opts->aregs[7], SCRATCH1, SZ_D); dst = call(dst, opts->read_32); @@ -4724,6 +4721,66 @@ dst = add_ir(dst, 2, SCRATCH2, SZ_D); dst = jmp(dst, opts->write_16); + opts->get_sr = dst; + dst = mov_rdisp8r(dst, CONTEXT, offsetof(m68k_context, status), SCRATCH1, SZ_B); + dst = shl_ir(dst, 8, SCRATCH1, SZ_W); + if (opts->flag_regs[FLAG_X] >= 0) { + dst = mov_rr(dst, opts->flag_regs[FLAG_X], SCRATCH1, SZ_B); + } else { + int8_t offset = offsetof(m68k_context, flags); + if (offset) { + dst = mov_rdisp8r(dst, CONTEXT, offset, SCRATCH1, SZ_B); + } else { + dst = mov_rindr(dst, CONTEXT, SCRATCH1, SZ_B); + } + } + for (int flag = FLAG_N; flag <= FLAG_C; flag++) + { + dst = shl_ir(dst, 1, SCRATCH1, SZ_B); + if (opts->flag_regs[flag] >= 0) { + dst = or_rr(dst, opts->flag_regs[flag], SCRATCH1, SZ_B); + } else { + dst = or_rdisp8r(dst, CONTEXT, offsetof(m68k_context, flags) + flag, SCRATCH1, SZ_B); + } + } + dst = retn(dst); + + opts->set_sr = dst; + for (int flag = FLAG_C; flag >= FLAG_X; flag--) + { + dst = rcr_ir(dst, 1, SCRATCH1, SZ_B); + if (opts->flag_regs[flag] >= 0) { + dst = setcc_r(dst, CC_C, opts->flag_regs[flag]); + } else { + int8_t offset = offsetof(m68k_context, flags) + flag; + if (offset) { + dst = setcc_rdisp8(dst, CC_C, CONTEXT, offset); + } else { + dst = setcc_rind(dst, CC_C, CONTEXT); + } + } + } + dst = shr_ir(dst, 8, SCRATCH1, SZ_W); + dst = mov_rrdisp8(dst, SCRATCH1, CONTEXT, offsetof(m68k_context, status), SZ_B); + dst = retn(dst); + + opts->set_ccr = dst; + for (int flag = FLAG_C; flag >= FLAG_X; flag--) + { + dst = rcr_ir(dst, 1, SCRATCH1, SZ_B); + if (opts->flag_regs[flag] >= 0) { + dst = setcc_r(dst, CC_C, opts->flag_regs[flag]); + } else { + int8_t offset = offsetof(m68k_context, flags) + flag; + if (offset) { + dst = setcc_rdisp8(dst, CC_C, CONTEXT, offset); + } else { + dst = setcc_rind(dst, CC_C, CONTEXT); + } + } + } + dst = retn(dst); + opts->handle_cycle_limit_int = dst; dst = cmp_rdisp8r(dst, CONTEXT, offsetof(m68k_context, int_cycle), CYCLES, SZ_D); uint8_t * do_int = dst+1; @@ -4766,7 +4823,7 @@ dst = call(dst, opts->write_32_lowfirst); //save status register dst = sub_ir(dst, 2, opts->aregs[7], SZ_D); - dst = call(dst, (uint8_t *)get_sr); + dst = call(dst, opts->get_sr); dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); dst = call(dst, opts->write_16); //update status register @@ -4802,7 +4859,7 @@ dst = call(dst, opts->write_32_lowfirst); //save status register dst = sub_ir(dst, 2, opts->aregs[7], SZ_D); - dst = call(dst, (uint8_t *)get_sr); + dst = call(dst, opts->get_sr); dst = mov_rr(dst, opts->aregs[7], SCRATCH2, SZ_D); dst = call(dst, opts->write_16); //set supervisor bit diff -r 90aca661542b -r 3090d016c9e9 m68k_to_x86.h --- a/m68k_to_x86.h Mon Feb 17 19:58:37 2014 -0800 +++ b/m68k_to_x86.h Tue Feb 18 20:32:10 2014 -0800 @@ -46,6 +46,9 @@ uint8_t *retrans_stub; uint8_t *native_addr; uint8_t *native_addr_and_sync; + uint8_t *get_sr; + uint8_t *set_sr; + uint8_t *set_ccr; } x86_68k_options; typedef struct { diff -r 90aca661542b -r 3090d016c9e9 runtime.S --- a/runtime.S Mon Feb 17 19:58:37 2014 -0800 +++ b/runtime.S Tue Feb 18 20:32:10 2014 -0800 @@ -70,56 +70,5 @@ mov %rdi, %rax ret - .global get_sr -get_sr: - mov 5(%rsi), %cl - shl $8, %cx - mov (%rsi), %cl - shl $1, %cl - or %bl, %cl - shl $1, %cl - or %dl, %cl - shl $1, %cl - or %bh, %cl - shl $1, %cl - or %dh, %cl - ret - .global set_sr -set_sr: - mov %cl, %dh - and $1, %dh - shr $1, %cl - mov %cl, %bh - and $1, %bh - shr $1, %cl - mov %cl, %dl - and $1, %dl - shr $1, %cl - mov %cl, %bl - and $1, %bl - shr $1, %cl - and $1, %cl - mov %cl, (%rsi) - shr $8, %cx - mov %cl, 5(%rsi) - ret - .global set_ccr -set_ccr: - mov %cl, %dh - and $1, %dh - shr $1, %cl - mov %cl, %bh - and $1, %bh - shr $1, %cl - mov %cl, %dl - and $1, %dl - shr $1, %cl - mov %cl, %bl - and $1, %bl - shr $1, %cl - and $1, %cl - mov %cl, (%rsi) - ret -