42 #ifndef COPROC_AVAILABILITY_CHECK
43 #define COPROC_AVAILABILITY_CHECK(x) { \
44 const int cpnr = (x); \
45 int low_pc = ((size_t)ic - (size_t)cpu->cd.mips.cur_ic_page) \
46 / sizeof(struct mips_instr_call); \
47 cpu->pc &= ~((MIPS_IC_ENTRIES_PER_PAGE-1) \
48 << MIPS_INSTR_ALIGNMENT_SHIFT); \
49 cpu->pc += (low_pc << MIPS_INSTR_ALIGNMENT_SHIFT); \
50 if (!(cpu->cd.mips.coproc[0]->reg[COP0_STATUS] & \
51 ((1 << cpnr) << STATUS_CU_SHIFT)) ) { \
52 mips_cpu_exception(cpu, EXCEPTION_CPU, \
53 0, 0, cpnr, 0, 0, 0); \
60 #ifndef COP0_AVAILABILITY_CHECK_INCLUDED
61 #define COP0_AVAILABILITY_CHECK_INCLUDED
83 if (
cpu->
pc <= 0x7fffffff)
97 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
98 /
sizeof(
struct mips_instr_call);
120 fatal(
"FATAL ERROR: An internal error occured in the MIPS"
121 " dyntrans code. Please contact the author with detailed"
122 " repro steps on how to trigger this bug.\n");
134 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
135 /
sizeof(
struct mips_instr_call);
151 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
152 /
sizeof(
struct mips_instr_call);
191 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
207 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
214 X(beq_samepage_addiu)
218 reg(
ic[1].arg[1]) = (int32_t)
219 ((int32_t)
reg(
ic[1].arg[0]) + (int32_t)
ic[1].arg[2]);
221 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
ic->arg[2];
230 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
ic->arg[2];
248 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
264 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
271 X(bne_samepage_addiu)
275 reg(
ic[1].arg[1]) = (int32_t)
276 ((int32_t)
reg(
ic[1].arg[0]) + (int32_t)
ic[1].arg[2]);
278 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
ic->arg[2];
287 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
ic->arg[2];
302 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
313 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
ic->arg[2];
341 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
358 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
380 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
397 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
427 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
443 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
465 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
482 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
512 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
528 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
550 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
567 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
597 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
613 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
635 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
652 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
672 int x = (rs >= 0), low_pc;
675 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
676 /
sizeof(
struct mips_instr_call);
690 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
700 int x = (rs >= 0), low_pc;
703 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
704 /
sizeof(
struct mips_instr_call);
714 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
725 int x = (rs >= 0), low_pc;
728 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
729 /
sizeof(
struct mips_instr_call);
744 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
754 int x = (rs >= 0), low_pc;
757 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
758 /
sizeof(
struct mips_instr_call);
769 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
789 int x = (rs < 0), low_pc;
792 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
793 /
sizeof(
struct mips_instr_call);
807 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
817 int x = (rs < 0), low_pc;
820 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
821 /
sizeof(
struct mips_instr_call);
831 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
842 int x = (rs < 0), low_pc;
845 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
846 /
sizeof(
struct mips_instr_call);
861 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
871 int x = (rs < 0), low_pc;
874 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
875 /
sizeof(
struct mips_instr_call);
886 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
916 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
932 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
954 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
971 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
1019 reg(
ic[1].arg[1]) = (int32_t)
1020 ((int32_t)
reg(
ic[1].arg[0]) + (int32_t)
ic[1].arg[2]);
1046 rd += (int32_t)
ic->arg[2];
1047 reg(
ic->arg[1]) = rd;
1064 rd += (int32_t)
ic->arg[2];
1065 reg(
ic->arg[1]) = rd;
1094 old_pc &= ~0x03ffffff;
1095 cpu->
pc = old_pc | (uint32_t)
ic->arg[0];
1111 old_pc &= ~0x03ffffff;
1112 cpu->
pc = old_pc | (int32_t)
ic->arg[0];
1128 old_pc &= ~0x03ffffff;
1129 cpu->
pc = old_pc | (int32_t)
ic->arg[0];
1158 int msb =
ic->arg[2] >> 5, pos =
ic->arg[2] & 0x1f;
1159 int size = msb + 1 - pos;
1160 uint32_t rt =
reg(
ic->arg[0]);
1161 uint32_t rs =
reg(
ic->arg[1]);
1162 uint32_t mask = (-1) << pos;
1164 mask <<= (32 - pos - size);
1165 mask >>= (32 - pos - size);
1167 reg(
ic->arg[0]) = (int32_t) ((rt & ~mask) | ((rs << pos) & mask));
1180 int msbd =
ic->arg[2] >> 5, lsb =
ic->arg[2] & 0x1f;
1181 int size = msbd + 1;
1182 uint32_t rs =
reg(
ic->arg[1]);
1183 uint32_t x = (rs << (32-lsb-size)) >> (32-lsb-size);
1184 reg(
ic->arg[0]) = (int32_t) (x >> lsb);
1197 int msbd =
ic->arg[2] >> 6, lsb =
ic->arg[2] & 0x3f;
1198 int size = msbd + 1;
1199 uint64_t rs =
reg(
ic->arg[1]);
1200 uint64_t x = (rs << (uint64_t)(64-lsb-size)) >> (uint64_t)(64-lsb-size);
1201 reg(
ic->arg[0]) = x >> lsb;
1217 uint64_t x =
reg(
ic->arg[0]);
1218 x = ((x & 0x00ff00ff00ff00ffULL) << 8)
1219 | ((x & 0xff00ff00ff00ff00ULL) >> 8);
1220 reg(
ic->arg[1]) = x;
1224 uint64_t x =
reg(
ic->arg[0]);
1225 x = ((x & 0x000000000000ffffULL) << 48)
1226 | ((x & 0x00000000ffff0000ULL) << 16)
1227 | ((x & 0x0000ffff00000000ULL) >> 16)
1228 | ((x & 0xffff000000000000ULL) >> 48);
1229 reg(
ic->arg[1]) = x;
1233 uint32_t x =
reg(
ic->arg[0]);
1234 x = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8);
1235 reg(
ic->arg[1]) = (int32_t) x;
1261 int32_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]);
1265 else if (a == (int32_t)0x80000000U && b == -1)
1268 res = a / b, rem = a - b*res;
1274 uint32_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]);
1279 res = a / b, rem = a - b*res;
1285 int64_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]);
1289 else if (a == (int64_t)0x8000000000000000ULL && b == -1)
1299 uint64_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]);
1311 int32_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]);
1312 int64_t res = (int64_t)a * (int64_t)b;
1320 int32_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]);
1321 int64_t res = (int64_t)a * (int64_t)b;
1324 reg(
ic->arg[2]) = (int32_t)res;
1328 uint32_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]);
1329 uint64_t res = (uint64_t)a * (uint64_t)b;
1337 uint32_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]);
1338 uint64_t res = (uint64_t)a * (uint64_t)b;
1341 reg(
ic->arg[2]) = (int32_t)res;
1345 uint64_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]), c = 0;
1346 uint64_t hi = 0, lo = 0;
1352 for (; a; a >>= 1) {
1354 uint64_t old_lo = lo;
1360 c = (c << 1) | (b >> 63); b <<= 1;
1374 uint64_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]), c = 0;
1375 uint64_t hi = 0, lo = 0;
1376 for (; a; a >>= 1) {
1378 uint64_t old_lo = lo;
1384 c = (c << 1) | (b >> 63); b <<= 1;
1394 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1395 /
sizeof(
struct mips_instr_call);
1407 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1408 /
sizeof(
struct mips_instr_call);
1420 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1421 /
sizeof(
struct mips_instr_call);
1433 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1434 /
sizeof(
struct mips_instr_call);
1446 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1447 /
sizeof(
struct mips_instr_call);
1459 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1460 /
sizeof(
struct mips_instr_call);
1479 int32_t rs =
reg(
ic->arg[0]), rt =
reg(
ic->arg[1]);
1480 int32_t rd = rs + rt;
1482 if ((rs >= 0 && rt >= 0 && rd < 0) || (rs < 0 && rt < 0 && rd >= 0)) {
1484 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1485 /
sizeof(
struct mips_instr_call);
1491 reg(
ic->arg[2]) = rd;
1496 int64_t rs =
reg(
ic->arg[0]), rt =
reg(
ic->arg[1]);
1497 int64_t rd = rs + rt;
1499 if ((rs >= 0 && rt >= 0 && rd < 0) || (rs < 0 && rt < 0 && rd >= 0)) {
1501 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1502 /
sizeof(
struct mips_instr_call);
1508 reg(
ic->arg[2]) = rd;
1514 int32_t rs =
reg(
ic->arg[0]), rt = -
reg(
ic->arg[1]);
1515 int32_t rd = rs + rt;
1517 if ((rs >= 0 && rt >= 0 && rd < 0) || (rs < 0 && rt < 0 && rd >= 0)) {
1519 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1520 /
sizeof(
struct mips_instr_call);
1526 reg(
ic->arg[2]) = rd;
1532 int64_t rs =
reg(
ic->arg[0]), rt = -
reg(
ic->arg[1]);
1533 int64_t rd = rs + rt;
1535 if ((rs >= 0 && rt >= 0 && rd < 0) || (rs < 0 && rt < 0 && rd >= 0)) {
1537 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1538 /
sizeof(
struct mips_instr_call);
1544 reg(
ic->arg[2]) = rd;
1560 reg(
ic->arg[2]) = (int32_t)(
reg(
ic->arg[0]) << sa); }
1561 X(srl) {
reg(
ic->arg[2]) = (int32_t)((uint32_t)
reg(
ic->arg[0]) >>
ic->arg[1]); }
1563 reg(
ic->arg[2]) = (int32_t)((uint32_t)
reg(
ic->arg[0]) >> sa); }
1566 reg(
ic->arg[2]) = (int32_t)((int32_t)
reg(
ic->arg[0]) >> sa); }
1571 (uint64_t)
ic->arg[1]);}
1573 reg(
ic->arg[2]) = (uint64_t)
reg(
ic->arg[0]) >> sa; }
1576 reg(
ic->arg[2]) = (int64_t)
reg(
ic->arg[0]) >> sa; }
1578 ( (int32_t)
reg(
ic->arg[0]) * (int32_t)
reg(
ic->arg[1]) ); }
1584 uint32_t result =
reg(
ic->arg[0]);
1585 int sa =
ic->arg[1];
1587 result = (result >> sa) | (result << (32-sa));
1589 reg(
ic->arg[2]) = (int32_t) result;
1594 uint32_t result =
reg(
ic->arg[0]);
1595 int sa =
reg(
ic->arg[1]);
1597 result = (result >> sa) | (result << (32-sa));
1599 reg(
ic->arg[2]) = (int32_t) result;
1641 int64_t rs = (int32_t)
reg(
ic->arg[0]), rt = (int32_t)
reg(
ic->arg[1]);
1642 int64_t sum = rs * rt,
1649 int64_t rs = (int32_t)
reg(
ic->arg[0]), rt = (int32_t)
reg(
ic->arg[1]);
1650 int64_t sum = rs * rt,
1654 reg(
ic->arg[2]) = (int32_t)hilo;
1658 int64_t rs = (int32_t)
reg(
ic->arg[0]), rt = (int32_t)
reg(
ic->arg[1]);
1659 int64_t sum = rs * rt,
1666 int64_t rs = (uint32_t)
reg(
ic->arg[0]), rt = (uint32_t)
reg(
ic->arg[1]);
1667 int64_t sum = rs * rt,
1674 int64_t rs = (uint32_t)
reg(
ic->arg[0]), rt = (uint32_t)
reg(
ic->arg[1]);
1675 int64_t sum = rs * rt,
1679 reg(
ic->arg[2]) = (int32_t)hilo;
1683 int64_t rs = (uint32_t)
reg(
ic->arg[0]), rt = (uint32_t)
reg(
ic->arg[1]);
1684 int64_t sum = rs * rt,
1708 uint32_t x =
reg(
ic->arg[0]);
1710 for (count=0; count<32; count++) {
1711 if (x & 0x80000000UL)
1715 reg(
ic->arg[1]) = count;
1719 uint32_t x =
reg(
ic->arg[0]);
1721 for (count=0; count<32; count++) {
1722 if (!(x & 0x80000000UL))
1726 reg(
ic->arg[1]) = count;
1730 uint64_t x =
reg(
ic->arg[0]);
1732 for (count=0; count<64; count++) {
1733 if (x & 0x8000000000000000ULL)
1737 reg(
ic->arg[1]) = count;
1741 uint64_t x =
reg(
ic->arg[0]);
1743 for (count=0; count<64; count++) {
1744 if (!(x & 0x8000000000000000ULL))
1748 reg(
ic->arg[1]) = count;
1764 int32_t rs =
reg(
ic->arg[0]), imm = (int32_t)
ic->arg[2];
1765 int32_t rt = rs + imm;
1767 if ((rs >= 0 && imm >= 0 && rt < 0) || (rs < 0 && imm < 0 && rt >= 0)) {
1769 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1770 /
sizeof(
struct mips_instr_call);
1776 reg(
ic->arg[1]) = rt;
1780 reg(
ic->arg[1]) = (int32_t)
1781 ((int32_t)
reg(
ic->arg[0]) + (int32_t)
ic->arg[2]);
1785 int64_t rs =
reg(
ic->arg[0]), imm = (int32_t)
ic->arg[2];
1786 int64_t rt = rs + imm;
1788 if ((rs >= 0 && imm >= 0 && rt < 0) || (rs < 0 && imm < 0 && rt >= 0)) {
1790 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1791 /
sizeof(
struct mips_instr_call);
1797 reg(
ic->arg[1]) = rt;
1801 reg(
ic->arg[1]) =
reg(
ic->arg[0]) + (int32_t)
ic->arg[2];
1823 reg(
ic->arg[0]) = (int32_t)
ic->arg[1];
1839 int fs =
ic->arg[1] & 31;
1847 int rd =
ic->arg[1] & 31, select =
ic->arg[1] >> 5;
1853 reg(
ic->arg[0]) = (int32_t)tmp;
1858 int rd =
ic->arg[1] & 31;
1869 int rd =
ic->arg[1] & 31, select =
ic->arg[1] >> 5;
1870 uint64_t tmp = (int32_t)
reg(
ic->arg[0]);
1896 cpu->
pc +=
sizeof(uint32_t);
1903 int rd =
ic->arg[1] & 31, select =
ic->arg[1] >> 5;
1908 (uint64_t *)
ic->arg[0], select);
1913 int rd =
ic->arg[1] & 31;
1924 int rd =
ic->arg[1] & 31, select =
ic->arg[1] >> 5;
1929 (uint64_t *)
ic->arg[0], 1, select);
1943 int x, cc =
ic->arg[0];
1956 if (!(
ic->arg[1] & 1))
1961 if (x || !(
ic->arg[1] & 2))
1971 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
1996 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1997 /
sizeof(
struct mips_instr_call);
2004 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
2005 /
sizeof(
struct mips_instr_call);
2028 int res, low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
2029 /
sizeof(
struct mips_instr_call);
2048 default:
fatal(
"TODO: Unimplemented machine type for PROM magic trap\n");
2301 uint8_t word[
sizeof(uint32_t)];
2304 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
2305 /
sizeof(
struct mips_instr_call);
2310 if (
addr & (
sizeof(word)-1)) {
2311 fatal(
"TODO: load linked unaligned access: exception\n");
2326 (
addr >> 4) & 0xffffffffULL;
2329 reg(
ic->arg[0]) = (int32_t) (word[0] + (word[1] << 8)
2330 + (word[2] << 16) + (word[3] << 24));
2332 reg(
ic->arg[0]) = (int32_t) (word[3] + (word[2] << 8)
2333 + (word[1] << 16) + (word[0] << 24));
2339 uint8_t word[
sizeof(uint64_t)];
2342 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
2343 /
sizeof(
struct mips_instr_call);
2348 if (
addr & (
sizeof(word)-1)) {
2349 fatal(
"TODO: load linked unaligned access: exception\n");
2364 (
addr >> 4) & 0xffffffffULL;
2367 reg(
ic->arg[0]) = word[0] + (word[1] << 8)
2368 + (word[2] << 16) + ((uint64_t)word[3] << 24) +
2369 + ((uint64_t)word[4] << 32) + ((uint64_t)word[5] << 40)
2370 + ((uint64_t)word[6] << 48) + ((uint64_t)word[7] << 56);
2372 reg(
ic->arg[0]) = word[7] + (word[6] << 8)
2373 + (word[5] << 16) + ((uint64_t)word[4] << 24) +
2374 + ((uint64_t)word[3] << 32) + ((uint64_t)word[2] << 40)
2375 + ((uint64_t)word[1] << 48) + ((uint64_t)word[0] << 56);
2380 uint64_t r =
reg(
ic->arg[0]);
2382 uint8_t word[
sizeof(uint32_t)];
2385 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
2386 /
sizeof(
struct mips_instr_call);
2391 if (
addr & (
sizeof(word)-1)) {
2392 fatal(
"TODO: sc unaligned access: exception\n");
2397 word[0]=r; word[1]=r>>8; word[2]=r>>16; word[3]=r>>24;
2399 word[3]=r; word[2]=r>>8; word[1]=r>>16; word[0]=r>>24;
2406 reg(
ic->arg[0]) = 0;
2432 reg(
ic->arg[0]) = 1;
2438 uint64_t r =
reg(
ic->arg[0]);
2440 uint8_t word[
sizeof(uint64_t)];
2443 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
2444 /
sizeof(
struct mips_instr_call);
2449 if (
addr & (
sizeof(word)-1)) {
2450 fatal(
"TODO: sc unaligned access: exception\n");
2455 word[0]=r; word[1]=r>>8; word[2]=r>>16; word[3]=r>>24;
2456 word[4]=r>>32; word[5]=r>>40; word[6]=r>>48; word[7]=r>>56;
2458 word[7]=r; word[6]=r>>8; word[5]=r>>16; word[4]=r>>24;
2459 word[3]=r>>32; word[2]=r>>40; word[1]=r>>48; word[0]=r>>56;
2466 reg(
ic->arg[0]) = 0;
2492 reg(
ic->arg[0]) = 1;
2533 uint64_t fpr, *backup_ptr;
2537 backup_ptr = (uint64_t *)
ic->arg[0];
2538 ic->arg[0] = (
size_t) &fpr;
2549 backup_ptr[0] = (int64_t)(int32_t) fpr;
2550 backup_ptr[1] = (int64_t)(int32_t) (fpr >> 32);
2555 ic->arg[0] = (size_t) backup_ptr;
2561 uint64_t fpr, *backup_ptr;
2565 backup_ptr = (uint64_t *)
ic->arg[0];
2566 ic->arg[0] = (
size_t) &fpr;
2569 uint32_t lo = backup_ptr[0];
2570 uint32_t hi = backup_ptr[1];
2571 fpr = (((uint64_t)hi) << 32) | lo;
2584 ic->arg[0] = (size_t) backup_ptr;
2641 uint64_t *rYp = (uint64_t *)
ic[1].arg[0];
2643 unsigned char *
page;
2654 if (rYp == (uint64_t *)
ic->arg[0])
2655 rYp = (uint64_t *)
ic[1].arg[1];
2659 bytes_to_write = rY - rX;
2660 if ((rX & 0xfff) + bytes_to_write > 0x1000) {
2661 bytes_to_write = 0x1000 - (rX & 0xfff);
2670 memset(
page + (rX & 0xfff), 0, bytes_to_write);
2672 reg(
ic->arg[0]) = rX + bytes_to_write;
2676 (
struct mips_instr_call *) &
ic[0] :
2677 (
struct mips_instr_call *) &
ic[3];
2719 X(netbsd_r3k_picache_do_inv)
2730 reg(
ic[3].arg[0]) = ry;
2750 uint32_t
addr, pageindex, i;
2753 reg(
ic[0].arg[0]) = (int32_t)
ic[0].arg[1];
2756 pageindex =
addr >> 12;
2757 i = (
addr & 0xfff) >> 2;
2783 uint32_t
addr, addr2, pageindex, pageindex2, i, i2;
2784 int32_t *
page, *page2;
2786 reg(
ic[0].arg[0]) = (int32_t)
ic[0].arg[1];
2789 pageindex =
addr >> 12;
2790 i = (
addr & 0xfff) >> 2;
2793 addr2 =
reg(
ic[5].arg[1]) + (int32_t)
ic[5].arg[2];
2794 pageindex2 = addr2 >> 12;
2795 i2 = (addr2 & 0xfff) >> 2;
2796 page2 = (int32_t *)
cpu->
cd.
mips.host_load[pageindex2];
2819 uint32_t pageindex = rx >> 12;
2831 mips32_loadstore[1](
cpu,
ic);
2843 }
while (i < 0x1000 && rv != 0);
2847 reg(
ic[0].arg[1]) = (rx & ~0xfff) + i;
2848 reg(
ic[2].arg[0]) = rv;
2862 X(addiu_bne_samepage_addiu)
2872 reg(
ic[0].arg[1]) = (int32_t)
2873 ((int32_t)
reg(
ic[0].arg[0]) + (int32_t)
ic[0].arg[2]);
2874 rs =
reg(
ic[1].arg[0]);
2875 rt =
reg(
ic[1].arg[1]);
2876 reg(
ic[2].arg[1]) = (int32_t)
2877 ((int32_t)
reg(
ic[2].arg[0]) + (int32_t)
ic[2].arg[2]);
2879 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
ic[1].arg[2];
2897 reg(
ic[1].arg[1]) =
reg(
ic[1].arg[0]) & (uint32_t)
ic[1].arg[2];
2898 reg(
ic[2].arg[2]) = (int32_t)(
reg(
ic[2].arg[0])<<(int32_t)
ic[2].arg[1]);
2916 reg(
ic[0].arg[1]) =
reg(
ic[0].arg[0]) & (uint32_t)
ic[0].arg[2];
2917 reg(
ic[1].arg[2]) = (int32_t)(
reg(
ic[1].arg[0])<<(int32_t)
ic[1].arg[1]);
2935 reg(
ic[0].arg[0]) = (int32_t)
ic[0].arg[1];
2936 reg(
ic[1].arg[1]) =
reg(
ic[1].arg[0]) | (uint32_t)
ic[1].arg[2];
2954 reg(
ic[0].arg[0]) = (int32_t)
ic[0].arg[1];
2955 reg(
ic[1].arg[1]) = (int32_t)
2956 ((int32_t)
reg(
ic[1].arg[0]) + (int32_t)
ic[1].arg[2]);
2970 reg(
ic[1].arg[1]) = (int32_t)
2971 ( (int32_t)
reg(
ic[1].arg[0]) + (int32_t)
ic[1].arg[2] );
2973 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
ic->arg[2];
2982 X(b_samepage_daddiu)
2984 *(uint64_t *)
ic[1].arg[1] = *(uint64_t *)
ic[1].arg[0] +
2985 (int32_t)
ic[1].arg[2];
2987 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
ic->arg[2];
3046 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
3047 /
sizeof(
struct mips_instr_call);
3060 fatal(
"end_of_page2: fatal error, we're in a delay slot\n");
3088 (int32_t)
ic[-2].arg[2] == 4 &&
3090 (
ic[-1].arg[0] ==
ic[-2].arg[0] ||
3091 ic[-1].arg[1] ==
ic[-2].arg[0]) &&
3092 ic[-1].arg[0] !=
ic[-1].arg[1] &&
3093 ic[-1].arg[2] == (
size_t) &
ic[-2] &&
3094 ic[0].arg[0] !=
ic[0].arg[1] &&
3095 ic[0].arg[1] ==
ic[-2].arg[0] && (int32_t)
ic[0].arg[2] == -4) {
3121 if ((
ic[-3].
f ==
instr(multi_sw_3_be) ||
3122 ic[-3].f ==
instr(multi_sw_3_le)) &&
3123 ic[-3].arg[1] ==
ic[0].arg[1]) {
3125 ic[-3].f =
instr(multi_sw_4_le);
3127 ic[-3].f =
instr(multi_sw_4_be);
3131 if ((
ic[-2].
f ==
instr(multi_sw_2_be) ||
3132 ic[-2].
f ==
instr(multi_sw_2_le)) &&
3133 ic[-2].arg[1] ==
ic[0].arg[1]) {
3135 ic[-2].f =
instr(multi_sw_3_le);
3137 ic[-2].f =
instr(multi_sw_3_be);
3140 if (
ic[-1].
f ==
ic[0].
f &&
ic[-1].arg[1] ==
ic[0].arg[1]) {
3142 ic[-1].f =
instr(multi_sw_2_le);
3144 ic[-1].f =
instr(multi_sw_2_be);
3170 if ((
ic[-3].
f ==
instr(multi_lw_3_be) ||
3171 ic[-3].f ==
instr(multi_lw_3_le)) &&
3172 ic[-3].arg[1] ==
ic[0].arg[1] &&
3173 ic[-1].arg[0] !=
ic[0].arg[1]) {
3175 ic[-3].f =
instr(multi_lw_4_le);
3177 ic[-3].f =
instr(multi_lw_4_be);
3181 if ((
ic[-2].
f ==
instr(multi_lw_2_be) ||
3182 ic[-2].
f ==
instr(multi_lw_2_le)) &&
3183 ic[-2].arg[1] ==
ic[0].arg[1] &&
3184 ic[-1].arg[0] !=
ic[0].arg[1]) {
3186 ic[-2].f =
instr(multi_lw_3_le);
3188 ic[-2].f =
instr(multi_lw_3_be);
3192 if (
ic[-1].
f ==
ic[0].
f &&
3193 ic[-1].arg[1] ==
ic[0].arg[1] &&
3194 ic[-1].arg[0] !=
ic[0].arg[1]) {
3196 ic[-1].f =
instr(multi_lw_2_le);
3198 ic[-1].f =
instr(multi_lw_2_be);
3220 struct mips_instr_call *
ic,
int low_addr)
3231 (int32_t)
ic[-5].arg[2] == 4 &&
ic[-4].
f ==
instr(bne_samepage) &&
3232 ic[-4].arg[0] ==
ic[-5].arg[0] &&
ic[-4].arg[0] !=
ic[-4].arg[1] &&
3233 ic[-4].arg[2] == (size_t) &
ic[-5] &&
3234 ic[-3].arg[1] ==
ic[-5].arg[0] &&
3236 ic[-8].f =
instr(netbsd_r3k_picache_do_inv);
3259 ic[-7].f == mips32_loadstore[4 + 1] &&
3260 ic[-7].arg[0] ==
ic[-1].arg[0] &&
3261 ic[-7].arg[0] ==
ic[-3].arg[0] &&
3262 ic[-7].arg[0] ==
ic[-5].arg[0] &&
3263 ic[-7].arg[0] ==
ic[-7].arg[1] &&
3264 ic[-7].arg[0] ==
ic[-8].arg[0] &&
3267 ic[-5].f ==
instr(bne_samepage_nop) &&
3269 ic[-3].f == mips32_loadstore[4 + 1] &&
3272 ic[-1].arg[2] == (
size_t) &
ic[-8] &&
3273 ic[-1].f ==
instr(beq_samepage)) {
3274 ic[-8].f =
instr(linux_pmax_idle);
3279 ic[-3].
f == mips32_loadstore[4 + 1] &&
3280 ic[-3].arg[0] ==
ic[-1].arg[0] &&
3281 ic[-3].arg[1] ==
ic[-4].arg[0] &&
3284 ic[-1].arg[2] == (
size_t) &
ic[-4] &&
3285 ic[-1].f ==
instr(beq_samepage)) {
3286 ic[-4].f =
instr(netbsd_pmax_idle);
3290 if ((
ic[-3].
f == mips32_loadstore[1] ||
3291 ic[-3].
f == mips32_loadstore[16 + 1]) &&
3292 ic[-3].arg[2] == 0 &&
3293 ic[-3].arg[0] ==
ic[-1].arg[0] &&
ic[-3].arg[1] ==
ic[-2].arg[0] &&
3294 ic[-2].arg[0] ==
ic[-2].arg[1] &&
ic[-2].arg[2] == 1 &&
3297 ic[-1].f ==
instr(bne_samepage)) {
3298 ic[-3].f =
instr(netbsd_strlen);
3303 if (
ic[-1].
f ==
instr(bne_samepage)) {
3304 ic[-1].f =
instr(bne_samepage_nop);
3308 if (
ic[-1].
f ==
instr(beq_samepage)) {
3309 ic[-1].f =
instr(beq_samepage_nop);
3332 ic[-2].f =
instr(xor_andi_sll);
3373 if (
ic[-4].
f ==
instr(multi_addu_3) ||
3374 ic[-3].f ==
instr(multi_addu_3))
3378 ic[-2].f =
instr(multi_addu_3);
3398 ic[-1].f ==
instr(bne_samepage)) {
3399 ic[-2].f =
instr(addiu_bne_samepage_addiu);
3408 if (
ic[-1].
f ==
instr(b_samepage)) {
3409 ic[-1].f =
instr(b_samepage_addiu);
3413 if (
ic[-1].
f ==
instr(beq_samepage)) {
3414 ic[-1].f =
instr(beq_samepage_addiu);
3418 if (
ic[-1].
f ==
instr(bne_samepage)) {
3419 ic[-1].f =
instr(bne_samepage_addiu);
3424 ic[-1].f =
instr(jr_ra_addiu);
3444 if (
ic[-1].
f ==
instr(b_samepage)) {
3445 ic[-1].f =
instr(b_samepage_daddiu);
3465 uint64_t
addr, low_pc;
3466 uint32_t iword, imm;
3467 unsigned char *
page;
3468 unsigned char ib[4];
3469 int main_opcode, rt, rs, rd, sa, s6, x64 = 0, s10;
3470 int in_crosspage_delayslot = 0;
3471 void (*samepage_function)(
struct cpu *,
struct mips_instr_call *);
3472 int store, signedness, size;
3475 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
3476 /
sizeof(
struct mips_instr_call);
3482 in_crosspage_delayslot = 1;
3505 page = l3->host_load[x3];
3511 memcpy(ib,
page + (
addr & 0xffc),
sizeof(ib));
3516 fatal(
"to_be_translated(): read failed: TODO\n");
3522 uint32_t *p = (uint32_t *) ib;
3532 #define DYNTRANS_TO_BE_TRANSLATED_HEAD
3534 #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
3546 main_opcode = iword >> 26;
3547 rs = (iword >> 21) & 31;
3548 rt = (iword >> 16) & 31;
3549 rd = (iword >> 11) & 31;
3550 sa = (iword >> 6) & 31;
3551 imm = (int16_t)iword;
3553 s10 = (rs << 5) | sa;
3555 switch (main_opcode) {
3584 x64 = 1; sa = -1;
break;
3589 x64 = 1; sa = -1;
break;
3594 x64 = 1; sa = -1;
break;
3608 if (sa >= 0 && rs != 0x00) {
3611 static int warning_rotate = 0;
3612 if (!warning_rotate &&
3614 fatal(
"[ WARNING! MIPS32/64 "
3615 "revision 2 rotate opcode"
3616 " used, but the %s process"
3617 "or does not implement "
3618 "such instructions. Only "
3620 "warning once. ]\n",
3639 if (sa < 0 && (s10 & 0x1f) != 0) {
3640 int orig_sa = (iword >> 6) & 31;
3643 if (orig_sa == 0x01) {
3779 fatal(
"TODO: rd NON-zero\n");
3808 ic->arg[2] = (
addr & 0xffc) + 8;
3831 fatal(
"TODO: branch in delay "
3838 if (((iword >> 6) & 0xfffff) == 0x30378) {
3847 if (((iword >> 6) & 0xfffff) == 0x30378) {
3871 samepage_function = NULL;
3872 switch (main_opcode) {
3875 samepage_function =
instr(beq_samepage);
3879 samepage_function =
instr(b_samepage);
3884 samepage_function =
instr(bne_samepage);
3888 samepage_function =
instr(beql_samepage);
3892 samepage_function =
instr(b_samepage);
3897 samepage_function =
instr(bnel_samepage);
3901 samepage_function =
instr(blez_samepage);
3905 samepage_function =
instr(blezl_samepage);
3909 samepage_function =
instr(bgtz_samepage);
3913 samepage_function =
instr(bgtzl_samepage);
3919 + (
addr & 0xffc) + 4 );
3927 ic->f = samepage_function;
3931 fatal(
"TODO: branch in delay slot? (2)\n");
3953 ic->arg[2] = (int16_t)iword;
3955 ic->arg[2] = (uint16_t)iword;
3957 switch (main_opcode) {
3969 if (
ic->arg[2] == 0) {
3973 ic->arg[2] =
ic->arg[1];
3991 ic->arg[1] = (int32_t) (imm << 16);
4000 switch (main_opcode) {
4013 ic->arg[0] = (iword & 0x03ffffff) << 2;
4014 ic->arg[1] = (
addr & 0xffc) + 8;
4017 fatal(
"TODO: branch in delay slot (=%i)? (3);"
4018 " addr=%016" PRIx64
" iword=%08" PRIx32
"\n",
4027 if ((iword >> 25) & 1) {
4028 ic->arg[2] =
addr & 0xffc;
4029 switch (iword & 0xff) {
4054 static int warned = 0;
4058 fatal(
"{ WARNING: Attempt to "
4059 "execute the WAIT instruct"
4060 "ion, but the emulated CPU "
4061 "is neither RM52xx, nor "
4071 static int warned = 0;
4075 fatal(
"{ WARNING: Attempt to "
4076 "execute a R41xx instruct"
4077 "ion, but the emulated CPU "
4078 "doesn't support it! }\n");
4104 fatal(
"UNIMPLEMENTED cop0 (func "
4105 "0x%02x)\n", iword & 0xff);
4115 ic->arg[1] = rd + ((iword & 7) << 5);
4116 ic->arg[2] =
addr & 0xffc;
4124 ic->arg[1] = rd + ((iword & 7) << 5);
4125 ic->arg[2] =
addr & 0xffc;
4127 if (rs ==
COPz_MFCz && (iword & 7) == 0 &&
4139 ic->arg[1] = rd + ((iword & 7) << 5);
4140 ic->arg[2] =
addr & 0xffc;
4150 if ((iword & 0xffdf) == 0x6000) {
4154 static int warning_ei_di = 0;
4155 if (!warning_ei_di &&
4157 fatal(
"[ WARNING! MIPS32/64 "
4158 "revision 2 di or ei opcode"
4159 " used, but the %s process"
4160 "or does not implement "
4161 "such instructions. Only "
4163 "warning once. ]\n",
4175 ic->arg[1] = iword & 0x20;
4178 fatal(
"Unimplemented COP0_MFMCz\n");
4183 if (iword == 0x4100ffff) {
4188 fatal(
"Unimplemented COP0_BCzc\n");
4194 fatal(
"UNIMPLEMENTED cop0 (rs = %i)\n", rs);
4216 ic->arg[0] = (iword >> 18) & 7;
4217 ic->arg[1] = (iword >> 16) & 3;
4218 ic->arg[2] = (int32_t) ((imm <<
4222 fatal(
"TODO: branch in delay slot 4\n");
4228 fatal(
"Attempt to execute a non-cc-0 "
4229 "BC* instruction on an isa level "
4230 "%i cpu. TODO: How should this be "
4254 ic->arg[0] = (uint32_t)iword & ((1 << 26) - 1);
4258 fatal(
"COP1 floating point opcode = 0x%02x\n", rs);
4272 fatal(
"COP2 functionality not yet implemented\n");
4285 if (iword == 0x4d00ffff) {
4291 fatal(
"COP3 iword=0x%08x\n", iword);
4299 int mmi_subopcode = (iword >> 6) & 0x1f;
4324 switch (mmi_subopcode) {
4341 switch (mmi_subopcode) {
4425 samepage_function = NULL;
4429 samepage_function =
instr(bgez_samepage);
4433 samepage_function =
instr(bgezl_samepage);
4437 samepage_function =
instr(bltz_samepage);
4441 samepage_function =
instr(bltzl_samepage);
4445 samepage_function =
instr(bgezal_samepage);
4449 samepage_function =
instr(bgezall_samepage);
4453 samepage_function =
instr(bltzal_samepage);
4457 samepage_function =
instr(bltzall_samepage);
4462 + (
addr & 0xffc) + 4;
4472 ic->f = samepage_function;
4476 fatal(
"TODO: branch in delay slot:5\n");
4482 fatal(
"UNIMPLEMENTED regimm rt=%i\n", rt);
4499 size = 2; signedness = 0; store = 0;
4500 switch (main_opcode) {
4501 case HI6_LB: size = 0; signedness = 1;
break;
4502 case HI6_LBU: size = 0;
break;
4503 case HI6_LH: size = 1; signedness = 1;
break;
4504 case HI6_LHU: size = 1;
break;
4505 case HI6_LW: signedness = 1;
break;
4507 case HI6_LD: size = 3; x64 = 1;
break;
4508 case HI6_SB: store = 1; size = 0;
break;
4509 case HI6_SH: store = 1; size = 1;
break;
4510 case HI6_SW: store = 1;
break;
4511 case HI6_SD: store = 1; size = 3; x64 = 1;
break;
4521 + store * 8 + size * 2 + signedness];
4524 ic->arg[2] = (int32_t)imm;
4535 if (main_opcode ==
HI6_SW)
4552 switch (main_opcode) {
4560 ic->arg[2] = (int32_t)imm;
4563 fatal(
"HM... unusual load linked\n");
4578 switch (main_opcode) {
4590 ic->arg[2] = (int32_t)imm;
4610 ic->arg[2] = (int32_t)imm;
4611 switch (main_opcode) {
4634 fatal(
"TODO: lwc3 not implemented yet\n");
4642 fatal(
"TODO: R5900 128-bit loads\n");
4647 fatal(
"TODO: MDMX\n");
4655 fatal(
"TODO: R5900 128-bit stores\n");
4661 static int warning = 0;
4663 fatal(
"[ WARNING! SPECIAL3 opcode used, but"
4664 " the %s processor does not implement "
4665 "such instructions. Only printing this "
4666 "warning once. ]\n",
4678 int msbd = rd, lsb = (iword >> 6) & 0x1f;
4681 ic->arg[2] = (msbd << 5) + lsb;
4692 int msbd = rd, lsb = (iword >> 6) & 0x1f;
4699 ic->arg[2] = (msbd << 6) + lsb;
4708 int msb = rd, lsb = (iword >> 6) & 0x1f;
4711 ic->arg[2] = (msb << 5) + lsb;
4754 case 0:
ic->f =
instr(rdhwr_cpunum);
4759 case 2:
ic->f =
instr(rdhwr_cc);
4764 case 29:
ic->f =
instr(reserved);
4768 fatal(
"unimplemented rdhwr "
4769 "register rd=%i\n", rd);
4789 static int has_warned = 0;
4791 fatal(
"[ WARNING/NOTE: attempt to execute a 64-bit"
4792 " instruction on an emulated 32-bit processor; "
4793 "pc=0x%08" PRIx32
" ]\n", (uint32_t)
cpu->
pc);
4806 #define DYNTRANS_TO_BE_TRANSLATED_TAIL
4808 #undef DYNTRANS_TO_BE_TRANSLATED_TAIL