Support JIT on Mach/ppc platforms. Mach/i386 (Darwin/x86) is to follow.

This commit is contained in:
gbeauche 2005-06-14 06:32:52 +00:00
parent 957bee00cf
commit 46f9e6d2ea
7 changed files with 89 additions and 33 deletions

View File

@ -1033,7 +1033,7 @@ fi
AC_MSG_RESULT($HAVE_ICC)
dnl Determine the generated object format
AC_CACHE_CHECK([whether the compiler can generate ELF objects],
AC_CACHE_CHECK([the format of compiler generated objects],
ac_cv_object_format, [
echo 'int i;' > conftest.$ac_ext
ac_cv_object_format=no
@ -1042,6 +1042,9 @@ AC_CACHE_CHECK([whether the compiler can generate ELF objects],
*"ELF"*)
ac_cv_object_format=elf
;;
*"Mach-O"*)
ac_cv_object_format=mach
;;
*)
ac_cv_object_format=unknown
;;
@ -1074,6 +1077,9 @@ if [[ "x$EMULATED_PPC" = "xyes" ]]; then
i?86:elf)
ac_cv_use_dyngen=yes
;;
powerpc:mach)
ac_cv_use_dyngen=yes
;;
*:*)
ac_cv_use_dyngen=no
;;
@ -1099,14 +1105,19 @@ if [[ "x$EMULATED_PPC" = "xyes" ]]; then
case $host_cpu in
i?86)
DYNGEN_OP_FLAGS="-fomit-frame-pointer -mpreferred-stack-boundary=2"
if [[ "x$HAVE_GCC30" = "xyes" ]]; then
DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -falign-functions=0"
else
DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -malign-functions=0"
;;
powerpc)
if [[ "x$ac_cv_object_format" = "xmach" ]]; then
DYNGEN_OP_FLAGS="-mdynamic-no-pic"
fi
;;
esac
DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -finline-limit=10000 -g0"
if [[ "x$HAVE_GCC30" = "xyes" ]]; then
DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -falign-functions=0"
else
DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -malign-functions=0"
fi
DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -finline-limit=10000 -fno-exceptions -g0"
if [[ "x$HAVE_GCC30" = "xyes" ]]; then
DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -fno-reorder-blocks -fno-optimize-sibling-calls"
fi

View File

@ -237,6 +237,9 @@ DEFINE_OP(8,T0,1,T1);
#ifdef __powerpc__
#define FORCE_RET() asm volatile ("blr")
#endif
#ifdef __ppc__
#define FORCE_RET() asm volatile ("blr")
#endif
#ifdef __s390__
#define FORCE_RET() asm volatile ("br %r14")
#endif
@ -292,13 +295,17 @@ void OPPROTO op_execute(uint8 *entry_point, basic_cpu *this_cpu)
#endif
SLOW_DISPATCH(entry_point);
func(); // NOTE: never called, fake to make compiler save return point
#ifdef ASM_OP_EXEC_RETURN_INSN
asm volatile ("1: .byte " ASM_OP_EXEC_RETURN_INSN);
#else
asm volatile (ASM_DATA_SECTION);
asm volatile (".global " ASM_NAME(op_exec_return_offset));
asm volatile (ASM_GLOBAL " " ASM_NAME(op_exec_return_offset));
asm volatile (ASM_NAME(op_exec_return_offset) ":");
asm volatile (".long 1f-" ASM_NAME(op_execute));
asm volatile (ASM_SIZE(op_exec_return_offset));
asm volatile (ASM_PREVIOUS_SECTION);
asm volatile ("1:");
#endif
#ifdef REG_T3
reg_T3 = saved_T3;
#endif

View File

