Mercurial > repos > blastem
comparison m68k_core_x86.c @ 2455:4aef84fbe2e2
Fix bit instruction penalty cycle check for cases when bit number is out of range
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 19 Feb 2024 23:00:49 -0800 |
parents | 1fba97414ba6 |
children | d74d3998482c |
comparison
equal
deleted
inserted
replaced
2454:b1e8e7554f2f | 2455:4aef84fbe2e2 |
---|---|
1620 inst->op == M68K_BCLR ? 8 : 6) | 1620 inst->op == M68K_BCLR ? 8 : 6) |
1621 ); | 1621 ); |
1622 if (src_op->mode == MODE_IMMED) { | 1622 if (src_op->mode == MODE_IMMED) { |
1623 if (inst->extra.size == OPSIZE_BYTE) { | 1623 if (inst->extra.size == OPSIZE_BYTE) { |
1624 src_op->disp &= 0x7; | 1624 src_op->disp &= 0x7; |
1625 } else if (inst->op != M68K_BTST && src_op->disp > 15) { | 1625 } else if (inst->op != M68K_BTST && (src_op->disp & 31) > 15) { |
1626 //bit operations that need to save the result have a 2 cycle penalty when operating on the upper word | 1626 //bit operations that need to save the result have a 2 cycle penalty when operating on the upper word |
1627 cycles(&opts->gen, 2); | 1627 cycles(&opts->gen, 2); |
1628 } | 1628 } |
1629 if (dst_op->mode == MODE_REG_DIRECT) { | 1629 if (dst_op->mode == MODE_REG_DIRECT) { |
1630 op_ir(code, inst, src_op->disp, dst_op->base, inst->extra.size); | 1630 op_ir(code, inst, src_op->disp, dst_op->base, inst->extra.size); |
1646 mov_rr(code, src_op->base, opts->gen.scratch1, SZ_B); | 1646 mov_rr(code, src_op->base, opts->gen.scratch1, SZ_B); |
1647 } else { | 1647 } else { |
1648 mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_B); | 1648 mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_B); |
1649 } | 1649 } |
1650 src_op->base = opts->gen.scratch1; | 1650 src_op->base = opts->gen.scratch1; |
1651 } | 1651 } |
1652 } | 1652 } |
1653 uint8_t size = inst->extra.size; | 1653 uint8_t size = inst->extra.size; |
1654 if (dst_op->mode == MODE_REG_DISPLACE8) { | 1654 if (dst_op->mode == MODE_REG_DISPLACE8 || (inst->op != M68K_BTST && inst->extra.size != OPSIZE_BYTE)) { |
1655 if (src_op->base != opts->gen.scratch1 && src_op->base != opts->gen.scratch2) { | 1655 if (src_op->base != opts->gen.scratch1 && src_op->base != opts->gen.scratch2) { |
1656 if (src_op->mode == MODE_REG_DIRECT) { | 1656 if (src_op->mode == MODE_REG_DIRECT) { |
1657 mov_rr(code, src_op->base, opts->gen.scratch1, SZ_D); | 1657 mov_rr(code, src_op->base, opts->gen.scratch1, SZ_D); |
1658 } else { | 1658 } else { |
1659 mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_D); | 1659 mov_rdispr(code, src_op->base, src_op->disp, opts->gen.scratch1, SZ_D); |
1662 src_op->base = opts->gen.scratch1; | 1662 src_op->base = opts->gen.scratch1; |
1663 } | 1663 } |
1664 //b### with register destination is modulo 32 | 1664 //b### with register destination is modulo 32 |
1665 //x86 with a memory destination isn't modulo anything | 1665 //x86 with a memory destination isn't modulo anything |
1666 //so use an and here to force the value to be modulo 32 | 1666 //so use an and here to force the value to be modulo 32 |
1667 and_ir(code, 31, opts->gen.scratch1, SZ_D); | 1667 //we also need to do this for the 2 cycle penalty check below |
1668 and_ir(code, 31, src_op->base, SZ_D); | |
1668 } else if(inst->dst.addr_mode != MODE_REG) { | 1669 } else if(inst->dst.addr_mode != MODE_REG) { |
1669 //b### with memory destination is modulo 8 | 1670 //b### with memory destination is modulo 8 |
1670 //x86-64 doesn't support 8-bit bit operations | 1671 //x86-64 doesn't support 8-bit bit operations |
1671 //so we fake it by forcing the bit number to be modulo 8 | 1672 //so we fake it by forcing the bit number to be modulo 8 |
1672 and_ir(code, 7, src_op->base, SZ_D); | 1673 and_ir(code, 7, src_op->base, SZ_D); |