comparison m68k_core_x86.c @ 1276:2d8b9d40f5ea

Fix undefined flags on overflow and divide by zero for divu based on hardware test. Fix saving result of divu when destination is not stored in a host register
author Michael Pavone <pavone@retrodev.com>
date Thu, 09 Mar 2017 23:50:46 -0800
parents 779920729249
children c5821f9de325
comparison
equal deleted inserted replaced
1275:f36ef4847ef2 1276:2d8b9d40f5ea
1757 break; 1757 break;
1758 case MODE_ABSOLUTE: 1758 case MODE_ABSOLUTE:
1759 isize = 6; 1759 isize = 6;
1760 break; 1760 break;
1761 } 1761 }
1762 //zero seems to clear all flags
1763 update_flags(opts, N0|Z0|V0);
1762 mov_ir(code, VECTOR_INT_DIV_ZERO, opts->gen.scratch2, SZ_D); 1764 mov_ir(code, VECTOR_INT_DIV_ZERO, opts->gen.scratch2, SZ_D);
1763 mov_ir(code, inst->address+isize, opts->gen.scratch1, SZ_D); 1765 mov_ir(code, inst->address+isize, opts->gen.scratch1, SZ_D);
1764 jmp(code, opts->trap); 1766 jmp(code, opts->trap);
1765 1767
1766 *not_zero = code->cur - (not_zero + 1); 1768 *not_zero = code->cur - (not_zero + 1);
1767 cmp_rr(code, opts->gen.scratch1, opts->gen.scratch2, SZ_D); 1769 cmp_rr(code, opts->gen.scratch1, opts->gen.scratch2, SZ_D);
1768 code_ptr not_overflow = code->cur+1; 1770 code_ptr not_overflow = code->cur+1;
1769 jcc(code, CC_C, not_overflow); 1771 jcc(code, CC_C, not_overflow);
1770 1772
1771 //flags N and Z flags are set based on internal subtraction of src from top 16-bits of dst 1773 //overflow seems to always set the N and clear Z
1772 and_ir(code, 0xFFFF0000, opts->gen.scratch2, SZ_D); 1774 update_flags(opts, N1|Z0|V1);
1773 cmp_rr(code, opts->gen.scratch1, opts->gen.scratch2, SZ_D);
1774 //TODO: verify N and Z flags are set like I think they are, microcode was a bit confusing
1775 update_flags(opts, N|Z|V1);
1776 cycles(&opts->gen, 10); 1775 cycles(&opts->gen, 10);
1777 code_ptr end = code->cur+1; 1776 code_ptr end = code->cur+1;
1778 jmp(code, end); 1777 jmp(code, end);
1779 1778
1780 *not_overflow = code->cur - (not_overflow + 1); 1779 *not_overflow = code->cur - (not_overflow + 1);
1791 update_flags(opts, V0|Z|N); 1790 update_flags(opts, V0|Z|N);
1792 1791
1793 if (dst_op->mode == MODE_REG_DIRECT) { 1792 if (dst_op->mode == MODE_REG_DIRECT) {
1794 mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_D); 1793 mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_D);
1795 } else { 1794 } else {
1796 mov_rrdisp(code, RAX, dst_op->base, dst_op->disp, SZ_D); 1795 mov_rrdisp(code, opts->gen.scratch1, dst_op->base, dst_op->disp, SZ_D);
1797 } 1796 }
1798 1797
1799 *end = code->cur - (end + 1); 1798 *end = code->cur - (end + 1);
1800 } 1799 }
1801 1800