summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2014-03-08 00:15:09 -0800
committerMichael Pavone <pavone@retrodev.com>2014-03-08 00:15:09 -0800
commitf0a88e3789cfff8dabb5a13d4e17efdcc2ded309 (patch)
tree5b01c64f44f0cd534ce9a5fa9a90cec88502366d
parent80c3f6c80dfecb51045dc09c712938703e059c38 (diff)
Move translate_m68k_movem to m68k_core.c
-rw-r--r--m68k_core.c142
-rw-r--r--m68k_core_x86.c167
-rw-r--r--m68k_internal.h12
3 files changed, 172 insertions, 149 deletions
diff --git a/m68k_core.c b/m68k_core.c
index d7a78a0..d3cc208 100644
--- a/m68k_core.c
+++ b/m68k_core.c
@@ -349,6 +349,148 @@ void translate_m68k_move_usp(m68k_options *opts, m68kinst *inst)
}
}
+void translate_m68k_movem(m68k_options * opts, m68kinst * inst)
+{
+ code_info *code = &opts->gen.code;
+ int8_t bit,reg,sec_reg;
+ uint8_t early_cycles;
+ if(inst->src.addr_mode == MODE_REG) {
+ //reg to mem
+ early_cycles = 8;
+ int8_t dir;
+ switch (inst->dst.addr_mode)
+ {
+ case MODE_AREG_INDIRECT:
+ case MODE_AREG_PREDEC:
+ areg_to_native(opts, inst->dst.params.regs.pri, opts->gen.scratch2);
+ break;
+ case MODE_AREG_DISPLACE:
+ early_cycles += BUS;
+ calc_areg_displace(opts, &inst->dst, opts->gen.scratch2);
+ break;
+ case MODE_AREG_INDEX_DISP8:
+ early_cycles += 6;
+ calc_areg_index_disp8(opts, &inst->dst, opts->gen.scratch2);
+ break;
+ case MODE_PC_DISPLACE:
+ early_cycles += BUS;
+ ldi_native(opts, inst->dst.params.regs.displacement + inst->address+2, opts->gen.scratch2);
+ break;
+ case MODE_PC_INDEX_DISP8:
+ early_cycles += 6;
+ ldi_native(opts, inst->address+2, opts->gen.scratch2);
+ calc_index_disp8(opts, &inst->dst, opts->gen.scratch2);
+ case MODE_ABSOLUTE:
+ early_cycles += 4;
+ case MODE_ABSOLUTE_SHORT:
+ early_cycles += 4;
+ ldi_native(opts, inst->dst.params.immed, opts->gen.scratch2);
+ break;
+ default:
+ m68k_disasm(inst, disasm_buf);
+ printf("%X: %s\naddress mode %d not implemented (movem dst)\n", inst->address, disasm_buf, inst->dst.addr_mode);
+ exit(1);
+ }
+ if (inst->dst.addr_mode == MODE_AREG_PREDEC) {
+ reg = 15;
+ dir = -1;
+ } else {
+ reg = 0;
+ dir = 1;
+ }
+ cycles(&opts->gen, early_cycles);
+ for(bit=0; reg < 16 && reg >= 0; reg += dir, bit++) {
+ if (inst->src.params.immed & (1 << bit)) {
+ if (inst->dst.addr_mode == MODE_AREG_PREDEC) {
+ subi_native(opts, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch2);
+ }
+ push_native(opts, opts->gen.scratch2);
+ if (reg > 7) {
+ areg_to_native(opts, reg-8, opts->gen.scratch1);
+ } else {
+ dreg_to_native(opts, reg, opts->gen.scratch1);
+ }
+ if (inst->extra.size == OPSIZE_LONG) {
+ call(code, opts->write_32_lowfirst);
+ } else {
+ call(code, opts->write_16);
+ }
+ pop_native(opts, opts->gen.scratch2);
+ if (inst->dst.addr_mode != MODE_AREG_PREDEC) {
+ addi_native(opts, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch2);
+ }
+ }
+ }
+ if (inst->dst.addr_mode == MODE_AREG_PREDEC) {
+ native_to_areg(opts, opts->gen.scratch2, inst->dst.params.regs.pri);
+ }
+ } else {
+ //mem to reg
+ early_cycles = 4;
+ switch (inst->src.addr_mode)
+ {
+ case MODE_AREG_INDIRECT:
+ case MODE_AREG_POSTINC:
+ areg_to_native(opts, inst->src.params.regs.pri, opts->gen.scratch1);
+ break;
+ case MODE_AREG_DISPLACE:
+ early_cycles += BUS;
+ reg = opts->gen.scratch2;
+ calc_areg_displace(opts, &inst->src, opts->gen.scratch1);
+ break;
+ case MODE_AREG_INDEX_DISP8:
+ early_cycles += 6;
+ calc_areg_index_disp8(opts, &inst->src, opts->gen.scratch1);
+ break;
+ case MODE_PC_DISPLACE:
+ early_cycles += BUS;
+ ldi_native(opts, inst->src.params.regs.displacement + inst->address+2, opts->gen.scratch1);
+ break;
+ case MODE_PC_INDEX_DISP8:
+ early_cycles += 6;
+ ldi_native(opts, inst->address+2, opts->gen.scratch1);
+ calc_index_disp8(opts, &inst->src, opts->gen.scratch1);
+ break;
+ case MODE_ABSOLUTE:
+ early_cycles += 4;
+ case MODE_ABSOLUTE_SHORT:
+ early_cycles += 4;
+ ldi_native(opts, inst->src.params.immed, opts->gen.scratch1);
+ break;
+ default:
+ m68k_disasm(inst, disasm_buf);
+ printf("%X: %s\naddress mode %d not implemented (movem src)\n", inst->address, disasm_buf, inst->src.addr_mode);
+ exit(1);
+ }
+ cycles(&opts->gen, early_cycles);
+ for(reg = 0; reg < 16; reg ++) {
+ if (inst->dst.params.immed & (1 << reg)) {
+ push_native(opts, opts->gen.scratch1);
+ if (inst->extra.size == OPSIZE_LONG) {
+ call(code, opts->read_32);
+ } else {
+ call(code, opts->read_16);
+ }
+ if (inst->extra.size == OPSIZE_WORD) {
+ sign_extend16_native(opts, opts->gen.scratch1);
+ }
+ if (reg > 7) {
+ native_to_areg(opts, opts->gen.scratch1, reg-8);
+ } else {
+ native_to_dreg(opts, opts->gen.scratch1, reg);
+ }
+ pop_native(opts, opts->gen.scratch1);
+ addi_native(opts, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch1);
+ }
+ }
+ if (inst->src.addr_mode == MODE_AREG_POSTINC) {
+ native_to_areg(opts, opts->gen.scratch1, inst->src.params.regs.pri);
+ }
+ }
+ //prefetch
+ cycles(&opts->gen, 4);
+}
+
void translate_m68k_nop(m68k_options *opts, m68kinst *inst)
{
cycles(&opts->gen, BUS);
diff --git a/m68k_core_x86.c b/m68k_core_x86.c
index 7b3facf..ea11e2a 100644
--- a/m68k_core_x86.c
+++ b/m68k_core_x86.c
@@ -264,6 +264,31 @@ 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)
+{
+ add_ir(&opts->gen.code, value, reg, SZ_D);
+}
+
+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) {
@@ -699,148 +724,6 @@ void translate_m68k_move(m68k_options * opts, m68kinst * inst)
cycles(&opts->gen, BUS);
}
-void translate_m68k_movem(m68k_options * opts, m68kinst * inst)
-{
- code_info *code = &opts->gen.code;
- int8_t bit,reg,sec_reg;
- uint8_t early_cycles;
- if(inst->src.addr_mode == MODE_REG) {
- //reg to mem
- early_cycles = 8;
- int8_t dir;
- switch (inst->dst.addr_mode)
- {
- case MODE_AREG_INDIRECT:
- case MODE_AREG_PREDEC:
- areg_to_native(opts, inst->dst.params.regs.pri, opts->gen.scratch2);
- break;
- case MODE_AREG_DISPLACE:
- early_cycles += BUS;
- calc_areg_displace(opts, &inst->dst, opts->gen.scratch2);
- break;
- case MODE_AREG_INDEX_DISP8:
- early_cycles += 6;
- calc_areg_index_disp8(opts, &inst->dst, opts->gen.scratch2);
- break;
- case MODE_PC_DISPLACE:
- early_cycles += BUS;
- mov_ir(code, inst->dst.params.regs.displacement + inst->address+2, opts->gen.scratch2, SZ_D);
- break;
- case MODE_PC_INDEX_DISP8:
- early_cycles += 6;
- mov_ir(code, inst->address+2, opts->gen.scratch2, SZ_D);
- calc_index_disp8(opts, &inst->dst, opts->gen.scratch2);
- case MODE_ABSOLUTE:
- early_cycles += 4;
- case MODE_ABSOLUTE_SHORT:
- early_cycles += 4;
- mov_ir(code, inst->dst.params.immed, opts->gen.scratch2, SZ_D);
- break;
- default:
- m68k_disasm(inst, disasm_buf);
- printf("%X: %s\naddress mode %d not implemented (movem dst)\n", inst->address, disasm_buf, inst->dst.addr_mode);
- exit(1);
- }
- if (inst->dst.addr_mode == MODE_AREG_PREDEC) {
- reg = 15;
- dir = -1;
- } else {
- reg = 0;
- dir = 1;
- }
- cycles(&opts->gen, early_cycles);
- for(bit=0; reg < 16 && reg >= 0; reg += dir, bit++) {
- if (inst->src.params.immed & (1 << bit)) {
- if (inst->dst.addr_mode == MODE_AREG_PREDEC) {
- sub_ir(code, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch2, SZ_D);
- }
- push_r(code, opts->gen.scratch2);
- if (reg > 7) {
- areg_to_native(opts, reg-8, opts->gen.scratch1);
- } else {
- dreg_to_native(opts, reg, opts->gen.scratch1);
- }
- if (inst->extra.size == OPSIZE_LONG) {
- call(code, opts->write_32_lowfirst);
- } else {
- call(code, opts->write_16);
- }
- pop_r(code, opts->gen.scratch2);
- if (inst->dst.addr_mode != MODE_AREG_PREDEC) {
- add_ir(code, (inst->extra.size == OPSIZE_LONG) ? 4 : 2, opts->gen.scratch2, SZ_D);
- }
- }
- }
- if (inst->dst.addr_mode == MODE_AREG_PREDEC) {
- native_to_areg(opts, opts->gen.scratch2, inst->dst.params.regs.pri);
- }
- } else {
- //mem to reg
- early_cycles = 4;
- switch (inst->src.addr_mode)
- {
- case MODE_AREG_INDIRECT:
- case MODE_AREG_POSTINC:
- areg_to_native(opts, inst->src.params.regs.pri, opts->gen.scratch1);
- break;
- case MODE_AREG_DISPLACE:
- early_cycles += BUS;
- reg = opts->gen.scratch2;
- calc_areg_displace(opts, &inst->src, opts->gen.scratch1);
- break;
- case MODE_AREG_INDEX_DISP8:
- early_cycles += 6;
- calc_areg_index_disp8(opts, &inst->src, opts->gen.scratch1);
- break;
- case MODE_PC_DISPLACE:
- early_cycles += BUS;
- mov_ir(code, inst->src.params.regs.displacement + inst->address+2, opts->gen.scratch1, SZ_D);
- break;
- case MODE_PC_INDEX_DISP8:
- early_cycles += 6;
- mov_ir(code, inst->address+2, opts->gen.scratch1, SZ_D);
- calc_index_disp8(opts, &inst->src, opts->gen.scratch1);
- break;
- case MODE_ABSOLUTE:
- early_cycles += 4;
- case MODE_ABSOLUTE_SHORT:
- early_cycles += 4;
- 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 (movem src)\n", inst->address, disasm_buf, inst->src.addr_mode);
- exit(1);
- }
- cycles(&opts->gen, early_cycles);
- for(reg = 0; reg < 16; reg ++) {
- if (inst->dst.params.immed & (1 << reg)) {
- push_r(code, opts->gen.scratch1);
- if (inst->extra.size == OPSIZE_LONG) {
- call(code, opts->read_32);
- } else {
- call(code, opts->read_16);
- }
- if (inst->extra.size == OPSIZE_WORD) {
- movsx_rr(code, opts->gen.scratch1, opts->gen.scratch1, SZ_W, SZ_D);
- }
- if (reg > 7) {
- native_to_areg(opts, opts->gen.scratch1, reg-8);
- } else {
- 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) {
- native_to_areg(opts, opts->gen.scratch1, inst->src.params.regs.pri);
- }
- }
- //prefetch
- cycles(&opts->gen, 4);
-}
-
void translate_m68k_clr(m68k_options * opts, m68kinst * inst)
{
code_info *code = &opts->gen.code;
diff --git a/m68k_internal.h b/m68k_internal.h
index 2767084..1a06e03 100644
--- a/m68k_internal.h
+++ b/m68k_internal.h
@@ -19,6 +19,11 @@ void native_to_areg(m68k_options *opts, uint8_t native_reg, uint8_t reg);
void native_to_dreg(m68k_options *opts, uint8_t native_reg, uint8_t reg);
void ldi_areg(m68k_options *opts, int32_t value, uint8_t reg);
void ldi_native(m68k_options *opts, int32_t value, uint8_t reg);
+void addi_native(m68k_options *opts, int32_t value, uint8_t reg);
+void subi_native(m68k_options *opts, int32_t value, uint8_t reg);
+void push_native(m68k_options *opts, uint8_t reg);
+void pop_native(m68k_options *opts, uint8_t reg);
+void sign_extend16_native(m68k_options *opts, uint8_t reg);
void addi_areg(m68k_options *opts, int32_t val, uint8_t reg);
void subi_areg(m68k_options *opts, int32_t val, uint8_t reg);
void add_areg_native(m68k_options *opts, uint8_t reg, uint8_t native_reg);
@@ -49,20 +54,13 @@ code_ptr get_native_address_trans(m68k_context * context, uint32_t address);
void * m68k_retranslate_inst(uint32_t address, m68k_context * context);
//individual instructions
-void translate_m68k_lea_pea(m68k_options * opts, m68kinst * inst);
-void translate_m68k_bsr(m68k_options * opts, m68kinst * inst);
-void translate_m68k_jmp_jsr(m68k_options * opts, m68kinst * inst);
void translate_m68k_bcc(m68k_options * opts, m68kinst * inst);
void translate_m68k_scc(m68k_options * opts, m68kinst * inst);
void translate_m68k_dbcc(m68k_options * opts, m68kinst * inst);
-void translate_m68k_unlk(m68k_options * opts, m68kinst * inst);
-void translate_m68k_link(m68k_options * opts, m68kinst * inst);
-void translate_m68k_rts(m68k_options * opts, m68kinst * inst);
void translate_m68k_rtr(m68k_options *opts, m68kinst * inst);
void translate_m68k_trap(m68k_options *opts, m68kinst *inst);
void translate_m68k_move(m68k_options * opts, m68kinst * inst);
void translate_m68k_movep(m68k_options * opts, m68kinst * inst);
-void translate_m68k_movem(m68k_options * opts, m68kinst * inst);
void translate_m68k_arith(m68k_options *opts, m68kinst * inst, uint32_t flag_mask, host_ea *src_op, host_ea *dst_op);
void translate_m68k_unary(m68k_options *opts, m68kinst *inst, uint32_t flag_mask, host_ea *dst_op);
void translate_m68k_invalid(m68k_options *opts, m68kinst *inst);