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;