@@ -114,7 +114,7 @@ static inline int tlb_set_page(CPUState *env1, target_ulong vaddr,
#define CODE_GEN_AVG_BLOCK_SIZE 64
#endif
-#if defined(_ARCH_PPC) || defined(__x86_64__) || defined(__arm__) || defined(__i386__)
+#if defined(_ARCH_PPC) || defined(__x86_64__) || defined(__arm__) || defined(__i386__) || defined(__mips__)
#define USE_DIRECT_JUMP
#endif
@@ -222,6 +222,17 @@ static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr
__asm __volatile__ ("swi 0x9f0002" : : "r" (_beg), "r" (_end), "r" (_flg));
#endif
}
+#elif defined(__mips__)
+static inline void tb_set_jmp_target1(unsigned long jmp_addr, unsigned long addr)
+{
+ *(uint32_t *)jmp_addr = 0x08000000 | ((addr >> 2) & 0x03ffffff);
+#if QEMU_GNUC_PREREQ(4, 1)
+ void __clear_cache(char *beg, char *end);
+ __clear_cache((char *) jmp_addr, (char *) jmp_addr + 4);
+#else
+# error __clear_cache not available
+#endif
+}
#endif
static inline void tb_set_jmp_target(TranslationBlock *tb,
@@ -454,6 +454,13 @@ static void code_gen_alloc(unsigned long tb_size)
start = (void *) 0x01000000UL;
if (code_gen_buffer_size > 16 * 1024 * 1024)
code_gen_buffer_size = 16 * 1024 * 1024;
+#elif defined(__mips__)
+ /* Map the buffer aligned on a 256M boundary, so we can use direct
+ calls and branches (R_MIPS_26 relocation) */
+ flags |= MAP_FIXED;
+ start = (void *) 0x30000000UL;
+ if (code_gen_buffer_size > 256 * 1024 * 1024)
+ code_gen_buffer_size = 256 * 1024 * 1024;
#endif
code_gen_buffer = mmap(start, code_gen_buffer_size,
PROT_WRITE | PROT_READ | PROT_EXEC,
@@ -1042,7 +1042,8 @@ static inline void tcg_out_op(TCGContext *s, int opc,
case INDEX_op_goto_tb:
if (s->tb_jmp_offset) {
/* direct jump method */
- tcg_abort();
+ s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;
+ s->code_ptr += 4;
} else {
/* indirect jump method */
tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_AT, (tcg_target_long)(s->tb_next + args[0]));
@@ -98,10 +98,5 @@ enum {
static inline void flush_icache_range(unsigned long start, unsigned long stop)
{
-#if QEMU_GNUC_PREREQ(4, 1)
- void __clear_cache(char *beg, char *end);
__clear_cache((char *) start, (char *) stop);
-#else
-# error __clear_cache not available
-#endif
}
Use direct jumps on MIPS hosts. The jump address has to be written atomically, so a R_MIPS_26 needs to be used. It means the code generation buffer should not be bigger than 256MB, and has to be aligned on a 256MB boundary. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> --- exec-all.h | 13 ++++++++++++- exec.c | 7 +++++++ tcg/mips/tcg-target.c | 3 ++- tcg/mips/tcg-target.h | 5 ----- 4 files changed, 21 insertions(+), 7 deletions(-)