42 static void gather_statistics(
struct cpu *
cpu)
48 int low_pc = ((size_t)cpu->
cd.DYNTRANS_ARCH.next_ic - (
size_t)
49 cpu->
cd.DYNTRANS_ARCH.cur_ic_page) /
sizeof(
struct DYNTRANS_IC);
52 fatal(
"statistics gathering with no filename set is" 65 strlcat(buf,
" ",
sizeof(buf));
69 snprintf(buf +
strlen(buf),
sizeof(buf),
75 cpu->
cd.DYNTRANS_ARCH.cur_ic_page;
76 a = cpu->
cd.DYNTRANS_ARCH.cur_physpage->physaddr;
77 a &= ~((DYNTRANS_IC_ENTRIES_PER_PAGE-1) <<
81 snprintf(buf +
strlen(buf),
sizeof(buf),
82 "0x%08" PRIx32, (uint32_t)a);
84 snprintf(buf +
strlen(buf),
sizeof(buf),
85 "0x%016" PRIx64, (uint64_t)a);
90 a &= ~((DYNTRANS_IC_ENTRIES_PER_PAGE-1) <<
91 DYNTRANS_INSTR_ALIGNMENT_SHIFT);
94 snprintf(buf +
strlen(buf),
sizeof(buf),
95 "0x%08" PRIx32, (uint32_t)a);
97 snprintf(buf +
strlen(buf),
sizeof(buf),
98 "0x%016" PRIx64, (uint64_t)a);
108 #define S gather_statistics(cpu) 114 #define I ic = cpu->cd.DYNTRANS_ARCH.next_ic ++; ic->f(cpu, ic); 119 #define I ic = cpu->cd.DYNTRANS_ARCH.next_ic ++; \ 121 int low_pc = ((size_t)cpu->cd.DYNTRANS_ARCH.next_ic - \ 122 (size_t)cpu->cd.DYNTRANS_ARCH.cur_ic_page) / \ 123 sizeof(struct DYNTRANS_IC); \ 124 printf("cur_ic_page=%p ic=%p (low_pc=0x%x)\n", \ 125 cpu->cd.DYNTRANS_ARCH.cur_ic_page, \ 126 ic, low_pc << DYNTRANS_INSTR_ALIGNMENT_SHIFT); \ 167 #ifdef DYNTRANS_RUN_INSTR_DEF 180 int low_pc, n_instrs;
183 #ifdef DYNTRANS_DUALMODE_32 185 DYNTRANS_PC_TO_POINTERS32(cpu);
268 cpu->
cd.DYNTRANS_ARCH.cur_ic_page;
283 unsigned char instr[1 <<
285 if (!cpu->
memory_rw(cpu, cpu->
mem, cached_pc, &instr[0],
287 fatal(
"XXX_run_instr(): could not read " 288 "the instruction\n");
290 #ifdef DYNTRANS_DELAYSLOT 295 #ifdef DYNTRANS_DELAYSLOT 299 fatal(
"WARNING: ihd func not yet" 311 cpu, instr, 1, cpu->
pc);
379 low_pc = ((size_t)cpu->
cd.DYNTRANS_ARCH.next_ic - (
size_t)
380 cpu->
cd.DYNTRANS_ARCH.cur_ic_page) /
sizeof(
struct DYNTRANS_IC);
404 int32_t diff1, diff2;
410 (int32_t) (old + n_instrs);
424 if (diff1 > 0 && diff2 <= 0)
455 #ifdef DYNTRANS_FUNCTION_TRACE_DEF 465 int show_symbolic_function_name = 1;
469 int x, print_dots = 1, n_args_to_print =
470 #if defined(DYNTRANS_ALPHA) 473 #if defined(DYNTRANS_SH) || defined(DYNTRANS_M88K) 481 if (n_args >= 0 && n_args <= n_args_to_print) {
483 n_args_to_print = n_args;
489 show_symbolic_function_name = 0;
504 for (x=0; x<n_args_to_print; x++) {
505 int64_t d = cpu->
cd.DYNTRANS_ARCH.
529 if (d > -256 && d < 256)
532 memset(strbuf, 0,
sizeof(strbuf));
534 cpu->
mem, d, strbuf,
sizeof(strbuf));
535 fatal(
"\"%s\"", strbuf);
540 if (
strlen(strbuf) >=
sizeof(strbuf)-1)
542 }
else if (symbol != NULL && ot == 0 &&
543 show_symbolic_function_name)
544 fatal(
"&%s", symbol);
547 fatal(
"0x%" PRIx32, (uint32_t)d);
549 fatal(
"0x%" PRIx64, (uint64_t)d);
552 if (x < n_args_to_print - 1)
563 #ifdef DYNTRANS_TC_ALLOCATE_DEFAULT_PAGE_DEF 579 memcpy(ppp, cpu->
cd.DYNTRANS_ARCH.physpage_template,
sizeof(
594 #ifdef DYNTRANS_PC_TO_POINTERS_FUNC 607 cached_pc = cpu->
pc, physaddr = 0;
608 uint32_t physpage_ofs;
609 int ok, pagenr, table_index;
610 uint32_t *physpage_entryp;
628 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
637 if (cpu->
cd.DYNTRANS_ARCH.host_load[index] != NULL) {
638 physaddr = cpu->
cd.DYNTRANS_ARCH.phys_addr[index];
642 if (l3->host_load[x3] != NULL) {
643 physaddr = l3->phys_addr[x3];
652 #if defined(MODE32) && defined(DYNTRANS_MIPS) 680 if (cpu->
cd.DYNTRANS_ARCH.host_load[index] != NULL) {
681 paddr = cpu->
cd.DYNTRANS_ARCH.phys_addr[index];
690 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
692 if (l3->host_load[x3] != NULL) {
693 paddr = l3->phys_addr[x3];
708 fatal(
"FATAL: could not find physical" 709 " address of the exception handler?");
720 if (cpu->
cd.DYNTRANS_ARCH.host_load[index] == NULL) {
722 if (l3->host_load[x3] == NULL) {
727 if (host_page != NULL) {
729 host_page, 0, physaddr);
734 #ifdef UNSTABLE_DEVEL 735 fatal(
"[ dyntrans: resetting the translation cache ]\n");
744 physpage_ofs = *physpage_entryp;
748 while (physpage_ofs != 0) {
753 if (ppp->physaddr == physaddr)
757 physpage_ofs = ppp->next_ofs;
765 if (physpage_ofs == 0) {
766 uint32_t previous_first_page_in_chain;
772 previous_first_page_in_chain = *physpage_entryp;
775 *physpage_entryp = physpage_ofs =
785 ppp->next_ofs = previous_first_page_in_chain;
791 if (cpu->
cd.DYNTRANS_ARCH.host_load[index] != NULL)
792 cpu->
cd.DYNTRANS_ARCH.phys_page[index] = ppp;
794 if (l3->host_load[x3] != NULL)
795 l3->phys_page[x3] = ppp;
803 if (ppp->translations_bitmap == 0) {
808 cpu->
cd.DYNTRANS_ARCH.cur_ic_page = &ppp->ics[0];
810 cpu->
cd.DYNTRANS_ARCH.next_ic = cpu->
cd.DYNTRANS_ARCH.cur_ic_page +
845 ppp = cpu->
cd.DYNTRANS_ARCH.phys_page[index];
859 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
861 ppp = l3->phys_page[x3];
871 cpu->
cd.DYNTRANS_ARCH.cur_ic_page = &ppp->ics[0];
872 cpu->
cd.DYNTRANS_ARCH.next_ic = cpu->
cd.DYNTRANS_ARCH.cur_ic_page +
883 #ifdef DYNTRANS_INIT_TABLES 888 #ifdef DYNTRANS_DUALMODE_32 889 static void instr32(to_be_translated)(
struct cpu *,
struct DYNTRANS_IC *);
890 static void instr32(end_of_page)(
struct cpu *,
struct DYNTRANS_IC *);
893 #ifdef DYNTRANS_DUALMODE_32 894 #define TO_BE_TRANSLATED ( cpu->is_32bit? instr32(to_be_translated) : \ 895 instr(to_be_translated) ) 897 #define TO_BE_TRANSLATED ( instr(to_be_translated) ) 900 #ifdef DYNTRANS_DELAYSLOT 902 #ifdef DYNTRANS_DUALMODE_32 903 static void instr32(end_of_page2)(
struct cpu *,
struct DYNTRANS_IC *);
927 ppp->translations_bitmap = 0;
928 ppp->translation_ranges_ofs = 0;
932 ppp->ics[i].f = TO_BE_TRANSLATED;
935 ppp->ics[DYNTRANS_IC_ENTRIES_PER_PAGE + 0].f =
937 cpu->
is_32bit? instr32(end_of_page) :
942 #ifdef DYNTRANS_DELAYSLOT 943 ppp->ics[DYNTRANS_IC_ENTRIES_PER_PAGE + 1].f =
944 #ifdef DYNTRANS_DUALMODE_32 945 cpu->
is_32bit? instr32(end_of_page2) :
950 cpu->
cd.DYNTRANS_ARCH.physpage_template = ppp;
961 cpu->
cd.DYNTRANS_ARCH.l2_64_dummy = dummy_l2;
962 cpu->
cd.DYNTRANS_ARCH.l3_64_dummy = dummy_l3;
965 cpu->
cd.DYNTRANS_ARCH.l1_64[x1] = dummy_l2;
968 dummy_l2->l3[x2] = dummy_l3;
975 #ifdef DYNTRANS_INVAL_ENTRY 991 vaddr_page,
int flags)
997 cpu->
cd.DYNTRANS_ARCH.is_userpage[index >> 5] &= ~(1 << (index & 31));
1003 cpu->
cd.DYNTRANS_ARCH.host_store[index] = NULL;
1005 int tlbi = cpu->
cd.DYNTRANS_ARCH.vaddr_to_tlbindex[index];
1006 cpu->
cd.DYNTRANS_ARCH.host_load[index] = NULL;
1007 cpu->
cd.DYNTRANS_ARCH.host_store[index] = NULL;
1008 cpu->
cd.DYNTRANS_ARCH.phys_addr[index] = 0;
1009 cpu->
cd.DYNTRANS_ARCH.phys_page[index] = NULL;
1011 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[tlbi-1].valid = 0;
1012 cpu->
cd.DYNTRANS_ARCH.vaddr_to_tlbindex[index] = 0;
1018 uint32_t x1, x2, x3;
1026 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
1027 if (l2 == cpu->
cd.DYNTRANS_ARCH.l2_64_dummy)
1031 if (l3 == cpu->
cd.DYNTRANS_ARCH.l3_64_dummy)
1034 if (flags & JUST_MARK_AS_NON_WRITABLE) {
1035 l3->host_store[x3] = NULL;
1047 for (x1 = 0; x1 <= mask1; x1 ++) {
1048 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
1049 if (l2 == cpu->
cd.DYNTRANS_ARCH.l2_64_dummy)
1052 for (x1b = 0; x1b <= mask1; x1b ++)
1054 l2 == cpu->
cd.DYNTRANS_ARCH.l1_64[x1b]) {
1055 fatal(
"L2 reuse: %p\n", l2);
1064 for (i=0; i<=mask3; i++)
1065 if (l3->vaddr_to_tlbindex[i])
1067 if (n != l3->refcount) {
1068 printf(
"Z: %i in use, but refcount = %i!\n", n, l3->refcount);
1073 for (i=0; i<=mask3; i++)
1074 if (l3->host_load[i] != NULL)
1076 if (n != l3->refcount) {
1077 printf(
"ZHL: %i in use, but refcount = %i!\n", n, l3->refcount);
1111 l3->host_load[x3] = NULL;
1112 l3->host_store[x3] = NULL;
1113 l3->phys_addr[x3] = 0;
1114 l3->phys_page[x3] = NULL;
1115 if (l3->vaddr_to_tlbindex[x3] != 0) {
1116 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[
1117 l3->vaddr_to_tlbindex[x3] - 1].valid = 0;
1130 l3->vaddr_to_tlbindex[x3] = 0;
1132 if (l3->refcount < 0) {
1133 fatal(
"xxx_invalidate_tlb_entry(): huh? Refcount bug.\n");
1137 if (l3->refcount == 0) {
1138 l3->next = cpu->
cd.DYNTRANS_ARCH.next_free_l3;
1139 cpu->
cd.DYNTRANS_ARCH.next_free_l3 = l3;
1140 l2->l3[x2] = cpu->
cd.DYNTRANS_ARCH.l3_64_dummy;
1147 for (i=0; i<=mask3; i++)
1148 if (l3->host_load[i] != NULL) {
1149 fatal(
"TRYING TO RETURN A NON-CLEAN L3 PAGE!\n");
1155 if (l2->refcount < 0) {
1156 fatal(
"xxx_invalidate_tlb_entry(): Refcount bug L2.\n");
1159 if (l2->refcount == 0) {
1160 l2->next = cpu->
cd.DYNTRANS_ARCH.next_free_l2;
1161 cpu->
cd.DYNTRANS_ARCH.next_free_l2 = l2;
1162 cpu->
cd.DYNTRANS_ARCH.l1_64[x1] =
1163 cpu->
cd.DYNTRANS_ARCH.l2_64_dummy;
1171 #ifdef DYNTRANS_INVALIDATE_TC 1216 if (cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid &&
1217 (cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page
1218 & 0xf0000000) == addr_page) {
1222 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid=0;
1231 if (cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid) {
1235 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid=0;
1244 fatal(
"HUH? Invalidate: Not vaddr, all, or paddr?\n");
1249 if (cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid && addr_page
1250 == cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].paddr_page) {
1252 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page,
1255 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r]
1258 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r]
1267 #ifdef DYNTRANS_INVALIDATE_TC_CODE 1282 vaddr_page, paddr_page;
1290 int pagenr, table_index;
1291 uint32_t physpage_ofs, *physpage_entryp;
1297 physpage_entryp = &(((uint32_t *)cpu->
1298 translation_cache)[table_index]);
1299 physpage_ofs = *physpage_entryp;
1303 if (physpage_ofs == 0)
1306 prev_ppp = ppp = NULL;
1309 while (physpage_ofs != 0) {
1316 if (ppp->physaddr == addr)
1320 physpage_ofs = ppp->next_ofs;
1325 if (physpage_ofs == 0)
1337 if (prev_ppp != NULL)
1338 prev_ppp->next_ofs = ppp->next_ofs;
1340 *physpage_entryp = ppp->next_ofs;
1352 if (ppp != NULL && ppp->translations_bitmap != 0) {
1353 uint32_t x = ppp->translations_bitmap;
1372 for (i=0; i<n; i++) {
1375 ppp->ics[i*m + j].f =
1382 ppp->translations_bitmap = 0;
1385 if (ppp->translation_ranges_ofs != 0) {
1387 (
struct physpage_ranges *)
1389 ppp->translation_ranges_ofs);
1399 if (cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid) {
1400 vaddr_page = cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r]
1402 paddr_page = cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r]
1406 (flags & INVALIDATE_PADDR && paddr_page == addr) ||
1411 cpu->
cd.DYNTRANS_ARCH.phys_page[index] = NULL;
1416 uint32_t x1, x2, x3;
1425 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
1427 l3->phys_page[x3] = NULL;
1437 #ifdef DYNTRANS_UPDATE_TRANSLATION_TABLE 1444 unsigned char *host_page,
int writeflag, uint64_t paddr_page)
1446 int found, r, useraccess = 0;
1450 vaddr_page &= 0xffffffffULL;
1452 if (paddr_page > 0xffffffffULL) {
1453 fatal(
"update_translation_table(): v=0x%016" PRIx64
", h=%p w=%i" 1454 " p=0x%016" PRIx64
"\n", vaddr_page, host_page, writeflag,
1466 uint32_t x1, x2, x3;
1479 writeflag &= ~MEMORY_USER_ACCESS;
1485 #ifdef DYNTRANS_M88K 1502 found = (int)cpu->
cd.DYNTRANS_ARCH.vaddr_to_tlbindex[
1510 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
1511 if (l2 == cpu->
cd.DYNTRANS_ARCH.l2_64_dummy)
1515 if (l3 == cpu->
cd.DYNTRANS_ARCH.l3_64_dummy)
1518 found = (int)l3->vaddr_to_tlbindex[x3] - 1;
1524 static unsigned int x = 0;
1527 if (cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid) {
1530 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page,
1534 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid = 1;
1535 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].host_page = host_page;
1536 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].paddr_page = paddr_page;
1537 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page = vaddr_page;
1538 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag =
1544 cpu->
cd.DYNTRANS_ARCH.host_load[index] = host_page;
1545 cpu->
cd.DYNTRANS_ARCH.host_store[index] =
1546 writeflag? host_page : NULL;
1547 cpu->
cd.DYNTRANS_ARCH.phys_addr[index] = paddr_page;
1548 cpu->
cd.DYNTRANS_ARCH.phys_page[index] = NULL;
1549 cpu->
cd.DYNTRANS_ARCH.vaddr_to_tlbindex[index] = r + 1;
1552 cpu->
cd.DYNTRANS_ARCH.is_userpage[index >> 5]
1553 |= 1 << (index & 31);
1556 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
1557 if (l2 == cpu->
cd.DYNTRANS_ARCH.l2_64_dummy) {
1558 if (cpu->
cd.DYNTRANS_ARCH.next_free_l2 != NULL) {
1559 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1] =
1560 cpu->
cd.DYNTRANS_ARCH.next_free_l2;
1561 cpu->
cd.DYNTRANS_ARCH.next_free_l2 = l2->next;
1565 cpu->
cd.DYNTRANS_ARCH.l1_64[x1] =
1570 l2->l3[i] = cpu->
cd.DYNTRANS_ARCH.
1573 if (l2->refcount != 0) {
1574 fatal(
"Huh? l2 Refcount problem.\n");
1578 if (l2 == cpu->
cd.DYNTRANS_ARCH.l2_64_dummy) {
1579 fatal(
"INTERNAL ERROR L2 reuse\n");
1583 if (l3 == cpu->
cd.DYNTRANS_ARCH.l3_64_dummy) {
1584 if (cpu->
cd.DYNTRANS_ARCH.next_free_l3 != NULL) {
1586 cpu->
cd.DYNTRANS_ARCH.next_free_l3;
1587 cpu->
cd.DYNTRANS_ARCH.next_free_l3 = l3->next;
1593 if (l3->refcount != 0) {
1594 fatal(
"Huh? l3 Refcount problem.\n");
1599 if (l3 == cpu->
cd.DYNTRANS_ARCH.l3_64_dummy) {
1600 fatal(
"INTERNAL ERROR L3 reuse\n");
1604 l3->host_load[x3] = host_page;
1605 l3->host_store[x3] = writeflag? host_page : NULL;
1606 l3->phys_addr[x3] = paddr_page;
1607 l3->phys_page[x3] = NULL;
1608 l3->vaddr_to_tlbindex[x3] = r + 1;
1615 for (i=0; i<=mask3; i++)
1616 if (l3->vaddr_to_tlbindex[i])
1618 if (n != l3->refcount) {
1619 printf(
"X: %i in use, but refcount = %i!\n", n, l3->refcount);
1624 for (i=0; i<=mask3; i++)
1625 if (l3->host_load[i] != NULL)
1627 if (n != l3->refcount) {
1628 printf(
"XHL: %i in use, but refcount = %i!\n", n, l3->refcount);
1644 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag = 1;
1646 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag = 0;
1649 cpu->
cd.DYNTRANS_ARCH.phys_page[index] = NULL;
1651 cpu->
cd.DYNTRANS_ARCH.is_userpage[index>>5] &= ~(1<<(index&31));
1653 cpu->
cd.DYNTRANS_ARCH.is_userpage[index >> 5]
1654 |= 1 << (index & 31);
1656 if (cpu->
cd.DYNTRANS_ARCH.phys_addr[index] == paddr_page) {
1657 if (writeflag & MEM_WRITE)
1658 cpu->
cd.DYNTRANS_ARCH.host_store[index] =
1660 if (writeflag & MEM_DOWNGRADE)
1661 cpu->
cd.DYNTRANS_ARCH.host_store[index] = NULL;
1664 cpu->
cd.DYNTRANS_ARCH.host_load[index] = host_page;
1665 cpu->
cd.DYNTRANS_ARCH.host_store[index] =
1666 writeflag? host_page : NULL;
1667 cpu->
cd.DYNTRANS_ARCH.phys_addr[index] = paddr_page;
1674 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
1676 if (l3->phys_addr[x3] == paddr_page) {
1677 if (writeflag & MEM_WRITE)
1678 l3->host_store[x3] = host_page;
1679 if (writeflag & MEM_DOWNGRADE)
1680 l3->host_store[x3] = NULL;
1683 l3->host_load[x3] = host_page;
1684 l3->host_store[x3] = writeflag? host_page : NULL;
1685 l3->phys_addr[x3] = paddr_page;
1696 for (i=0; i<=mask3; i++)
1697 if (l3->vaddr_to_tlbindex[i])
1699 if (n != l3->refcount) {
1700 printf(
"Y: %i in use, but refcount = %i!\n", n, l3->refcount);
1705 for (i=0; i<=mask3; i++)
1706 if (l3->host_load[i] != NULL)
1708 if (n != l3->refcount) {
1709 printf(
"YHL: %i in use, but refcount = %i!\n", n, l3->refcount);
1710 printf(
"Entry r = %i\n", r);
1711 printf(
"Valid = %i\n",
1712 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid);
1727 #ifdef DYNTRANS_TO_BE_TRANSLATED_HEAD 1744 fatal(
"BREAKPOINT: pc = 0x%" PRIx32
"\n(The " 1745 "instruction has not yet executed.)\n",
1748 fatal(
"BREAKPOINT: pc = 0x%" PRIx64
"\n(The " 1749 "instruction has not yet executed.)\n",
1752 #ifdef DYNTRANS_DELAYSLOT 1754 fatal(
"ERROR! Breakpoint in a delay" 1755 " slot! Not yet supported.\n");
1759 goto stop_running_translated;
1768 #ifdef DYNTRANS_TO_BE_TRANSLATED_TAIL 1776 cpu->
cd.DYNTRANS_ARCH.cur_ic_page;
1781 sizeof(cpu->
cd.DYNTRANS_ARCH.cur_physpage->
1782 translations_bitmap));
1783 x /= addr_per_translation_range;
1785 cpu->
cd.DYNTRANS_ARCH.cur_physpage->
1786 translations_bitmap |= (1 << x);
1801 && !in_crosspage_delayslot
1803 && cpu->
cd.DYNTRANS_ARCH.combination_check != NULL
1805 cpu->
cd.DYNTRANS_ARCH.combination_check(cpu,
ic,
1809 cpu->
cd.DYNTRANS_ARCH.combination_check = NULL;
1812 if (
ic->f == TO_BE_TRANSLATED) {
1813 fatal(
"INTERNAL ERROR: ic->f not set!\n");
1816 if (
ic->f == NULL) {
1817 fatal(
"INTERNAL ERROR: ic->f == NULL!\n");
1837 || in_crosspage_delayslot
1842 ic->f = TO_BE_TRANSLATED;
1850 uint64_t baseaddr = cpu->
pc;
1859 void (*old_f)(
struct cpu *,
1863 if (old_f != TO_BE_TRANSLATED)
1870 if (
ic[i].
f == old_f)
1898 ic->f = TO_BE_TRANSLATED;
1904 fatal(
"to_be_translated(): TODO: unimplemented instruction");
1908 fatal(
" at 0x%" PRIx32
"\n", (uint32_t)cpu->
pc);
1910 fatal(
" at 0x%" PRIx64
"\n", (uint64_t)cpu->
pc);
1919 stop_running_translated:
1923 ic = cpu->
cd.DYNTRANS_ARCH.next_ic = ¬hing_call;
1924 cpu->
cd.DYNTRANS_ARCH.next_ic ++;
1926 #ifdef DYNTRANS_DELAYSLOT void * zeroed_alloc(size_t s)
void fatal(const char *fmt,...)
#define DYNTRANS_INIT_TABLES
int(* translate_v2p)(struct cpu *, uint64_t vaddr, uint64_t *return_paddr, int flags)
#define JUST_MARK_AS_NON_WRITABLE
#define DYNTRANS_INVALIDATE_TC
#define DYNTRANS_TC_ALLOCATE
#define DYNTRANS_PC_TO_POINTERS
#define DYNTRANS_PC_TO_POINTERS_GENERIC
struct arm_instr_call * ic
struct breakpoints breakpoints
#define DYNTRANS_UPDATE_TRANSLATION_TABLE
void f(int s, int func, int only_name)
int memory_points_to_string(struct cpu *cpu, struct memory *mem, uint64_t addr, int min_string_length)
#define DYNTRANS_L2_64_TABLE
#define DYNTRANS_PAGESIZE
#define DYNTRANS_PC_TO_POINTERS_FUNC
#define DYNTRANS_MAX_VPH_TLB_ENTRIES
void m88k_exception(struct cpu *cpu, int vector, int is_trap)
void sh_exception(struct cpu *cpu, int expevt, int intevt, uint32_t vaddr)
char * get_symbol_name(struct symbol_context *, uint64_t addr, uint64_t *offset)
#define DYNTRANS_DELAYSLOT
#define M88K_EXCEPTION_INTERRUPT
int debugger_n_steps_left_before_interaction
int translation_readahead
int32_t count_register_read_count
#define CHECK_ALLOCATION(ptr)
#define DYNTRANS_TC_ALLOCATE_DEFAULT_PAGE_DEF
void arm_exception(struct cpu *cpu, int exception_nr)
uint64_t reg[N_MIPS_COPROC_REGS]
#define ARM_EXCEPTION_IRQ
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
struct interrupt irq_compare
size_t translation_cache_cur_ofs
int compare_interrupts_pending
#define INTERRUPT_ASSERT(istruct)
unsigned char * translation_cache
void mips_cpu_exception(struct cpu *cpu, int exccode, int tlb, uint64_t vaddr, int coproc_nr, uint64_t vaddr_vpn2, int vaddr_asid, int x_64)
#define ENTER_SINGLE_STEPPING
#define SH_SR_IMASK_SHIFT
struct mips_coproc * coproc[N_MIPS_COPROCS]
void cpu_register_dump(struct machine *m, struct cpu *cpu, int gprs, int coprocs)
#define DYNTRANS_INVALIDATE_TLB_ENTRY
void ppc_exception(struct cpu *cpu, int exception_nr)
uint32_t cr[N_M88K_CONTROL_REGS]
int(* instruction_has_delayslot)(struct cpu *cpu, unsigned char *ib)
void COMBINE() strlen(struct cpu *cpu, struct arm_instr_call *ic, int low_addr)
#define CACHE_INSTRUCTION
#define MEMORY_USER_ACCESS
#define MAX_DYNTRANS_READAHEAD
struct symbol_context symbol_context
#define DYNTRANS_IC_ENTRIES_PER_PAGE
#define DYNTRANS_PC_TO_IC_ENTRY
#define DYNTRANS_RUN_INSTR_DEF
int allow_instruction_combinations
#define DYNTRANS_FUNCTION_TRACE_DEF
char * memory_conv_to_string(struct cpu *cpu, struct memory *mem, uint64_t addr, char *buf, int bufsize)
#define DYNTRANS_DUALMODE_32
#define EXCEPTION_IN_DELAY_SLOT
size_t dyntrans_cache_size
void(* update_translation_table)(struct cpu *, uint64_t vaddr_page, unsigned char *host_page, int writeflag, uint64_t paddr_page)
#define DYNTRANS_INVALIDATE_TC_CODE
struct statistics statistics
int cpu_disassemble_instr(struct machine *m, struct cpu *cpu, unsigned char *instr, int running, uint64_t addr)
addr & if(addr >=0x24 &&page !=NULL)
#define PPC_EXCEPTION_DEC
#define N_SAFE_DYNTRANS_LIMIT
void cpu_create_or_reset_tc(struct cpu *cpu)
#define DYNTRANS_TC_PHYSPAGE
#define DYNTRANS_INSTR_ALIGNMENT_SHIFT
struct mips_cpu_type_def cpu_type
#define DYNTRANS_L3_64_TABLE
#define DYNTRANS_ADDR_TO_PAGENR
volatile int single_step_breakpoint
#define PAGENR_TO_TABLE_INDEX(a)
struct ppc_cpu_type_def cpu_type
#define INVALIDATE_VADDR_UPPER4
int arm_cpu_interpret_thumb_SLOW(struct cpu *cpu)
void(* invalidate_translation_caches)(struct cpu *, uint64_t paddr, int flags)
unsigned char * memory_paddr_to_hostaddr(struct memory *mem, uint64_t paddr, int writeflag)