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];
1167 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1168 /
sizeof(
struct mips_instr_call);
1182 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1183 /
sizeof(
struct mips_instr_call);
1197 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1198 /
sizeof(
struct mips_instr_call);
1212 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1213 /
sizeof(
struct mips_instr_call);
1227 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1228 /
sizeof(
struct mips_instr_call);
1242 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1243 /
sizeof(
struct mips_instr_call);
1261 int msb =
ic->arg[2] >> 5, pos =
ic->arg[2] & 0x1f;
1262 int size = msb + 1 - pos;
1263 uint32_t rt =
reg(
ic->arg[0]);
1264 uint32_t rs =
reg(
ic->arg[1]);
1265 uint32_t mask = (-1) << pos;
1267 mask <<= (32 - pos - size);
1268 mask >>= (32 - pos - size);
1270 reg(
ic->arg[0]) = (int32_t) ((rt & ~mask) | ((rs << pos) & mask));
1283 int msbd =
ic->arg[2] >> 5, lsb =
ic->arg[2] & 0x1f;
1284 int size = msbd + 1;
1285 uint32_t rs =
reg(
ic->arg[1]);
1286 uint32_t x = (rs << (32-lsb-size)) >> (32-lsb-size);
1287 reg(
ic->arg[0]) = (int32_t) (x >> lsb);
1300 int msbd =
ic->arg[2] >> 6, lsb =
ic->arg[2] & 0x3f;
1301 int size = msbd + 1;
1302 uint64_t rs =
reg(
ic->arg[1]);
1303 uint64_t x = (rs << (uint64_t)(64-lsb-size)) >> (uint64_t)(64-lsb-size);
1304 reg(
ic->arg[0]) = x >> lsb;
1320 uint64_t x =
reg(
ic->arg[0]);
1321 x = ((x & 0x00ff00ff00ff00ffULL) << 8)
1322 | ((x & 0xff00ff00ff00ff00ULL) >> 8);
1323 reg(
ic->arg[1]) = x;
1327 uint64_t x =
reg(
ic->arg[0]);
1328 x = ((x & 0x000000000000ffffULL) << 48)
1329 | ((x & 0x00000000ffff0000ULL) << 16)
1330 | ((x & 0x0000ffff00000000ULL) >> 16)
1331 | ((x & 0xffff000000000000ULL) >> 48);
1332 reg(
ic->arg[1]) = x;
1336 uint32_t x =
reg(
ic->arg[0]);
1337 x = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8);
1338 reg(
ic->arg[1]) = (int32_t) x;
1364 int32_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]);
1368 else if (a == (int32_t)0x80000000U && b == -1)
1371 res = a / b, rem = a - b*res;
1377 uint32_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]);
1382 res = a / b, rem = a - b*res;
1388 int64_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]);
1392 else if (a == (int64_t)0x8000000000000000ULL && b == -1)
1402 uint64_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]);
1414 int32_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]);
1415 int64_t res = (int64_t)a * (int64_t)b;
1423 int32_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]);
1424 int64_t res = (int64_t)a * (int64_t)b;
1427 reg(
ic->arg[2]) = (int32_t)res;
1431 uint32_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]);
1432 uint64_t res = (uint64_t)a * (uint64_t)b;
1440 uint32_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]);
1441 uint64_t res = (uint64_t)a * (uint64_t)b;
1444 reg(
ic->arg[2]) = (int32_t)res;
1448 uint64_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]), c = 0;
1449 uint64_t hi = 0, lo = 0;
1455 for (; a; a >>= 1) {
1457 uint64_t old_lo = lo;
1463 c = (c << 1) | (b >> 63); b <<= 1;
1477 uint64_t a =
reg(
ic->arg[0]), b =
reg(
ic->arg[1]), c = 0;
1478 uint64_t hi = 0, lo = 0;
1479 for (; a; a >>= 1) {
1481 uint64_t old_lo = lo;
1487 c = (c << 1) | (b >> 63); b <<= 1;
1497 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1498 /
sizeof(
struct mips_instr_call);
1510 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1511 /
sizeof(
struct mips_instr_call);
1523 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1524 /
sizeof(
struct mips_instr_call);
1536 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1537 /
sizeof(
struct mips_instr_call);
1549 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1550 /
sizeof(
struct mips_instr_call);
1562 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1563 /
sizeof(
struct mips_instr_call);
1582 int32_t rs =
reg(
ic->arg[0]), rt =
reg(
ic->arg[1]);
1583 int32_t rd = rs + rt;
1585 if (unlikely((rs >= 0 && rt >= 0 && rd < 0) || (rs < 0 && rt < 0 && rd >= 0))) {
1587 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1588 /
sizeof(
struct mips_instr_call);
1594 reg(
ic->arg[2]) = rd;
1599 int64_t rs =
reg(
ic->arg[0]), rt =
reg(
ic->arg[1]);
1600 int64_t rd = rs + rt;
1602 if (unlikely((rs >= 0 && rt >= 0 && rd < 0) || (rs < 0 && rt < 0 && rd >= 0))) {
1604 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1605 /
sizeof(
struct mips_instr_call);
1611 reg(
ic->arg[2]) = rd;
1617 int32_t rs =
reg(
ic->arg[0]), rt = -
reg(
ic->arg[1]);
1618 int32_t rd = rs + rt;
1620 if (unlikely((rs >= 0 && rt >= 0 && rd < 0) || (rs < 0 && rt < 0 && rd >= 0))) {
1622 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1623 /
sizeof(
struct mips_instr_call);
1629 reg(
ic->arg[2]) = rd;
1635 int64_t rs =
reg(
ic->arg[0]), rt = -
reg(
ic->arg[1]);
1636 int64_t rd = rs + rt;
1638 if (unlikely((rs >= 0 && rt >= 0 && rd < 0) || (rs < 0 && rt < 0 && rd >= 0))) {
1640 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1641 /
sizeof(
struct mips_instr_call);
1647 reg(
ic->arg[2]) = rd;
1663 reg(
ic->arg[2]) = (int32_t)(
reg(
ic->arg[0]) << sa); }
1664 X(srl) {
reg(
ic->arg[2]) = (int32_t)((uint32_t)
reg(
ic->arg[0]) >>
ic->arg[1]); }
1666 reg(
ic->arg[2]) = (int32_t)((uint32_t)
reg(
ic->arg[0]) >> sa); }
1669 reg(
ic->arg[2]) = (int32_t)((int32_t)
reg(
ic->arg[0]) >> sa); }
1674 (uint64_t)
ic->arg[1]);}
1676 reg(
ic->arg[2]) = (uint64_t)
reg(
ic->arg[0]) >> sa; }
1679 reg(
ic->arg[2]) = (int64_t)
reg(
ic->arg[0]) >> sa; }
1681 ( (int32_t)
reg(
ic->arg[0]) * (int32_t)
reg(
ic->arg[1]) ); }
1687 uint32_t result =
reg(
ic->arg[0]);
1688 int sa =
ic->arg[1];
1690 result = (result >> sa) | (result << (32-sa));
1692 reg(
ic->arg[2]) = (int32_t) result;
1697 uint32_t result =
reg(
ic->arg[0]);
1698 int sa =
reg(
ic->arg[1]);
1700 result = (result >> sa) | (result << (32-sa));
1702 reg(
ic->arg[2]) = (int32_t) result;
1744 int64_t rs = (int32_t)
reg(
ic->arg[0]), rt = (int32_t)
reg(
ic->arg[1]);
1745 int64_t sum = rs * rt,
1752 int64_t rs = (int32_t)
reg(
ic->arg[0]), rt = (int32_t)
reg(
ic->arg[1]);
1753 int64_t sum = rs * rt,
1757 reg(
ic->arg[2]) = (int32_t)hilo;
1761 int64_t rs = (int32_t)
reg(
ic->arg[0]), rt = (int32_t)
reg(
ic->arg[1]);
1762 int64_t sum = rs * rt,
1769 int64_t rs = (uint32_t)
reg(
ic->arg[0]), rt = (uint32_t)
reg(
ic->arg[1]);
1770 int64_t sum = rs * rt,
1777 int64_t rs = (uint32_t)
reg(
ic->arg[0]), rt = (uint32_t)
reg(
ic->arg[1]);
1778 int64_t sum = rs * rt,
1782 reg(
ic->arg[2]) = (int32_t)hilo;
1786 int64_t rs = (uint32_t)
reg(
ic->arg[0]), rt = (uint32_t)
reg(
ic->arg[1]);
1787 int64_t sum = rs * rt,
1811 uint32_t x =
reg(
ic->arg[0]);
1813 for (count=0; count<32; count++) {
1814 if (x & 0x80000000UL)
1818 reg(
ic->arg[1]) = count;
1822 uint32_t x =
reg(
ic->arg[0]);
1824 for (count=0; count<32; count++) {
1825 if (!(x & 0x80000000UL))
1829 reg(
ic->arg[1]) = count;
1833 uint64_t x =
reg(
ic->arg[0]);
1835 for (count=0; count<64; count++) {
1836 if (x & 0x8000000000000000ULL)
1840 reg(
ic->arg[1]) = count;
1844 uint64_t x =
reg(
ic->arg[0]);
1846 for (count=0; count<64; count++) {
1847 if (!(x & 0x8000000000000000ULL))
1851 reg(
ic->arg[1]) = count;
1867 int32_t rs =
reg(
ic->arg[0]), imm = (int32_t)
ic->arg[2];
1868 int32_t rt = rs + imm;
1870 if (unlikely((rs >= 0 && imm >= 0 && rt < 0) || (rs < 0 && imm < 0 && rt >= 0))) {
1872 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1873 /
sizeof(
struct mips_instr_call);
1879 reg(
ic->arg[1]) = rt;
1883 reg(
ic->arg[1]) = (int32_t)
1884 ((int32_t)
reg(
ic->arg[0]) + (int32_t)
ic->arg[2]);
1888 int64_t rs =
reg(
ic->arg[0]), imm = (int32_t)
ic->arg[2];
1889 int64_t rt = rs + imm;
1891 if (unlikely((rs >= 0 && imm >= 0 && rt < 0) || (rs < 0 && imm < 0 && rt >= 0))) {
1893 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
1894 /
sizeof(
struct mips_instr_call);
1900 reg(
ic->arg[1]) = rt;
1904 reg(
ic->arg[1]) =
reg(
ic->arg[0]) + (int32_t)
ic->arg[2];
1926 reg(
ic->arg[0]) = (int32_t)
ic->arg[1];
1942 int fs =
ic->arg[1] & 31;
1950 int rd =
ic->arg[1] & 31, select =
ic->arg[1] >> 5;
1956 reg(
ic->arg[0]) = (int32_t)tmp;
1961 int rd =
ic->arg[1] & 31;
1972 int rd =
ic->arg[1] & 31, select =
ic->arg[1] >> 5;
1973 uint64_t tmp = (int32_t)
reg(
ic->arg[0]);
1999 cpu->
pc +=
sizeof(uint32_t);
2006 int rd =
ic->arg[1] & 31, select =
ic->arg[1] >> 5;
2011 (uint64_t *)
ic->arg[0], select);
2016 int rd =
ic->arg[1] & 31;
2027 int rd =
ic->arg[1] & 31, select =
ic->arg[1] >> 5;
2032 (uint64_t *)
ic->arg[0], 1, select);
2046 int x, cc =
ic->arg[0];
2059 if (!(
ic->arg[1] & 1))
2064 if (x || !(
ic->arg[1] & 2))
2074 cpu->
pc = old_pc + (int32_t)
ic->arg[2];
2099 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
2100 /
sizeof(
struct mips_instr_call);
2107 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
2108 /
sizeof(
struct mips_instr_call);
2131 int res, low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
2132 /
sizeof(
struct mips_instr_call);
2151 default:
fatal(
"TODO: Unimplemented machine type for PROM magic trap\n");
2404 uint8_t word[
sizeof(uint32_t)];
2407 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
2408 /
sizeof(
struct mips_instr_call);
2413 if (
addr & (
sizeof(word)-1)) {
2414 fatal(
"TODO: load linked unaligned access: exception\n");
2429 (
addr >> 4) & 0xffffffffULL;
2432 reg(
ic->arg[0]) = (int32_t) (word[0] + (word[1] << 8)
2433 + (word[2] << 16) + (word[3] << 24));
2435 reg(
ic->arg[0]) = (int32_t) (word[3] + (word[2] << 8)
2436 + (word[1] << 16) + (word[0] << 24));
2442 uint8_t word[
sizeof(uint64_t)];
2445 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
2446 /
sizeof(
struct mips_instr_call);
2451 if (
addr & (
sizeof(word)-1)) {
2452 fatal(
"TODO: load linked unaligned access: exception\n");
2467 (
addr >> 4) & 0xffffffffULL;
2470 reg(
ic->arg[0]) = word[0] + (word[1] << 8)
2471 + (word[2] << 16) + ((uint64_t)word[3] << 24) +
2472 + ((uint64_t)word[4] << 32) + ((uint64_t)word[5] << 40)
2473 + ((uint64_t)word[6] << 48) + ((uint64_t)word[7] << 56);
2475 reg(
ic->arg[0]) = word[7] + (word[6] << 8)
2476 + (word[5] << 16) + ((uint64_t)word[4] << 24) +
2477 + ((uint64_t)word[3] << 32) + ((uint64_t)word[2] << 40)
2478 + ((uint64_t)word[1] << 48) + ((uint64_t)word[0] << 56);
2483 uint64_t r =
reg(
ic->arg[0]);
2485 uint8_t word[
sizeof(uint32_t)];
2488 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
2489 /
sizeof(
struct mips_instr_call);
2494 if (
addr & (
sizeof(word)-1)) {
2495 fatal(
"TODO: sc unaligned access: exception\n");
2500 word[0]=r; word[1]=r>>8; word[2]=r>>16; word[3]=r>>24;
2502 word[3]=r; word[2]=r>>8; word[1]=r>>16; word[0]=r>>24;
2509 reg(
ic->arg[0]) = 0;
2535 reg(
ic->arg[0]) = 1;
2541 uint64_t r =
reg(
ic->arg[0]);
2543 uint8_t word[
sizeof(uint64_t)];
2546 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
2547 /
sizeof(
struct mips_instr_call);
2552 if (
addr & (
sizeof(word)-1)) {
2553 fatal(
"TODO: sc unaligned access: exception\n");
2558 word[0]=r; word[1]=r>>8; word[2]=r>>16; word[3]=r>>24;
2559 word[4]=r>>32; word[5]=r>>40; word[6]=r>>48; word[7]=r>>56;
2561 word[7]=r; word[6]=r>>8; word[5]=r>>16; word[4]=r>>24;
2562 word[3]=r>>32; word[2]=r>>40; word[1]=r>>48; word[0]=r>>56;
2569 reg(
ic->arg[0]) = 0;
2595 reg(
ic->arg[0]) = 1;
2636 uint64_t fpr, *backup_ptr;
2640 backup_ptr = (uint64_t *)
ic->arg[0];
2641 ic->arg[0] = (
size_t) &fpr;
2652 backup_ptr[0] = (int64_t)(int32_t) fpr;
2653 backup_ptr[1] = (int64_t)(int32_t) (fpr >> 32);
2658 ic->arg[0] = (size_t) backup_ptr;
2664 uint64_t fpr, *backup_ptr;
2668 backup_ptr = (uint64_t *)
ic->arg[0];
2669 ic->arg[0] = (
size_t) &fpr;
2672 uint32_t lo = backup_ptr[0];
2673 uint32_t hi = backup_ptr[1];
2674 fpr = (((uint64_t)hi) << 32) | lo;
2687 ic->arg[0] = (size_t) backup_ptr;
2744 uint64_t *rYp = (uint64_t *)
ic[1].arg[0];
2746 unsigned char *
page;
2757 if (rYp == (uint64_t *)
ic->arg[0])
2758 rYp = (uint64_t *)
ic[1].arg[1];
2762 bytes_to_write = rY - rX;
2763 if ((rX & 0xfff) + bytes_to_write > 0x1000) {
2764 bytes_to_write = 0x1000 - (rX & 0xfff);
2773 memset(
page + (rX & 0xfff), 0, bytes_to_write);
2775 reg(
ic->arg[0]) = rX + bytes_to_write;
2779 (
struct mips_instr_call *) &
ic[0] :
2780 (
struct mips_instr_call *) &
ic[3];
2820 X(netbsd_r3k_picache_do_inv)
2831 reg(
ic[3].arg[0]) = ry;
2851 uint32_t
addr, pageindex, i;
2854 reg(
ic[0].arg[0]) = (int32_t)
ic[0].arg[1];
2857 pageindex =
addr >> 12;
2858 i = (
addr & 0xfff) >> 2;
2884 uint32_t
addr, addr2, pageindex, pageindex2, i, i2;
2885 int32_t *
page, *page2;
2887 reg(
ic[0].arg[0]) = (int32_t)
ic[0].arg[1];
2890 pageindex =
addr >> 12;
2891 i = (
addr & 0xfff) >> 2;
2894 addr2 =
reg(
ic[5].arg[1]) + (int32_t)
ic[5].arg[2];
2895 pageindex2 = addr2 >> 12;
2896 i2 = (addr2 & 0xfff) >> 2;
2897 page2 = (int32_t *)
cpu->
cd.
mips.host_load[pageindex2];
2920 uint32_t pageindex = rx >> 12;
2932 mips32_loadstore[1](
cpu,
ic);
2944 }
while (i < 0x1000 && rv != 0);
2948 reg(
ic[0].arg[1]) = (rx & ~0xfff) + i;
2949 reg(
ic[2].arg[0]) = rv;
2963 X(addiu_bne_samepage_addiu)
2973 reg(
ic[0].arg[1]) = (int32_t)
2974 ((int32_t)
reg(
ic[0].arg[0]) + (int32_t)
ic[0].arg[2]);
2975 rs =
reg(
ic[1].arg[0]);
2976 rt =
reg(
ic[1].arg[1]);
2977 reg(
ic[2].arg[1]) = (int32_t)
2978 ((int32_t)
reg(
ic[2].arg[0]) + (int32_t)
ic[2].arg[2]);
2980 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
ic[1].arg[2];
2998 reg(
ic[1].arg[1]) =
reg(
ic[1].arg[0]) & (uint32_t)
ic[1].arg[2];
2999 reg(
ic[2].arg[2]) = (int32_t)(
reg(
ic[2].arg[0])<<(int32_t)
ic[2].arg[1]);
3017 reg(
ic[0].arg[1]) =
reg(
ic[0].arg[0]) & (uint32_t)
ic[0].arg[2];
3018 reg(
ic[1].arg[2]) = (int32_t)(
reg(
ic[1].arg[0])<<(int32_t)
ic[1].arg[1]);
3036 reg(
ic[0].arg[0]) = (int32_t)
ic[0].arg[1];
3037 reg(
ic[1].arg[1]) =
reg(
ic[1].arg[0]) | (uint32_t)
ic[1].arg[2];
3055 reg(
ic[0].arg[0]) = (int32_t)
ic[0].arg[1];
3056 reg(
ic[1].arg[1]) = (int32_t)
3057 ((int32_t)
reg(
ic[1].arg[0]) + (int32_t)
ic[1].arg[2]);
3071 reg(
ic[1].arg[1]) = (int32_t)
3072 ( (int32_t)
reg(
ic[1].arg[0]) + (int32_t)
ic[1].arg[2] );
3074 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
ic->arg[2];
3083 X(b_samepage_daddiu)
3085 *(uint64_t *)
ic[1].arg[1] = *(uint64_t *)
ic[1].arg[0] +
3086 (int32_t)
ic[1].arg[2];
3088 cpu->
cd.
mips.next_ic = (
struct mips_instr_call *)
ic->arg[2];
3147 int low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
3148 /
sizeof(
struct mips_instr_call);
3161 fatal(
"end_of_page2: fatal error, we're in a delay slot\n");
3189 (int32_t)
ic[-2].arg[2] == 4 &&
3191 (
ic[-1].arg[0] ==
ic[-2].arg[0] ||
3192 ic[-1].arg[1] ==
ic[-2].arg[0]) &&
3193 ic[-1].arg[0] !=
ic[-1].arg[1] &&
3194 ic[-1].arg[2] == (
size_t) &
ic[-2] &&
3195 ic[0].arg[0] !=
ic[0].arg[1] &&
3196 ic[0].arg[1] ==
ic[-2].arg[0] && (int32_t)
ic[0].arg[2] == -4) {
3220 if ((
ic[-4].
f ==
instr(multi_sw_4_be) ||
3221 ic[-4].f ==
instr(multi_sw_4_le)) &&
3222 ic[-4].arg[1] ==
ic[0].arg[1]) {
3224 ic[-4].f =
instr(multi_sw_5_le);
3226 ic[-4].f =
instr(multi_sw_5_be);
3230 if ((
ic[-3].
f ==
instr(multi_sw_3_be) ||
3231 ic[-3].
f ==
instr(multi_sw_3_le)) &&
3232 ic[-3].arg[1] ==
ic[0].arg[1]) {
3234 ic[-3].f =
instr(multi_sw_4_le);
3236 ic[-3].f =
instr(multi_sw_4_be);
3240 if ((
ic[-2].
f ==
instr(multi_sw_2_be) ||
3241 ic[-2].
f ==
instr(multi_sw_2_le)) &&
3242 ic[-2].arg[1] ==
ic[0].arg[1]) {
3244 ic[-2].f =
instr(multi_sw_3_le);
3246 ic[-2].f =
instr(multi_sw_3_be);
3249 if (
ic[-1].
f ==
ic[0].
f &&
ic[-1].arg[1] ==
ic[0].arg[1]) {
3251 ic[-1].f =
instr(multi_sw_2_le);
3253 ic[-1].f =
instr(multi_sw_2_be);
3276 if ((
ic[-4].
f ==
instr(multi_lw_4_be) ||
3277 ic[-4].f ==
instr(multi_lw_4_le)) &&
3278 ic[-4].arg[1] ==
ic[0].arg[1] &&
3279 ic[-1].arg[0] !=
ic[0].arg[1]) {
3281 ic[-4].f =
instr(multi_lw_5_le);
3283 ic[-4].f =
instr(multi_lw_5_be);
3287 if ((
ic[-3].
f ==
instr(multi_lw_3_be) ||
3288 ic[-3].
f ==
instr(multi_lw_3_le)) &&
3289 ic[-3].arg[1] ==
ic[0].arg[1] &&
3290 ic[-1].arg[0] !=
ic[0].arg[1]) {
3292 ic[-3].f =
instr(multi_lw_4_le);
3294 ic[-3].f =
instr(multi_lw_4_be);
3298 if ((
ic[-2].
f ==
instr(multi_lw_2_be) ||
3299 ic[-2].
f ==
instr(multi_lw_2_le)) &&
3300 ic[-2].arg[1] ==
ic[0].arg[1] &&
3301 ic[-1].arg[0] !=
ic[0].arg[1]) {
3303 ic[-2].f =
instr(multi_lw_3_le);
3305 ic[-2].f =
instr(multi_lw_3_be);
3309 if (
ic[-1].
f ==
ic[0].
f &&
3310 ic[-1].arg[1] ==
ic[0].arg[1] &&
3311 ic[-1].arg[0] !=
ic[0].arg[1]) {
3313 ic[-1].f =
instr(multi_lw_2_le);
3315 ic[-1].f =
instr(multi_lw_2_be);
3336 struct mips_instr_call *
ic,
int low_addr)
3347 (int32_t)
ic[-5].arg[2] == 4 &&
ic[-4].
f ==
instr(bne_samepage) &&
3348 ic[-4].arg[0] ==
ic[-5].arg[0] &&
ic[-4].arg[0] !=
ic[-4].arg[1] &&
3349 ic[-4].arg[2] == (size_t) &
ic[-5] &&
3350 ic[-3].arg[1] ==
ic[-5].arg[0] &&
3352 ic[-8].f =
instr(netbsd_r3k_picache_do_inv);
3375 ic[-7].f == mips32_loadstore[4 + 1] &&
3376 ic[-7].arg[0] ==
ic[-1].arg[0] &&
3377 ic[-7].arg[0] ==
ic[-3].arg[0] &&
3378 ic[-7].arg[0] ==
ic[-5].arg[0] &&
3379 ic[-7].arg[0] ==
ic[-7].arg[1] &&
3380 ic[-7].arg[0] ==
ic[-8].arg[0] &&
3383 ic[-5].f ==
instr(bne_samepage_nop) &&
3385 ic[-3].f == mips32_loadstore[4 + 1] &&
3388 ic[-1].arg[2] == (
size_t) &
ic[-8] &&
3389 ic[-1].f ==
instr(beq_samepage)) {
3390 ic[-8].f =
instr(linux_pmax_idle);
3395 ic[-3].
f == mips32_loadstore[4 + 1] &&
3396 ic[-3].arg[0] ==
ic[-1].arg[0] &&
3397 ic[-3].arg[1] ==
ic[-4].arg[0] &&
3400 ic[-1].arg[2] == (
size_t) &
ic[-4] &&
3401 ic[-1].f ==
instr(beq_samepage)) {
3402 ic[-4].f =
instr(netbsd_pmax_idle);
3406 if ((
ic[-3].
f == mips32_loadstore[1] ||
3407 ic[-3].
f == mips32_loadstore[16 + 1]) &&
3408 ic[-3].arg[2] == 0 &&
3409 ic[-3].arg[0] ==
ic[-1].arg[0] &&
ic[-3].arg[1] ==
ic[-2].arg[0] &&
3410 ic[-2].arg[0] ==
ic[-2].arg[1] &&
ic[-2].arg[2] == 1 &&
3413 ic[-1].f ==
instr(bne_samepage)) {
3414 ic[-3].f =
instr(netbsd_strlen);
3419 if (
ic[-1].
f ==
instr(bne_samepage)) {
3420 ic[-1].f =
instr(bne_samepage_nop);
3424 if (
ic[-1].
f ==
instr(beq_samepage)) {
3425 ic[-1].f =
instr(beq_samepage_nop);
3448 ic[-2].f =
instr(xor_andi_sll);
3489 if (
ic[-4].
f ==
instr(multi_addu_3) ||
3490 ic[-3].f ==
instr(multi_addu_3))
3494 ic[-2].f =
instr(multi_addu_3);
3514 ic[-1].f ==
instr(bne_samepage)) {
3515 ic[-2].f =
instr(addiu_bne_samepage_addiu);
3524 if (
ic[-1].
f ==
instr(b_samepage)) {
3525 ic[-1].f =
instr(b_samepage_addiu);
3529 if (
ic[-1].
f ==
instr(beq_samepage)) {
3530 ic[-1].f =
instr(beq_samepage_addiu);
3534 if (
ic[-1].
f ==
instr(bne_samepage)) {
3535 ic[-1].f =
instr(bne_samepage_addiu);
3540 ic[-1].f =
instr(jr_ra_addiu);
3560 if (
ic[-1].
f ==
instr(b_samepage)) {
3561 ic[-1].f =
instr(b_samepage_daddiu);
3581 uint64_t
addr, low_pc;
3582 uint32_t iword, imm;
3583 unsigned char *
page;
3584 unsigned char ib[4];
3585 int main_opcode, rt, rs, rd, sa, s6, x64 = 0, s10;
3586 int in_crosspage_delayslot = 0;
3587 void (*samepage_function)(
struct cpu *,
struct mips_instr_call *);
3588 int store, signedness, size;
3591 low_pc = ((size_t)
ic - (
size_t)
cpu->
cd.
mips.cur_ic_page)
3592 /
sizeof(
struct mips_instr_call);
3598 in_crosspage_delayslot = 1;
3621 page = l3->host_load[x3];
3627 memcpy(ib,
page + (
addr & 0xffc),
sizeof(ib));
3632 fatal(
"to_be_translated(): read failed: TODO\n");
3638 uint32_t *p = (uint32_t *) ib;
3648 #define DYNTRANS_TO_BE_TRANSLATED_HEAD
3650 #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
3662 main_opcode = iword >> 26;
3663 rs = (iword >> 21) & 31;
3664 rt = (iword >> 16) & 31;
3665 rd = (iword >> 11) & 31;
3666 sa = (iword >> 6) & 31;
3667 imm = (int16_t)iword;
3669 s10 = (rs << 5) | sa;
3671 switch (main_opcode) {
3700 x64 = 1; sa = -1;
break;
3705 x64 = 1; sa = -1;
break;
3710 x64 = 1; sa = -1;
break;
3724 if (sa >= 0 && rs != 0x00) {
3727 static int warning_rotate = 0;
3728 if (!warning_rotate &&
3730 fatal(
"[ WARNING! MIPS32/64 "
3731 "revision 2 rotate opcode"
3732 " used, but the %s process"
3733 "or does not implement "
3734 "such instructions. Only "
3736 "warning once. ]\n",
3755 if (sa < 0 && (s10 & 0x1f) != 0) {
3756 int orig_sa = (iword >> 6) & 31;
3759 if (orig_sa == 0x01) {
3895 fatal(
"TODO: rd NON-zero\n");
3924 ic->arg[2] = (
addr & 0xffc) + 8;
3947 fatal(
"TODO: branch in delay "
3954 if (((iword >> 6) & 0xfffff) == 0x30378) {
3963 if (((iword >> 6) & 0xfffff) == 0x30378) {
3987 samepage_function = NULL;
3988 switch (main_opcode) {
3991 samepage_function =
instr(beq_samepage);
3995 samepage_function =
instr(b_samepage);
4000 samepage_function =
instr(bne_samepage);
4004 samepage_function =
instr(beql_samepage);
4008 samepage_function =
instr(b_samepage);
4013 samepage_function =
instr(bnel_samepage);
4017 samepage_function =
instr(blez_samepage);
4021 samepage_function =
instr(blezl_samepage);
4025 samepage_function =
instr(bgtz_samepage);
4029 samepage_function =
instr(bgtzl_samepage);
4035 + (
addr & 0xffc) + 4 );
4043 ic->f = samepage_function;
4047 fatal(
"TODO: branch in delay slot? (2)\n");
4069 ic->arg[2] = (int16_t)iword;
4071 ic->arg[2] = (uint16_t)iword;
4073 switch (main_opcode) {
4085 if (
ic->arg[2] == 0) {
4089 ic->arg[2] =
ic->arg[1];
4107 ic->arg[1] = (int32_t) (imm << 16);
4116 switch (main_opcode) {
4129 ic->arg[0] = (iword & 0x03ffffff) << 2;
4130 ic->arg[1] = (
addr & 0xffc) + 8;
4133 fatal(
"TODO: branch in delay slot (=%i)? (3);"
4134 " addr=%016" PRIx64
" iword=%08" PRIx32
"\n",
4143 if ((iword >> 25) & 1) {
4144 ic->arg[2] =
addr & 0xffc;
4145 switch (iword & 0xff) {
4170 static int warned = 0;
4174 fatal(
"{ WARNING: Attempt to "
4175 "execute the WAIT instruct"
4176 "ion, but the emulated CPU "
4177 "is neither RM52xx, nor "
4187 static int warned = 0;
4191 fatal(
"{ WARNING: Attempt to "
4192 "execute a R41xx instruct"
4193 "ion, but the emulated CPU "
4194 "doesn't support it! }\n");
4220 fatal(
"UNIMPLEMENTED cop0 (func "
4221 "0x%02x)\n", iword & 0xff);
4231 ic->arg[1] = rd + ((iword & 7) << 5);
4232 ic->arg[2] =
addr & 0xffc;
4240 ic->arg[1] = rd + ((iword & 7) << 5);
4241 ic->arg[2] =
addr & 0xffc;
4243 if (rs ==
COPz_MFCz && (iword & 7) == 0 &&
4255 ic->arg[1] = rd + ((iword & 7) << 5);
4256 ic->arg[2] =
addr & 0xffc;
4266 if ((iword & 0xffdf) == 0x6000) {
4270 static int warning_ei_di = 0;
4271 if (!warning_ei_di &&
4273 fatal(
"[ WARNING! MIPS32/64 "
4274 "revision 2 di or ei opcode"
4275 " used, but the %s process"
4276 "or does not implement "
4277 "such instructions. Only "
4279 "warning once. ]\n",
4291 ic->arg[1] = iword & 0x20;
4294 fatal(
"Unimplemented COP0_MFMCz\n");
4299 if (iword == 0x4100ffff) {
4304 fatal(
"Unimplemented COP0_BCzc\n");
4310 fatal(
"UNIMPLEMENTED cop0 (rs = %i)\n", rs);
4332 ic->arg[0] = (iword >> 18) & 7;
4333 ic->arg[1] = (iword >> 16) & 3;
4334 ic->arg[2] = (int32_t) ((imm <<
4338 fatal(
"TODO: branch in delay slot 4\n");
4344 fatal(
"Attempt to execute a non-cc-0 "
4345 "BC* instruction on an isa level "
4346 "%i cpu. TODO: How should this be "
4370 ic->arg[0] = (uint32_t)iword & ((1 << 26) - 1);
4374 fatal(
"COP1 floating point opcode = 0x%02x\n", rs);
4388 fatal(
"COP2 functionality not yet implemented\n");
4401 if (iword == 0x4d00ffff) {
4407 fatal(
"COP3 iword=0x%08x\n", iword);
4415 int mmi_subopcode = (iword >> 6) & 0x1f;
4440 switch (mmi_subopcode) {
4457 switch (mmi_subopcode) {
4541 samepage_function = NULL;
4545 samepage_function =
instr(bgez_samepage);
4549 samepage_function =
instr(bgezl_samepage);
4553 samepage_function =
instr(bltz_samepage);
4557 samepage_function =
instr(bltzl_samepage);
4561 samepage_function =
instr(bgezal_samepage);
4565 samepage_function =
instr(bgezall_samepage);
4569 samepage_function =
instr(bltzal_samepage);
4573 samepage_function =
instr(bltzall_samepage);
4578 + (
addr & 0xffc) + 4;
4588 ic->f = samepage_function;
4592 fatal(
"TODO: branch in delay slot:5\n");
4612 ic->arg[2] = (int64_t)(int16_t)imm;
4615 static int warning = 0;
4617 fatal(
"[ WARNING! Trap opcode used, but"
4618 " the %s processor does not implement "
4619 "such instructions. Only printing this "
4620 "warning once. ]\n",
4629 fatal(
"UNIMPLEMENTED regimm rt=%i\n", rt);
4646 size = 2; signedness = 0; store = 0;
4647 switch (main_opcode) {
4648 case HI6_LB: size = 0; signedness = 1;
break;
4649 case HI6_LBU: size = 0;
break;
4650 case HI6_LH: size = 1; signedness = 1;
break;
4651 case HI6_LHU: size = 1;
break;
4652 case HI6_LW: signedness = 1;
break;
4654 case HI6_LD: size = 3; x64 = 1;
break;
4655 case HI6_SB: store = 1; size = 0;
break;
4656 case HI6_SH: store = 1; size = 1;
break;
4657 case HI6_SW: store = 1;
break;
4658 case HI6_SD: store = 1; size = 3; x64 = 1;
break;
4668 + store * 8 + size * 2 + signedness];
4671 ic->arg[2] = (int32_t)imm;
4681 if (main_opcode ==
HI6_SW)
4697 switch (main_opcode) {
4705 ic->arg[2] = (int32_t)imm;
4708 fatal(
"HM... unusual load linked\n");
4723 switch (main_opcode) {
4735 ic->arg[2] = (int32_t)imm;
4755 ic->arg[2] = (int32_t)imm;
4756 switch (main_opcode) {
4779 fatal(
"TODO: lwc3 not implemented yet\n");
4787 fatal(
"TODO: R5900 128-bit loads\n");
4792 fatal(
"TODO: MDMX\n");
4800 fatal(
"TODO: R5900 128-bit stores\n");
4806 static int warning = 0;
4808 fatal(
"[ WARNING! SPECIAL3 opcode used, but"
4809 " the %s processor does not implement "
4810 "such instructions. Only printing this "
4811 "warning once. ]\n",
4823 int msbd = rd, lsb = (iword >> 6) & 0x1f;
4826 ic->arg[2] = (msbd << 5) + lsb;
4837 int msbd = rd, lsb = (iword >> 6) & 0x1f;
4844 ic->arg[2] = (msbd << 6) + lsb;
4853 int msb = rd, lsb = (iword >> 6) & 0x1f;
4856 ic->arg[2] = (msb << 5) + lsb;
4899 case 0:
ic->f =
instr(rdhwr_cpunum);
4904 case 2:
ic->f =
instr(rdhwr_cc);
4909 case 29:
ic->f =
instr(reserved);
4913 fatal(
"unimplemented rdhwr "
4914 "register rd=%i\n", rd);
4934 static int has_warned = 0;
4936 fatal(
"[ WARNING/NOTE: attempt to execute a 64-bit"
4937 " instruction on an emulated 32-bit processor; "
4938 "pc=0x%08" PRIx32
" ]\n", (uint32_t)
cpu->
pc);
4951 #define DYNTRANS_TO_BE_TRANSLATED_TAIL
4953 #undef DYNTRANS_TO_BE_TRANSLATED_TAIL