Mercurial > repos > blastem
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 |