diff options
author | Richard Henderson <rth@twiddle.net> | 2014-04-24 19:39:20 +0000 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2014-05-24 08:48:37 -0700 |
commit | b6bfeea92aea8dbad61ea21cc0c3a2df4d42b96b (patch) | |
tree | b3ca98b196ef093d5a232d8ccbd777cb0236a88c | |
parent | 33fac20bb2ae7fe48932bd950a74ff2f7b134b0f (diff) | |
download | qemu-b6bfeea92aea8dbad61ea21cc0c3a2df4d42b96b.zip qemu-b6bfeea92aea8dbad61ea21cc0c3a2df4d42b96b.tar.gz qemu-b6bfeea92aea8dbad61ea21cc0c3a2df4d42b96b.tar.bz2 |
tcg-mips: Enable direct chaining of TBs
Now that the code_gen_buffer is constrained to not cross 256mb
regions, we are assured that we can use J to reach another TB.
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
-rw-r--r-- | include/exec/exec-all.h | 4 | ||||
-rw-r--r-- | tcg/mips/tcg-target.c | 11 |
2 files changed, 12 insertions, 3 deletions
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h index 8bc2eb6..c964ca4 100644 --- a/include/exec/exec-all.h +++ b/include/exec/exec-all.h @@ -131,7 +131,7 @@ static inline void tlb_flush(CPUState *cpu, int flush_global) #if defined(__arm__) || defined(_ARCH_PPC) \ || defined(__x86_64__) || defined(__i386__) \ || defined(__sparc__) || defined(__aarch64__) \ - || defined(__s390x__) \ + || defined(__s390x__) || defined(__mips__) \ || defined(CONFIG_TCG_INTERPRETER) #define USE_DIRECT_JUMP #endif @@ -268,7 +268,7 @@ static inline void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr) __asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg)); #endif } -#elif defined(__sparc__) +#elif defined(__sparc__) || defined(__mips__) void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr); #else #error tb_set_jmp_target1 is missing diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index ad752c4..8855d50 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -1354,7 +1354,9 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, case INDEX_op_goto_tb: if (s->tb_jmp_offset) { /* direct jump method */ - tcg_abort(); + s->tb_jmp_offset[a0] = tcg_current_code_size(s); + /* Avoid clobbering the address during retranslation. */ + tcg_out32(s, OPC_J | (*(uint32_t *)s->code_ptr & 0x3ffffff)); } else { /* indirect jump method */ tcg_out_ld(s, TCG_TYPE_PTR, TCG_TMP0, TCG_REG_ZERO, @@ -1805,3 +1807,10 @@ static void tcg_target_init(TCGContext *s) tcg_add_target_add_op_defs(mips_op_defs); } + +void tb_set_jmp_target1(uintptr_t jmp_addr, uintptr_t addr) +{ + uint32_t *ptr = (uint32_t *)jmp_addr; + *ptr = deposit32(*ptr, 0, 26, addr >> 2); + flush_icache_range(jmp_addr, jmp_addr + 4); +} |