changed basic block exit generation
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@322 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
ede28208d8
commit
9621339dca
@ -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
|
||||
|
||||
|
36
dyngen.c
36
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");
|
||||
|
||||
|
6
dyngen.h
6
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;
|
||||
|
2
exec.h
2
exec.h
@ -225,7 +225,7 @@ label ## n:\
|
||||
T0 = (long)(tbparam) + (n);\
|
||||
EIP = eip;\
|
||||
dummy_label ## n:\
|
||||
return;\
|
||||
EXIT_TB();\
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
5
op-arm.c
5
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();
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user