> Could someone help me to confirm that I understand how the QEMU cross page > boundary checking correctly or not? Below is the source code I am looking at, > > static inline void gen_goto_tb(DisasContext *s, int tb_num, target_ulong eip) > { > > if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) || --- > (1) > (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK)) { --- > (2) > } > > } > > (a) (b) > tb->pc --> ________ tb->pc --> ________ > | | | | > | | ----------------- > | | | | > |________| s->pc --> |________| > > ---------------- ----------------- > ________ ________ > | | | | > pc --> | | pc --> | | > | | | | > |________| |________| > > > My understanding is, if tb itself doesn't cross guest page boundary (a), then > condition (1) is enough to check if the jump target (pc) is in the same guest > page as tb is. Or, tb itself spans two guest pages (b), then we have to use > condition (2) to check if the jump target (pc) is in the same guest page as tb > is. In summary, those check (1) and (2) are used to avoid block linking to > cross > guest page boundary. > > Am I right? If so far so good, I am curious about why we need (s->pc - 1) > instead of just (s->pc). Could you shed some light on that? Thanks in advance!
s->pc is updated each time a byte of code is fetched, when an instruction is fully decoded s->pc points to the first byte of the next instruction. I see that it only makes difference when a branching instruction ends exactly at a page boundary. In this case (s->pc - 1) prevents from linking to the next page, which seems to be its main purpose. -- Thanks. -- Max