Home | History | Annotate | Download | only in qemu

Lines Matching refs:tb

55 /* make various TB consistency checks */
63 /* TB consistency checks only implemented for usermode emulation. */
663 TranslationBlock *tb;
667 for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
668 if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
669 address >= tb->pc + tb->size)) {
671 address, (long)tb->pc, tb->size);
680 TranslationBlock *tb;
684 for(tb = tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
685 flags1 = page_get_flags(tb->pc);
686 flags2 = page_get_flags(tb->pc + tb->size - 1);
689 (long)tb->pc, tb->size, flags1, flags2);
695 static void tb_jmp_check(TranslationBlock *tb)
700 /* suppress any remaining jumps to this TB */
701 tb1 = tb->jmp_first;
710 if (tb1 != tb) {
711 printf("ERROR: jmp_list from 0x%08lx\n", (long)tb);
717 /* invalidate one TB */
718 static inline void tb_remove(TranslationBlock **ptb, TranslationBlock *tb,
724 if (tb1 == tb) {
732 static inline void tb_page_remove(TranslationBlock **ptb, TranslationBlock *tb)
741 if (tb1 == tb) {
749 static inline void tb_jmp_remove(TranslationBlock *tb, int n)
754 ptb = &tb->jmp_next[n];
757 /* find tb(n) in circular list */
762 if (n1 == n && tb1 == tb)
770 /* now we can suppress tb(n) from the list */
771 *ptb = tb->jmp_next[n];
773 tb->jmp_next[n] = NULL;
777 /* reset the jump entry 'n' of a TB so that it is not chained to
778 another TB */
779 static inline void tb_reset_jump(TranslationBlock *tb, int n)
781 tb_set_jmp_target(tb, n, (unsigned long)(tb->tc_ptr + tb->tb_next_offset[n]));
784 void tb_phys_invalidate(TranslationBlock *tb, target_ulong page_addr)
792 /* remove the TB from the hash list */
793 phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
795 tb_remove(&tb_phys_hash[h], tb,
798 /* remove the TB from the page list */
799 if (tb->page_addr[0] != page_addr) {
800 p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);
801 tb_page_remove(&p->first_tb, tb);
804 if (tb->page_addr[1] != -1 && tb->page_addr[1] != page_addr) {
805 p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);
806 tb_page_remove(&p->first_tb, tb);
812 /* remove the TB from the hash list */
813 h = tb_jmp_cache_hash_func(tb->pc);
815 if (env->tb_jmp_cache[h] == tb)
819 /* suppress this TB from the two jump lists */
820 tb_jmp_remove(tb, 0);
821 tb_jmp_remove(tb, 1);
823 /* suppress any remaining jumps to this TB */
824 tb1 = tb->jmp_first;
835 tb->jmp_first = (TranslationBlock *)((long)tb | 2); /* fail safe */
838 if (tb->tpc2gpc != NULL) {
839 qemu_free(tb->tpc2gpc);
840 tb->tpc2gpc = NULL;
841 tb->tpc2gpc_pairs = 0;
878 TranslationBlock *tb;
882 tb = p->first_tb;
883 while (tb != NULL) {
884 n = (long)tb & 3;
885 tb = (TranslationBlock *)((long)tb & ~3);
886 /* NOTE: this is subtle as a TB may span two physical pages */
890 tb_start = tb->pc & ~TARGET_PAGE_MASK;
891 tb_end = tb_start + tb->size;
896 tb_end = ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
899 tb = tb->page_next[n];
907 TranslationBlock *tb;
913 tb = tb_alloc(pc);
914 if (!tb) {
918 tb = tb_alloc(pc);
919 /* Don't forget to invalidate previous TB info. */
923 tb->tc_ptr = tc_ptr;
924 tb->cs_base = cs_base;
925 tb->flags = flags;
926 tb->cflags = cflags;
928 tb->bb_rec = NULL;
929 tb->prev_time = 0;
931 cpu_gen_code(env, tb, &code_gen_size);
935 virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
940 tb_link_phys(tb, phys_pc, phys_page2);
941 return tb;
948 TB if code is modified inside this TB. */
952 TranslationBlock *tb, *tb_next, *saved_tb;
978 tb = p->first_tb;
979 while (tb != NULL) {
980 n = (long)tb & 3;
981 tb = (TranslationBlock *)((long)tb & ~3);
982 tb_next = tb->page_next[n];
983 /* NOTE: this is subtle as a TB may span two physical pages */
987 tb_start = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
988 tb_end = tb_start + tb->size;
990 tb_start = tb->page_addr[1];
991 tb_end = tb_start + ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
1003 if (current_tb == tb &&
1005 /* If we are modifying the current TB, we must stop
1025 tb_phys_invalidate(tb, -1);
1032 tb = tb_next;
1086 TranslationBlock *tb;
1102 tb = p->first_tb;
1104 if (tb && pc != 0) {
1108 while (tb != NULL) {
1109 n = (long)tb & 3;
1110 tb = (TranslationBlock *)((long)tb & ~3);
1112 if (current_tb == tb &&
1114 /* If we are modifying the current TB, we must stop
1126 tb_phys_invalidate(tb, addr);
1127 tb = tb->page_next[n];
1143 /* add the tb in the target page and protect it if necessary */
1144 static inline void tb_alloc_page(TranslationBlock *tb,
1150 tb->page_addr[n] = page_addr;
1152 tb->page_next[n] = p->first_tb;
1154 p->first_tb = (TranslationBlock *)((long)tb | n);
1188 protected. So we handle the case where only the first TB is
1202 TranslationBlock *tb;
1207 tb = &tbs[nb_tbs++];
1208 tb->pc = pc;
1209 tb->cflags = 0;
1211 tb->tpc2gpc = NULL;
1212 tb->tpc2gpc_pairs = 0;
1214 return tb;
1217 void tb_free(TranslationBlock *tb)
1219 /* In practice this is mostly used for single use temporary TB
1220 Ignore the hard cases and just back up if this TB happens to
1222 if (nb_tbs > 0 && tb == &tbs[nb_tbs - 1]) {
1223 code_gen_ptr = tb->tc_ptr;
1228 /* add a new TB and link it to the physical page tables. phys_page2 is
1229 (-1) to indicate that only one page contains the TB. */
1230 void tb_link_phys(TranslationBlock *tb,
1236 /* Grab the mmap lock to stop another thread invalidating this TB
1242 tb->phys_hash_next = *ptb;
1243 *ptb = tb;
1246 tb_alloc_page(tb, 0, phys_pc & TARGET_PAGE_MASK);
1248 tb_alloc_page(tb, 1, phys_page2);
1250 tb->page_addr[1] = -1;
1252 tb->jmp_first = (TranslationBlock *)((long)tb | 2);
1253 tb->jmp_next[0] = NULL;
1254 tb->jmp_next[1] = NULL;
1257 if (tb->tb_next_offset[0] != 0xffff)
1258 tb_reset_jump(tb, 0);
1259 if (tb->tb_next_offset[1] != 0xffff)
1260 tb_reset_jump(tb, 1);
1268 /* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr <
1269 tb[1].tc_ptr. Return NULL if not found */
1274 TranslationBlock *tb;
1286 tb = &tbs[m];
1287 v = (unsigned long)tb->tc_ptr;
1289 return tb;
1299 static void tb_reset_jump_recursive(TranslationBlock *tb);
1301 static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n)
1306 tb1 = tb->jmp_next[n];
1316 /* we are now sure now that tb jumps to tb1 */
1319 /* remove tb from the jmp_first list */
1325 if (n1 == n && tb1 == tb)
1329 *ptb = tb->jmp_next[n];
1330 tb->jmp_next[n] = NULL;
1332 /* suppress the jump to next tb in generated code */
1333 tb_reset_jump(tb, n);
1335 /* suppress jumps in the tb on which we could have jumped */
1340 static void tb_reset_jump_recursive(TranslationBlock *tb)
1342 tb_reset_jump_recursive2(tb, 0);
1343 tb_reset_jump_recursive2(tb, 1);
1565 /* FIXME: TB unchaining isn't SMP safe. For now just ignore the
1570 TranslationBlock *tb;
1573 tb = env->current_tb;
1575 all the potentially executing TB */
1576 if (tb && !testandset(&interrupt_lock)) {
1578 tb_reset_jump_recursive(tb);
1629 "show generated host assembly code for each compiled TB" },
1631 "show target assembly code for each compiled TB" },
1633 "show micro ops for each compiled TB" },
1643 "show trace before each executed TB (lots of logs)" },
1771 /* Discard jump cache entries for any tb which might potentially
1791 /* must reset current TB so that interrupts cannot modify the
1836 /* must reset current TB so that interrupts cannot modify the
2795 TranslationBlock *tb;
2801 /* We re-entered the check after replacing the TB. Now raise
2814 tb = tb_find_pc(env->mem_io_pc);
2815 if (!tb) {
2816 cpu_abort(env, "check_watchpoint: could not find TB for "
2819 cpu_restore_state(tb, env, env->mem_io_pc, NULL);
2820 tb_phys_invalidate(tb, -1);
3701 must be at the end of the TB */
3704 TranslationBlock *tb;
3709 tb = tb_find_pc((unsigned long)retaddr);
3710 if (!tb) {
3711 cpu_abort(env, "cpu_io_recompile: could not find TB for pc=%p",
3714 n = env->icount_decr.u16.low + tb->icount;
3715 cpu_restore_state(tb, env, (unsigned long)retaddr, NULL);
3719 /* Generate a new TB ending on the I/O insn. */
3722 they were already the first instruction in the TB. If this is not
3723 the first instruction in a TB then re-execute the preceding
3741 cpu_abort(env, "TB too big during recompile");
3744 pc = tb->pc;
3745 cs_base = tb->cs_base;
3746 flags = tb->flags;
3747 tb_phys_invalidate(tb, -1);
3751 /* TODO: If env->pc != tb->pc (i.e. the faulting instruction was not
3752 the first in the TB) then we end up generating a whole new TB and
3755 second new TB. */
3764 TranslationBlock *tb;
3772 tb = &tbs[i];
3773 target_code_size += tb->size;
3774 if (tb->size > max_target_code_size)
3775 max_target_code_size = tb->size;
3776 if (tb->page_addr[1] != -1)
3778 if (tb->tb_next_offset[0] != 0xffff) {
3780 tb->tb_next_offset[1] != 0xffff) {
3789 cpu_fprintf(f, "TB count %d/%d\n",
3791 cpu_fprintf(f, "TB avg target size %d max=%d bytes\n",
3794 cpu_fprintf(f, "TB avg host size %d bytes (expansion ratio: %0.1f)\n",
3797 cpu_fprintf(f, "cross page TB count %d (%d%%)\n",
3806 cpu_fprintf(f, "TB flush count %d\n", tb_flush_count);
3807 cpu_fprintf(f, "TB invalidate count %d\n", tb_phys_invalidate_count);