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
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);