summaryrefslogtreecommitdiff
path: root/exec.c
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-05-27 23:29:48 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-05-27 23:29:48 +0000
commita513fe19ac4896a09c6c338204d76c39e652451f (patch)
tree7a8db2852cb3d88849cbe69ade4129983a3a2b5b /exec.c
parentf4beb510a41980e119f787746442ca1b87c06754 (diff)
downloadqemu-a513fe19ac4896a09c6c338204d76c39e652451f.tar.gz
precise exceptions
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@194 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'exec.c')
-rw-r--r--exec.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/exec.c b/exec.c
index 8f332c9aed..2e84f557b4 100644
--- a/exec.c
+++ b/exec.c
@@ -531,3 +531,34 @@ void page_unprotect_range(uint8_t *data, unsigned long data_size)
page_unprotect(addr);
}
}
+
+/* find the TB 'tb' such that tb[0].tc_ptr <= tc_ptr <
+ tb[1].tc_ptr. Return NULL if not found */
+TranslationBlock *tb_find_pc(unsigned long tc_ptr)
+{
+ int m_min, m_max, m;
+ unsigned long v;
+ TranslationBlock *tb;
+
+ if (nb_tbs <= 0)
+ return NULL;
+ if (tc_ptr < (unsigned long)code_gen_buffer ||
+ tc_ptr >= (unsigned long)code_gen_ptr)
+ return NULL;
+ /* binary search (cf Knuth) */
+ m_min = 0;
+ m_max = nb_tbs - 1;
+ while (m_min <= m_max) {
+ m = (m_min + m_max) >> 1;
+ tb = &tbs[m];
+ v = (unsigned long)tb->tc_ptr;
+ if (v == tc_ptr)
+ return tb;
+ else if (tc_ptr < v) {
+ m_max = m - 1;
+ } else {
+ m_min = m + 1;
+ }
+ }
+ return &tbs[m_max];
+}