Mercurial > repos > blastem
diff m68k_core.c @ 581:9f40aa5243c2
Combine implementations of lea and pea. Update bit instructions to use the op_ family of functions to simplify their implementation a bit.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 05 Mar 2014 19:26:53 -0800 |
parents | 1594525e2157 |
children | c05fcbfe1b1a |
line wrap: on
line diff
--- 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)