Mercurial > repos > blastem
comparison m68k_core_x86.c @ 2224:d8b0244101c4
Fix bad 68K instruction timings revealed by Ti_'s test ROM, except those that involve exception timing
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 05 Sep 2022 00:49:03 -0700 |
parents | 522d04e2adcd |
children | e22137f0aca4 |
comparison
equal
deleted
inserted
replaced
2223:1cccc57c069a | 2224:d8b0244101c4 |
---|---|
852 uint8_t cond = inst->extra.cond; | 852 uint8_t cond = inst->extra.cond; |
853 host_ea dst_op; | 853 host_ea dst_op; |
854 inst->extra.size = OPSIZE_BYTE; | 854 inst->extra.size = OPSIZE_BYTE; |
855 translate_m68k_op(inst, &dst_op, opts, 1); | 855 translate_m68k_op(inst, &dst_op, opts, 1); |
856 if (cond == COND_TRUE || cond == COND_FALSE) { | 856 if (cond == COND_TRUE || cond == COND_FALSE) { |
857 if ((inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG) && inst->extra.cond == COND_TRUE) { | 857 if ((inst->dst.addr_mode == MODE_REG || inst->dst.addr_mode == MODE_AREG) && cond == COND_TRUE) { |
858 cycles(&opts->gen, 6); | 858 cycles(&opts->gen, 6); |
859 } else { | 859 } else { |
860 cycles(&opts->gen, BUS); | 860 cycles(&opts->gen, BUS); |
861 } | 861 } |
862 if (dst_op.mode == MODE_REG_DIRECT) { | 862 if (dst_op.mode == MODE_REG_DIRECT) { |
1315 if ((inst->op == M68K_ADDX || inst->op == M68K_SUBX) && inst->src.addr_mode != MODE_REG) { | 1315 if ((inst->op == M68K_ADDX || inst->op == M68K_SUBX) && inst->src.addr_mode != MODE_REG) { |
1316 numcycles = 4; | 1316 numcycles = 4; |
1317 } else if (size == OPSIZE_LONG) { | 1317 } else if (size == OPSIZE_LONG) { |
1318 if (inst->op == M68K_CMP) { | 1318 if (inst->op == M68K_CMP) { |
1319 numcycles = inst->src.addr_mode > MODE_AREG && inst->dst.addr_mode > MODE_AREG ? 4 : 6; | 1319 numcycles = inst->src.addr_mode > MODE_AREG && inst->dst.addr_mode > MODE_AREG ? 4 : 6; |
1320 } else if (inst->op == M68K_AND && inst->variant == VAR_IMMEDIATE && inst->dst.addr_mode == MODE_REG) { | |
1321 numcycles = 6; | |
1322 } else if (inst->dst.addr_mode == MODE_REG) { | 1320 } else if (inst->dst.addr_mode == MODE_REG) { |
1323 numcycles = inst->src.addr_mode <= MODE_AREG || inst->src.addr_mode == MODE_IMMEDIATE ? 8 : 6; | 1321 numcycles = inst->src.addr_mode <= MODE_AREG || inst->src.addr_mode == MODE_IMMEDIATE ? 8 : 6; |
1324 } else if (inst->dst.addr_mode == MODE_AREG) { | 1322 } else if (inst->dst.addr_mode == MODE_AREG) { |
1325 numcycles = numcycles = inst->src.addr_mode <= MODE_AREG || inst->src.addr_mode == MODE_IMMEDIATE | 1323 numcycles = numcycles = inst->src.addr_mode <= MODE_AREG || inst->src.addr_mode == MODE_IMMEDIATE |
1326 || inst->extra.size == OPSIZE_WORD ? 8 : 6; | 1324 || inst->extra.size == OPSIZE_WORD ? 8 : 6; |
1614 } | 1612 } |
1615 | 1613 |
1616 void translate_m68k_bit(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) | 1614 void translate_m68k_bit(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op) |
1617 { | 1615 { |
1618 code_info *code = &opts->gen.code; | 1616 code_info *code = &opts->gen.code; |
1619 cycles(&opts->gen, inst->extra.size == OPSIZE_BYTE ? 4 : ( | 1617 cycles(&opts->gen, inst->extra.size == OPSIZE_BYTE ? (dst_op->mode == MODE_IMMED ? 6 : 4) : ( |
1620 inst->op == M68K_BTST ? 6 : (inst->op == M68K_BCLR ? 10 : 8)) | 1618 inst->op == M68K_BCLR ? 8 : 6) |
1621 ); | 1619 ); |
1622 if (src_op->mode == MODE_IMMED) { | 1620 if (src_op->mode == MODE_IMMED) { |
1623 if (inst->extra.size == OPSIZE_BYTE) { | 1621 if (inst->extra.size == OPSIZE_BYTE) { |
1624 src_op->disp &= 0x7; | 1622 src_op->disp &= 0x7; |
1623 } else if (inst->op != M68K_BTST && src_op->disp > 15) { | |
1624 //bit operations that need to save the result have a 2 cycle penalty when operating on the upper word | |
1625 cycles(&opts->gen, 2); | |
1625 } | 1626 } |
1626 if (dst_op->mode == MODE_REG_DIRECT) { | 1627 if (dst_op->mode == MODE_REG_DIRECT) { |
1627 op_ir(code, inst, src_op->disp, dst_op->base, inst->extra.size); | 1628 op_ir(code, inst, src_op->disp, dst_op->base, inst->extra.size); |
1628 } else { | 1629 } else { |
1629 op_irdisp(code, inst, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size); | 1630 op_irdisp(code, inst, src_op->disp, dst_op->base, dst_op->disp, inst->extra.size); |
1667 //x86-64 doesn't support 8-bit bit operations | 1668 //x86-64 doesn't support 8-bit bit operations |
1668 //so we fake it by forcing the bit number to be modulo 8 | 1669 //so we fake it by forcing the bit number to be modulo 8 |
1669 and_ir(code, 7, src_op->base, SZ_D); | 1670 and_ir(code, 7, src_op->base, SZ_D); |
1670 size = SZ_D; | 1671 size = SZ_D; |
1671 } | 1672 } |
1673 if (inst->op != M68K_BTST && inst->extra.size != OPSIZE_BYTE) { | |
1674 //bit operations that need to save the result have a 2 cycle penalty when operating on the upper word | |
1675 | |
1676 if (src_op->mode == MODE_REG_DISPLACE8) { | |
1677 cmp_irdisp(code, 16, src_op->base, src_op->disp, SZ_B); | |
1678 } else { | |
1679 cmp_ir(code, 16, src_op->base, SZ_B); | |
1680 } | |
1681 code_ptr jmp_off = code->cur + 1; | |
1682 jcc(code, CC_C, jmp_off + 1); | |
1683 cycles(&opts->gen, 2); | |
1684 *jmp_off = code->cur - (jmp_off + 1); | |
1685 } | |
1672 if (dst_op->mode == MODE_IMMED) { | 1686 if (dst_op->mode == MODE_IMMED) { |
1673 dst_op->base = src_op->base == opts->gen.scratch1 ? opts->gen.scratch2 : opts->gen.scratch1; | 1687 dst_op->base = src_op->base == opts->gen.scratch1 ? opts->gen.scratch2 : opts->gen.scratch1; |
1674 mov_ir(code, dst_op->disp, dst_op->base, SZ_B); | 1688 mov_ir(code, dst_op->disp, dst_op->base, SZ_B); |
1675 dst_op->mode = MODE_REG_DIRECT; | 1689 dst_op->mode = MODE_REG_DIRECT; |
1676 } | 1690 } |
1793 } | 1807 } |
1794 if (divisor_shift <= dividend) { | 1808 if (divisor_shift <= dividend) { |
1795 context->flags[FLAG_V] = 1; | 1809 context->flags[FLAG_V] = 1; |
1796 context->flags[FLAG_N] = 1; | 1810 context->flags[FLAG_N] = 1; |
1797 context->flags[FLAG_Z] = 0; | 1811 context->flags[FLAG_Z] = 0; |
1798 cycles += 2; | 1812 cycles += 4; |
1799 context->current_cycle += cycles * context->options->gen.clock_divider; | 1813 context->current_cycle += cycles * context->options->gen.clock_divider; |
1800 return orig_dividend; | 1814 return orig_dividend; |
1801 } | 1815 } |
1802 uint16_t quotient = 0; | 1816 uint16_t quotient = 0; |
1803 uint16_t bit = 0; | 1817 uint16_t bit = 0; |