[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 5/5] tcg/mips: use direct jumps
From: |
Aurelien Jarno |
Subject: |
[Qemu-devel] [PATCH 5/5] tcg/mips: use direct jumps |
Date: |
Thu, 22 Oct 2009 21:31:12 +0200 |
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 <address@hidden>
---
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(-)
diff --git a/exec-all.h b/exec-all.h
index 820b59e..21d6c91 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -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,
diff --git a/exec.c b/exec.c
index 076d26b..1d3f48c 100644
--- a/exec.c
+++ b/exec.c
@@ -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,
diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c
index 03fdcbf..d445169 100644
--- a/tcg/mips/tcg-target.c
+++ b/tcg/mips/tcg-target.c
@@ -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]));
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index ba91623..3d36100 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -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
}
--
1.6.1.3