mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-09-07 16:54:28 +00:00
Support JIT on Mach/ppc platforms. Mach/i386 (Darwin/x86) is to follow.
This commit is contained in:
parent
957bee00cf
commit
46f9e6d2ea
@ -1033,7 +1033,7 @@ fi
|
|||||||
AC_MSG_RESULT($HAVE_ICC)
|
AC_MSG_RESULT($HAVE_ICC)
|
||||||
|
|
||||||
dnl Determine the generated object format
|
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, [
|
ac_cv_object_format, [
|
||||||
echo 'int i;' > conftest.$ac_ext
|
echo 'int i;' > conftest.$ac_ext
|
||||||
ac_cv_object_format=no
|
ac_cv_object_format=no
|
||||||
@ -1042,6 +1042,9 @@ AC_CACHE_CHECK([whether the compiler can generate ELF objects],
|
|||||||
*"ELF"*)
|
*"ELF"*)
|
||||||
ac_cv_object_format=elf
|
ac_cv_object_format=elf
|
||||||
;;
|
;;
|
||||||
|
*"Mach-O"*)
|
||||||
|
ac_cv_object_format=mach
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
ac_cv_object_format=unknown
|
ac_cv_object_format=unknown
|
||||||
;;
|
;;
|
||||||
@ -1074,6 +1077,9 @@ if [[ "x$EMULATED_PPC" = "xyes" ]]; then
|
|||||||
i?86:elf)
|
i?86:elf)
|
||||||
ac_cv_use_dyngen=yes
|
ac_cv_use_dyngen=yes
|
||||||
;;
|
;;
|
||||||
|
powerpc:mach)
|
||||||
|
ac_cv_use_dyngen=yes
|
||||||
|
;;
|
||||||
*:*)
|
*:*)
|
||||||
ac_cv_use_dyngen=no
|
ac_cv_use_dyngen=no
|
||||||
;;
|
;;
|
||||||
@ -1099,14 +1105,19 @@ if [[ "x$EMULATED_PPC" = "xyes" ]]; then
|
|||||||
case $host_cpu in
|
case $host_cpu in
|
||||||
i?86)
|
i?86)
|
||||||
DYNGEN_OP_FLAGS="-fomit-frame-pointer -mpreferred-stack-boundary=2"
|
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"
|
powerpc)
|
||||||
else
|
if [[ "x$ac_cv_object_format" = "xmach" ]]; then
|
||||||
DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -malign-functions=0"
|
DYNGEN_OP_FLAGS="-mdynamic-no-pic"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
esac
|
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
|
if [[ "x$HAVE_GCC30" = "xyes" ]]; then
|
||||||
DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -fno-reorder-blocks -fno-optimize-sibling-calls"
|
DYNGEN_OP_FLAGS="$DYNGEN_OP_FLAGS -fno-reorder-blocks -fno-optimize-sibling-calls"
|
||||||
fi
|
fi
|
||||||
|
@ -237,6 +237,9 @@ DEFINE_OP(8,T0,1,T1);
|
|||||||
#ifdef __powerpc__
|
#ifdef __powerpc__
|
||||||
#define FORCE_RET() asm volatile ("blr")
|
#define FORCE_RET() asm volatile ("blr")
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __ppc__
|
||||||
|
#define FORCE_RET() asm volatile ("blr")
|
||||||
|
#endif
|
||||||
#ifdef __s390__
|
#ifdef __s390__
|
||||||
#define FORCE_RET() asm volatile ("br %r14")
|
#define FORCE_RET() asm volatile ("br %r14")
|
||||||
#endif
|
#endif
|
||||||
@ -292,13 +295,17 @@ void OPPROTO op_execute(uint8 *entry_point, basic_cpu *this_cpu)
|
|||||||
#endif
|
#endif
|
||||||
SLOW_DISPATCH(entry_point);
|
SLOW_DISPATCH(entry_point);
|
||||||
func(); // NOTE: never called, fake to make compiler save return 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 (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 (ASM_NAME(op_exec_return_offset) ":");
|
||||||
asm volatile (".long 1f-" ASM_NAME(op_execute));
|
asm volatile (".long 1f-" ASM_NAME(op_execute));
|
||||||
asm volatile (ASM_SIZE(op_exec_return_offset));
|
asm volatile (ASM_SIZE(op_exec_return_offset));
|
||||||
asm volatile (ASM_PREVIOUS_SECTION);
|
asm volatile (ASM_PREVIOUS_SECTION);
|
||||||
asm volatile ("1:");
|
asm volatile ("1:");
|
||||||
|
#endif
|
||||||
#ifdef REG_T3
|
#ifdef REG_T3
|
||||||
reg_T3 = saved_T3;
|
reg_T3 = saved_T3;
|
||||||
#endif
|
#endif
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
// Set jump target address
|
// Set jump target address
|
||||||
static inline void dg_set_jmp_target(uint8 *jmp_addr, uint8 *addr)
|
static inline void dg_set_jmp_target(uint8 *jmp_addr, uint8 *addr)
|
||||||
{
|
{
|
||||||
#if defined(__powerpc__)
|
#if defined(__powerpc__) || defined(__ppc__)
|
||||||
// patch the branch destination
|
// patch the branch destination
|
||||||
uint32 *ptr = (uint32 *)jmp_addr;
|
uint32 *ptr = (uint32 *)jmp_addr;
|
||||||
uint32 val = *ptr;
|
uint32 val = *ptr;
|
||||||
@ -241,7 +241,7 @@ public:
|
|||||||
inline bool
|
inline bool
|
||||||
basic_dyngen::direct_jump_possible(uintptr target) const
|
basic_dyngen::direct_jump_possible(uintptr target) const
|
||||||
{
|
{
|
||||||
#if defined(__powerpc__)
|
#if defined(__powerpc__) || defined(__ppc__)
|
||||||
const uintptr LI_OFFSET_MAX = 1 << 26;
|
const uintptr LI_OFFSET_MAX = 1 << 26;
|
||||||
return (((target - (uintptr)code_ptr()) < LI_OFFSET_MAX) ||
|
return (((target - (uintptr)code_ptr()) < LI_OFFSET_MAX) ||
|
||||||
(((uintptr)code_ptr() - target) < LI_OFFSET_MAX));
|
(((uintptr)code_ptr() - target) < LI_OFFSET_MAX));
|
||||||
@ -283,7 +283,7 @@ basic_dyngen::gen_exec_return()
|
|||||||
inline bool
|
inline bool
|
||||||
basic_dyngen::direct_call_possible(uintptr target) const
|
basic_dyngen::direct_call_possible(uintptr target) const
|
||||||
{
|
{
|
||||||
#if defined(__powerpc__)
|
#if defined(__powerpc__) || defined(__ppc__)
|
||||||
const uintptr LI_OFFSET_MAX = 1 << 26;
|
const uintptr LI_OFFSET_MAX = 1 << 26;
|
||||||
return (((target - (uintptr)code_ptr()) < LI_OFFSET_MAX) ||
|
return (((target - (uintptr)code_ptr()) < LI_OFFSET_MAX) ||
|
||||||
(((uintptr)code_ptr() - target) < LI_OFFSET_MAX));
|
(((uintptr)code_ptr() - target) < LI_OFFSET_MAX));
|
||||||
|
@ -85,7 +85,11 @@ extern int __op_param1 __hidden;
|
|||||||
extern int __op_param2 __hidden;
|
extern int __op_param2 __hidden;
|
||||||
extern int __op_param3 __hidden;
|
extern int __op_param3 __hidden;
|
||||||
#else
|
#else
|
||||||
|
#if defined(__APPLE__) && defined(__MACH__)
|
||||||
|
static int __op_param1, __op_param2, __op_param3;
|
||||||
|
#else
|
||||||
extern int __op_param1, __op_param2, __op_param3;
|
extern int __op_param1, __op_param2, __op_param3;
|
||||||
|
#endif
|
||||||
#define PARAM1 ((long)(&__op_param1))
|
#define PARAM1 ((long)(&__op_param1))
|
||||||
#define PARAM2 ((long)(&__op_param2))
|
#define PARAM2 ((long)(&__op_param2))
|
||||||
#define PARAM3 ((long)(&__op_param3))
|
#define PARAM3 ((long)(&__op_param3))
|
||||||
@ -97,7 +101,7 @@ extern int __op_cpuparam;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Direct block chaining support
|
// Direct block chaining support
|
||||||
#if defined(__powerpc__)
|
#if defined(__powerpc__) || defined(__ppc__)
|
||||||
#define DYNGEN_FAST_DISPATCH(TARGET) asm volatile ("b " ASM_NAME(TARGET))
|
#define DYNGEN_FAST_DISPATCH(TARGET) asm volatile ("b " ASM_NAME(TARGET))
|
||||||
#endif
|
#endif
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
@ -108,15 +112,26 @@ extern int __op_jmp0, __op_jmp1;
|
|||||||
|
|
||||||
// Sections handling
|
// Sections handling
|
||||||
#if defined(__CYGWIN__) || defined(_WIN32)
|
#if defined(__CYGWIN__) || defined(_WIN32)
|
||||||
#define ASM_DATA_SECTION ".section .data\n"
|
#define ASM_DATA_SECTION ".section .data\n"
|
||||||
#define ASM_PREVIOUS_SECTION ".section .text\n"
|
#define ASM_PREVIOUS_SECTION ".section .text\n"
|
||||||
#define ASM_NAME(NAME) "_" #NAME
|
#define ASM_GLOBAL ".global"
|
||||||
#define ASM_SIZE(NAME) ""
|
#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
|
#else
|
||||||
#define ASM_DATA_SECTION ".section \".data\"\n"
|
#define ASM_DATA_SECTION ".section \".data\"\n"
|
||||||
#define ASM_PREVIOUS_SECTION ".previous\n"
|
#define ASM_PREVIOUS_SECTION ".previous\n"
|
||||||
#define ASM_NAME(NAME) #NAME
|
#define ASM_GLOBAL ".global"
|
||||||
#define ASM_SIZE(NAME) ".size " ASM_NAME(NAME) ",.-" ASM_NAME(NAME)
|
#define ASM_NAME(NAME) #NAME
|
||||||
|
#define ASM_SIZE(NAME) ".size " ASM_NAME(NAME) ",.-" ASM_NAME(NAME)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* DYNGEN_EXEC_H */
|
#endif /* DYNGEN_EXEC_H */
|
||||||
|
@ -39,13 +39,18 @@
|
|||||||
#define CONFIG_WIN32 1
|
#define CONFIG_WIN32 1
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef CONFIG_DARWIN
|
||||||
|
#if defined(__APPLE__) && defined(__MACH__)
|
||||||
|
#define CONFIG_DARWIN 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* host cpu defs */
|
/* host cpu defs */
|
||||||
#if CONFIG_WIN32
|
#if CONFIG_WIN32
|
||||||
#define HOST_I386 1
|
#define HOST_I386 1
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
#define HOST_I386 1
|
#define HOST_I386 1
|
||||||
#elif defined(__powerpc__)
|
#elif defined(__powerpc__) || defined(__ppc__)
|
||||||
#define HOST_PPC 1
|
#define HOST_PPC 1
|
||||||
#elif defined(__s390__)
|
#elif defined(__s390__)
|
||||||
#define HOST_S390 1
|
#define HOST_S390 1
|
||||||
@ -1083,6 +1088,7 @@ struct symtab_command *symtabcmd = 0;
|
|||||||
/* section */
|
/* section */
|
||||||
struct section *section_hdr;
|
struct section *section_hdr;
|
||||||
struct section *text_sec_hdr;
|
struct section *text_sec_hdr;
|
||||||
|
struct section *data_sec_hdr;
|
||||||
uint8_t **sdata;
|
uint8_t **sdata;
|
||||||
|
|
||||||
/* relocs */
|
/* relocs */
|
||||||
@ -1265,11 +1271,11 @@ static const char * get_reloc_name(EXE_RELOC * rel, int * sslide)
|
|||||||
|
|
||||||
switch(rel->r_type)
|
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;
|
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;
|
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;
|
break;
|
||||||
case PPC_RELOC_BR24:
|
case PPC_RELOC_BR24:
|
||||||
sectoffset = ( *(uint32_t *)(text + rel->r_address) & 0x03fffffc );
|
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);
|
sdata = (uint8_t **)malloc(sizeof(void *) * segment->nsects);
|
||||||
memset(sdata, 0, sizeof(void *) * segment->nsects);
|
memset(sdata, 0, sizeof(void *) * segment->nsects);
|
||||||
|
|
||||||
/* Load the data in section data */
|
/* Load the data in section data */
|
||||||
for(i = 0; i < segment->nsects; i++) {
|
for(i = 0; i < segment->nsects; i++)
|
||||||
sdata[i] = load_data(fd, section_hdr[i].offset, section_hdr[i].size);
|
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 section */
|
||||||
text_sec_hdr = find_mach_sec_hdr(section_hdr, segment->nsects, SEG_TEXT, SECT_TEXT);
|
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 */
|
/* 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++) {
|
for(i = 0, sym = symtab, syment = symtab_std; i < nb_syms; i++, sym++, syment++) {
|
||||||
const char *name;
|
|
||||||
struct nlist *sym_follow, *sym_next = 0;
|
struct nlist *sym_follow, *sym_next = 0;
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
name = find_str_by_index(sym->n_un.n_strx);
|
|
||||||
memset(sym, 0, sizeof(*sym));
|
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;
|
continue;
|
||||||
|
|
||||||
memcpy(sym, syment, sizeof(*syment));
|
memcpy(sym, syment, sizeof(*syment));
|
||||||
@ -1581,8 +1591,16 @@ void gen_code(const char *name, const char *demangled_name,
|
|||||||
p_start = text + offset;
|
p_start = text + offset;
|
||||||
p_end = p_start + size;
|
p_end = p_start + size;
|
||||||
start_offset = offset;
|
start_offset = offset;
|
||||||
if (op_execute)
|
if (op_execute) {
|
||||||
copy_size = p_end - p_start;
|
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
|
else
|
||||||
#if defined(HOST_I386) || defined(HOST_AMD64)
|
#if defined(HOST_I386) || defined(HOST_AMD64)
|
||||||
#ifdef CONFIG_FORMAT_COFF
|
#ifdef CONFIG_FORMAT_COFF
|
||||||
@ -2130,11 +2148,16 @@ void gen_code(const char *name, const char *demangled_name,
|
|||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case PPC_RELOC_BR24:
|
case PPC_RELOC_BR24:
|
||||||
|
if (!strstart(sym_name, "__op_param", &p)) {
|
||||||
fprintf(outfile, "{\n");
|
fprintf(outfile, "{\n");
|
||||||
fprintf(outfile, " uint32_t imm = *(uint32_t *)(code_ptr() + %d) & 0x3fffffc;\n", slide);
|
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",
|
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 );
|
slide, slide, name, sslide );
|
||||||
fprintf(outfile, "}\n");
|
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;
|
break;
|
||||||
case PPC_RELOC_HI16:
|
case PPC_RELOC_HI16:
|
||||||
fprintf(outfile, " *(uint16_t *)(code_ptr() + %d + 2) = (%s + %d) >> 16;\n",
|
fprintf(outfile, " *(uint16_t *)(code_ptr() + %d + 2) = (%s + %d) >> 16;\n",
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
// Default cache size
|
// Default cache size
|
||||||
#if defined(__alpha__)
|
#if defined(__alpha__)
|
||||||
const int JIT_CACHE_SIZE = 2 * 1024 * 1024;
|
const int JIT_CACHE_SIZE = 2 * 1024 * 1024;
|
||||||
#elif defined(__powerpc__)
|
#elif defined(__powerpc__) || defined(__ppc__)
|
||||||
const int JIT_CACHE_SIZE = 4 * 1024 * 1024;
|
const int JIT_CACHE_SIZE = 4 * 1024 * 1024;
|
||||||
#else
|
#else
|
||||||
const int JIT_CACHE_SIZE = 8 * 1024 * 1024;
|
const int JIT_CACHE_SIZE = 8 * 1024 * 1024;
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
/// Optimized memory accessors
|
/// 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
|
# define VM_CAN_ACCESS_UNALIGNED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user