@ -28,7 +28,7 @@
// Set jump target address
static inline void dg_set_jmp_target(uint8 *jmp_addr, uint8 *addr)
{
#if defined(__powerpc__)
#if defined(__powerpc__) || defined(__ppc__)
// patch the branch destination
uint32 *ptr = (uint32 *)jmp_addr;
uint32 val = *ptr;
@ -241,7 +241,7 @@ public:
inline bool
basic_dyngen::direct_jump_possible(uintptr target) const
{
#if defined(__powerpc__)
#if defined(__powerpc__) || defined(__ppc__)
const uintptr LI_OFFSET_MAX = 1 << 26;
return (((target - (uintptr)code_ptr()) < LI_OFFSET_MAX) ||
(((uintptr)code_ptr() - target) < LI_OFFSET_MAX));
@ -283,7 +283,7 @@ basic_dyngen::gen_exec_return()
inline bool
basic_dyngen::direct_call_possible(uintptr target) const
{
#if defined(__powerpc__)
#if defined(__powerpc__) || defined(__ppc__)
const uintptr LI_OFFSET_MAX = 1 << 26;
return (((target - (uintptr)code_ptr()) < LI_OFFSET_MAX) ||
(((uintptr)code_ptr() - target) < LI_OFFSET_MAX));

View File

@ -85,7 +85,11 @@ extern int __op_param1 __hidden;
extern int __op_param2 __hidden;
extern int __op_param3 __hidden;
#else
#if defined(__APPLE__) && defined(__MACH__)
static int __op_param1, __op_param2, __op_param3;
#else
extern int __op_param1, __op_param2, __op_param3;
#endif
#define PARAM1 ((long)(&__op_param1))
#define PARAM2 ((long)(&__op_param2))
#define PARAM3 ((long)(&__op_param3))
@ -97,7 +101,7 @@ extern int __op_cpuparam;
#endif
// Direct block chaining support
#if defined(__powerpc__)
#if defined(__powerpc__) || defined(__ppc__)
#define DYNGEN_FAST_DISPATCH(TARGET) asm volatile ("b " ASM_NAME(TARGET))
#endif
#if defined(__i386__) || defined(__x86_64__)
@ -108,15 +112,26 @@ extern int __op_jmp0, __op_jmp1;
// Sections handling
#if defined(__CYGWIN__) || defined(_WIN32)
#define ASM_DATA_SECTION ".section .data\n"
#define ASM_PREVIOUS_SECTION ".section .text\n"
#define ASM_NAME(NAME) "_" #NAME
#define ASM_SIZE(NAME) ""
#define ASM_DATA_SECTION ".section .data\n"
#define ASM_PREVIOUS_SECTION ".section .text\n"
#define ASM_GLOBAL ".global"
#define ASM_NAME(NAME) "_" #NAME
#define ASM_SIZE ""
#elif defined(__APPLE__) && defined(__MACH__)
#define ASM_DATA_SECTION ".data\n"
#define ASM_PREVIOUS_SECTION ".text\n"
#define ASM_GLOBAL ".globl"
#define ASM_NAME(NAME) "_" #NAME
#define ASM_SIZE ""
#if defined(__ppc__)
#define ASM_OP_EXEC_RETURN_INSN "0x18,0xde,0xad,0xff"
#endif
#else
#define ASM_DATA_SECTION ".section \".data\"\n"
#define ASM_PREVIOUS_SECTION ".previous\n"
#define ASM_NAME(NAME) #NAME
#define ASM_SIZE(NAME) ".size " ASM_NAME(NAME) ",.-" ASM_NAME(NAME)
#define ASM_DATA_SECTION ".section \".data\"\n"
#define ASM_PREVIOUS_SECTION ".previous\n"
#define ASM_GLOBAL ".global"
#define ASM_NAME(NAME) #NAME
#define ASM_SIZE(NAME) ".size " ASM_NAME(NAME) ",.-" ASM_NAME(NAME)
#endif
#endif /* DYNGEN_EXEC_H */

View File

@ -39,13 +39,18 @@
#define CONFIG_WIN32 1
#endif
#endif
#ifndef CONFIG_DARWIN
#if defined(__APPLE__) && defined(__MACH__)
#define CONFIG_DARWIN 1
#endif
#endif
/* host cpu defs */
#if CONFIG_WIN32
#define HOST_I386 1
#elif defined(__i386__)
#define HOST_I386 1
#elif defined(__powerpc__)
#elif defined(__powerpc__) || defined(__ppc__)
#define HOST_PPC 1
#elif defined(__s390__)
#define HOST_S390 1
@ -1083,6 +1088,7 @@ struct symtab_command *symtabcmd = 0;
/* section */
struct section *section_hdr;
struct section *text_sec_hdr;
struct section *data_sec_hdr;
uint8_t **sdata;
/* relocs */
@ -1265,11 +1271,11 @@ static const char * get_reloc_name(EXE_RELOC * rel, int * sslide)
switch(rel->r_type)
{
case PPC_RELOC_LO16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset & 0xffff);
case PPC_RELOC_LO16: fetch_next_pair_value(rel+1, &other_half); sectoffset |= (other_half << 16);
break;
case PPC_RELOC_HI16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (other_half & 0xffff);
case PPC_RELOC_HI16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset << 16) | (uint16_t)(other_half & 0xffff);
break;
case PPC_RELOC_HA16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (other_half & 0xffff);
case PPC_RELOC_HA16: fetch_next_pair_value(rel+1, &other_half); sectoffset = (sectoffset << 16) + (int16_t)(other_half & 0xffff);
break;
case PPC_RELOC_BR24:
sectoffset = ( *(uint32_t *)(text + rel->r_address) & 0x03fffffc );
@ -1384,10 +1390,16 @@ int load_object(const char *filename, FILE *outfile)
sdata = (uint8_t **)malloc(sizeof(void *) * segment->nsects);
memset(sdata, 0, sizeof(void *) * segment->nsects);
/* Load the data in section data */
for(i = 0; i < segment->nsects; i++) {
/* Load the data in section data */
for(i = 0; i < segment->nsects; i++)
sdata[i] = load_data(fd, section_hdr[i].offset, section_hdr[i].size);
}
/* data section */
data_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_DATA, SECT_DATA);
i = find_mach_sec_index(section_hdr, segment->nsects, SEG_DATA, SECT_DATA);
if (i == -1 || !data_sec_hdr)
error("could not find __DATA,__data section");
data = sdata[i];
/* text section */
text_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
@ -1415,13 +1427,11 @@ int load_object(const char *filename, FILE *outfile)
/* Now transform the symtab, to an extended version, with the sym size, and the C name */
for(i = 0, sym = symtab, syment = symtab_std; i < nb_syms; i++, sym++, syment++) {
const char *name;
struct nlist *sym_follow, *sym_next = 0;
unsigned int j;
name = find_str_by_index(sym->n_un.n_strx);
memset(sym, 0, sizeof(*sym));
if ( sym->n_type & N_STAB ) /* Debug symbols are skipped */
if ( syment->n_type & N_STAB ) /* Debug symbols are skipped */
continue;
memcpy(sym, syment, sizeof(*syment));
@ -1581,8 +1591,16 @@ void gen_code(const char *name, const char *demangled_name,
p_start = text + offset;
p_end = p_start + size;
start_offset = offset;
if (op_execute)
copy_size = p_end - p_start;
if (op_execute) {
uint8_t *p;
copy_size = p_end - p_start;
#if defined(HOST_PPC)
for (p = p_start; p < p_end; p += 4) {
if (get32((uint32_t *)p) == 0x18deadff)
fprintf(outfile, "DEFINE_CST(op_exec_return_offset,0x%xL)\n\n", (p + 4) - p_start);
}
#endif
}
else
#if defined(HOST_I386) || defined(HOST_AMD64)
#ifdef CONFIG_FORMAT_COFF
@ -2130,11 +2148,16 @@ void gen_code(const char *name, const char *demangled_name,
switch(type) {
case PPC_RELOC_BR24:
if (!strstart(sym_name, "__op_param", &p)) {
fprintf(outfile, "{\n");
fprintf(outfile, " uint32_t imm = *(uint32_t *)(code_ptr() + %d) & 0x3fffffc;\n", slide);
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = (*(uint32_t *)(code_ptr() + %d) & ~0x03fffffc) | ((imm + ((long)%s - (long)code_ptr()) + %d) & 0x03fffffc);\n",
slide, slide, name, sslide );
fprintf(outfile, "}\n");
} else {
fprintf(outfile, " *(uint32_t *)(code_ptr() + %d) = (*(uint32_t *)(code_ptr() + %d) & ~0x03fffffc) | (((long)%s - (long)code_ptr() - %d) & 0x03fffffc);\n",
slide, slide, final_sym_name, slide);
}
break;
case PPC_RELOC_HI16:
fprintf(outfile, " *(uint16_t *)(code_ptr() + %d + 2) = (%s + %d) >> 16;\n",

View File

@ -32,7 +32,7 @@
// Default cache size
#if defined(__alpha__)
const int JIT_CACHE_SIZE = 2 * 1024 * 1024;
#elif defined(__powerpc__)
#elif defined(__powerpc__) || defined(__ppc__)
const int JIT_CACHE_SIZE = 4 * 1024 * 1024;
#else
const int JIT_CACHE_SIZE = 8 * 1024 * 1024;

View File

@ -25,7 +25,7 @@
/// Optimized memory accessors
///
#if defined(__i386__) || defined(__powerpc__) || defined(__m68k__) || defined(__x86_64__)
#if defined(__i386__) || defined(__powerpc__) || defined(__ppc__) || defined(__m68k__) || defined(__x86_64__)
# define VM_CAN_ACCESS_UNALIGNED
#endif