# HG changeset patch # User Michael Pavone # Date 1394266509 28800 # Node ID 963d5901f583987dfe62586edf82089bf0fa65c4 # Parent 55c5b0f913ceff247e930103038699fae7641657 Move translate_m68k_movem to m68k_core.c diff -r 55c5b0f913ce -r 963d5901f583 m68k_core.c --- a/m68k_core.c Fri Mar 07 23:26:46 2014 -0800 +++ b/m68k_core.c Sat Mar 08 00:15:09 2014 -0800 @@ -349,6 +349,148 @@ } } +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 -r 55c5b0f913ce -r 963d5901f583 m68k_core_x86.c --- a/m68k_core_x86.c Fri Mar 07 23:26:46 2014 -0800 +++ b/m68k_core_x86.c Sat Mar 08 00:15:09 2014 -0800 @@ -264,6 +264,31 @@ 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 @@ 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 -r 55c5b0f913ce -r 963d5901f583 m68k_internal.h --- a/m68k_internal.h Fri Mar 07 23:26:46 2014 -0800 +++ b/m68k_internal.h Sat Mar 08 00:15:09 2014 -0800 @@ -19,6 +19,11 @@ 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 @@ 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);