comparison 68kinst.c @ 1462:d276ec2fff11

More instruction decoder fixes
author Michael Pavone <pavone@retrodev.com>
date Thu, 07 Sep 2017 00:42:28 -0700
parents b81428ef0396
children 63f309cfbef9
comparison
equal deleted inserted replaced
1461:aa945f1bdd71 1462:d276ec2fff11
267 } 267 }
268 268
269 uint8_t m68k_valid_immed_limited_dst(m68k_op_info *dst) 269 uint8_t m68k_valid_immed_limited_dst(m68k_op_info *dst)
270 { 270 {
271 if (dst->addr_mode == MODE_AREG || dst->addr_mode > MODE_ABSOLUTE) { 271 if (dst->addr_mode == MODE_AREG || dst->addr_mode > MODE_ABSOLUTE) {
272 return 0;
273 }
274 return 1;
275 }
276
277 uint8_t m68k_valid_full_arith_dst(m68k_op_info *dst)
278 {
279 if (dst->addr_mode < MODE_AREG_INDIRECT || dst->addr_mode > MODE_ABSOLUTE) {
272 return 0; 280 return 0;
273 } 281 }
274 return 1; 282 return 1;
275 } 283 }
276 284
653 decoded->op = M68K_MOVE; 661 decoded->op = M68K_MOVE;
654 decoded->extra.size = optype == MOVE_BYTE ? OPSIZE_BYTE : (optype == MOVE_WORD ? OPSIZE_WORD : OPSIZE_LONG); 662 decoded->extra.size = optype == MOVE_BYTE ? OPSIZE_BYTE : (optype == MOVE_WORD ? OPSIZE_WORD : OPSIZE_LONG);
655 opmode = (*istream >> 6) & 0x7; 663 opmode = (*istream >> 6) & 0x7;
656 reg = m68k_reg_quick_field(*istream); 664 reg = m68k_reg_quick_field(*istream);
657 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 665 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
658 if (!istream) { 666 if (!istream || (decoded->src.addr_mode == MODE_AREG && optype == MOVE_BYTE)) {
659 decoded->op = M68K_INVALID; 667 decoded->op = M68K_INVALID;
660 break; 668 break;
661 } 669 }
662 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst)); 670 istream = m68k_decode_op_ex(istream, opmode, reg, decoded->extra.size, &(decoded->dst));
663 if (!istream || decoded->dst.addr_mode > MODE_ABSOLUTE || (decoded->dst.addr_mode == MODE_AREG && optype == MOVE_BYTE)) { 671 if (!istream || decoded->dst.addr_mode > MODE_ABSOLUTE || (decoded->dst.addr_mode == MODE_AREG && optype == MOVE_BYTE)) {
935 decoded->op = M68K_INVALID; 943 decoded->op = M68K_INVALID;
936 break; 944 break;
937 } 945 }
938 } else { 946 } else {
939 //it would appear bit 6 needs to be set for it to be a valid instruction here 947 //it would appear bit 6 needs to be set for it to be a valid instruction here
948 if (!(*istream & 0x40)) {
949 decoded->op = M68K_INVALID;
950 break;
951 }
940 switch((*istream >> 3) & 0x7) 952 switch((*istream >> 3) & 0x7)
941 { 953 {
942 case 0: 954 case 0:
943 case 1: 955 case 1:
944 //TRAP 956 //TRAP
1070 #endif 1082 #endif
1071 } else { 1083 } else {
1072 decoded->op = M68K_SCC; 1084 decoded->op = M68K_SCC;
1073 decoded->extra.cond = (*istream >> 8) & 0xF; 1085 decoded->extra.cond = (*istream >> 8) & 0xF;
1074 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst)); 1086 istream = m68k_decode_op(istream, OPSIZE_BYTE, &(decoded->dst));
1075 if (!istream) { 1087 if (!istream || !m68k_valid_immed_limited_dst(&decoded->dst)) {
1076 decoded->op = M68K_INVALID; 1088 decoded->op = M68K_INVALID;
1077 break; 1089 break;
1078 } 1090 }
1079 } 1091 }
1080 } else { 1092 } else {
1091 decoded->op = M68K_SUB; 1103 decoded->op = M68K_SUB;
1092 } else { 1104 } else {
1093 decoded->op = M68K_ADD; 1105 decoded->op = M68K_ADD;
1094 } 1106 }
1095 istream = m68k_decode_op(istream, size, &(decoded->dst)); 1107 istream = m68k_decode_op(istream, size, &(decoded->dst));
1096 if (!istream) { 1108 if (!istream || decoded->dst.addr_mode > MODE_ABSOLUTE || (size == OPSIZE_BYTE && decoded->dst.addr_mode == MODE_AREG)) {
1097 decoded->op = M68K_INVALID; 1109 decoded->op = M68K_INVALID;
1098 break; 1110 break;
1099 } 1111 }
1100 } 1112 }
1101 break; 1113 break;
1220 } else { 1232 } else {
1221 decoded->extra.size = size; 1233 decoded->extra.size = size;
1222 decoded->src.addr_mode = MODE_REG; 1234 decoded->src.addr_mode = MODE_REG;
1223 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); 1235 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream);
1224 istream = m68k_decode_op(istream, size, &(decoded->dst)); 1236 istream = m68k_decode_op(istream, size, &(decoded->dst));
1225 if (!istream) { 1237 if (!istream || !m68k_valid_full_arith_dst(&decoded->dst)) {
1226 decoded->op = M68K_INVALID; 1238 decoded->op = M68K_INVALID;
1227 break; 1239 break;
1228 } 1240 }
1229 } 1241 }
1230 } else { 1242 } else {
1248 decoded->extra.size = size; 1260 decoded->extra.size = size;
1249 decoded->dst.addr_mode = MODE_REG; 1261 decoded->dst.addr_mode = MODE_REG;
1250 } 1262 }
1251 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1263 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream);
1252 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 1264 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
1253 if (!istream) { 1265 if (!istream || (decoded->src.addr_mode == MODE_AREG && decoded->extra.size == OPSIZE_BYTE)) {
1254 decoded->op = M68K_INVALID; 1266 decoded->op = M68K_INVALID;
1255 break; 1267 break;
1256 } 1268 }
1257 } 1269 }
1258 break; 1270 break;
1284 if (decoded->dst.addr_mode == MODE_AREG) { 1296 if (decoded->dst.addr_mode == MODE_AREG) {
1285 //CMPM 1297 //CMPM
1286 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_AREG_POSTINC; 1298 decoded->src.addr_mode = decoded->dst.addr_mode = MODE_AREG_POSTINC;
1287 decoded->src.params.regs.pri = decoded->dst.params.regs.pri; 1299 decoded->src.params.regs.pri = decoded->dst.params.regs.pri;
1288 decoded->dst.params.regs.pri = reg; 1300 decoded->dst.params.regs.pri = reg;
1301 } else if (!m68k_valid_immed_limited_dst(&decoded->dst)){
1302 decoded->op = M68K_INVALID;
1303 break;
1289 } else { 1304 } else {
1290 //EOR 1305 //EOR
1291 decoded->op = M68K_EOR; 1306 decoded->op = M68K_EOR;
1292 decoded->src.addr_mode = MODE_REG; 1307 decoded->src.addr_mode = MODE_REG;
1293 decoded->src.params.regs.pri = reg; 1308 decoded->src.params.regs.pri = reg;
1406 } else { 1421 } else {
1407 decoded->extra.size = size; 1422 decoded->extra.size = size;
1408 decoded->src.addr_mode = MODE_REG; 1423 decoded->src.addr_mode = MODE_REG;
1409 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream); 1424 decoded->src.params.regs.pri = m68k_reg_quick_field(*istream);
1410 istream = m68k_decode_op(istream, size, &(decoded->dst)); 1425 istream = m68k_decode_op(istream, size, &(decoded->dst));
1411 if (!istream) { 1426 if (!istream || !m68k_valid_full_arith_dst(&decoded->dst)) {
1412 decoded->op = M68K_INVALID; 1427 decoded->op = M68K_INVALID;
1413 break; 1428 break;
1414 } 1429 }
1415 } 1430 }
1416 } else { 1431 } else {
1434 decoded->extra.size = size; 1449 decoded->extra.size = size;
1435 decoded->dst.addr_mode = MODE_REG; 1450 decoded->dst.addr_mode = MODE_REG;
1436 } 1451 }
1437 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream); 1452 decoded->dst.params.regs.pri = m68k_reg_quick_field(*istream);
1438 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src)); 1453 istream = m68k_decode_op(istream, decoded->extra.size, &(decoded->src));
1439 if (!istream) { 1454 if (!istream || (decoded->src.addr_mode == MODE_AREG && decoded->extra.size == OPSIZE_BYTE)) {
1440 decoded->op = M68K_INVALID; 1455 decoded->op = M68K_INVALID;
1441 break; 1456 break;
1442 } 1457 }
1443 } 1458 }
1444 break; 1459 break;
1471 decoded->op = M68K_ROL; 1486 decoded->op = M68K_ROL;
1472 break; 1487 break;
1473 } 1488 }
1474 decoded->extra.size = OPSIZE_WORD; 1489 decoded->extra.size = OPSIZE_WORD;
1475 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->dst)); 1490 istream = m68k_decode_op(istream, OPSIZE_WORD, &(decoded->dst));
1476 if (!istream) { 1491 if (!istream || !m68k_valid_full_arith_dst(&decoded->dst)) {
1477 decoded->op = M68K_INVALID; 1492 decoded->op = M68K_INVALID;
1478 break; 1493 break;
1479 } 1494 }
1480 } else if((*istream & 0xC0) != 0xC0) { 1495 } else if((*istream & 0xC0) != 0xC0) {
1481 switch(((*istream >> 2) & 0x6) | ((*istream >> 8) & 1)) 1496 switch(((*istream >> 2) & 0x6) | ((*istream >> 8) & 1))