diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2018-10-03 15:59:11 -0700 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2019-01-11 20:52:24 -0800 |
commit | 5d630cef4f91fd842df3b0b98ae8d3ac6eb2ce4a (patch) | |
tree | 862bf51c3daaa92444b0939d89abda4791406de4 /target/xtensa/op_helper.c | |
parent | 32a1a94dd324d33578dca1dc96d7896a0244d768 (diff) |
target/xtensa: rework zero overhead loops implementation
Don't invalidate TB with the end of zero overhead loop when LBEG or LEND
change. Instead encode the distance from the start of the page where the
TB starts to the LEND in the TB cs_base and generate loopback code when
the next PC matches encoded LEND. Distance to a destination within the
same page and up to a maximum instruction length into the next page is
encoded literally, otherwise it's zero. The distance from LEND to LBEG
is also encoded in the cs_base: it's encoded literally when less than
256 or as 0 otherwise. This allows for TB chaining for the loopback
branch at the end of a loop for the most common loop sizes.
With this change the resulting emulation speed is about 10% higher in
softmmu mode on uClibc-ng and LTP tests. Emulation speed in linux
user mode is a few percent lower because there's no direct TB chaining
between different memory pages. Testing with lower limit on direct TB
chaining range shows gradual slowdown to ~15% for the block size of 64
bytes and ~50% for the block size of 32 bytes.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/xtensa/op_helper.c')
-rw-r--r-- | target/xtensa/op_helper.c | 24 |
1 files changed, 0 insertions, 24 deletions
diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c index e4b42ab3e5..078aeb6c2c 100644 --- a/target/xtensa/op_helper.c +++ b/target/xtensa/op_helper.c @@ -107,13 +107,6 @@ static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr) } } -#else - -static void tb_invalidate_virtual_addr(CPUXtensaState *env, uint32_t vaddr) -{ - tb_invalidate_phys_addr(vaddr); -} - #endif void HELPER(exception)(CPUXtensaState *env, uint32_t excp) @@ -370,23 +363,6 @@ void HELPER(movsp)(CPUXtensaState *env, uint32_t pc) } } -void HELPER(wsr_lbeg)(CPUXtensaState *env, uint32_t v) -{ - if (env->sregs[LBEG] != v) { - tb_invalidate_virtual_addr(env, env->sregs[LEND] - 1); - env->sregs[LBEG] = v; - } -} - -void HELPER(wsr_lend)(CPUXtensaState *env, uint32_t v) -{ - if (env->sregs[LEND] != v) { - tb_invalidate_virtual_addr(env, env->sregs[LEND] - 1); - env->sregs[LEND] = v; - tb_invalidate_virtual_addr(env, env->sregs[LEND] - 1); - } -} - void HELPER(dump_state)(CPUXtensaState *env) { XtensaCPU *cpu = xtensa_env_get_cpu(env); |