Home | History | Annotate | Download | only in qemu

Lines Matching refs:tb

45 /* make various TB consistency checks */
49 /* TB consistency checks only implemented for usermode emulation. */
123 static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
137 int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_size_ptr)
153 gen_intermediate_code(env, tb);
156 gen_code_buf = tb->tc_ptr;
157 tb->tb_next_offset[0] = 0xffff;
158 tb->tb_next_offset[1] = 0xffff;
159 s->tb_next_offset = tb->tb_next_offset;
161 s->tb_jmp_offset = tb->tb_jmp_offset;
165 tb->tb_jmp_offset[2] = 0xffff;
166 tb->tb_jmp_offset[3] = 0xffff;
169 s->tb_next = tb->tb_next;
181 s->code_in_len += tb->size;
188 log_disas(tb->tc_ptr, *gen_code_size_ptr);
198 static int cpu_restore_state_from_tb(TranslationBlock *tb, CPUArchState *env,
213 gen_intermediate_code_pc(env, tb);
217 env->icount_decr.u16.low += tb->icount;
223 tc_ptr = (uintptr_t)tb->tc_ptr;
227 s->tb_next_offset = tb->tb_next_offset;
229 s->tb_jmp_offset = tb->tb_jmp_offset;
233 s->tb_next = tb->tb_next;
244 restore_state_to_opc(env, tb, j);
255 TranslationBlock *tb;
257 tb = tb_find_pc(retaddr);
258 if (tb) {
259 cpu_restore_state_from_tb(tb, env, retaddr);
499 but not so small that we can't have a fair number of TB's live. */
618 from TB's to the prologue are going to be in range. It also means
658 TranslationBlock *tb;
665 tb = &tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs++];
666 tb->pc = pc;
667 tb->cflags = 0;
668 return tb;
671 void tb_free(TranslationBlock *tb)
673 /* In practice this is mostly used for single use temporary TB
674 Ignore the hard cases and just back up if this TB happens to
677 tb == &tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs - 1]) {
678 tcg_ctx.code_gen_ptr = tb->tc_ptr;
762 TranslationBlock *tb;
767 for (tb = tb_ctx.tb_phys_hash[i]; tb != NULL; tb = tb->phys_hash_next) {
768 if (!(address + TARGET_PAGE_SIZE <= tb->pc ||
769 address >= tb->pc + tb->size)) {
772 address, (long)tb->pc, tb->size);
781 TranslationBlock *tb;
785 for (tb = tcg_ctx.tb_ctx.tb_phys_hash[i]; tb != NULL;
786 tb = tb->phys_hash_next) {
787 flags1 = page_get_flags(tb->pc);
788 flags2 = page_get_flags(tb->pc + tb->size - 1);
791 (long)tb->pc, tb->size, flags1, flags2);
799 static inline void tb_hash_remove(TranslationBlock **ptb, TranslationBlock *tb)
805 if (tb1 == tb) {
813 static inline void tb_page_remove(TranslationBlock **ptb, TranslationBlock *tb)
822 if (tb1 == tb) {
830 static inline void tb_jmp_remove(TranslationBlock *tb, int n)
835 ptb = &tb->jmp_next[n];
838 /* find tb(n) in circular list */
843 if (n1 == n && tb1 == tb) {
852 /* now we can suppress tb(n) from the list */
853 *ptb = tb->jmp_next[n];
855 tb->jmp_next[n] = NULL;
859 /* reset the jump entry 'n' of a TB so that it is not chained to
860 another TB */
861 static inline void tb_reset_jump(TranslationBlock *tb, int n)
863 tb_set_jmp_target(tb, n, (uintptr_t)(tb->tc_ptr + tb->tb_next_offset[n]));
866 /* invalidate one TB */
867 void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
875 /* remove the TB from the hash list */
876 phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
878 tb_hash_remove(&tcg_ctx.tb_ctx.tb_phys_hash[h], tb);
880 /* remove the TB from the page list */
881 if (tb->page_addr[0] != page_addr) {
882 p = page_find(tb->page_addr[0] >> TARGET_PAGE_BITS);
883 tb_page_remove(&p->first_tb, tb);
886 if (tb->page_addr[1] != -1 && tb->page_addr[1] != page_addr) {
887 p = page_find(tb->page_addr[1] >> TARGET_PAGE_BITS);
888 tb_page_remove(&p->first_tb, tb);
894 /* remove the TB from the hash list */
895 h = tb_jmp_cache_hash_func(tb->pc);
898 if (env->tb_jmp_cache[h] == tb) {
903 /* suppress this TB from the two jump lists */
904 tb_jmp_remove(tb, 0);
905 tb_jmp_remove(tb, 1);
907 /* suppress any remaining jumps to this TB */
908 tb1 = tb->jmp_first;
920 tb->jmp_first = (TranslationBlock *)((uintptr_t)tb | 2); /* fail safe */
955 TranslationBlock *tb;
959 tb = p->first_tb;
960 while (tb != NULL) {
961 n = (uintptr_t)tb & 3;
962 tb = (TranslationBlock *)((uintptr_t)tb & ~3);
963 /* NOTE: this is subtle as a TB may span two physical pages */
967 tb_start = tb->pc & ~TARGET_PAGE_MASK;
968 tb_end = tb_start + tb->size;
974 tb_end = ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
977 tb = tb->page_next[n];
985 TranslationBlock *tb;
992 tb = tb_alloc(pc);
993 if (!tb) {
997 tb = tb_alloc(pc);
998 /* Don't forget to invalidate previous TB info. */
1002 tb->tc_ptr = tc_ptr;
1003 tb->cs_base = cs_base;
1004 tb->flags = flags;
1005 tb->cflags = cflags;
1006 cpu_gen_code(env, tb, &code_gen_size);
1011 virt_page2 = (pc + tb->size - 1) & TARGET_PAGE_MASK;
1016 tb_link_page(tb, phys_pc, phys_page2);
1017 return tb;
1024 * access: the virtual CPU will exit the current TB if code is modified inside
1025 * this TB.
1041 * access: the virtual CPU will exit the current TB if code is modified inside
1042 * this TB.
1047 TranslationBlock *tb, *tb_next, *saved_tb;
1076 tb = p->first_tb;
1077 while (tb != NULL) {
1078 n = (uintptr_t)tb & 3;
1079 tb = (TranslationBlock *)((uintptr_t)tb & ~3);
1080 tb_next = tb->page_next[n];
1081 /* NOTE: this is subtle as a TB may span two physical pages */
1085 tb_start = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
1086 tb_end = tb_start + tb->size;
1088 tb_start = tb->page_addr[1];
1089 tb_end = tb_start + ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
1101 if (current_tb == tb &&
1103 /* If we are modifying the current TB, we must stop
1122 tb_phys_invalidate(tb, -1);
1130 tb = tb_next;
1193 TranslationBlock *tb;
1210 tb = p->first_tb;
1212 if (tb && pc != 0) {
1216 while (tb != NULL) {
1217 n = (uintptr_t)tb & 3;
1218 tb = (TranslationBlock *)((uintptr_t)tb & ~3);
1220 if (current_tb == tb &&
1222 /* If we are modifying the current TB, we must stop
1234 tb_phys_invalidate(tb, addr);
1235 tb = tb->page_next[n];
1254 /* add the tb in the target page and protect it if necessary */
1255 static inline void tb_alloc_page(TranslationBlock *tb,
1263 tb->page_addr[n] = page_addr;
1265 tb->page_next[n] = p->first_tb;
1269 p->first_tb = (TranslationBlock *)((uintptr_t)tb | n);
1303 protected. So we handle the case where only the first TB is
1313 /* add a new TB and link it to the physical page tables. phys_page2 is
1314 (-1) to indicate that only one page contains the TB. */
1315 static void tb_link_page(TranslationBlock *tb, tb_page_addr_t phys_pc,
1321 /* Grab the mmap lock to stop another thread invalidating this TB
1327 tb->phys_hash_next = *ptb;
1328 *ptb = tb;
1331 tb_alloc_page(tb, 0, phys_pc & TARGET_PAGE_MASK);
1333 tb_alloc_page(tb, 1, phys_page2);
1335 tb->page_addr[1] = -1;
1338 tb->jmp_first = (TranslationBlock *)((uintptr_t)tb | 2);
1339 tb->jmp_next[0] = NULL;
1340 tb->jmp_next[1] = NULL;
1343 if (tb->tb_next_offset[0] != 0xffff) {
1344 tb_reset_jump(tb, 0);
1346 if (tb->tb_next_offset[1] != 0xffff) {
1347 tb_reset_jump(tb, 1);
1356 /* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr <
1357 tb[1].tc_ptr. Return NULL if not found */
1362 TranslationBlock *tb;
1376 tb = &tcg_ctx.tb_ctx.tbs[m];
1377 v = (uintptr_t)tb->tc_ptr;
1379 return tb;
1410 TranslationBlock *tb;
1412 tb = tb_find_pc(env->mem_io_pc);
1413 if (!tb) {
1414 cpu_abort(env, "check_watchpoint: could not find TB for pc=%p",
1417 cpu_restore_state_from_tb(tb, env, env->mem_io_pc);
1418 tb_phys_invalidate(tb, -1);
1453 static inline void tb_reset_jump_recursive2(TranslationBlock *tb, int n)
1458 tb1 = tb->jmp_next[n];
1468 /* we are now sure now that tb jumps to tb1 */
1471 /* remove tb from the jmp_first list */
1477 if (n1 == n && tb1 == tb)
1481 *ptb = tb->jmp_next[n];
1482 tb->jmp_next[n] = NULL;
1484 /* suppress the jump to next tb in generated code */
1485 tb_reset_jump(tb, n);
1487 /* suppress jumps in the tb on which we could have jumped */
1492 void tb_reset_jump_recursive(TranslationBlock *tb)
1494 tb_reset_jump_recursive2(tb, 0);
1495 tb_reset_jump_recursive2(tb, 1);
1499 must be at the end of the TB */
1502 TranslationBlock *tb;
1507 tb = tb_find_pc(retaddr);
1508 if (!tb) {
1509 cpu_abort(env, "cpu_io_recompile: could not find TB for pc=%p",
1512 n = env->icount_decr.u16.low + tb->icount;
1513 cpu_restore_state_from_tb(tb, env, retaddr);
1517 /* Generate a new TB ending on the I/O insn. */
1520 they were already the first instruction in the TB. If this is not
1521 the first instruction in a TB then re-execute the preceding
1539 cpu_abort(env, "TB too big during recompile");
1543 pc = tb->pc;
1544 cs_base = tb->cs_base;
1545 flags = tb->flags;
1546 tb_phys_invalidate(tb, -1);
1550 /* TODO: If env->pc != tb->pc (i.e. the faulting instruction was not
1551 the first in the TB) then we end up generating a whole new TB and
1554 second new TB. */
1562 /* Discard jump cache entries for any tb which might potentially
1577 TranslationBlock *tb;
1585 tb = &tcg_ctx.tb_ctx.tbs[i];
1586 target_code_size += tb->size;
1587 if (tb->size > max_target_code_size) {
1588 max_target_code_size = tb->size;
1590 if (tb->page_addr[1] != -1) {
1593 if (tb->tb_next_offset[0] != 0xffff) {
1595 if (tb->tb_next_offset[1] != 0xffff) {
1605 cpu_fprintf(f, "TB count %d/%d\n",
1607 cpu_fprintf(f, "TB avg target size %d max=%d bytes\n",
1611 cpu_fprintf(f, "TB avg host size %td bytes (expansion ratio: %0.1f)\n",
1618 cpu_fprintf(f, "cross page TB count %d (%d%%)\n", cross_page,
1629 cpu_fprintf(f, "TB flush count %d\n", tcg_ctx.tb_ctx.tb_flush_count);
1630 cpu_fprintf(f, "TB invalidate count %d\n",