Commit 510ff0b730d1ba25a382ac3f6f73571ea731b8e5
1 parent
e6dbd3b3
Generate m68k address faults.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2871 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
88 additions
and
43 deletions
target-m68k/translate.c
| ... | ... | @@ -43,6 +43,7 @@ static inline void qemu_assert(int cond, const char *msg) |
| 43 | 43 | /* internal defines */ |
| 44 | 44 | typedef struct DisasContext { |
| 45 | 45 | CPUM68KState *env; |
| 46 | + target_ulong insn_pc; /* Start of the current instruction. */ | |
| 46 | 47 | target_ulong pc; |
| 47 | 48 | int is_jmp; |
| 48 | 49 | int cc_op; |
| ... | ... | @@ -437,8 +438,7 @@ static int gen_lea(DisasContext *s, uint16_t insn, int opsize) |
| 437 | 438 | switch ((insn >> 3) & 7) { |
| 438 | 439 | case 0: /* Data register direct. */ |
| 439 | 440 | case 1: /* Address register direct. */ |
| 440 | - /* ??? generate bad addressing mode fault. */ | |
| 441 | - qemu_assert(0, "invalid addressing mode"); | |
| 441 | + return -1; | |
| 442 | 442 | case 2: /* Indirect register */ |
| 443 | 443 | case 3: /* Indirect postincrement. */ |
| 444 | 444 | reg += QREG_A0; |
| ... | ... | @@ -477,8 +477,7 @@ static int gen_lea(DisasContext *s, uint16_t insn, int opsize) |
| 477 | 477 | return gen_lea_indexed(s, opsize, -1); |
| 478 | 478 | case 4: /* Immediate. */ |
| 479 | 479 | default: |
| 480 | - /* ??? generate bad addressing mode fault. */ | |
| 481 | - qemu_assert(0, "invalid addressing mode"); | |
| 480 | + return -1; | |
| 482 | 481 | } |
| 483 | 482 | } |
| 484 | 483 | /* Should never happen. */ |
| ... | ... | @@ -496,6 +495,8 @@ static inline int gen_ea_once(DisasContext *s, uint16_t insn, int opsize, |
| 496 | 495 | tmp = *addrp; |
| 497 | 496 | } else { |
| 498 | 497 | tmp = gen_lea(s, insn, opsize); |
| 498 | + if (tmp == -1) | |
| 499 | + return -1; | |
| 499 | 500 | if (addrp) |
| 500 | 501 | *addrp = tmp; |
| 501 | 502 | } |
| ... | ... | @@ -548,6 +549,8 @@ static int gen_ea(DisasContext *s, uint16_t insn, int opsize, int val, |
| 548 | 549 | tmp = *addrp; |
| 549 | 550 | } else { |
| 550 | 551 | tmp = gen_lea(s, insn, opsize); |
| 552 | + if (tmp == -1) | |
| 553 | + return -1; | |
| 551 | 554 | if (addrp) |
| 552 | 555 | *addrp = tmp; |
| 553 | 556 | } |
| ... | ... | @@ -595,7 +598,7 @@ static int gen_ea(DisasContext *s, uint16_t insn, int opsize, int val, |
| 595 | 598 | } |
| 596 | 599 | return gen_im32(offset); |
| 597 | 600 | default: |
| 598 | - qemu_assert(0, "invalid addressing mode"); | |
| 601 | + return -1; | |
| 599 | 602 | } |
| 600 | 603 | } |
| 601 | 604 | /* Should never happen. */ |
| ... | ... | @@ -753,6 +756,27 @@ static void gen_exception(DisasContext *s, uint32_t where, int nr) |
| 753 | 756 | gen_op_raise_exception(nr); |
| 754 | 757 | } |
| 755 | 758 | |
| 759 | +static inline void gen_addr_fault(DisasContext *s) | |
| 760 | +{ | |
| 761 | + gen_exception(s, s->insn_pc, EXCP_ADDRESS); | |
| 762 | +} | |
| 763 | + | |
| 764 | +#define SRC_EA(result, opsize, val, addrp) do { \ | |
| 765 | + result = gen_ea(s, insn, opsize, val, addrp); \ | |
| 766 | + if (result == -1) { \ | |
| 767 | + gen_addr_fault(s); \ | |
| 768 | + return; \ | |
| 769 | + } \ | |
| 770 | + } while (0) | |
| 771 | + | |
| 772 | +#define DEST_EA(insn, opsize, val, addrp) do { \ | |
| 773 | + int ea_result = gen_ea(s, insn, opsize, val, addrp); \ | |
| 774 | + if (ea_result == -1) { \ | |
| 775 | + gen_addr_fault(s); \ | |
| 776 | + return; \ | |
| 777 | + } \ | |
| 778 | + } while (0) | |
| 779 | + | |
| 756 | 780 | /* Generate a jump to an immediate address. */ |
| 757 | 781 | static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest) |
| 758 | 782 | { |
| ... | ... | @@ -806,7 +830,7 @@ DISAS_INSN(mulw) |
| 806 | 830 | gen_op_ext16s32(tmp, reg); |
| 807 | 831 | else |
| 808 | 832 | gen_op_ext16u32(tmp, reg); |
| 809 | - src = gen_ea(s, insn, OS_WORD, sign ? -1 : 0, NULL); | |
| 833 | + SRC_EA(src, OS_WORD, sign ? -1 : 0, NULL); | |
| 810 | 834 | gen_op_mul32(tmp, tmp, src); |
| 811 | 835 | gen_op_mov32(reg, tmp); |
| 812 | 836 | /* Unlike m68k, coldfire always clears the overflow bit. */ |
| ... | ... | @@ -827,7 +851,7 @@ DISAS_INSN(divw) |
| 827 | 851 | } else { |
| 828 | 852 | gen_op_ext16u32(QREG_DIV1, reg); |
| 829 | 853 | } |
| 830 | - src = gen_ea(s, insn, OS_WORD, sign ? -1 : 0, NULL); | |
| 854 | + SRC_EA(src, OS_WORD, sign ? -1 : 0, NULL); | |
| 831 | 855 | gen_op_mov32(QREG_DIV2, src); |
| 832 | 856 | if (sign) { |
| 833 | 857 | gen_op_divs(1); |
| ... | ... | @@ -860,7 +884,7 @@ DISAS_INSN(divl) |
| 860 | 884 | num = DREG(ext, 12); |
| 861 | 885 | reg = DREG(ext, 0); |
| 862 | 886 | gen_op_mov32(QREG_DIV1, num); |
| 863 | - den = gen_ea(s, insn, OS_LONG, 0, NULL); | |
| 887 | + SRC_EA(den, OS_LONG, 0, NULL); | |
| 864 | 888 | gen_op_mov32(QREG_DIV2, den); |
| 865 | 889 | if (ext & 0x0800) { |
| 866 | 890 | gen_op_divs(2); |
| ... | ... | @@ -891,11 +915,11 @@ DISAS_INSN(addsub) |
| 891 | 915 | reg = DREG(insn, 9); |
| 892 | 916 | dest = gen_new_qreg(QMODE_I32); |
| 893 | 917 | if (insn & 0x100) { |
| 894 | - tmp = gen_ea(s, insn, OS_LONG, 0, &addr); | |
| 918 | + SRC_EA(tmp, OS_LONG, 0, &addr); | |
| 895 | 919 | src = reg; |
| 896 | 920 | } else { |
| 897 | 921 | tmp = reg; |
| 898 | - src = gen_ea(s, insn, OS_LONG, 0, NULL); | |
| 922 | + SRC_EA(src, OS_LONG, 0, NULL); | |
| 899 | 923 | } |
| 900 | 924 | if (add) { |
| 901 | 925 | gen_op_add32(dest, tmp, src); |
| ... | ... | @@ -908,7 +932,7 @@ DISAS_INSN(addsub) |
| 908 | 932 | } |
| 909 | 933 | gen_op_update_cc_add(dest, src); |
| 910 | 934 | if (insn & 0x100) { |
| 911 | - gen_ea(s, insn, OS_LONG, dest, &addr); | |
| 935 | + DEST_EA(insn, OS_LONG, dest, &addr); | |
| 912 | 936 | } else { |
| 913 | 937 | gen_op_mov32(reg, dest); |
| 914 | 938 | } |
| ... | ... | @@ -966,7 +990,7 @@ DISAS_INSN(bitop_reg) |
| 966 | 990 | else |
| 967 | 991 | opsize = OS_LONG; |
| 968 | 992 | op = (insn >> 6) & 3; |
| 969 | - src1 = gen_ea(s, insn, opsize, 0, op ? &addr: NULL); | |
| 993 | + SRC_EA(src1, opsize, 0, op ? &addr: NULL); | |
| 970 | 994 | src2 = DREG(insn, 9); |
| 971 | 995 | dest = gen_new_qreg(QMODE_I32); |
| 972 | 996 | |
| ... | ... | @@ -996,7 +1020,7 @@ DISAS_INSN(bitop_reg) |
| 996 | 1020 | break; |
| 997 | 1021 | } |
| 998 | 1022 | if (op) |
| 999 | - gen_ea(s, insn, opsize, dest, &addr); | |
| 1023 | + DEST_EA(insn, opsize, dest, &addr); | |
| 1000 | 1024 | } |
| 1001 | 1025 | |
| 1002 | 1026 | DISAS_INSN(sats) |
| ... | ... | @@ -1041,6 +1065,10 @@ DISAS_INSN(movem) |
| 1041 | 1065 | mask = lduw_code(s->pc); |
| 1042 | 1066 | s->pc += 2; |
| 1043 | 1067 | tmp = gen_lea(s, insn, OS_LONG); |
| 1068 | + if (tmp == -1) { | |
| 1069 | + gen_addr_fault(s); | |
| 1070 | + return; | |
| 1071 | + } | |
| 1044 | 1072 | addr = gen_new_qreg(QMODE_I32); |
| 1045 | 1073 | gen_op_mov32(addr, tmp); |
| 1046 | 1074 | is_load = ((insn & 0x0400) != 0); |
| ... | ... | @@ -1086,7 +1114,7 @@ DISAS_INSN(bitop_im) |
| 1086 | 1114 | return; |
| 1087 | 1115 | } |
| 1088 | 1116 | |
| 1089 | - src1 = gen_ea(s, insn, opsize, 0, op ? &addr: NULL); | |
| 1117 | + SRC_EA(src1, opsize, 0, op ? &addr: NULL); | |
| 1090 | 1118 | |
| 1091 | 1119 | gen_flush_flags(s); |
| 1092 | 1120 | tmp = gen_new_qreg(QMODE_I32); |
| ... | ... | @@ -1116,7 +1144,7 @@ DISAS_INSN(bitop_im) |
| 1116 | 1144 | break; |
| 1117 | 1145 | } |
| 1118 | 1146 | if (op) |
| 1119 | - gen_ea(s, insn, opsize, dest, &addr); | |
| 1147 | + DEST_EA(insn, opsize, dest, &addr); | |
| 1120 | 1148 | } |
| 1121 | 1149 | |
| 1122 | 1150 | DISAS_INSN(arith_im) |
| ... | ... | @@ -1128,7 +1156,7 @@ DISAS_INSN(arith_im) |
| 1128 | 1156 | int addr; |
| 1129 | 1157 | |
| 1130 | 1158 | op = (insn >> 9) & 7; |
| 1131 | - src1 = gen_ea(s, insn, OS_LONG, 0, (op == 6) ? NULL : &addr); | |
| 1159 | + SRC_EA(src1, OS_LONG, 0, (op == 6) ? NULL : &addr); | |
| 1132 | 1160 | src2 = gen_im32(read_im32(s)); |
| 1133 | 1161 | dest = gen_new_qreg(QMODE_I32); |
| 1134 | 1162 | switch (op) { |
| ... | ... | @@ -1168,7 +1196,7 @@ DISAS_INSN(arith_im) |
| 1168 | 1196 | abort(); |
| 1169 | 1197 | } |
| 1170 | 1198 | if (op != 6) { |
| 1171 | - gen_ea(s, insn, OS_LONG, dest, &addr); | |
| 1199 | + DEST_EA(insn, OS_LONG, dest, &addr); | |
| 1172 | 1200 | } |
| 1173 | 1201 | } |
| 1174 | 1202 | |
| ... | ... | @@ -1200,7 +1228,7 @@ DISAS_INSN(move) |
| 1200 | 1228 | default: |
| 1201 | 1229 | abort(); |
| 1202 | 1230 | } |
| 1203 | - src = gen_ea(s, insn, opsize, -1, NULL); | |
| 1231 | + SRC_EA(src, opsize, -1, NULL); | |
| 1204 | 1232 | op = (insn >> 6) & 7; |
| 1205 | 1233 | if (op == 1) { |
| 1206 | 1234 | /* movea */ |
| ... | ... | @@ -1211,7 +1239,7 @@ DISAS_INSN(move) |
| 1211 | 1239 | /* normal move */ |
| 1212 | 1240 | uint16_t dest_ea; |
| 1213 | 1241 | dest_ea = ((insn >> 9) & 7) | (op << 3); |
| 1214 | - gen_ea(s, dest_ea, opsize, src, NULL); | |
| 1242 | + DEST_EA(dest_ea, opsize, src, NULL); | |
| 1215 | 1243 | /* This will be correct because loads sign extend. */ |
| 1216 | 1244 | gen_logic_cc(s, src); |
| 1217 | 1245 | } |
| ... | ... | @@ -1247,6 +1275,10 @@ DISAS_INSN(lea) |
| 1247 | 1275 | |
| 1248 | 1276 | reg = AREG(insn, 9); |
| 1249 | 1277 | tmp = gen_lea(s, insn, OS_LONG); |
| 1278 | + if (tmp == -1) { | |
| 1279 | + gen_addr_fault(s); | |
| 1280 | + return; | |
| 1281 | + } | |
| 1250 | 1282 | gen_op_mov32(reg, tmp); |
| 1251 | 1283 | } |
| 1252 | 1284 | |
| ... | ... | @@ -1267,7 +1299,7 @@ DISAS_INSN(clr) |
| 1267 | 1299 | default: |
| 1268 | 1300 | abort(); |
| 1269 | 1301 | } |
| 1270 | - gen_ea (s, insn, opsize, gen_im32(0), NULL); | |
| 1302 | + DEST_EA(insn, opsize, gen_im32(0), NULL); | |
| 1271 | 1303 | gen_logic_cc(s, gen_im32(0)); |
| 1272 | 1304 | } |
| 1273 | 1305 | |
| ... | ... | @@ -1384,6 +1416,10 @@ DISAS_INSN(pea) |
| 1384 | 1416 | int tmp; |
| 1385 | 1417 | |
| 1386 | 1418 | tmp = gen_lea(s, insn, OS_LONG); |
| 1419 | + if (tmp == -1) { | |
| 1420 | + gen_addr_fault(s); | |
| 1421 | + return; | |
| 1422 | + } | |
| 1387 | 1423 | gen_push(s, tmp); |
| 1388 | 1424 | } |
| 1389 | 1425 | |
| ... | ... | @@ -1425,7 +1461,7 @@ DISAS_INSN(tst) |
| 1425 | 1461 | default: |
| 1426 | 1462 | abort(); |
| 1427 | 1463 | } |
| 1428 | - tmp = gen_ea(s, insn, opsize, -1, NULL); | |
| 1464 | + SRC_EA(tmp, opsize, -1, NULL); | |
| 1429 | 1465 | gen_logic_cc(s, tmp); |
| 1430 | 1466 | } |
| 1431 | 1467 | |
| ... | ... | @@ -1447,10 +1483,10 @@ DISAS_INSN(tas) |
| 1447 | 1483 | int addr; |
| 1448 | 1484 | |
| 1449 | 1485 | dest = gen_new_qreg(QMODE_I32); |
| 1450 | - src1 = gen_ea(s, insn, OS_BYTE, -1, &addr); | |
| 1486 | + SRC_EA(src1, OS_BYTE, -1, &addr); | |
| 1451 | 1487 | gen_logic_cc(s, src1); |
| 1452 | 1488 | gen_op_or32(dest, src1, gen_im32(0x80)); |
| 1453 | - gen_ea(s, insn, OS_BYTE, dest, &addr); | |
| 1489 | + DEST_EA(insn, OS_BYTE, dest, &addr); | |
| 1454 | 1490 | } |
| 1455 | 1491 | |
| 1456 | 1492 | DISAS_INSN(mull) |
| ... | ... | @@ -1469,7 +1505,7 @@ DISAS_INSN(mull) |
| 1469 | 1505 | return; |
| 1470 | 1506 | } |
| 1471 | 1507 | reg = DREG(ext, 12); |
| 1472 | - src1 = gen_ea(s, insn, OS_LONG, 0, NULL); | |
| 1508 | + SRC_EA(src1, OS_LONG, 0, NULL); | |
| 1473 | 1509 | dest = gen_new_qreg(QMODE_I32); |
| 1474 | 1510 | gen_op_mul32(dest, src1, reg); |
| 1475 | 1511 | gen_op_mov32(reg, dest); |
| ... | ... | @@ -1528,6 +1564,10 @@ DISAS_INSN(jump) |
| 1528 | 1564 | /* Load the target address first to ensure correct exception |
| 1529 | 1565 | behavior. */ |
| 1530 | 1566 | tmp = gen_lea(s, insn, OS_LONG); |
| 1567 | + if (tmp == -1) { | |
| 1568 | + gen_addr_fault(s); | |
| 1569 | + return; | |
| 1570 | + } | |
| 1531 | 1571 | if ((insn & 0x40) == 0) { |
| 1532 | 1572 | /* jsr */ |
| 1533 | 1573 | gen_push(s, gen_im32(s->pc)); |
| ... | ... | @@ -1543,7 +1583,7 @@ DISAS_INSN(addsubq) |
| 1543 | 1583 | int val; |
| 1544 | 1584 | int addr; |
| 1545 | 1585 | |
| 1546 | - src1 = gen_ea(s, insn, OS_LONG, 0, &addr); | |
| 1586 | + SRC_EA(src1, OS_LONG, 0, &addr); | |
| 1547 | 1587 | val = (insn >> 9) & 7; |
| 1548 | 1588 | if (val == 0) |
| 1549 | 1589 | val = 8; |
| ... | ... | @@ -1570,7 +1610,7 @@ DISAS_INSN(addsubq) |
| 1570 | 1610 | } |
| 1571 | 1611 | gen_op_update_cc_add(dest, src2); |
| 1572 | 1612 | } |
| 1573 | - gen_ea(s, insn, OS_LONG, dest, &addr); | |
| 1613 | + DEST_EA(insn, OS_LONG, dest, &addr); | |
| 1574 | 1614 | } |
| 1575 | 1615 | |
| 1576 | 1616 | DISAS_INSN(tpf) |
| ... | ... | @@ -1642,7 +1682,7 @@ DISAS_INSN(mvzs) |
| 1642 | 1682 | opsize = OS_WORD; |
| 1643 | 1683 | else |
| 1644 | 1684 | opsize = OS_BYTE; |
| 1645 | - src = gen_ea(s, insn, opsize, (insn & 0x80) ? 0 : -1, NULL); | |
| 1685 | + SRC_EA(src, opsize, (insn & 0x80) ? 0 : -1, NULL); | |
| 1646 | 1686 | reg = DREG(insn, 9); |
| 1647 | 1687 | gen_op_mov32(reg, src); |
| 1648 | 1688 | gen_logic_cc(s, src); |
| ... | ... | @@ -1658,11 +1698,11 @@ DISAS_INSN(or) |
| 1658 | 1698 | reg = DREG(insn, 9); |
| 1659 | 1699 | dest = gen_new_qreg(QMODE_I32); |
| 1660 | 1700 | if (insn & 0x100) { |
| 1661 | - src = gen_ea(s, insn, OS_LONG, 0, &addr); | |
| 1701 | + SRC_EA(src, OS_LONG, 0, &addr); | |
| 1662 | 1702 | gen_op_or32(dest, src, reg); |
| 1663 | - gen_ea(s, insn, OS_LONG, dest, &addr); | |
| 1703 | + DEST_EA(insn, OS_LONG, dest, &addr); | |
| 1664 | 1704 | } else { |
| 1665 | - src = gen_ea(s, insn, OS_LONG, 0, NULL); | |
| 1705 | + SRC_EA(src, OS_LONG, 0, NULL); | |
| 1666 | 1706 | gen_op_or32(dest, src, reg); |
| 1667 | 1707 | gen_op_mov32(reg, dest); |
| 1668 | 1708 | } |
| ... | ... | @@ -1674,7 +1714,7 @@ DISAS_INSN(suba) |
| 1674 | 1714 | int src; |
| 1675 | 1715 | int reg; |
| 1676 | 1716 | |
| 1677 | - src = gen_ea(s, insn, OS_LONG, 0, NULL); | |
| 1717 | + SRC_EA(src, OS_LONG, 0, NULL); | |
| 1678 | 1718 | reg = AREG(insn, 9); |
| 1679 | 1719 | gen_op_sub32(reg, reg, src); |
| 1680 | 1720 | } |
| ... | ... | @@ -1714,7 +1754,7 @@ DISAS_INSN(mov3q) |
| 1714 | 1754 | val = -1; |
| 1715 | 1755 | src = gen_im32(val); |
| 1716 | 1756 | gen_logic_cc(s, src); |
| 1717 | - gen_ea(s, insn, OS_LONG, src, NULL); | |
| 1757 | + DEST_EA(insn, OS_LONG, src, NULL); | |
| 1718 | 1758 | } |
| 1719 | 1759 | |
| 1720 | 1760 | DISAS_INSN(cmp) |
| ... | ... | @@ -1742,7 +1782,7 @@ DISAS_INSN(cmp) |
| 1742 | 1782 | default: |
| 1743 | 1783 | abort(); |
| 1744 | 1784 | } |
| 1745 | - src = gen_ea(s, insn, opsize, -1, NULL); | |
| 1785 | + SRC_EA(src, opsize, -1, NULL); | |
| 1746 | 1786 | reg = DREG(insn, 9); |
| 1747 | 1787 | dest = gen_new_qreg(QMODE_I32); |
| 1748 | 1788 | gen_op_sub32(dest, reg, src); |
| ... | ... | @@ -1761,7 +1801,7 @@ DISAS_INSN(cmpa) |
| 1761 | 1801 | } else { |
| 1762 | 1802 | opsize = OS_WORD; |
| 1763 | 1803 | } |
| 1764 | - src = gen_ea(s, insn, opsize, -1, NULL); | |
| 1804 | + SRC_EA(src, opsize, -1, NULL); | |
| 1765 | 1805 | reg = AREG(insn, 9); |
| 1766 | 1806 | dest = gen_new_qreg(QMODE_I32); |
| 1767 | 1807 | gen_op_sub32(dest, reg, src); |
| ... | ... | @@ -1776,12 +1816,12 @@ DISAS_INSN(eor) |
| 1776 | 1816 | int dest; |
| 1777 | 1817 | int addr; |
| 1778 | 1818 | |
| 1779 | - src = gen_ea(s, insn, OS_LONG, 0, &addr); | |
| 1819 | + SRC_EA(src, OS_LONG, 0, &addr); | |
| 1780 | 1820 | reg = DREG(insn, 9); |
| 1781 | 1821 | dest = gen_new_qreg(QMODE_I32); |
| 1782 | 1822 | gen_op_xor32(dest, src, reg); |
| 1783 | 1823 | gen_logic_cc(s, dest); |
| 1784 | - gen_ea(s, insn, OS_LONG, dest, &addr); | |
| 1824 | + DEST_EA(insn, OS_LONG, dest, &addr); | |
| 1785 | 1825 | } |
| 1786 | 1826 | |
| 1787 | 1827 | DISAS_INSN(and) |
| ... | ... | @@ -1794,11 +1834,11 @@ DISAS_INSN(and) |
| 1794 | 1834 | reg = DREG(insn, 9); |
| 1795 | 1835 | dest = gen_new_qreg(QMODE_I32); |
| 1796 | 1836 | if (insn & 0x100) { |
| 1797 | - src = gen_ea(s, insn, OS_LONG, 0, &addr); | |
| 1837 | + SRC_EA(src, OS_LONG, 0, &addr); | |
| 1798 | 1838 | gen_op_and32(dest, src, reg); |
| 1799 | - gen_ea(s, insn, OS_LONG, dest, &addr); | |
| 1839 | + DEST_EA(insn, OS_LONG, dest, &addr); | |
| 1800 | 1840 | } else { |
| 1801 | - src = gen_ea(s, insn, OS_LONG, 0, NULL); | |
| 1841 | + SRC_EA(src, OS_LONG, 0, NULL); | |
| 1802 | 1842 | gen_op_and32(dest, src, reg); |
| 1803 | 1843 | gen_op_mov32(reg, dest); |
| 1804 | 1844 | } |
| ... | ... | @@ -1810,7 +1850,7 @@ DISAS_INSN(adda) |
| 1810 | 1850 | int src; |
| 1811 | 1851 | int reg; |
| 1812 | 1852 | |
| 1813 | - src = gen_ea(s, insn, OS_LONG, 0, NULL); | |
| 1853 | + SRC_EA(src, OS_LONG, 0, NULL); | |
| 1814 | 1854 | reg = AREG(insn, 9); |
| 1815 | 1855 | gen_op_add32(reg, reg, src); |
| 1816 | 1856 | } |
| ... | ... | @@ -2114,7 +2154,7 @@ DISAS_INSN(fpu) |
| 2114 | 2154 | default: |
| 2115 | 2155 | goto undef; |
| 2116 | 2156 | } |
| 2117 | - gen_ea(s, insn, opsize, res, NULL); | |
| 2157 | + DEST_EA(insn, opsize, res, NULL); | |
| 2118 | 2158 | return; |
| 2119 | 2159 | case 4: /* fmove to control register. */ |
| 2120 | 2160 | switch ((ext >> 10) & 7) { |
| ... | ... | @@ -2141,7 +2181,7 @@ DISAS_INSN(fpu) |
| 2141 | 2181 | (ext >> 10) & 7); |
| 2142 | 2182 | goto undef; |
| 2143 | 2183 | } |
| 2144 | - gen_ea(s, insn, OS_LONG, res, NULL); | |
| 2184 | + DEST_EA(insn, OS_LONG, res, NULL); | |
| 2145 | 2185 | break; |
| 2146 | 2186 | case 6: /* fmovem */ |
| 2147 | 2187 | case 7: |
| ... | ... | @@ -2151,6 +2191,10 @@ DISAS_INSN(fpu) |
| 2151 | 2191 | if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0) |
| 2152 | 2192 | goto undef; |
| 2153 | 2193 | src = gen_lea(s, insn, OS_LONG); |
| 2194 | + if (src == -1) { | |
| 2195 | + gen_addr_fault(s); | |
| 2196 | + return; | |
| 2197 | + } | |
| 2154 | 2198 | addr = gen_new_qreg(QMODE_I32); |
| 2155 | 2199 | gen_op_mov32(addr, src); |
| 2156 | 2200 | mask = 0x80; |
| ... | ... | @@ -2186,7 +2230,7 @@ DISAS_INSN(fpu) |
| 2186 | 2230 | default: |
| 2187 | 2231 | goto undef; |
| 2188 | 2232 | } |
| 2189 | - tmp = gen_ea(s, insn, opsize, -1, NULL); | |
| 2233 | + SRC_EA(tmp, opsize, -1, NULL); | |
| 2190 | 2234 | if (opsize == OS_DOUBLE) { |
| 2191 | 2235 | src = tmp; |
| 2192 | 2236 | } else { |
| ... | ... | @@ -2846,6 +2890,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, |
| 2846 | 2890 | gen_opc_instr_start[lj] = 1; |
| 2847 | 2891 | } |
| 2848 | 2892 | last_cc_op = dc->cc_op; |
| 2893 | + dc->insn_pc = dc->pc; | |
| 2849 | 2894 | disas_m68k_insn(env, dc); |
| 2850 | 2895 | } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && |
| 2851 | 2896 | !env->singlestep_enabled && | ... | ... |