From 9621339dcacc148a86d312d1e71623202c9df7db Mon Sep 17 00:00:00 2001 From: bellard Date: Fri, 11 Jul 2003 15:17:41 +0000 Subject: changed basic block exit generation git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@322 c046a42c-6fe2-441c-8c8c-71466251a162 --- dyngen-exec.h | 26 ++++++++++++++++++++++++++ dyngen.c | 36 ++++-------------------------------- dyngen.h | 6 +----- exec.h | 2 +- op-arm.c | 5 +++++ op-i386.c | 5 +++++ translate-arm.c | 1 + translate-i386.c | 1 + 8 files changed, 44 insertions(+), 38 deletions(-) diff --git a/dyngen-exec.h b/dyngen-exec.h index f588ef0f37..e5b5e5fde8 100644 --- a/dyngen-exec.h +++ b/dyngen-exec.h @@ -125,6 +125,8 @@ extern int printf(const char *, ...); #define xglue(x, y) x ## y #define glue(x, y) xglue(x, y) +#define stringify(s) tostring(s) +#define tostring(s) #s #ifdef __alpha__ /* the symbols are considered non exported so a br immediate is generated */ @@ -153,3 +155,27 @@ extern int __op_param1, __op_param2, __op_param3; #endif extern int __op_jmp0, __op_jmp1; + +#ifdef __i386__ +#define EXIT_TB() asm volatile ("ret") +#endif +#ifdef __powerpc__ +#define EXIT_TB() asm volatile ("blr") +#endif +#ifdef __s390__ +#define EXIT_TB() asm volatile ("br %r14") +#endif +#ifdef __alpha__ +#define EXIT_TB() asm volatile ("ret") +#endif +#ifdef __ia64__ +#define EXIT_TB() asm volatile ("br.ret.sptk.many b0;;") +#endif +#ifdef __sparc__ +#define EXIT_TB() asm volatile ("jmpl %i0 + 8, %g0\n" + "nop") +#endif +#ifdef __arm__ +#define EXIT_TB() asm volatile ("b exec_loop") +#endif + diff --git a/dyngen.c b/dyngen.c index c6c373bd1a..762ee9d566 100644 --- a/dyngen.c +++ b/dyngen.c @@ -1306,38 +1306,10 @@ fprintf(outfile, " the_end:\n" ); -/* generate epilogue */ - switch(ELF_ARCH) { - case EM_386: - fprintf(outfile, "*gen_code_ptr++ = 0xc3; /* ret */\n"); - break; - case EM_PPC: - fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x4e800020; /* blr */\n"); - break; - case EM_S390: - fprintf(outfile, "*((uint16_t *)gen_code_ptr)++ = 0x07fe; /* br %%r14 */\n"); - break; - case EM_ALPHA: - fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x6bfa8001; /* ret */\n"); - break; - case EM_IA_64: - fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x00840008; /* br.ret.sptk.many b0;; */\n"); - break; - case EM_SPARC: - case EM_SPARC32PLUS: - fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x81c62008; /* jmpl %%i0 + 8, %%g0 */\n"); - fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x01000000; /* nop */\n"); - break; - case EM_SPARCV9: - fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x81c7e008; /* ret */\n"); - fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x81e80000; /* restore */\n"); - break; - case EM_ARM: - fprintf(outfile, "gen_code_ptr = arm_flush_ldr(gen_code_ptr, arm_ldr_table, arm_ldr_ptr, arm_data_table, arm_data_ptr, 0);\n"); - break; - default: - error("unknown ELF architecture"); - } +/* generate some code patching */ +#ifdef HOST_ARM +fprintf(outfile, "gen_code_ptr = arm_flush_ldr(gen_code_ptr, arm_ldr_table, arm_ldr_ptr, arm_data_table, arm_data_ptr, 0);\n"); +#endif /* flush instruction cache */ fprintf(outfile, "flush_icache_range((unsigned long)gen_code_buf, (unsigned long)gen_code_ptr);\n"); diff --git a/dyngen.h b/dyngen.h index 645ce41974..47fe263e4b 100644 --- a/dyngen.h +++ b/dyngen.h @@ -152,11 +152,7 @@ static uint8_t *arm_flush_ldr(uint8_t *gen_code_ptr, data_size = (uint8_t *)data_end - (uint8_t *)data_start; - if (!gen_jmp) { - /* b exec_loop */ - arm_reloc_pc24((uint32_t *)gen_code_ptr, 0xeafffffe, (long)(&exec_loop)); - gen_code_ptr += 4; - } else { + if (gen_jmp) { /* generate branch to skip the data */ if (data_size == 0) return gen_code_ptr; diff --git a/exec.h b/exec.h index 0241292922..5ae28ef9b1 100644 --- a/exec.h +++ b/exec.h @@ -225,7 +225,7 @@ label ## n:\ T0 = (long)(tbparam) + (n);\ EIP = eip;\ dummy_label ## n:\ - return;\ + EXIT_TB();\ } while (0) #endif diff --git a/op-arm.c b/op-arm.c index 8e5cce0e9b..fcc4ddc3d4 100644 --- a/op-arm.c +++ b/op-arm.c @@ -338,6 +338,11 @@ void OPPROTO op_jmp(void) JUMP_TB(PARAM1, 1, PARAM2); } +void OPPROTO op_exit_tb(void) +{ + EXIT_TB(); +} + void OPPROTO op_movl_T0_psr(void) { T0 = compute_cpsr(); diff --git a/op-i386.c b/op-i386.c index 84b75d07b0..be8b5a113d 100644 --- a/op-i386.c +++ b/op-i386.c @@ -566,6 +566,11 @@ void OPPROTO op_movl_T0_0(void) T0 = 0; } +void OPPROTO op_exit_tb(void) +{ + EXIT_TB(); +} + /* multiple size ops */ #define ldul ldl diff --git a/translate-arm.c b/translate-arm.c index 8b249ba150..c9759f81b7 100644 --- a/translate-arm.c +++ b/translate-arm.c @@ -828,6 +828,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock *tb, int searc case DISAS_JUMP: /* indicate that the hash table must be used to find the next TB */ gen_op_movl_T0_0(); + gen_op_exit_tb(); break; case DISAS_TB_JUMP: /* nothing more to generate */ diff --git a/translate-i386.c b/translate-i386.c index a8ee672b24..871d997414 100644 --- a/translate-i386.c +++ b/translate-i386.c @@ -4163,6 +4163,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock *tb, int searc if (dc->is_jmp != DISAS_TB_JUMP) { /* indicate that the hash table must be used to find the next TB */ gen_op_movl_T0_0(); + gen_op_exit_tb(); } *gen_opc_ptr = INDEX_op_end; /* we don't forget to fill the last values */ -- cgit v1.2.1