# HG changeset patch # User Michael Pavone # Date 1394076413 28800 # Node ID 9f40aa5243c248e4a172d0891ecca31cdb2b653e # Parent 5157bc966c1ace72411bf3aa3809dc1212730796 Combine implementations of lea and pea. Update bit instructions to use the op_ family of functions to simplify their implementation a bit. diff -r 5157bc966c1a -r 9f40aa5243c2 m68k_core.c --- a/m68k_core.c Wed Mar 05 09:33:50 2014 -0800 +++ b/m68k_core.c Wed Mar 05 19:26:53 2014 -0800 @@ -86,10 +86,10 @@ } } -void translate_m68k_lea(m68k_options * opts, m68kinst * inst) +void translate_m68k_lea_pea(m68k_options * opts, m68kinst * inst) { code_info *code = &opts->gen.code; - int8_t dst_reg = native_reg(&(inst->dst), opts); + int8_t dst_reg = inst->op == M68K_PEA ? opts->gen.scratch1 : native_reg(&(inst->dst), opts); switch(inst->src.addr_mode) { case MODE_AREG_INDIRECT: @@ -118,13 +118,17 @@ dst_reg = opts->gen.scratch1; } calc_areg_index_disp8(opts, &inst->src, dst_reg); - if (dst_reg == opts->gen.scratch1) { + if (dst_reg == opts->gen.scratch1 && inst->op != M68K_PEA) { native_to_areg(opts, opts->gen.scratch1, inst->dst.params.regs.pri); } break; case MODE_PC_DISPLACE: cycles(&opts->gen, 8); - ldi_areg(opts, inst->src.params.regs.displacement + inst->address+2, inst->dst.params.regs.pri); + if (inst->op == M68K_PEA) { + ldi_native(opts, inst->src.params.regs.displacement + inst->address+2, dst_reg); + } else { + ldi_areg(opts, inst->src.params.regs.displacement + inst->address+2, inst->dst.params.regs.pri); + } break; case MODE_PC_INDEX_DISP8: cycles(&opts->gen, BUS*3); @@ -133,61 +137,29 @@ } ldi_native(opts, inst->address+2, dst_reg); calc_index_disp8(opts, &inst->src, dst_reg); - if (dst_reg == opts->gen.scratch1) { + if (dst_reg == opts->gen.scratch1 && inst->op != M68K_PEA) { native_to_areg(opts, opts->gen.scratch1, inst->dst.params.regs.pri); } break; case MODE_ABSOLUTE: case MODE_ABSOLUTE_SHORT: cycles(&opts->gen, (inst->src.addr_mode == MODE_ABSOLUTE) ? BUS * 3 : BUS * 2); - ldi_areg(opts, inst->src.params.immed, inst->dst.params.regs.pri); + if (inst->op == M68K_PEA) { + ldi_native(opts, inst->src.params.immed, dst_reg); + } else { + ldi_areg(opts, inst->src.params.immed, inst->dst.params.regs.pri); + } 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; - switch(inst->src.addr_mode) - { - case MODE_AREG_INDIRECT: - cycles(&opts->gen, BUS); - areg_to_native(opts, inst->src.params.regs.pri, opts->gen.scratch1); - break; - case MODE_AREG_DISPLACE: - cycles(&opts->gen, 8); - calc_areg_displace(opts, &inst->src, opts->gen.scratch1); - break; - case MODE_AREG_INDEX_DISP8: - cycles(&opts->gen, 6);//TODO: Check to make sure this is correct - calc_areg_index_disp8(opts, &inst->src, opts->gen.scratch1); - break; - case MODE_PC_DISPLACE: - cycles(&opts->gen, 8); - ldi_native(opts, inst->src.params.regs.displacement + inst->address+2, opts->gen.scratch1); - break; - case MODE_PC_INDEX_DISP8: - cycles(&opts->gen, BUS*3);//TODO: Check to make sure this is correct - ldi_native(opts, inst->address+2, opts->gen.scratch1); - calc_index_disp8(opts, &inst->src, opts->gen.scratch1); - break; - case MODE_ABSOLUTE: - case MODE_ABSOLUTE_SHORT: - cycles(&opts->gen, (inst->src.addr_mode == MODE_ABSOLUTE) ? BUS * 3 : BUS * 2); - 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 (lea src)\n", inst->address, disasm_buf, inst->src.addr_mode); - exit(1); + if (inst->op == M68K_PEA) { + subi_areg(opts, 4, 7); + areg_to_native(opts, 7, opts->gen.scratch2); + call(code, opts->write_32_lowfirst); } - subi_areg(opts, 4, 7); - areg_to_native(opts, 7, opts->gen.scratch2); - call(code, opts->write_32_lowfirst); } void push_const(m68k_options *opts, int32_t value) diff -r 5157bc966c1a -r 9f40aa5243c2 m68k_core_x86.c --- a/m68k_core_x86.c Wed Mar 05 09:33:50 2014 -0800 +++ b/m68k_core_x86.c Wed Mar 05 19:26:53 2014 -0800 @@ -1300,6 +1300,10 @@ case M68K_ADD: add_ir(code, val, dst, size); break; case M68K_ADDX: adc_ir(code, val, dst, size); break; case M68K_AND: and_ir(code, val, dst, size); break; + case M68K_BTST: bt_ir(code, val, dst, size); break; + case M68K_BSET: bts_ir(code, val, dst, size); break; + case M68K_BCLR: btr_ir(code, val, dst, size); break; + case M68K_BCHG: btc_ir(code, val, dst, size); break; case M68K_EOR: xor_ir(code, val, dst, size); break; case M68K_OR: or_ir(code, val, dst, size); break; case M68K_ROL: rol_ir(code, val, dst, size); break; @@ -1318,6 +1322,10 @@ case M68K_ADD: add_irdisp(code, val, dst, disp, size); break; case M68K_ADDX: adc_irdisp(code, val, dst, disp, size); break; case M68K_AND: and_irdisp(code, val, dst, disp, size); break; + case M68K_BTST: bt_irdisp(code, val, dst, disp, size); break; + case M68K_BSET: bts_irdisp(code, val, dst, disp, size); break; + case M68K_BCLR: btr_irdisp(code, val, dst, disp, size); break; + case M68K_BCHG: btc_irdisp(code, val, dst, disp, size); break; case M68K_EOR: xor_irdisp(code, val, dst, disp, size); break; case M68K_OR: or_irdisp(code, val, dst, disp, size); break; case M68K_ROL: rol_irdisp(code, val, dst, disp, size); break; @@ -1336,6 +1344,10 @@ case M68K_ADD: add_rr(code, src, dst, size); break; case M68K_ADDX: adc_rr(code, src, dst, size); break; case M68K_AND: and_rr(code, src, dst, size); break; + case M68K_BTST: bt_rr(code, src, dst, size); break; + case M68K_BSET: bts_rr(code, src, dst, size); break; + case M68K_BCLR: btr_rr(code, src, dst, size); break; + case M68K_BCHG: btc_rr(code, src, dst, size); break; case M68K_EOR: xor_rr(code, src, dst, size); break; case M68K_OR: or_rr(code, src, dst, size); break; case M68K_SUB: sub_rr(code, src, dst, size); break; @@ -1350,6 +1362,10 @@ case M68K_ADD: add_rrdisp(code, src, dst, disp, size); break; case M68K_ADDX: adc_rrdisp(code, src, dst, disp, size); break; case M68K_AND: and_rrdisp(code, src, dst, disp, size); break; + case M68K_BTST: bt_rrdisp(code, src, dst, disp, size); break; + case M68K_BSET: bts_rrdisp(code, src, dst, disp, size); break; + case M68K_BCLR: btr_rrdisp(code, src, dst, disp, size); break; + case M68K_BCHG: btc_rrdisp(code, src, dst, disp, size); break; case M68K_EOR: xor_rrdisp(code, src, dst, disp, size); break; case M68K_OR: or_rrdisp(code, src, dst, disp, size); break; case M68K_SUB: sub_rrdisp(code, src, dst, disp, size); break; @@ -1482,10 +1498,8 @@ check_cycles_int(&opts->gen, inst->address); if (inst->op == M68K_MOVE) { return translate_m68k_move(opts, inst); - } else if(inst->op == M68K_LEA) { - return translate_m68k_lea(opts, inst); - } else if(inst->op == M68K_PEA) { - return translate_m68k_pea(opts, inst); + } else if(inst->op == M68K_LEA || inst->op == M68K_PEA) { + return translate_m68k_lea_pea(opts, inst); } else if(inst->op == M68K_BSR) { return translate_m68k_bsr(opts, inst); } else if(inst->op == M68K_BCC) { @@ -1637,30 +1651,10 @@ if (inst->extra.size == OPSIZE_BYTE) { src_op.disp &= 0x7; } - if (inst->op == M68K_BTST) { - if (dst_op.mode == MODE_REG_DIRECT) { - bt_ir(code, src_op.disp, dst_op.base, inst->extra.size); - } else { - bt_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); - } - } else if (inst->op == M68K_BSET) { - if (dst_op.mode == MODE_REG_DIRECT) { - bts_ir(code, src_op.disp, dst_op.base, inst->extra.size); - } else { - bts_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); - } - } else if (inst->op == M68K_BCLR) { - if (dst_op.mode == MODE_REG_DIRECT) { - btr_ir(code, src_op.disp, dst_op.base, inst->extra.size); - } else { - btr_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); - } + if (dst_op.mode == MODE_REG_DIRECT) { + op_ir(code, inst, src_op.disp, dst_op.base, inst->extra.size); } else { - if (dst_op.mode == MODE_REG_DIRECT) { - btc_ir(code, src_op.disp, dst_op.base, inst->extra.size); - } else { - btc_irdisp(code, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); - } + op_irdisp(code, inst, src_op.disp, dst_op.base, dst_op.disp, inst->extra.size); } } else { if (src_op.mode == MODE_REG_DISPLACE8 || (inst->dst.addr_mode != MODE_REG && src_op.base != opts->gen.scratch1 && src_op.base != opts->gen.scratch2)) { @@ -1703,30 +1697,10 @@ and_ir(code, 7, src_op.base, SZ_D); size = SZ_D; } - if (inst->op == M68K_BTST) { - if (dst_op.mode == MODE_REG_DIRECT) { - bt_rr(code, src_op.base, dst_op.base, size); - } else { - bt_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, size); - } - } else if (inst->op == M68K_BSET) { - if (dst_op.mode == MODE_REG_DIRECT) { - bts_rr(code, src_op.base, dst_op.base, size); - } else { - bts_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, size); - } - } else if (inst->op == M68K_BCLR) { - if (dst_op.mode == MODE_REG_DIRECT) { - btr_rr(code, src_op.base, dst_op.base, size); - } else { - btr_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, size); - } + if (dst_op.mode == MODE_REG_DIRECT) { + op_rr(code, inst, src_op.base, dst_op.base, size); } else { - if (dst_op.mode == MODE_REG_DIRECT) { - btc_rr(code, src_op.base, dst_op.base, size); - } else { - btc_rrdisp(code, src_op.base, dst_op.base, dst_op.disp, size); - } + op_rrdisp(code, inst, src_op.base, dst_op.base, dst_op.disp, size); } if (src_op.base == opts->gen.scratch2) { pop_r(code, opts->gen.scratch2); diff -r 5157bc966c1a -r 9f40aa5243c2 m68k_internal.h --- a/m68k_internal.h Wed Mar 05 09:33:50 2014 -0800 +++ b/m68k_internal.h Wed Mar 05 19:26:53 2014 -0800 @@ -46,8 +46,7 @@ code_ptr get_native_address_trans(m68k_context * context, uint32_t address); //individual instructions -void translate_m68k_lea(m68k_options * opts, m68kinst * inst); -void translate_m68k_pea(m68k_options * opts, m68kinst * inst); +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_unlk(m68k_options * opts, m68kinst * inst);