Mercurial > repos > blastem
diff m68k_core_x86.c @ 574:1594525e2157
More 68K core refactoring to both reduce the amount of code and better split the host-cpu specific parts from the generic parts
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 03 Mar 2014 22:17:20 -0800 |
parents | c90fc522e7e3 |
children | a6f2db4df70d |
line wrap: on
line diff
--- a/m68k_core_x86.c Mon Mar 03 22:16:41 2014 -0800 +++ b/m68k_core_x86.c Mon Mar 03 22:17:20 2014 -0800 @@ -14,9 +14,6 @@ #include <stdlib.h> #include <string.h> -#define BUS 4 -#define PREDEC_PENALTY 2 - #define CYCLES RAX #define LIMIT RBP #define CONTEXT RSI @@ -36,15 +33,6 @@ FLAG_C }; -char disasm_buf[1024]; - -m68k_context * sync_components(m68k_context * context, uint32_t address); - -void m68k_invalid(); -void bcd_add(); -void bcd_sub(); - - void set_flag(m68k_options * opts, uint8_t val, uint8_t flag) { if (opts->flag_regs[flag] >= 0) { @@ -181,6 +169,145 @@ } } +void areg_to_native(m68k_options *opts, uint8_t reg, uint8_t native_reg) +{ + if (opts->aregs[reg] >= 0) { + mov_rr(&opts->gen.code, opts->aregs[reg], native_reg, SZ_D); + } else { + mov_rdispr(&opts->gen.code, opts->gen.context_reg, areg_offset(reg), native_reg, SZ_D); + } +} + +void dreg_to_native(m68k_options *opts, uint8_t reg, uint8_t native_reg) +{ + if (opts->dregs[reg] >= 0) { + mov_rr(&opts->gen.code, opts->dregs[reg], native_reg, SZ_D); + } else { + mov_rdispr(&opts->gen.code, opts->gen.context_reg, dreg_offset(reg), native_reg, SZ_D); + } +} + +void areg_to_native_sx(m68k_options *opts, uint8_t reg, uint8_t native_reg) +{ + if (opts->aregs[reg] >= 0) { + movsx_rr(&opts->gen.code, opts->aregs[reg], native_reg, SZ_W, SZ_D); + } else { + movsx_rdispr(&opts->gen.code, opts->gen.context_reg, areg_offset(reg), native_reg, SZ_W, SZ_D); + } +} + +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 { + 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 { + 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 { + 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 { + 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_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 { + 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 { + 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 { + 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 { + 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 { + add_dreg_native(opts, sec_reg, native_reg); + } + } 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 { + 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); +} + void translate_m68k_op(m68kinst * inst, x86_ea * ea, m68k_options * opts, uint8_t dst) { code_info *code = &opts->gen.code; @@ -230,18 +357,10 @@ if (!dst) { cycles(&opts->gen, PREDEC_PENALTY); } - if (opts->aregs[op->params.regs.pri] >= 0) { - sub_ir(code, dec_amount, opts->aregs[op->params.regs.pri], SZ_D); - } else { - sub_irdisp(code, dec_amount, opts->gen.context_reg, reg_offset(op), SZ_D); - } + subi_areg(opts, dec_amount, op->params.regs.pri); case MODE_AREG_INDIRECT: case MODE_AREG_POSTINC: - if (opts->aregs[op->params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[op->params.regs.pri], opts->gen.scratch1, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(op), opts->gen.scratch1, SZ_D); - } + areg_to_native(opts, op->params.regs.pri, opts->gen.scratch1); m68k_read_size(opts, inst->extra.size); if (dst) { @@ -250,33 +369,20 @@ pop_r(code, opts->gen.scratch2); } else { //save reg value in opts->gen.scratch2 so we can use it to save the result in memory later - if (opts->aregs[op->params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[op->params.regs.pri], opts->gen.scratch2, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(op), opts->gen.scratch2, SZ_D); - } + areg_to_native(opts, op->params.regs.pri, opts->gen.scratch2); } } if (op->addr_mode == MODE_AREG_POSTINC) { inc_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (op->params.regs.pri == 7 ? 2 : 1)); - if (opts->aregs[op->params.regs.pri] >= 0) { - add_ir(code, inc_amount, opts->aregs[op->params.regs.pri], SZ_D); - } else { - add_irdisp(code, inc_amount, opts->gen.context_reg, reg_offset(op), SZ_D); - } + addi_areg(opts, inc_amount, op->params.regs.pri); } ea->mode = MODE_REG_DIRECT; ea->base = (!dst && inst->dst.addr_mode == MODE_AREG_PREDEC && inst->op != M68K_MOVE) ? opts->gen.scratch2 : opts->gen.scratch1; break; case MODE_AREG_DISPLACE: cycles(&opts->gen, BUS); - if (opts->aregs[op->params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[op->params.regs.pri], opts->gen.scratch1, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(op), opts->gen.scratch1, SZ_D); - } - add_ir(code, op->params.regs.displacement, opts->gen.scratch1, SZ_D); + calc_areg_displace(opts, op, opts->gen.scratch1); if (dst) { push_r(code, opts->gen.scratch1); } @@ -290,45 +396,7 @@ break; case MODE_AREG_INDEX_DISP8: cycles(&opts->gen, 6); - if (opts->aregs[op->params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[op->params.regs.pri], opts->gen.scratch1, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(op), opts->gen.scratch1, SZ_D); - } - sec_reg = (op->params.regs.sec >> 1) & 0x7; - if (op->params.regs.sec & 1) { - if (op->params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D); - } - } - } else { - if (op->params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D); - } - } - add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D); - } - if (op->params.regs.displacement) { - add_ir(code, op->params.regs.displacement, opts->gen.scratch1, SZ_D); - } + calc_areg_index_disp8(opts, op, opts->gen.scratch1); if (dst) { push_r(code, opts->gen.scratch1); } @@ -357,40 +425,7 @@ case MODE_PC_INDEX_DISP8: cycles(&opts->gen, 6); mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D); - sec_reg = (op->params.regs.sec >> 1) & 0x7; - if (op->params.regs.sec & 1) { - if (op->params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D); - } - } - } else { - if (op->params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D); - } - } - add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D); - } - if (op->params.regs.displacement) { - add_ir(code, op->params.regs.displacement, opts->gen.scratch1, SZ_D); - } + calc_index_disp8(opts, op, opts->gen.scratch1); if (dst) { push_r(code, opts->gen.scratch1); } @@ -450,11 +485,7 @@ code_info *code = &opts->gen.code; if (inst->dst.addr_mode != MODE_REG && inst->dst.addr_mode != MODE_AREG) { if (inst->dst.addr_mode == MODE_AREG_PREDEC && inst->src.addr_mode == MODE_AREG_PREDEC && inst->op != M68K_MOVE) { - if (opts->aregs[inst->dst.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D); - } + areg_to_native(opts, inst->dst.params.regs.pri, opts->gen.scratch2); } switch (inst->extra.size) { @@ -531,18 +562,10 @@ 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)); - if (opts->aregs[inst->dst.params.regs.pri] >= 0) { - sub_ir(code, dec_amount, opts->aregs[inst->dst.params.regs.pri], SZ_D); - } else { - sub_irdisp(code, dec_amount, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D); - } + subi_areg(opts, dec_amount, inst->dst.params.regs.pri); case MODE_AREG_INDIRECT: case MODE_AREG_POSTINC: - if (opts->aregs[inst->dst.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D); - } + 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); @@ -561,21 +584,12 @@ 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)); - if (opts->aregs[inst->dst.params.regs.pri] >= 0) { - add_ir(code, inc_amount, opts->aregs[inst->dst.params.regs.pri], SZ_D); - } else { - add_irdisp(code, inc_amount, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D); - } + addi_areg(opts, inc_amount, inst->dst.params.regs.pri); } break; case MODE_AREG_DISPLACE: cycles(&opts->gen, BUS); - if (opts->aregs[inst->dst.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D); - } - add_ir(code, inst->dst.params.regs.displacement, opts->gen.scratch2, SZ_D); + calc_areg_displace(opts, &inst->dst, 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); @@ -594,50 +608,13 @@ break; case MODE_AREG_INDEX_DISP8: cycles(&opts->gen, 6);//TODO: Check to make sure this is correct - if (opts->aregs[inst->dst.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D); + //calc_areg_index_disp8 will clober scratch1 when a 16-bit index is used + if (src.base == opts->gen.scratch1 && !(inst->dst.params.regs.sec & 1)) { + push_r(code, opts->gen.scratch1); } - sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7; - if (inst->dst.params.regs.sec & 1) { - if (inst->dst.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - add_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - add_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D); - } - } - } else { - if (src.base == opts->gen.scratch1) { - push_r(code, opts->gen.scratch1); - } - if (inst->dst.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D); - } - } - add_rr(code, opts->gen.scratch1, opts->gen.scratch2, SZ_D); - if (src.base == opts->gen.scratch1) { - pop_r(code, opts->gen.scratch1); - } - } - if (inst->dst.params.regs.displacement) { - add_ir(code, inst->dst.params.regs.displacement, opts->gen.scratch2, SZ_D); + calc_areg_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); } if (src.mode == MODE_REG_DIRECT) { if (src.base != opts->gen.scratch1) { @@ -677,45 +654,12 @@ case MODE_PC_INDEX_DISP8: cycles(&opts->gen, 6);//TODO: Check to make sure this is correct mov_ir(code, inst->address, opts->gen.scratch2, SZ_D); - sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7; - if (inst->dst.params.regs.sec & 1) { - if (inst->dst.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - add_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - add_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D); - } - } - } else { - if (src.base == opts->gen.scratch1) { - push_r(code, opts->gen.scratch1); - } - if (inst->dst.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D); - } - } - add_rr(code, opts->gen.scratch1, opts->gen.scratch2, SZ_D); - if (src.base == opts->gen.scratch1) { - pop_r(code, opts->gen.scratch1); - } + if (src.base == opts->gen.scratch1 && !(inst->dst.params.regs.sec & 1)) { + push_r(code, opts->gen.scratch1); } - if (inst->dst.params.regs.displacement) { - add_ir(code, inst->dst.params.regs.displacement, opts->gen.scratch2, SZ_D); + 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); } if (src.mode == MODE_REG_DIRECT) { if (src.base != opts->gen.scratch1) { @@ -780,63 +724,15 @@ { case MODE_AREG_INDIRECT: case MODE_AREG_PREDEC: - if (opts->aregs[inst->dst.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D); - } + areg_to_native(opts, inst->dst.params.regs.pri, opts->gen.scratch2); break; case MODE_AREG_DISPLACE: early_cycles += BUS; - reg = opts->gen.scratch2; - if (opts->aregs[inst->dst.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D); - } - add_ir(code, inst->dst.params.regs.displacement, opts->gen.scratch2, SZ_D); + calc_areg_displace(opts, &inst->dst, opts->gen.scratch2); break; case MODE_AREG_INDEX_DISP8: early_cycles += 6; - if (opts->aregs[inst->dst.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D); - } - sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7; - if (inst->dst.params.regs.sec & 1) { - if (inst->dst.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - add_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - add_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D); - } - } - } else { - if (inst->dst.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D); - } - } - add_rr(code, opts->gen.scratch1, opts->gen.scratch2, SZ_D); - } - if (inst->dst.params.regs.displacement) { - add_ir(code, inst->dst.params.regs.displacement, opts->gen.scratch2, SZ_D); - } + calc_areg_index_disp8(opts, &inst->dst, opts->gen.scratch2); break; case MODE_PC_DISPLACE: early_cycles += BUS; @@ -845,41 +741,7 @@ case MODE_PC_INDEX_DISP8: early_cycles += 6; mov_ir(code, inst->address+2, opts->gen.scratch2, SZ_D); - sec_reg = (inst->dst.params.regs.sec >> 1) & 0x7; - if (inst->dst.params.regs.sec & 1) { - if (inst->dst.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - add_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - add_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D); - } - } - } else { - if (inst->dst.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D); - } - } - add_rr(code, opts->gen.scratch1, opts->gen.scratch2, SZ_D); - } - if (inst->dst.params.regs.displacement) { - add_ir(code, inst->dst.params.regs.displacement, opts->gen.scratch2, SZ_D); - } - break; + calc_index_disp8(opts, &inst->dst, opts->gen.scratch2); case MODE_ABSOLUTE: early_cycles += 4; case MODE_ABSOLUTE_SHORT: @@ -906,17 +768,9 @@ } push_r(code, opts->gen.scratch2); if (reg > 7) { - if (opts->aregs[reg-8] >= 0) { - mov_rr(code, opts->aregs[reg-8], opts->gen.scratch1, inst->extra.size); - } else { - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * (reg-8), opts->gen.scratch1, inst->extra.size); - } + areg_to_native(opts, reg-8, opts->gen.scratch1); } else { - if (opts->dregs[reg] >= 0) { - mov_rr(code, opts->dregs[reg], opts->gen.scratch1, inst->extra.size); - } else { - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t) * (reg), opts->gen.scratch1, inst->extra.size); - } + dreg_to_native(opts, reg, opts->gen.scratch1); } if (inst->extra.size == OPSIZE_LONG) { call(code, opts->write_32_lowfirst); @@ -930,11 +784,7 @@ } } if (inst->dst.addr_mode == MODE_AREG_PREDEC) { - if (opts->aregs[inst->dst.params.regs.pri] >= 0) { - mov_rr(code, opts->gen.scratch2, opts->aregs[inst->dst.params.regs.pri], SZ_D); - } else { - mov_rrdisp(code, opts->gen.scratch2, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D); - } + native_to_areg(opts, opts->gen.scratch2, inst->dst.params.regs.pri); } } else { //mem to reg @@ -943,63 +793,16 @@ { case MODE_AREG_INDIRECT: case MODE_AREG_POSTINC: - if (opts->aregs[inst->src.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D); - } + areg_to_native(opts, inst->src.params.regs.pri, opts->gen.scratch1); break; case MODE_AREG_DISPLACE: early_cycles += BUS; reg = opts->gen.scratch2; - if (opts->aregs[inst->src.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D); - } - add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D); + calc_areg_displace(opts, &inst->src, opts->gen.scratch1); break; case MODE_AREG_INDEX_DISP8: early_cycles += 6; - if (opts->aregs[inst->src.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D); - } - sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; - if (inst->src.params.regs.sec & 1) { - if (inst->src.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D); - } - } - } else { - if (inst->src.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D); - } - } - add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D); - } - if (inst->src.params.regs.displacement) { - add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D); - } + calc_areg_index_disp8(opts, &inst->src, opts->gen.scratch1); break; case MODE_PC_DISPLACE: early_cycles += BUS; @@ -1008,40 +811,7 @@ case MODE_PC_INDEX_DISP8: early_cycles += 6; mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D); - sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; - if (inst->src.params.regs.sec & 1) { - if (inst->src.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D); - } - } - } else { - if (inst->src.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D); - } - } - add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D); - } - if (inst->src.params.regs.displacement) { - add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D); - } + calc_index_disp8(opts, &inst->src, opts->gen.scratch1); break; case MODE_ABSOLUTE: early_cycles += 4; @@ -1067,28 +837,16 @@ movsx_rr(code, opts->gen.scratch1, opts->gen.scratch1, SZ_W, SZ_D); } if (reg > 7) { - if (opts->aregs[reg-8] >= 0) { - mov_rr(code, opts->gen.scratch1, opts->aregs[reg-8], SZ_D); - } else { - mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * (reg-8), SZ_D); - } + native_to_areg(opts, opts->gen.scratch1, reg-8); } else { - if (opts->dregs[reg] >= 0) { - mov_rr(code, opts->gen.scratch1, opts->dregs[reg], SZ_D); - } else { - mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t) * (reg), SZ_D); - } + native_to_dreg(opts, opts->gen.scratch1, reg); } pop_r(code, opts->gen.scratch1); add_ir(code, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch1, SZ_D); } } if (inst->src.addr_mode == MODE_AREG_POSTINC) { - if (opts->aregs[inst->src.params.regs.pri] >= 0) { - mov_rr(code, opts->gen.scratch1, opts->aregs[inst->src.params.regs.pri], SZ_D); - } else { - mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, reg_offset(&(inst->src)), SZ_D); - } + native_to_areg(opts, opts->gen.scratch1, inst->src.params.regs.pri); } } //prefetch @@ -1141,270 +899,6 @@ //M68K EXT only operates on registers so no need for a call to save result here } -void translate_m68k_lea(m68k_options * opts, m68kinst * inst) -{ - code_info *code = &opts->gen.code; - int8_t dst_reg = native_reg(&(inst->dst), opts), sec_reg; - switch(inst->src.addr_mode) - { - case MODE_AREG_INDIRECT: - cycles(&opts->gen, BUS); - if (opts->aregs[inst->src.params.regs.pri] >= 0) { - if (dst_reg >= 0) { - mov_rr(code, opts->aregs[inst->src.params.regs.pri], dst_reg, SZ_D); - } else { - mov_rrdisp(code, opts->aregs[inst->src.params.regs.pri], opts->gen.context_reg, offsetof(m68k_context, aregs) + 4 * inst->dst.params.regs.pri, SZ_D); - } - } else { - if (dst_reg >= 0) { - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, dst_reg, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, opts->gen.scratch1, SZ_D); - mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, aregs) + 4 * inst->dst.params.regs.pri, SZ_D); - } - } - break; - case MODE_AREG_DISPLACE: - cycles(&opts->gen, 8); - if (dst_reg >= 0) { - if (inst->src.params.regs.pri != inst->dst.params.regs.pri) { - if (opts->aregs[inst->src.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->src.params.regs.pri], dst_reg, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), dst_reg, SZ_D); - } - } - add_ir(code, inst->src.params.regs.displacement, dst_reg, SZ_D); - } else { - if (inst->src.params.regs.pri != inst->dst.params.regs.pri) { - if (opts->aregs[inst->src.params.regs.pri] >= 0) { - mov_rrdisp(code, opts->aregs[inst->src.params.regs.pri], opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D); - mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D); - } - } - add_irdisp(code, inst->src.params.regs.displacement, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D); - } - break; - case MODE_AREG_INDEX_DISP8: - cycles(&opts->gen, 12); - if (opts->aregs[inst->src.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch2, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch2, SZ_D); - } - sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; - if (inst->src.params.regs.sec & 1) { - if (inst->src.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - add_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - add_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_D); - } - } - } else { - if (inst->src.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_W, SZ_D); - } - } - add_rr(code, opts->gen.scratch1, opts->gen.scratch2, SZ_D); - } - if (inst->src.params.regs.displacement) { - add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch2, SZ_D); - } - if (dst_reg >= 0) { - mov_rr(code, opts->gen.scratch2, dst_reg, SZ_D); - } else { - mov_rrdisp(code, opts->gen.scratch2, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D); - } - break; - case MODE_PC_DISPLACE: - cycles(&opts->gen, 8); - if (dst_reg >= 0) { - mov_ir(code, inst->src.params.regs.displacement + inst->address+2, dst_reg, SZ_D); - } else { - mov_irdisp(code, inst->src.params.regs.displacement + inst->address+2, opts->gen.context_reg, offsetof(m68k_context, aregs) + 4 * inst->dst.params.regs.pri, SZ_D); - } - break; - case MODE_PC_INDEX_DISP8: - cycles(&opts->gen, BUS*3); - mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D); - sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; - if (inst->src.params.regs.sec & 1) { - if (inst->src.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D); - } - } - } else { - if (inst->src.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D); - } - } - add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D); - } - if (inst->src.params.regs.displacement) { - add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D); - } - if (dst_reg >= 0) { - mov_rr(code, opts->gen.scratch1, dst_reg, SZ_D); - } else { - mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D); - } - break; - case MODE_ABSOLUTE: - case MODE_ABSOLUTE_SHORT: - cycles(&opts->gen, (inst->src.addr_mode == MODE_ABSOLUTE) ? BUS * 3 : BUS * 2); - if (dst_reg >= 0) { - mov_ir(code, inst->src.params.immed, dst_reg, SZ_D); - } else { - mov_irdisp(code, inst->src.params.immed, opts->gen.context_reg, reg_offset(&(inst->dst)), SZ_D); - } - break; - default: - m68k_disasm(inst, disasm_buf); - printf("%X: %s\naddress mode %d not implemented (lea src)\n", inst->address, disasm_buf, inst->src.addr_mode); - exit(1); - } -} - -void translate_m68k_pea(m68k_options * opts, m68kinst * inst) -{ - code_info *code = &opts->gen.code; - uint8_t sec_reg; - switch(inst->src.addr_mode) - { - case MODE_AREG_INDIRECT: - cycles(&opts->gen, BUS); - if (opts->aregs[inst->src.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, opts->gen.scratch1, SZ_D); - } - break; - case MODE_AREG_DISPLACE: - cycles(&opts->gen, 8); - if (opts->aregs[inst->src.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D); - } - add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D); - break; - case MODE_AREG_INDEX_DISP8: - cycles(&opts->gen, 6);//TODO: Check to make sure this is correct - if (opts->aregs[inst->src.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D); - } - sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; - if (inst->src.params.regs.sec & 1) { - if (inst->src.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D); - } - } - } else { - if (inst->src.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D); - } - } - add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D); - } - if (inst->src.params.regs.displacement) { - add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D); - } - break; - case MODE_PC_DISPLACE: - cycles(&opts->gen, 8); - mov_ir(code, inst->src.params.regs.displacement + inst->address+2, opts->gen.scratch1, SZ_D); - break; - case MODE_ABSOLUTE: - case MODE_ABSOLUTE_SHORT: - cycles(&opts->gen, (inst->src.addr_mode == MODE_ABSOLUTE) ? BUS * 3 : BUS * 2); - mov_ir(code, inst->src.params.immed, opts->gen.scratch1, SZ_D); - break; - default: - m68k_disasm(inst, disasm_buf); - printf("%X: %s\naddress mode %d not implemented (lea src)\n", inst->address, disasm_buf, inst->src.addr_mode); - exit(1); - } - sub_ir(code, 4, opts->aregs[7], SZ_D); - mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D); - call(code, opts->write_32_lowfirst); -} - -void translate_m68k_bsr(m68k_options * opts, m68kinst * inst) -{ - code_info *code = &opts->gen.code; - int32_t disp = inst->src.params.immed; - uint32_t after = inst->address + (inst->variant == VAR_BYTE ? 2 : 4); - //TODO: Add cycles in the right place relative to pushing the return address on the stack - cycles(&opts->gen, 10); - mov_ir(code, after, opts->gen.scratch1, SZ_D); - sub_ir(code, 4, opts->aregs[7], SZ_D); - mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D); - call(code, opts->write_32_highfirst); - code_ptr dest_addr = get_native_address(opts->gen.native_code_map, (inst->address+2) + disp); - if (!dest_addr) { - opts->gen.deferred = defer_address(opts->gen.deferred, (inst->address+2) + disp, code->cur + 1); - //dummy address to be replaced later - dest_addr = code->cur + 256; - } - jmp(code, dest_addr); -} - uint8_t m68k_eval_cond(m68k_options * opts, uint8_t cc) { uint8_t cond = CC_NZ; @@ -1458,15 +952,10 @@ cycles(&opts->gen, 10);//TODO: Adjust this for branch not taken case int32_t disp = inst->src.params.immed; uint32_t after = inst->address + 2; - code_ptr dest_addr = get_native_address(opts->gen.native_code_map, after + disp); if (inst->extra.cond == COND_TRUE) { - if (!dest_addr) { - opts->gen.deferred = defer_address(opts->gen.deferred, after + disp, code->cur + 1); - //dummy address to be replaced later, make sure it generates a 4-byte displacement - dest_addr = code->cur + 256; - } - jmp(code, dest_addr); + jump_m68k_abs(opts, after + disp); } else { + code_ptr dest_addr = get_native_address(opts->gen.native_code_map, 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); @@ -1520,214 +1009,6 @@ m68k_save_result(inst, opts); } -void translate_m68k_jmp_jsr(m68k_options * opts, m68kinst * inst) -{ - uint8_t is_jsr = inst->op == M68K_JSR; - code_info *code = &opts->gen.code; - code_ptr dest_addr; - uint8_t sec_reg; - uint32_t after; - uint32_t m68k_addr; - switch(inst->src.addr_mode) - { - case MODE_AREG_INDIRECT: - cycles(&opts->gen, BUS*2); - if (is_jsr) { - mov_ir(code, inst->address + 2, opts->gen.scratch1, SZ_D); - sub_ir(code, 4, opts->aregs[7], SZ_D); - mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D); - call(code, opts->write_32_highfirst); - } - if (opts->aregs[inst->src.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, opts->gen.scratch1, SZ_D); - } - call(code, opts->native_addr); - jmp_r(code, opts->gen.scratch1); - break; - case MODE_AREG_DISPLACE: - cycles(&opts->gen, BUS*2); - if (is_jsr) { - mov_ir(code, inst->address + 4, opts->gen.scratch1, SZ_D); - sub_ir(code, 4, opts->aregs[7], SZ_D); - mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D); - call(code, opts->write_32_highfirst); - } - if (opts->aregs[inst->src.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + 4 * inst->src.params.regs.pri, opts->gen.scratch1, SZ_D); - } - add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D); - call(code, opts->native_addr); - jmp_r(code, opts->gen.scratch1); - break; - case MODE_AREG_INDEX_DISP8: - cycles(&opts->gen, BUS*3);//TODO: CHeck that this is correct - if (is_jsr) { - mov_ir(code, inst->address + 4, opts->gen.scratch1, SZ_D); - sub_ir(code, 4, opts->aregs[7], SZ_D); - mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D); - call(code, opts->write_32_highfirst); - } - if (opts->aregs[inst->src.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D); - } - sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; - if (inst->src.params.regs.sec & 1) { - //32-bit index register - if (inst->src.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D); - } - } - } else { - //16-bit index register - if (inst->src.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D); - } - } - add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D); - } - if (inst->src.params.regs.displacement) { - add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D); - } - call(code, opts->native_addr); - jmp_r(code, opts->gen.scratch1); - break; - case MODE_PC_DISPLACE: - //TODO: Add cycles in the right place relative to pushing the return address on the stack - cycles(&opts->gen, 10); - if (is_jsr) { - mov_ir(code, inst->address + 4, opts->gen.scratch1, SZ_D); - sub_ir(code, 4, opts->aregs[7], SZ_D); - mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D); - call(code, opts->write_32_highfirst); - } - m68k_addr = inst->src.params.regs.displacement + inst->address + 2; - if ((m68k_addr & 0xFFFFFF) < 0x400000) { - dest_addr = get_native_address(opts->gen.native_code_map, m68k_addr); - if (!dest_addr) { - opts->gen.deferred = defer_address(opts->gen.deferred, m68k_addr, code->cur + 1); - //dummy address to be replaced later, make sure it generates a 4-byte displacement - dest_addr = code->cur + 256; - } - jmp(code, dest_addr); - } else { - mov_ir(code, m68k_addr, opts->gen.scratch1, SZ_D); - call(code, opts->native_addr); - jmp_r(code, opts->gen.scratch1); - } - break; - case MODE_PC_INDEX_DISP8: - cycles(&opts->gen, BUS*3);//TODO: CHeck that this is correct - if (is_jsr) { - mov_ir(code, inst->address + 4, opts->gen.scratch1, SZ_D); - sub_ir(code, 4, opts->aregs[7], SZ_D); - mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D); - call(code, opts->write_32_highfirst); - } - mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D); - sec_reg = (inst->src.params.regs.sec >> 1) & 0x7; - if (inst->src.params.regs.sec & 1) { - if (inst->src.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - add_rr(code, opts->aregs[sec_reg], opts->gen.scratch1, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - add_rr(code, opts->dregs[sec_reg], opts->gen.scratch1, SZ_D); - } else { - add_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch1, SZ_D); - } - } - } else { - if (inst->src.params.regs.sec & 0x10) { - if (opts->aregs[sec_reg] >= 0) { - movsx_rr(code, opts->aregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D); - } - } else { - if (opts->dregs[sec_reg] >= 0) { - movsx_rr(code, opts->dregs[sec_reg], opts->gen.scratch2, SZ_W, SZ_D); - } else { - movsx_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, dregs) + sizeof(uint32_t)*sec_reg, opts->gen.scratch2, SZ_W, SZ_D); - } - } - add_rr(code, opts->gen.scratch2, opts->gen.scratch1, SZ_D); - } - if (inst->src.params.regs.displacement) { - add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D); - } - call(code, opts->native_addr); - jmp_r(code, opts->gen.scratch1); - break; - case MODE_ABSOLUTE: - case MODE_ABSOLUTE_SHORT: - //TODO: Add cycles in the right place relative to pushing the return address on the stack - cycles(&opts->gen, inst->src.addr_mode == MODE_ABSOLUTE ? 12 : 10); - if (is_jsr) { - mov_ir(code, inst->address + (inst->src.addr_mode == MODE_ABSOLUTE ? 6 : 4), opts->gen.scratch1, SZ_D); - sub_ir(code, 4, opts->aregs[7], SZ_D); - mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D); - call(code, opts->write_32_highfirst); - } - m68k_addr = inst->src.params.immed; - if ((m68k_addr & 0xFFFFFF) < 0x400000) { - dest_addr = get_native_address(opts->gen.native_code_map, m68k_addr); - if (!dest_addr) { - opts->gen.deferred = defer_address(opts->gen.deferred, m68k_addr, code->cur + 1); - //dummy address to be replaced later, make sure it generates a 4-byte displacement - dest_addr = code->cur + 256; - } - jmp(code, dest_addr); - } else { - mov_ir(code, m68k_addr, opts->gen.scratch1, SZ_D); - call(code, opts->native_addr); - jmp_r(code, opts->gen.scratch1); - } - break; - default: - m68k_disasm(inst, disasm_buf); - printf("%s\naddress mode %d not yet supported (%s)\n", disasm_buf, inst->src.addr_mode, is_jsr ? "jsr" : "jmp"); - exit(1); - } -} - -void translate_m68k_rts(m68k_options * opts, m68kinst * inst) -{ - code_info *code = &opts->gen.code; - //TODO: Add cycles - mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D); - add_ir(code, 4, opts->aregs[7], SZ_D); - call(code, opts->read_32); - call(code, opts->native_addr); - jmp_r(code, opts->gen.scratch1); -} - void translate_m68k_dbcc(m68k_options * opts, m68kinst * inst) { code_info *code = &opts->gen.code; @@ -1752,13 +1033,7 @@ code_ptr loop_end_loc = code->cur + 1; jcc(code, CC_Z, code->cur + 2); uint32_t after = inst->address + 2; - code_ptr dest_addr = get_native_address(opts->gen.native_code_map, after + inst->src.params.immed); - if (!dest_addr) { - opts->gen.deferred = defer_address(opts->gen.deferred, after + inst->src.params.immed, code->cur + 1); - //dummy address to be replaced later, make sure it generates a 4-byte displacement - dest_addr = code->cur + 256; - } - jmp(code, dest_addr); + jump_m68k_abs(opts, after + inst->src.params.immed); *loop_end_loc = code->cur - (loop_end_loc+1); if (skip_loc) { cycles(&opts->gen, 2); @@ -1769,44 +1044,13 @@ } } -void translate_m68k_link(m68k_options * opts, m68kinst * inst) -{ - code_info *code = &opts->gen.code; - int8_t reg = native_reg(&(inst->src), opts); - //compensate for displacement word - cycles(&opts->gen, BUS); - sub_ir(code, 4, opts->aregs[7], SZ_D); - mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D); - if (reg >= 0) { - mov_rr(code, reg, opts->gen.scratch1, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D); - } - call(code, opts->write_32_highfirst); - if (reg >= 0) { - mov_rr(code, opts->aregs[7], reg, SZ_D); - } else { - mov_rrdisp(code, opts->aregs[7], opts->gen.context_reg, reg_offset(&(inst->src)), SZ_D); - } - add_ir(code, inst->dst.params.immed, opts->aregs[7], SZ_D); - //prefetch - cycles(&opts->gen, BUS); -} - void translate_m68k_movep(m68k_options * opts, m68kinst * inst) { code_info *code = &opts->gen.code; int8_t reg; cycles(&opts->gen, BUS*2); if (inst->src.addr_mode == MODE_REG) { - if (opts->aregs[inst->dst.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->dst.params.regs.pri], opts->gen.scratch2, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->dst)), opts->gen.scratch2, SZ_D); - } - if (inst->dst.params.regs.displacement) { - add_ir(code, inst->dst.params.regs.displacement, opts->gen.scratch2, SZ_D); - } + calc_areg_displace(opts, &inst->dst, opts->gen.scratch2); reg = native_reg(&(inst->src), opts); if (inst->extra.size == OPSIZE_LONG) { if (reg >= 0) { @@ -1848,14 +1092,7 @@ add_ir(code, 2, opts->gen.scratch2, SZ_D); call(code, opts->write_8); } else { - if (opts->aregs[inst->src.params.regs.pri] >= 0) { - mov_rr(code, opts->aregs[inst->src.params.regs.pri], opts->gen.scratch1, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, reg_offset(&(inst->src)), opts->gen.scratch1, SZ_D); - } - if (inst->src.params.regs.displacement) { - add_ir(code, inst->src.params.regs.displacement, opts->gen.scratch1, SZ_D); - } + calc_areg_displace(opts, &inst->src, opts->gen.scratch1); reg = native_reg(&(inst->dst), opts); if (inst->extra.size == OPSIZE_LONG) { if (reg >= 0) { @@ -2144,6 +1381,8 @@ return translate_m68k_movem(opts, inst); } else if(inst->op == M68K_LINK) { return translate_m68k_link(opts, inst); + } else if(inst->op == M68K_UNLK) { + return translate_m68k_unlk(opts, inst); } else if(inst->op == M68K_EXT) { return translate_m68k_ext(opts, inst); } else if(inst->op == M68K_SCC) { @@ -2723,19 +1962,16 @@ //TODO: Trap if not in supervisor mode //bt_irdisp(code, BIT_SUPERVISOR, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); if (inst->src.addr_mode == MODE_UNUSED) { - if (dst_op.mode == MODE_REG_DIRECT) { - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, dst_op.base, SZ_D); - } else { - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->gen.scratch1, SZ_D); + areg_to_native(opts, 8, dst_op.mode == MODE_REG_DIRECT ? dst_op.base : opts->gen.scratch1); + if (dst_op.mode != MODE_REG_DIRECT) { mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, SZ_D); } } else { - if (src_op.mode == MODE_REG_DIRECT) { - mov_rrdisp(code, src_op.base, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); - } else { + if (src_op.mode != MODE_REG_DIRECT) { mov_rdispr(code, src_op.base, src_op.disp, opts->gen.scratch1, SZ_D); - mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); + src_op.base = opts->gen.scratch1; } + native_to_areg(opts, src_op.base, 8); } break; //case M68K_MOVEP: @@ -3133,39 +2369,26 @@ case M68K_RTE: //TODO: Trap if not in system mode //Read saved SR - mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D); + areg_to_native(opts, 7, opts->gen.scratch1); call(code, opts->read_16); - add_ir(code, 2, opts->aregs[7], SZ_D); + addi_areg(opts, 2, 7); call(code, opts->set_sr); //Read saved PC - mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D); + areg_to_native(opts, 7, opts->gen.scratch1); call(code, opts->read_32); - add_ir(code, 4, opts->aregs[7], SZ_D); + 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); end_off = code->cur + 1; jcc(code, CC_C, code->cur + 2); - mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D); - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D); - mov_rrdisp(code, opts->gen.scratch2, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); + 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); break; case M68K_RTR: - //Read saved CCR - mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D); - call(code, opts->read_16); - add_ir(code, 2, opts->aregs[7], SZ_D); - call(code, opts->set_ccr); - //Read saved PC - mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D); - call(code, opts->read_32); - add_ir(code, 4, opts->aregs[7], SZ_D); - //Get native address and jump to it - call(code, opts->native_addr); - jmp_r(code, opts->gen.scratch1); + translate_m68k_rtr(opts, inst); break; case M68K_SBCD: { if (src_op.base != opts->gen.scratch2) { @@ -3216,9 +2439,7 @@ mov_irdisp(code, (src_op.disp >> 8), opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); if (!((inst->src.params.immed >> 8) & (1 << BIT_SUPERVISOR))) { //leave supervisor mode - mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D); - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->aregs[7], SZ_D); - mov_rrdisp(code, opts->gen.scratch1, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); + swap_ssp_usp(opts); } code_ptr loop_top = code->cur; call(code, opts->do_sync); @@ -3317,9 +2538,7 @@ break; //case M68K_TAS: case M68K_TRAP: - mov_ir(code, src_op.disp + VECTOR_TRAP_0, opts->gen.scratch2, SZ_D); - mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D); - jmp(code, opts->trap); + translate_m68k_trap(opts, inst); break; //case M68K_TRAPV: case M68K_TST: @@ -3334,22 +2553,6 @@ set_flag_cond(opts, CC_S, FLAG_N); set_flag(opts, 0, FLAG_V); break; - case M68K_UNLK: - cycles(&opts->gen, BUS); - if (dst_op.mode == MODE_REG_DIRECT) { - mov_rr(code, dst_op.base, opts->aregs[7], SZ_D); - } else { - mov_rdispr(code, dst_op.base, dst_op.disp, opts->aregs[7], SZ_D); - } - mov_rr(code, opts->aregs[7], opts->gen.scratch1, SZ_D); - call(code, opts->read_32); - if (dst_op.mode == MODE_REG_DIRECT) { - mov_rr(code, opts->gen.scratch1, dst_op.base, SZ_D); - } else { - mov_rrdisp(code, opts->gen.scratch1, dst_op.base, dst_op.disp, SZ_D); - } - add_ir(code, 4, opts->aregs[7], SZ_D); - break; default: m68k_disasm(inst, disasm_buf); printf("%X: %s\ninstruction %d not yet implemented\n", inst->address, disasm_buf, inst->op); @@ -4141,18 +3344,16 @@ 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); - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->gen.scratch2, SZ_D); - mov_rrdisp(code, opts->aregs[7], opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); - mov_rr(code, opts->gen.scratch2, opts->aregs[7], SZ_D); + swap_ssp_usp(opts); *already_supervisor = code->cur - (already_supervisor+1); //save PC - sub_ir(code, 4, opts->aregs[7], SZ_D); - mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D); + subi_areg(opts, 4, 7); + areg_to_native(opts, 7, opts->gen.scratch2); call(code, opts->write_32_lowfirst); //save status register - sub_ir(code, 2, opts->aregs[7], SZ_D); + subi_areg(opts, 2, 7); call(code, opts->get_sr); - mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D); + areg_to_native(opts, 7, opts->gen.scratch2); call(code, opts->write_16); //update status register and_irdisp(code, 0xF8, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); @@ -4177,18 +3378,16 @@ 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); - mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, opts->gen.scratch2, SZ_D); - mov_rrdisp(code, opts->aregs[7], opts->gen.context_reg, offsetof(m68k_context, aregs) + sizeof(uint32_t) * 8, SZ_D); - mov_rr(code, opts->gen.scratch2, opts->aregs[7], SZ_D); + swap_ssp_usp(opts); *already_supervisor = code->cur - (already_supervisor+1); //save PC - sub_ir(code, 4, opts->aregs[7], SZ_D); - mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D); + subi_areg(opts, 4, 7); + areg_to_native(opts, 7, opts->gen.scratch2); call(code, opts->write_32_lowfirst); //save status register - sub_ir(code, 2, opts->aregs[7], SZ_D); + subi_areg(opts, 2, 7); call(code, opts->get_sr); - mov_rr(code, opts->aregs[7], opts->gen.scratch2, SZ_D); + areg_to_native(opts, 7, opts->gen.scratch2); call(code, opts->write_16); //set supervisor bit or_irdisp(code, 0x20, opts->gen.context_reg, offsetof(m68k_context, status), SZ_B); @@ -4200,13 +3399,3 @@ cycles(&opts->gen, 18); jmp_r(code, opts->gen.scratch1); } - -void init_68k_context(m68k_context * context, native_map_slot * native_code_map, void * opts) -{ - memset(context, 0, sizeof(m68k_context)); - context->native_code_map = native_code_map; - context->options = opts; - context->int_cycle = 0xFFFFFFFF; - context->status = 0x27; -} -