trunk/src/emu/cpu/arcompact/arcompact_execute.c
| r242533 | r242534 | |
| 1266 | 1266 | { |
| 1267 | 1267 | BR_REGREG_SETUP |
| 1268 | 1268 | |
| 1269 | | // BRLO |
| 1269 | // BRLO (unsigned operation) |
| 1270 | 1270 | if (b < c) |
| 1271 | 1271 | { |
| 1272 | 1272 | BR_TAKEJUMP |
| r242533 | r242534 | |
| 1280 | 1280 | { |
| 1281 | 1281 | BR_REGREG_SETUP |
| 1282 | 1282 | |
| 1283 | | // BRHS |
| 1283 | // BRHS (unsigned operation) |
| 1284 | 1284 | if (b >= c) |
| 1285 | 1285 | { |
| 1286 | 1286 | BR_TAKEJUMP |
| r242533 | r242534 | |
| 1300 | 1300 | return m_pc + (size>>0); |
| 1301 | 1301 | } |
| 1302 | 1302 | |
| 1303 | #define BR_REGIMM_SETUP \ |
| 1304 | int size = 4; \ |
| 1305 | GET_01_01_01_BRANCH_ADDR \ |
| 1306 | COMMON32_GET_u6; \ |
| 1307 | COMMON32_GET_breg; \ |
| 1308 | int n = (op & 0x00000020) >> 5; \ |
| 1309 | UINT32 b,c; \ |
| 1310 | c = u; \ |
| 1311 | /* comparing a LIMM to an immediate is pointless, is it a valid encoding? */ \ |
| 1312 | if ((breg != LIMM_REG)) \ |
| 1313 | { \ |
| 1314 | b = m_regs[breg]; \ |
| 1315 | } \ |
| 1316 | else \ |
| 1317 | { \ |
| 1318 | UINT32 limm; \ |
| 1319 | GET_LIMM_32; \ |
| 1320 | size = 8; \ |
| 1321 | b = limm; \ |
| 1322 | } \ |
| 1323 | |
| 1324 | |
| 1303 | 1325 | // register -immediate cases |
| 1304 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle01_01_01_00(OPS_32) { return arcompact_01_01_01_helper(PARAMS, "BREQ"); } |
| 1305 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle01_01_01_01(OPS_32) { return arcompact_01_01_01_helper(PARAMS, "BRNE"); } |
| 1306 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle01_01_01_02(OPS_32) { return arcompact_01_01_01_helper(PARAMS, "BRLT"); } |
| 1307 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle01_01_01_03(OPS_32) { return arcompact_01_01_01_helper(PARAMS, "BRGE"); } |
| 1308 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle01_01_01_04(OPS_32) { return arcompact_01_01_01_helper(PARAMS, "BRLO"); } |
| 1326 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle01_01_01_00(OPS_32) // BREQ reg-imm |
| 1327 | { |
| 1328 | BR_REGIMM_SETUP |
| 1329 | |
| 1330 | // BREQ |
| 1331 | if (b == c) |
| 1332 | { |
| 1333 | BR_TAKEJUMP |
| 1334 | } |
| 1335 | |
| 1336 | return m_pc + (size>>0); |
| 1337 | } |
| 1309 | 1338 | |
| 1310 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle01_01_01_05(OPS_32) // register - immediate BRHS |
| 1339 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle01_01_01_01(OPS_32) // BRNE reg-imm |
| 1311 | 1340 | { |
| 1312 | | int size = 4; |
| 1341 | BR_REGIMM_SETUP |
| 1342 | |
| 1343 | // BRNE |
| 1344 | if (b != c) |
| 1345 | { |
| 1346 | BR_TAKEJUMP |
| 1347 | } |
| 1348 | |
| 1349 | return m_pc + (size>>0); |
| 1350 | } |
| 1313 | 1351 | |
| 1314 | | GET_01_01_01_BRANCH_ADDR |
| 1315 | | COMMON32_GET_u6; |
| 1316 | | COMMON32_GET_breg; |
| 1317 | 1352 | |
| 1318 | | int n = (op & 0x00000020) >> 5; |
| 1319 | 1353 | |
| 1320 | | UINT32 b,c; |
| 1321 | | |
| 1322 | | c = u; |
| 1323 | | |
| 1324 | | // comparing a LIMM to an immediate is pointless, is it a valid encoding? |
| 1325 | | if ((breg != LIMM_REG)) |
| 1354 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle01_01_01_02(OPS_32) // BRLT reg-imm |
| 1355 | { |
| 1356 | BR_REGIMM_SETUP |
| 1357 | |
| 1358 | // BRLT (signed operation) |
| 1359 | if ((INT32)b < (INT32)c) |
| 1326 | 1360 | { |
| 1327 | | b = m_regs[breg]; |
| 1361 | BR_TAKEJUMP |
| 1328 | 1362 | } |
| 1329 | | else |
| 1330 | | { |
| 1331 | | UINT32 limm; |
| 1332 | | GET_LIMM_32; |
| 1333 | | size = 8; |
| 1334 | | b = limm; |
| 1335 | | } |
| 1363 | |
| 1364 | return m_pc + (size>>0); |
| 1336 | 1365 | |
| 1337 | | // BRHS |
| 1338 | | if (b >= c) // check |
| 1366 | } |
| 1367 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle01_01_01_03(OPS_32) { return arcompact_01_01_01_helper(PARAMS, "BRGE"); } |
| 1368 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle01_01_01_04(OPS_32) { return arcompact_01_01_01_helper(PARAMS, "BRLO"); } |
| 1369 | |
| 1370 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle01_01_01_05(OPS_32) // register - immediate BRHS |
| 1371 | { |
| 1372 | BR_REGIMM_SETUP |
| 1373 | |
| 1374 | // BRHS (unsigned operation) |
| 1375 | if (b >= c) |
| 1339 | 1376 | { |
| 1340 | 1377 | BR_TAKEJUMP |
| 1341 | 1378 | } |
| r242533 | r242534 | |
| 1350 | 1387 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle02(OPS_32) |
| 1351 | 1388 | { |
| 1352 | 1389 | int size = 4; |
| 1390 | UINT32 limm = 0; |
| 1391 | |
| 1392 | int S = (op & 0x00008000) >> 15;// op &= ~0x00008000; |
| 1393 | int s = (op & 0x00ff0000) >> 16;// op &= ~0x00ff0000; |
| 1394 | if (S) s = -0x100 + s; |
| 1395 | |
| 1353 | 1396 | COMMON32_GET_breg; |
| 1397 | COMMON32_GET_areg |
| 1354 | 1398 | |
| 1355 | | //UINT32 limm = 0; |
| 1399 | int X = (op & 0x00000040) >> 6; //op &= ~0x00000040; |
| 1400 | int Z = (op & 0x00000180) >> 7; //op &= ~0x00000180; |
| 1401 | int a = (op & 0x00000600) >> 9; //op &= ~0x00000600; |
| 1402 | // int D = (op & 0x00000800) >> 11;// op &= ~0x00000800; // we don't use the data cache currently |
| 1403 | |
| 1404 | UINT32 address = m_regs[breg]; |
| 1405 | |
| 1356 | 1406 | if (breg == LIMM_REG) |
| 1357 | 1407 | { |
| 1358 | | //GET_LIMM_32; |
| 1408 | GET_LIMM_32; |
| 1359 | 1409 | size = 8; |
| 1410 | |
| 1411 | address = limm; |
| 1360 | 1412 | } |
| 1361 | 1413 | |
| 1362 | | arcompact_log("unimplemented LD %08x", op); |
| 1414 | // address manipulation |
| 1415 | if ((a == 0) || (a == 1)) |
| 1416 | { |
| 1417 | address = address + s; |
| 1418 | } |
| 1419 | else if (a == 2) |
| 1420 | { |
| 1421 | //address = address; |
| 1422 | } |
| 1423 | else if (a == 3) |
| 1424 | { |
| 1425 | if (Z == 0) |
| 1426 | address = address + (s << 2); |
| 1427 | else if (Z==2) |
| 1428 | address = address + (s << 1); |
| 1429 | else // Z == 1 and Z == 3 are invalid here |
| 1430 | arcompact_fatal("illegal LD %08x (data size %d mode %d)", op, Z, a); |
| 1431 | } |
| 1432 | |
| 1433 | UINT32 readdata = 0; |
| 1434 | |
| 1435 | // read data |
| 1436 | if (Z == 0) |
| 1437 | { |
| 1438 | readdata = READ32(address >> 2); |
| 1439 | |
| 1440 | if (X) // sign extend is not supported for long reads |
| 1441 | arcompact_fatal("illegal LD %08x (data size %d mode %d with X)", op, Z, a); |
| 1442 | |
| 1443 | } |
| 1444 | else if (Z == 1) |
| 1445 | { |
| 1446 | readdata = READ8(address >> 0); |
| 1447 | |
| 1448 | if (X) // todo |
| 1449 | arcompact_fatal("illegal LD %08x (data size %d mode %d with X)", op, Z, a); |
| 1450 | |
| 1451 | } |
| 1452 | else if (Z == 2) |
| 1453 | { |
| 1454 | readdata = READ16(address >> 1); |
| 1455 | |
| 1456 | if (X) // todo |
| 1457 | arcompact_fatal("illegal LD %08x (data size %d mode %d with X)", op, Z, a); |
| 1458 | |
| 1459 | } |
| 1460 | else if (Z == 3) |
| 1461 | { // Z == 3 is always illegal |
| 1462 | arcompact_fatal("illegal LD %08x (data size %d mode %d)", op, Z, a); |
| 1463 | } |
| 1464 | |
| 1465 | m_regs[areg] = readdata; |
| 1466 | |
| 1467 | // writeback / increment |
| 1468 | if ((a == 1) || (a == 2)) |
| 1469 | { |
| 1470 | if (breg==limm) |
| 1471 | arcompact_fatal("illegal LD %08x (data size %d mode %d)", op, Z, a); // using the LIMM as the base register and an increment mode is illegal |
| 1472 | |
| 1473 | m_regs[breg] = m_regs[breg] + s; |
| 1474 | } |
| 1475 | |
| 1363 | 1476 | return m_pc + (size>>0); |
| 1364 | 1477 | |
| 1365 | 1478 | } |
| r242533 | r242534 | |
| 1371 | 1484 | int got_limm = 0; |
| 1372 | 1485 | int S = (op & 0x00008000) >> 15; |
| 1373 | 1486 | int s = (op & 0x00ff0000) >> 16; |
| 1487 | if (S) s = -0x100 + s; |
| 1374 | 1488 | |
| 1375 | 1489 | COMMON32_GET_breg; |
| 1376 | 1490 | COMMON32_GET_creg; |
| 1377 | | |
| 1378 | | if (S) s = -0x100 + s; |
| 1379 | | |
| 1491 | |
| 1380 | 1492 | // int R = (op & 0x00000001) >> 0; // bit 0 is reserved |
| 1381 | 1493 | int Z = (op & 0x00000006) >> 1; |
| 1382 | 1494 | int a = (op & 0x00000018) >> 3; |
| r242533 | r242534 | |
| 2230 | 2342 | { |
| 2231 | 2343 | } |
| 2232 | 2344 | |
| 2233 | | arcompact_log("unimplemented LD %08x", op); |
| 2345 | arcompact_log("unimplemented LD %08x (type 04_3x)", op); |
| 2234 | 2346 | return m_pc + (size>>0); |
| 2235 | 2347 | } |
| 2236 | 2348 | |
| r242533 | r242534 | |
| 2557 | 2669 | |
| 2558 | 2670 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle0f_0x_helper(OPS_16, const char* optext, int nodst) |
| 2559 | 2671 | { |
| 2560 | | arcompact_log("unimplemented %s %04x", optext, op); |
| 2672 | arcompact_log("unimplemented %s %04x (0xf_0x group)", optext, op); |
| 2561 | 2673 | return m_pc + (2 >> 0); |
| 2562 | 2674 | } |
| 2563 | 2675 | |
| r242533 | r242534 | |
| 2570 | 2682 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle0f_0c(OPS_16) { return arcompact_handle0f_0x_helper(PARAMS, "MUL64_S",2); } // actual destination is special multiply registers |
| 2571 | 2683 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle0f_0d(OPS_16) { return arcompact_handle0f_0x_helper(PARAMS, "SEXB_S",0); } |
| 2572 | 2684 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle0f_0e(OPS_16) { return arcompact_handle0f_0x_helper(PARAMS, "SEXW_S",0); } |
| 2573 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle0f_0f(OPS_16) { return arcompact_handle0f_0x_helper(PARAMS, "EXTB_S",0); } |
| 2685 | |
| 2686 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle0f_0f(OPS_16) // EXTB_S |
| 2687 | { |
| 2688 | int breg, creg; |
| 2689 | |
| 2690 | COMMON16_GET_breg; |
| 2691 | COMMON16_GET_creg; |
| 2692 | |
| 2693 | REG_16BIT_RANGE(breg); |
| 2694 | REG_16BIT_RANGE(creg); |
| 2695 | |
| 2696 | m_regs[breg] = m_regs[creg] & 0xff; |
| 2697 | |
| 2698 | return m_pc + (2 >> 0); |
| 2699 | |
| 2700 | } |
| 2701 | |
| 2574 | 2702 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle0f_10(OPS_16) { return arcompact_handle0f_0x_helper(PARAMS, "EXTW_S",0); } |
| 2575 | 2703 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle0f_11(OPS_16) { return arcompact_handle0f_0x_helper(PARAMS, "ABS_S",0); } |
| 2576 | 2704 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle0f_12(OPS_16) { return arcompact_handle0f_0x_helper(PARAMS, "NOT_S",0); } |
| r242533 | r242534 | |
| 2669 | 2797 | |
| 2670 | 2798 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle_l7_0x_helper(OPS_16, const char* optext) |
| 2671 | 2799 | { |
| 2672 | | arcompact_log("unimplemented %s %04x", optext, op); |
| 2800 | arcompact_log("unimplemented %s %04x (l7_0x group)", optext, op); |
| 2673 | 2801 | return m_pc + (2 >> 0); |
| 2674 | 2802 | } |
| 2675 | 2803 | |
| 2676 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle17_00(OPS_16) |
| 2804 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle17_00(OPS_16) // ASL_S b, b, u5 |
| 2677 | 2805 | { |
| 2678 | | return arcompact_handle_l7_0x_helper(PARAMS, "ASL_S"); |
| 2806 | int breg, u; |
| 2807 | |
| 2808 | COMMON16_GET_breg; |
| 2809 | COMMON16_GET_u5; |
| 2810 | |
| 2811 | REG_16BIT_RANGE(breg); |
| 2812 | |
| 2813 | // only bottom 5 bits are used if ASL operations, we only have 5 bits anyway here |
| 2814 | m_regs[breg] = m_regs[breg] << (u&0x1f); |
| 2815 | |
| 2816 | return m_pc + (2 >> 0); |
| 2817 | |
| 2679 | 2818 | } |
| 2680 | 2819 | |
| 2681 | 2820 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle17_01(OPS_16) |
| r242533 | r242534 | |
| 2683 | 2822 | return arcompact_handle_l7_0x_helper(PARAMS, "LSR_S"); |
| 2684 | 2823 | } |
| 2685 | 2824 | |
| 2686 | | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle17_02(OPS_16) |
| 2825 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle17_02(OPS_16) // ASR_S b,b,u5 |
| 2687 | 2826 | { |
| 2688 | | return arcompact_handle_l7_0x_helper(PARAMS, "ASR_S"); |
| 2827 | int breg, u; |
| 2828 | |
| 2829 | COMMON16_GET_breg; |
| 2830 | COMMON16_GET_u5; |
| 2831 | |
| 2832 | REG_16BIT_RANGE(breg); |
| 2833 | |
| 2834 | // only bottom 5 bits are used if ASR operations, we only have 5 bits anyway here |
| 2835 | INT32 temp = (INT32)m_regs[breg]; // treat it as a signed value, so sign extension occurs during shift |
| 2836 | |
| 2837 | m_regs[breg] = temp >> (u&0x1f); |
| 2838 | |
| 2839 | return m_pc + (2 >> 0); |
| 2689 | 2840 | } |
| 2690 | 2841 | |
| 2691 | 2842 | ARCOMPACT_RETTYPE arcompact_device::arcompact_handle17_03(OPS_16) |