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