#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 */
#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
+
" 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");
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;
T0 = (long)(tbparam) + (n);\
EIP = eip;\
dummy_label ## n:\
- return;\
+ EXIT_TB();\
} while (0)
#endif
JUMP_TB(PARAM1, 1, PARAM2);
}
+void OPPROTO op_exit_tb(void)
+{
+ EXIT_TB();
+}
+
void OPPROTO op_movl_T0_psr(void)
{
T0 = compute_cpsr();
T0 = 0;
}
+void OPPROTO op_exit_tb(void)
+{
+ EXIT_TB();
+}
+
/* multiple size ops */
#define ldul ldl
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 */
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 */