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);
254 fatal(
"THUMB execution not implemented.\n");
265 cpu->
cd.DYNTRANS_ARCH.cur_ic_page;
280 unsigned char instr[1 <<
282 if (!cpu->
memory_rw(cpu, cpu->
mem, cached_pc, &instr[0],
284 fatal(
"XXX_run_instr(): could not read " 285 "the instruction\n");
287 #ifdef DYNTRANS_DELAYSLOT 291 cpu->
machine, cpu, instr, 1, 0);
292 #ifdef DYNTRANS_DELAYSLOT 296 fatal(
"WARNING: ihd func not yet" 376 low_pc = ((size_t)cpu->
cd.DYNTRANS_ARCH.next_ic - (
size_t)
377 cpu->
cd.DYNTRANS_ARCH.cur_ic_page) /
sizeof(
struct DYNTRANS_IC);
401 int32_t diff1, diff2;
407 (int32_t) (old + n_instrs);
421 if (diff1 > 0 && diff2 <= 0)
452 #ifdef DYNTRANS_FUNCTION_TRACE_DEF 462 int show_symbolic_function_name = 1;
466 int x, print_dots = 1, n_args_to_print =
467 #if defined(DYNTRANS_ALPHA) 470 #if defined(DYNTRANS_SH) || defined(DYNTRANS_M88K) 478 if (n_args >= 0 && n_args <= n_args_to_print) {
480 n_args_to_print = n_args;
486 show_symbolic_function_name = 0;
501 for (x=0; x<n_args_to_print; x++) {
502 int64_t d = cpu->
cd.DYNTRANS_ARCH.
526 if (d > -256 && d < 256)
530 cpu->
mem, d, strbuf,
sizeof(strbuf)));
531 else if (symbol != NULL && ot == 0 &&
532 show_symbolic_function_name)
533 fatal(
"&%s", symbol);
536 fatal(
"0x%" PRIx32, (uint32_t)d);
538 fatal(
"0x%" PRIx64, (uint64_t)d);
541 if (x < n_args_to_print - 1)
552 #ifdef DYNTRANS_TC_ALLOCATE_DEFAULT_PAGE_DEF 568 memcpy(ppp, cpu->
cd.DYNTRANS_ARCH.physpage_template,
sizeof(
583 #ifdef DYNTRANS_PC_TO_POINTERS_FUNC 596 cached_pc = cpu->
pc, physaddr = 0;
597 uint32_t physpage_ofs;
598 int ok, pagenr, table_index;
599 uint32_t *physpage_entryp;
617 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
626 if (cpu->
cd.DYNTRANS_ARCH.host_load[index] != NULL) {
627 physaddr = cpu->
cd.DYNTRANS_ARCH.phys_addr[index];
631 if (l3->host_load[x3] != NULL) {
632 physaddr = l3->phys_addr[x3];
641 #if defined(MODE32) && defined(DYNTRANS_MIPS) 669 if (cpu->
cd.DYNTRANS_ARCH.host_load[index] != NULL) {
670 paddr = cpu->
cd.DYNTRANS_ARCH.phys_addr[index];
679 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
681 if (l3->host_load[x3] != NULL) {
682 paddr = l3->phys_addr[x3];
697 fatal(
"FATAL: could not find physical" 698 " address of the exception handler?");
709 if (cpu->
cd.DYNTRANS_ARCH.host_load[index] == NULL) {
711 if (l3->host_load[x3] == NULL) {
716 if (host_page != NULL) {
718 host_page, 0, physaddr);
723 #ifdef UNSTABLE_DEVEL 724 fatal(
"[ dyntrans: resetting the translation cache ]\n");
733 physpage_ofs = *physpage_entryp;
737 while (physpage_ofs != 0) {
742 if (ppp->physaddr == physaddr)
746 physpage_ofs = ppp->next_ofs;
754 if (physpage_ofs == 0) {
755 uint32_t previous_first_page_in_chain;
761 previous_first_page_in_chain = *physpage_entryp;
764 *physpage_entryp = physpage_ofs =
774 ppp->next_ofs = previous_first_page_in_chain;
780 if (cpu->
cd.DYNTRANS_ARCH.host_load[index] != NULL)
781 cpu->
cd.DYNTRANS_ARCH.phys_page[index] = ppp;
783 if (l3->host_load[x3] != NULL)
784 l3->phys_page[x3] = ppp;
792 if (ppp->translations_bitmap == 0) {
797 cpu->
cd.DYNTRANS_ARCH.cur_ic_page = &ppp->ics[0];
799 cpu->
cd.DYNTRANS_ARCH.next_ic = cpu->
cd.DYNTRANS_ARCH.cur_ic_page +
834 ppp = cpu->
cd.DYNTRANS_ARCH.phys_page[index];
848 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
850 ppp = l3->phys_page[x3];
860 cpu->
cd.DYNTRANS_ARCH.cur_ic_page = &ppp->ics[0];
861 cpu->
cd.DYNTRANS_ARCH.next_ic = cpu->
cd.DYNTRANS_ARCH.cur_ic_page +
872 #ifdef DYNTRANS_INIT_TABLES 877 #ifdef DYNTRANS_DUALMODE_32 878 static void instr32(to_be_translated)(
struct cpu *,
struct DYNTRANS_IC *);
879 static void instr32(end_of_page)(
struct cpu *,
struct DYNTRANS_IC *);
882 #ifdef DYNTRANS_DUALMODE_32 883 #define TO_BE_TRANSLATED ( cpu->is_32bit? instr32(to_be_translated) : \ 884 instr(to_be_translated) ) 886 #define TO_BE_TRANSLATED ( instr(to_be_translated) ) 889 #ifdef DYNTRANS_DELAYSLOT 891 #ifdef DYNTRANS_DUALMODE_32 892 static void instr32(end_of_page2)(
struct cpu *,
struct DYNTRANS_IC *);
916 ppp->translations_bitmap = 0;
917 ppp->translation_ranges_ofs = 0;
921 ppp->ics[i].f = TO_BE_TRANSLATED;
924 ppp->ics[DYNTRANS_IC_ENTRIES_PER_PAGE + 0].f =
926 cpu->
is_32bit? instr32(end_of_page) :
931 #ifdef DYNTRANS_DELAYSLOT 932 ppp->ics[DYNTRANS_IC_ENTRIES_PER_PAGE + 1].f =
933 #ifdef DYNTRANS_DUALMODE_32 934 cpu->
is_32bit? instr32(end_of_page2) :
939 cpu->
cd.DYNTRANS_ARCH.physpage_template = ppp;
950 cpu->
cd.DYNTRANS_ARCH.l2_64_dummy = dummy_l2;
951 cpu->
cd.DYNTRANS_ARCH.l3_64_dummy = dummy_l3;
954 cpu->
cd.DYNTRANS_ARCH.l1_64[x1] = dummy_l2;
957 dummy_l2->l3[x2] = dummy_l3;
964 #ifdef DYNTRANS_INVAL_ENTRY 980 vaddr_page,
int flags)
986 cpu->
cd.DYNTRANS_ARCH.is_userpage[index >> 5] &= ~(1 << (index & 31));
992 cpu->
cd.DYNTRANS_ARCH.host_store[index] = NULL;
994 int tlbi = cpu->
cd.DYNTRANS_ARCH.vaddr_to_tlbindex[index];
995 cpu->
cd.DYNTRANS_ARCH.host_load[index] = NULL;
996 cpu->
cd.DYNTRANS_ARCH.host_store[index] = NULL;
997 cpu->
cd.DYNTRANS_ARCH.phys_addr[index] = 0;
998 cpu->
cd.DYNTRANS_ARCH.phys_page[index] = NULL;
1000 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[tlbi-1].valid = 0;
1001 cpu->
cd.DYNTRANS_ARCH.vaddr_to_tlbindex[index] = 0;
1007 uint32_t x1, x2, x3;
1015 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
1016 if (l2 == cpu->
cd.DYNTRANS_ARCH.l2_64_dummy)
1020 if (l3 == cpu->
cd.DYNTRANS_ARCH.l3_64_dummy)
1023 if (flags & JUST_MARK_AS_NON_WRITABLE) {
1024 l3->host_store[x3] = NULL;
1036 for (x1 = 0; x1 <= mask1; x1 ++) {
1037 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
1038 if (l2 == cpu->
cd.DYNTRANS_ARCH.l2_64_dummy)
1041 for (x1b = 0; x1b <= mask1; x1b ++)
1043 l2 == cpu->
cd.DYNTRANS_ARCH.l1_64[x1b]) {
1044 fatal(
"L2 reuse: %p\n", l2);
1053 for (i=0; i<=mask3; i++)
1054 if (l3->vaddr_to_tlbindex[i])
1056 if (n != l3->refcount) {
1057 printf(
"Z: %i in use, but refcount = %i!\n", n, l3->refcount);
1062 for (i=0; i<=mask3; i++)
1063 if (l3->host_load[i] != NULL)
1065 if (n != l3->refcount) {
1066 printf(
"ZHL: %i in use, but refcount = %i!\n", n, l3->refcount);
1100 l3->host_load[x3] = NULL;
1101 l3->host_store[x3] = NULL;
1102 l3->phys_addr[x3] = 0;
1103 l3->phys_page[x3] = NULL;
1104 if (l3->vaddr_to_tlbindex[x3] != 0) {
1105 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[
1106 l3->vaddr_to_tlbindex[x3] - 1].valid = 0;
1119 l3->vaddr_to_tlbindex[x3] = 0;
1121 if (l3->refcount < 0) {
1122 fatal(
"xxx_invalidate_tlb_entry(): huh? Refcount bug.\n");
1126 if (l3->refcount == 0) {
1127 l3->next = cpu->
cd.DYNTRANS_ARCH.next_free_l3;
1128 cpu->
cd.DYNTRANS_ARCH.next_free_l3 = l3;
1129 l2->l3[x2] = cpu->
cd.DYNTRANS_ARCH.l3_64_dummy;
1136 for (i=0; i<=mask3; i++)
1137 if (l3->host_load[i] != NULL) {
1138 fatal(
"TRYING TO RETURN A NON-CLEAN L3 PAGE!\n");
1144 if (l2->refcount < 0) {
1145 fatal(
"xxx_invalidate_tlb_entry(): Refcount bug L2.\n");
1148 if (l2->refcount == 0) {
1149 l2->next = cpu->
cd.DYNTRANS_ARCH.next_free_l2;
1150 cpu->
cd.DYNTRANS_ARCH.next_free_l2 = l2;
1151 cpu->
cd.DYNTRANS_ARCH.l1_64[x1] =
1152 cpu->
cd.DYNTRANS_ARCH.l2_64_dummy;
1160 #ifdef DYNTRANS_INVALIDATE_TC 1205 if (cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid &&
1206 (cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page
1207 & 0xf0000000) == addr_page) {
1211 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid=0;
1220 if (cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid) {
1224 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid=0;
1233 fatal(
"HUH? Invalidate: Not vaddr, all, or paddr?\n");
1238 if (cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid && addr_page
1239 == cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].paddr_page) {
1241 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page,
1244 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r]
1247 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r]
1256 #ifdef DYNTRANS_INVALIDATE_TC_CODE 1271 vaddr_page, paddr_page;
1279 int pagenr, table_index;
1280 uint32_t physpage_ofs, *physpage_entryp;
1286 physpage_entryp = &(((uint32_t *)cpu->
1287 translation_cache)[table_index]);
1288 physpage_ofs = *physpage_entryp;
1292 if (physpage_ofs == 0)
1295 prev_ppp = ppp = NULL;
1298 while (physpage_ofs != 0) {
1305 if (ppp->physaddr == addr)
1309 physpage_ofs = ppp->next_ofs;
1314 if (physpage_ofs == 0)
1326 if (prev_ppp != NULL)
1327 prev_ppp->next_ofs = ppp->next_ofs;
1329 *physpage_entryp = ppp->next_ofs;
1341 if (ppp != NULL && ppp->translations_bitmap != 0) {
1342 uint32_t x = ppp->translations_bitmap;
1361 for (i=0; i<n; i++) {
1364 ppp->ics[i*m + j].f =
1371 ppp->translations_bitmap = 0;
1374 if (ppp->translation_ranges_ofs != 0) {
1376 (
struct physpage_ranges *)
1378 ppp->translation_ranges_ofs);
1388 if (cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid) {
1389 vaddr_page = cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r]
1391 paddr_page = cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r]
1395 (flags & INVALIDATE_PADDR && paddr_page == addr) ||
1400 cpu->
cd.DYNTRANS_ARCH.phys_page[index] = NULL;
1405 uint32_t x1, x2, x3;
1414 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
1416 l3->phys_page[x3] = NULL;
1426 #ifdef DYNTRANS_UPDATE_TRANSLATION_TABLE 1433 unsigned char *host_page,
int writeflag, uint64_t paddr_page)
1435 int found, r, useraccess = 0;
1439 vaddr_page &= 0xffffffffULL;
1441 if (paddr_page > 0xffffffffULL) {
1442 fatal(
"update_translation_table(): v=0x%016" PRIx64
", h=%p w=%i" 1443 " p=0x%016" PRIx64
"\n", vaddr_page, host_page, writeflag,
1455 uint32_t x1, x2, x3;
1468 writeflag &= ~MEMORY_USER_ACCESS;
1474 #ifdef DYNTRANS_M88K 1491 found = (int)cpu->
cd.DYNTRANS_ARCH.vaddr_to_tlbindex[
1499 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
1500 if (l2 == cpu->
cd.DYNTRANS_ARCH.l2_64_dummy)
1504 if (l3 == cpu->
cd.DYNTRANS_ARCH.l3_64_dummy)
1507 found = (int)l3->vaddr_to_tlbindex[x3] - 1;
1513 static unsigned int x = 0;
1516 if (cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid) {
1519 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page,
1523 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid = 1;
1524 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].host_page = host_page;
1525 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].paddr_page = paddr_page;
1526 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].vaddr_page = vaddr_page;
1527 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag =
1533 cpu->
cd.DYNTRANS_ARCH.host_load[index] = host_page;
1534 cpu->
cd.DYNTRANS_ARCH.host_store[index] =
1535 writeflag? host_page : NULL;
1536 cpu->
cd.DYNTRANS_ARCH.phys_addr[index] = paddr_page;
1537 cpu->
cd.DYNTRANS_ARCH.phys_page[index] = NULL;
1538 cpu->
cd.DYNTRANS_ARCH.vaddr_to_tlbindex[index] = r + 1;
1541 cpu->
cd.DYNTRANS_ARCH.is_userpage[index >> 5]
1542 |= 1 << (index & 31);
1545 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
1546 if (l2 == cpu->
cd.DYNTRANS_ARCH.l2_64_dummy) {
1547 if (cpu->
cd.DYNTRANS_ARCH.next_free_l2 != NULL) {
1548 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1] =
1549 cpu->
cd.DYNTRANS_ARCH.next_free_l2;
1550 cpu->
cd.DYNTRANS_ARCH.next_free_l2 = l2->next;
1554 cpu->
cd.DYNTRANS_ARCH.l1_64[x1] =
1559 l2->l3[i] = cpu->
cd.DYNTRANS_ARCH.
1562 if (l2->refcount != 0) {
1563 fatal(
"Huh? l2 Refcount problem.\n");
1567 if (l2 == cpu->
cd.DYNTRANS_ARCH.l2_64_dummy) {
1568 fatal(
"INTERNAL ERROR L2 reuse\n");
1572 if (l3 == cpu->
cd.DYNTRANS_ARCH.l3_64_dummy) {
1573 if (cpu->
cd.DYNTRANS_ARCH.next_free_l3 != NULL) {
1575 cpu->
cd.DYNTRANS_ARCH.next_free_l3;
1576 cpu->
cd.DYNTRANS_ARCH.next_free_l3 = l3->next;
1582 if (l3->refcount != 0) {
1583 fatal(
"Huh? l3 Refcount problem.\n");
1588 if (l3 == cpu->
cd.DYNTRANS_ARCH.l3_64_dummy) {
1589 fatal(
"INTERNAL ERROR L3 reuse\n");
1593 l3->host_load[x3] = host_page;
1594 l3->host_store[x3] = writeflag? host_page : NULL;
1595 l3->phys_addr[x3] = paddr_page;
1596 l3->phys_page[x3] = NULL;
1597 l3->vaddr_to_tlbindex[x3] = r + 1;
1604 for (i=0; i<=mask3; i++)
1605 if (l3->vaddr_to_tlbindex[i])
1607 if (n != l3->refcount) {
1608 printf(
"X: %i in use, but refcount = %i!\n", n, l3->refcount);
1613 for (i=0; i<=mask3; i++)
1614 if (l3->host_load[i] != NULL)
1616 if (n != l3->refcount) {
1617 printf(
"XHL: %i in use, but refcount = %i!\n", n, l3->refcount);
1633 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag = 1;
1635 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].writeflag = 0;
1638 cpu->
cd.DYNTRANS_ARCH.phys_page[index] = NULL;
1640 cpu->
cd.DYNTRANS_ARCH.is_userpage[index>>5] &= ~(1<<(index&31));
1642 cpu->
cd.DYNTRANS_ARCH.is_userpage[index >> 5]
1643 |= 1 << (index & 31);
1645 if (cpu->
cd.DYNTRANS_ARCH.phys_addr[index] == paddr_page) {
1646 if (writeflag & MEM_WRITE)
1647 cpu->
cd.DYNTRANS_ARCH.host_store[index] =
1649 if (writeflag & MEM_DOWNGRADE)
1650 cpu->
cd.DYNTRANS_ARCH.host_store[index] = NULL;
1653 cpu->
cd.DYNTRANS_ARCH.host_load[index] = host_page;
1654 cpu->
cd.DYNTRANS_ARCH.host_store[index] =
1655 writeflag? host_page : NULL;
1656 cpu->
cd.DYNTRANS_ARCH.phys_addr[index] = paddr_page;
1663 l2 = cpu->
cd.DYNTRANS_ARCH.l1_64[x1];
1665 if (l3->phys_addr[x3] == paddr_page) {
1666 if (writeflag & MEM_WRITE)
1667 l3->host_store[x3] = host_page;
1668 if (writeflag & MEM_DOWNGRADE)
1669 l3->host_store[x3] = NULL;
1672 l3->host_load[x3] = host_page;
1673 l3->host_store[x3] = writeflag? host_page : NULL;
1674 l3->phys_addr[x3] = paddr_page;
1685 for (i=0; i<=mask3; i++)
1686 if (l3->vaddr_to_tlbindex[i])
1688 if (n != l3->refcount) {
1689 printf(
"Y: %i in use, but refcount = %i!\n", n, l3->refcount);
1694 for (i=0; i<=mask3; i++)
1695 if (l3->host_load[i] != NULL)
1697 if (n != l3->refcount) {
1698 printf(
"YHL: %i in use, but refcount = %i!\n", n, l3->refcount);
1699 printf(
"Entry r = %i\n", r);
1700 printf(
"Valid = %i\n",
1701 cpu->
cd.DYNTRANS_ARCH.vph_tlb_entry[r].valid);
1716 #ifdef DYNTRANS_TO_BE_TRANSLATED_HEAD 1733 fatal(
"BREAKPOINT: pc = 0x%" PRIx32
"\n(The " 1734 "instruction has not yet executed.)\n",
1737 fatal(
"BREAKPOINT: pc = 0x%" PRIx64
"\n(The " 1738 "instruction has not yet executed.)\n",
1741 #ifdef DYNTRANS_DELAYSLOT 1743 fatal(
"ERROR! Breakpoint in a delay" 1744 " slot! Not yet supported.\n");
1748 goto stop_running_translated;
1757 #ifdef DYNTRANS_TO_BE_TRANSLATED_TAIL 1765 cpu->
cd.DYNTRANS_ARCH.cur_ic_page;
1770 sizeof(cpu->
cd.DYNTRANS_ARCH.cur_physpage->
1771 translations_bitmap));
1772 x /= addr_per_translation_range;
1774 cpu->
cd.DYNTRANS_ARCH.cur_physpage->
1775 translations_bitmap |= (1 << x);
1790 && !in_crosspage_delayslot
1792 && cpu->
cd.DYNTRANS_ARCH.combination_check != NULL
1794 cpu->
cd.DYNTRANS_ARCH.combination_check(cpu,
ic,
1798 cpu->
cd.DYNTRANS_ARCH.combination_check = NULL;
1801 if (
ic->f == TO_BE_TRANSLATED) {
1802 fatal(
"INTERNAL ERROR: ic->f not set!\n");
1805 if (
ic->f == NULL) {
1806 fatal(
"INTERNAL ERROR: ic->f == NULL!\n");
1826 || in_crosspage_delayslot
1831 ic->f = TO_BE_TRANSLATED;
1839 uint64_t baseaddr = cpu->
pc;
1848 void (*old_f)(
struct cpu *,
1852 if (old_f != TO_BE_TRANSLATED)
1859 if (
ic[i].
f == old_f)
1887 ic->f = TO_BE_TRANSLATED;
1893 fatal(
"to_be_translated(): TODO: unimplemented instruction");
1897 fatal(
" at 0x%" PRIx32
"\n", (uint32_t)cpu->
pc);
1899 fatal(
" at 0x%" PRIx64
"\n", (uint64_t)cpu->
pc);
1908 stop_running_translated:
1912 ic = cpu->
cd.DYNTRANS_ARCH.next_ic = ¬hing_call;
1913 cpu->
cd.DYNTRANS_ARCH.next_ic ++;
1915 #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
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)