diff options
author | Alex Bennée <alex.bennee@linaro.org> | 2021-02-13 13:03:18 +0000 |
---|---|---|
committer | Alex Bennée <alex.bennee@linaro.org> | 2021-02-18 08:19:23 +0000 |
commit | bc662a33514ac862efefc73d6caa4e71581ccdae (patch) | |
tree | dd25f6267aafcaecb42bbbe0ac945e60afa13a1e /accel/tcg | |
parent | 4c134d07b9e584d2713d7b5d0fb5fdb752ad120c (diff) | |
download | qemu-bc662a33514ac862efefc73d6caa4e71581ccdae.zip qemu-bc662a33514ac862efefc73d6caa4e71581ccdae.tar.gz qemu-bc662a33514ac862efefc73d6caa4e71581ccdae.tar.bz2 |
accel/tcg: actually cache our partial icount TB
When we exit a block under icount with instructions left to execute we
might need a shorter than normal block to take us to the next
deterministic event. Instead of creating a throwaway block on demand
we use the existing compile flags mechanism to ensure we fetch (or
compile and fetch) a block with exactly the number of instructions we
need.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20210213130325.14781-17-alex.bennee@linaro.org>
Diffstat (limited to 'accel/tcg')
-rw-r--r-- | accel/tcg/cpu-exec.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index f2819ee..d24c1bd 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -730,16 +730,17 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb, /* Ensure global icount has gone forward */ icount_update(cpu); /* Refill decrementer and continue execution. */ - insns_left = MIN(0xffff, cpu->icount_budget); + insns_left = MIN(CF_COUNT_MASK, cpu->icount_budget); cpu_neg(cpu)->icount_decr.u16.low = insns_left; cpu->icount_extra = cpu->icount_budget - insns_left; - if (!cpu->icount_extra && insns_left < tb->icount) { - /* Execute any remaining instructions, then let the main loop - * handle the next event. - */ - if (insns_left > 0) { - cpu_exec_nocache(cpu, insns_left, tb, false); - } + + /* + * If the next tb has more instructions than we have left to + * execute we need to ensure we find/generate a TB with exactly + * insns_left instructions in it. + */ + if (!cpu->icount_extra && insns_left > 0 && insns_left < tb->icount) { + cpu->cflags_next_tb = (tb->cflags & ~CF_COUNT_MASK) | insns_left; } #endif } |