From e703c1aa093ff1831e44f15849b3348ec22b387b Mon Sep 17 00:00:00 2001 From: Alhad Deshpande Date: Fri, 5 Aug 2022 13:39:07 +0000 Subject: [PATCH 1/6] [ppc64le] Added memory patch thunking for function calls --- src/mono/mono/mini/cpu-ppc.mdesc | 2 +- src/mono/mono/mini/cpu-ppc64.mdesc | 2 +- src/mono/mono/mini/mini-ppc.c | 106 ++++++++++++----------------- src/mono/mono/mini/mini-ppc.h | 6 ++ src/mono/mono/mini/tramp-ppc.c | 9 ++- 5 files changed, 59 insertions(+), 66 deletions(-) diff --git a/src/mono/mono/mini/cpu-ppc.mdesc b/src/mono/mono/mini/cpu-ppc.mdesc index c92495c356fa51..301b96a6530bdf 100644 --- a/src/mono/mono/mini/cpu-ppc.mdesc +++ b/src/mono/mono/mini/cpu-ppc.mdesc @@ -348,4 +348,4 @@ atomic_cas_i4: src1:b src2:i src3:i dest:i len:38 liverange_start: len:0 liverange_end: len:0 -gc_safe_point: clob:c src1:i len:40 +gc_safe_point: clob:c src1:i len:44 diff --git a/src/mono/mono/mini/cpu-ppc64.mdesc b/src/mono/mono/mini/cpu-ppc64.mdesc index 4dca1bb3ab43cf..d2437a34fda45e 100644 --- a/src/mono/mono/mini/cpu-ppc64.mdesc +++ b/src/mono/mono/mini/cpu-ppc64.mdesc @@ -417,4 +417,4 @@ atomic_cas_i8: src1:b src2:i src3:i dest:i len:38 liverange_start: len:0 liverange_end: len:0 -gc_safe_point: clob:c src1:i len:40 +gc_safe_point: clob:c src1:i len:44 diff --git a/src/mono/mono/mini/mini-ppc.c b/src/mono/mono/mini/mini-ppc.c index 30dc899ab6969b..f8fc34278c5e1f 100644 --- a/src/mono/mono/mini/mini-ppc.c +++ b/src/mono/mono/mini/mini-ppc.c @@ -2690,21 +2690,27 @@ emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size, } static void -emit_thunk (guint8 *code, gconstpointer target) +emit_thunk (guint8 *code, gconstpointer target, gboolean is_memory_slot_thunk) { - guint8 *p = code; + if (!is_memory_slot_thunk){ + guint8 *p = code; - /* 2 bytes on 32bit, 5 bytes on 64bit */ - ppc_load_sequence (code, ppc_r0, target); + /* 2 bytes on 32bit, 5 bytes on 64bit */ + ppc_load_sequence (code, ppc_r0, target); - ppc_mtctr (code, ppc_r0); - ppc_bcctr (code, PPC_BR_ALWAYS, 0); + ppc_mtctr (code, ppc_r0); + ppc_bcctr (code, PPC_BR_ALWAYS, 0); - mono_arch_flush_icache (p, code - p); + mono_arch_flush_icache (p, code - p); + } + else{ + *(guint64*)code = (guint64)target; + code += sizeof (guint64); + } } static void -handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target) +handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target, gboolean is_memory_slot_thunk) { MonoJitInfo *ji = NULL; MonoThunkJitInfo *info; @@ -2731,11 +2737,14 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target) } g_assert (*(guint32*)thunks == 0); - emit_thunk (thunks, target); - ppc_patch (code, thunks); - cfg->arch.thunks += THUNK_SIZE; - cfg->arch.thunks_size -= THUNK_SIZE; + // memory patching + emit_thunk (thunks, target, is_memory_slot_thunk); + // code patching + ppc_load_ptr_sequence (code, PPC_CALL_REG, thunks); + + cfg->arch.thunks += MEMORY_SLOT_THUNK_SIZE; + cfg->arch.thunks_size -= MEMORY_SLOT_THUNK_SIZE; } else { ji = mini_jit_info_table_find (code); g_assert (ji); @@ -2745,7 +2754,7 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target) thunks = (guint8 *) ji->code_start + info->thunks_offset; thunks_size = info->thunks_size; - orig_target = mono_arch_get_call_target (code + 4); + orig_target = mono_arch_get_call_target (code); mono_mini_arch_lock (); @@ -2786,8 +2795,11 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target) g_assert_not_reached (); } - emit_thunk (target_thunk, target); - ppc_patch (code, target_thunk); + emit_thunk (target_thunk, target, is_memory_slot_thunk); + + if (!is_memory_slot_thunk) { + ppc_patch (code, target_thunk); + } mono_mini_arch_unlock (); } @@ -2841,7 +2853,7 @@ ppc_patch_full (MonoCompile *cfg, guchar *code, const guchar *target, gboolean i } } - handle_thunk (cfg, code, target); + handle_thunk (cfg, code, target, DEFAULT_THUNK); return; g_assert_not_reached (); @@ -2875,54 +2887,8 @@ ppc_patch_full (MonoCompile *cfg, guchar *code, const guchar *target, gboolean i if (prim == 15 || ins == 0x4e800021 || ins == 0x4e800020 || ins == 0x4e800420) { #ifdef TARGET_POWERPC64 - guint32 *seq = (guint32*)code; - guint32 *branch_ins; - /* the trampoline code will try to patch the blrl, blr, bcctr */ - if (ins == 0x4e800021 || ins == 0x4e800020 || ins == 0x4e800420) { - branch_ins = seq; - if (ppc_is_load_op (seq [-3]) || ppc_opcode (seq [-3]) == 31) /* ld || lwz || mr */ - code -= 32; - else - code -= 24; - } else { - if (ppc_is_load_op (seq [5]) -#ifdef PPC_USES_FUNCTION_DESCRIPTOR - /* With function descs we need to do more careful - matches. */ - || ppc_opcode (seq [5]) == 31 /* ld || lwz || mr */ -#endif - ) - branch_ins = seq + 8; - else - branch_ins = seq + 6; - } - - seq = (guint32*)code; - /* this is the lis/ori/sldi/oris/ori/(ld/ld|mr/nop)/mtlr/blrl sequence */ - g_assert (mono_ppc_is_direct_call_sequence (branch_ins)); - - if (ppc_is_load_op (seq [5])) { - g_assert (ppc_is_load_op (seq [6])); - - if (!is_fd) { - guint8 *buf = (guint8*)&seq [5]; - ppc_mr (buf, PPC_CALL_REG, ppc_r12); - ppc_nop (buf); - } - } else { - if (is_fd) - target = (const guchar*)mono_get_addr_from_ftnptr ((gpointer)target); - } - - /* FIXME: make this thread safe */ -#ifdef PPC_USES_FUNCTION_DESCRIPTOR - /* FIXME: we're assuming we're using r12 here */ - ppc_load_ptr_sequence (code, ppc_r12, target); -#else - ppc_load_ptr_sequence (code, PPC_CALL_REG, target); -#endif - mono_arch_flush_icache ((guint8*)seq, 28); + handle_thunk (cfg, code, target, MEMORY_SLOT_THUNK); #else guint32 *seq; /* the trampoline code will try to patch the blrl, blr, bcctr */ @@ -3349,8 +3315,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_break)); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); + ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); + cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; } else { ppc_bl (code, 0); } @@ -3823,8 +3791,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) mono_call_add_patch_info (cfg, call, offset); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); + ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); + cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; } else { ppc_bl (code, 0); } @@ -3926,8 +3896,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_throw_exception)); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); + ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); + cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; } else { ppc_bl (code, 0); } @@ -3940,8 +3912,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_rethrow_exception)); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); + ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); + cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; } else { ppc_bl (code, 0); } @@ -4584,8 +4558,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) GUINT_TO_POINTER (MONO_JIT_ICALL_mono_threads_state_poll)); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); + ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); + cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; } else { ppc_bl (code, 0); } @@ -5185,8 +5161,10 @@ mono_arch_emit_prolog (MonoCompile *cfg) GUINT_TO_POINTER (MONO_JIT_ICALL_mono_tls_get_lmf_addr_extern)); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); + ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); + cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; } else { ppc_bl (code, 0); } @@ -5466,8 +5444,10 @@ mono_arch_emit_exceptions (MonoCompile *cfg) patch_info->ip.i = code - cfg->native_code; if (FORCE_INDIR_CALL || cfg->method->dynamic) { ppc_load_func (code, PPC_CALL_REG, 0); + ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); ppc_mtctr (code, PPC_CALL_REG); ppc_bcctr (code, PPC_BR_ALWAYS, 0); + cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; } else { ppc_bl (code, 0); } diff --git a/src/mono/mono/mini/mini-ppc.h b/src/mono/mono/mini/mini-ppc.h index 60931e2827b73d..e381a2e8373255 100644 --- a/src/mono/mono/mini/mini-ppc.h +++ b/src/mono/mono/mini/mini-ppc.h @@ -38,6 +38,12 @@ #define THUNK_SIZE ((2 + 2) * 4) #endif +#ifdef TARGET_POWERPC64 +#define MEMORY_SLOT_THUNK_SIZE 8 +#define MEMORY_SLOT_THUNK 1 +#define DEFAULT_THUNK 0 +#endif + void ppc_patch (guchar *code, const guchar *target); struct MonoLMF { diff --git a/src/mono/mono/mini/tramp-ppc.c b/src/mono/mono/mini/tramp-ppc.c index 3a78709c6f8cb9..e4c1bde2d63434 100644 --- a/src/mono/mono/mini/tramp-ppc.c +++ b/src/mono/mono/mini/tramp-ppc.c @@ -178,7 +178,7 @@ mono_arch_patch_callsite (guint8 *method_start, guint8 *code_ptr, guint8 *addr) } /* Sanity check */ - g_assert (mono_ppc_is_direct_call_sequence (code)); + //g_assert (mono_ppc_is_direct_call_sequence (code)); ppc_patch ((guint8*)code, addr); } @@ -669,6 +669,13 @@ mono_arch_get_call_target (guint8 *code) guint8 *target = code - 4 + (disp * 4); return target; + } else if (((guint32*)(code - 28)) [0] >> 26 == 15) { + guint8 *thunk = ((((guint64*)(code - 28)) [0] & 0x0000ffff) << 48) + + ((((guint64*)(code - 24)) [0] & 0x0000ffff) << 32) + + ((((guint64*)(code - 16)) [0] & 0x0000ffff) << 16) + + (((guint64*)(code - 12)) [0] & 0x0000ffff); + + return thunk; } else { return NULL; } From eb2a57b681df17753c56c08aaad4dea8d986a8e4 Mon Sep 17 00:00:00 2001 From: Alhad Deshpande Date: Sun, 7 Aug 2022 11:07:09 +0000 Subject: [PATCH 2/6] Incorporated code review comments and changes in OP_TAILCALL for mempry patching --- src/mono/mono/mini/mini-ppc.c | 25 +++++++++++++++---------- src/mono/mono/mini/mini-ppc.h | 5 ++++- src/mono/mono/mini/tramp-ppc.c | 11 ++++++----- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/mono/mono/mini/mini-ppc.c b/src/mono/mono/mini/mini-ppc.c index f8fc34278c5e1f..fc331c8c6b6828 100644 --- a/src/mono/mono/mini/mini-ppc.c +++ b/src/mono/mono/mini/mini-ppc.c @@ -2740,11 +2740,14 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target, gboolean is_ // memory patching emit_thunk (thunks, target, is_memory_slot_thunk); - // code patching - ppc_load_ptr_sequence (code, PPC_CALL_REG, thunks); - cfg->arch.thunks += MEMORY_SLOT_THUNK_SIZE; - cfg->arch.thunks_size -= MEMORY_SLOT_THUNK_SIZE; + if (is_memory_slot_thunk) { + // code patching + ppc_load_ptr_sequence (code, PPC_CALL_REG, thunks); + + cfg->arch.thunks += MEMORY_SLOT_THUNK_SIZE; + cfg->arch.thunks_size -= MEMORY_SLOT_THUNK_SIZE; + } } else { ji = mini_jit_info_table_find (code); g_assert (ji); @@ -2754,7 +2757,7 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target, gboolean is_ thunks = (guint8 *) ji->code_start + info->thunks_offset; thunks_size = info->thunks_size; - orig_target = mono_arch_get_call_target (code); + orig_target = mono_arch_get_call_target (code + 4); mono_mini_arch_lock (); @@ -2763,7 +2766,7 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target, gboolean is_ /* The call already points to a thunk, because of trampolines etc. */ target_thunk = orig_target; } else { - for (p = thunks; p < thunks + thunks_size; p += THUNK_SIZE) { + for (p = thunks; p < thunks + thunks_size; p += MEMORY_SLOT_THUNK_SIZE) { if (((guint32 *) p) [0] == 0) { /* Free entry */ target_thunk = p; @@ -2853,7 +2856,7 @@ ppc_patch_full (MonoCompile *cfg, guchar *code, const guchar *target, gboolean i } } - handle_thunk (cfg, code, target, DEFAULT_THUNK); + handle_thunk (cfg, code, target, CODE_SEQUENCE_THUNK); return; g_assert_not_reached (); @@ -2887,7 +2890,6 @@ ppc_patch_full (MonoCompile *cfg, guchar *code, const guchar *target, gboolean i if (prim == 15 || ins == 0x4e800021 || ins == 0x4e800020 || ins == 0x4e800420) { #ifdef TARGET_POWERPC64 - handle_thunk (cfg, code, target, MEMORY_SLOT_THUNK); #else guint32 *seq; @@ -3749,7 +3751,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ppc_mr (code, ppc_sp, ppc_r12); mono_add_patch_info (cfg, (guint8*) code - cfg->native_code, MONO_PATCH_INFO_METHOD_JUMP, call->method); - cfg->thunk_area += THUNK_SIZE; + cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; if (cfg->compile_aot) { /* arch_emit_got_access () patches this */ ppc_load32 (code, ppc_r0, 0); @@ -3762,7 +3764,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ppc_mtctr (code, ppc_r0); ppc_bcctr (code, PPC_BR_ALWAYS, 0); } else { - ppc_b (code, 0); + ppc_load_func (code, ppc_r0, 0); + ppc_ldr (code, ppc_r0, 0, ppc_r0); + ppc_mtctr (code, ppc_r0); + ppc_bcctr (code, PPC_BR_ALWAYS, 0); } break; } diff --git a/src/mono/mono/mini/mini-ppc.h b/src/mono/mono/mini/mini-ppc.h index e381a2e8373255..611e60f93710ef 100644 --- a/src/mono/mono/mini/mini-ppc.h +++ b/src/mono/mono/mini/mini-ppc.h @@ -41,7 +41,10 @@ #ifdef TARGET_POWERPC64 #define MEMORY_SLOT_THUNK_SIZE 8 #define MEMORY_SLOT_THUNK 1 -#define DEFAULT_THUNK 0 +#define CODE_SEQUENCE_THUNK 0 + +#define GET_MEMORY_SLOT_ADDR_PART(v, o) ((v & 0x0000FFFF) << o) + #endif void ppc_patch (guchar *code, const guchar *target); diff --git a/src/mono/mono/mini/tramp-ppc.c b/src/mono/mono/mini/tramp-ppc.c index e4c1bde2d63434..baae30a0899fdb 100644 --- a/src/mono/mono/mini/tramp-ppc.c +++ b/src/mono/mono/mini/tramp-ppc.c @@ -669,11 +669,12 @@ mono_arch_get_call_target (guint8 *code) guint8 *target = code - 4 + (disp * 4); return target; - } else if (((guint32*)(code - 28)) [0] >> 26 == 15) { - guint8 *thunk = ((((guint64*)(code - 28)) [0] & 0x0000ffff) << 48) - + ((((guint64*)(code - 24)) [0] & 0x0000ffff) << 32) - + ((((guint64*)(code - 16)) [0] & 0x0000ffff) << 16) - + (((guint64*)(code - 12)) [0] & 0x0000ffff); + } else if (((guint32*)(code - 32)) [0] >> 26 == 15) { + + guint8 *thunk = GET_MEMORY_SLOT_ADDR_PART(((guint64*)(code - 32)) [0], 48) + + GET_MEMORY_SLOT_ADDR_PART(((guint64*)(code - 28)) [0], 32) + + GET_MEMORY_SLOT_ADDR_PART(((guint64*)(code - 20)) [0], 16) + + GET_MEMORY_SLOT_ADDR_PART(((guint64*)(code - 16)) [0], 0); return thunk; } else { From b0d75b838d8feea2e8b8772aa1c4a673ea72f2b9 Mon Sep 17 00:00:00 2001 From: Alhad Deshpande Date: Tue, 9 Aug 2022 07:11:41 +0000 Subject: [PATCH 3/6] [ppc64le] Fixed test failures and code refactoring --- src/mono/mono/mini/mini-ppc.c | 148 +++++++++++++++++++++++++-------- src/mono/mono/mini/mini-ppc.h | 18 ++-- src/mono/mono/mini/tramp-ppc.c | 18 ++-- 3 files changed, 132 insertions(+), 52 deletions(-) diff --git a/src/mono/mono/mini/mini-ppc.c b/src/mono/mono/mini/mini-ppc.c index fc331c8c6b6828..133dd9b19ea63d 100644 --- a/src/mono/mono/mini/mini-ppc.c +++ b/src/mono/mono/mini/mini-ppc.c @@ -2690,9 +2690,12 @@ emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size, } static void -emit_thunk (guint8 *code, gconstpointer target, gboolean is_memory_slot_thunk) +emit_thunk (guint8 *code, gconstpointer target) { - if (!is_memory_slot_thunk){ +#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN + *(guint64*)code = (guint64)target; + code += sizeof (guint64); +#else guint8 *p = code; /* 2 bytes on 32bit, 5 bytes on 64bit */ @@ -2702,15 +2705,11 @@ emit_thunk (guint8 *code, gconstpointer target, gboolean is_memory_slot_thunk) ppc_bcctr (code, PPC_BR_ALWAYS, 0); mono_arch_flush_icache (p, code - p); - } - else{ - *(guint64*)code = (guint64)target; - code += sizeof (guint64); - } +#endif } static void -handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target, gboolean is_memory_slot_thunk) +handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target) { MonoJitInfo *ji = NULL; MonoThunkJitInfo *info; @@ -2738,16 +2737,21 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target, gboolean is_ g_assert (*(guint32*)thunks == 0); +#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN // memory patching - emit_thunk (thunks, target, is_memory_slot_thunk); + emit_thunk (thunks, target); + // code patching + ppc_load_ptr_sequence (code, PPC_CALL_REG, thunks); - if (is_memory_slot_thunk) { - // code patching - ppc_load_ptr_sequence (code, PPC_CALL_REG, thunks); + cfg->arch.thunks += MEMORY_SLOT_THUNK_SIZE; + cfg->arch.thunks_size -= MEMORY_SLOT_THUNK_SIZE; +#else + emit_thunk (thunks, target); + ppc_patch (code, thunks); - cfg->arch.thunks += MEMORY_SLOT_THUNK_SIZE; - cfg->arch.thunks_size -= MEMORY_SLOT_THUNK_SIZE; - } + cfg->arch.thunks += THUNK_SIZE; + cfg->arch.thunks_size -= THUNK_SIZE; +#endif } else { ji = mini_jit_info_table_find (code); g_assert (ji); @@ -2765,8 +2769,10 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target, gboolean is_ if (orig_target >= thunks && orig_target < thunks + thunks_size) { /* The call already points to a thunk, because of trampolines etc. */ target_thunk = orig_target; - } else { - for (p = thunks; p < thunks + thunks_size; p += MEMORY_SLOT_THUNK_SIZE) { + } +#if (defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_BIG_ENDIAN) || !defined(TARGET_POWERPC64) + else { + for (p = thunks; p < thunks + thunks_size; p += THUNK_SIZE) { if (((guint32 *) p) [0] == 0) { /* Free entry */ target_thunk = p; @@ -2789,7 +2795,7 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target, gboolean is_ } } } - +#endif // g_print ("THUNK: %p %p %p\n", code, target, target_thunk); if (!target_thunk) { @@ -2798,11 +2804,10 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target, gboolean is_ g_assert_not_reached (); } - emit_thunk (target_thunk, target, is_memory_slot_thunk); - - if (!is_memory_slot_thunk) { - ppc_patch (code, target_thunk); - } + emit_thunk (target_thunk, target); +#if (defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_BIG_ENDIAN) || !defined(TARGET_POWERPC64) + ppc_patch (code, target_thunk); +#endif mono_mini_arch_unlock (); } @@ -2856,7 +2861,7 @@ ppc_patch_full (MonoCompile *cfg, guchar *code, const guchar *target, gboolean i } } - handle_thunk (cfg, code, target, CODE_SEQUENCE_THUNK); + handle_thunk (cfg, code, target); return; g_assert_not_reached (); @@ -2890,7 +2895,58 @@ ppc_patch_full (MonoCompile *cfg, guchar *code, const guchar *target, gboolean i if (prim == 15 || ins == 0x4e800021 || ins == 0x4e800020 || ins == 0x4e800420) { #ifdef TARGET_POWERPC64 - handle_thunk (cfg, code, target, MEMORY_SLOT_THUNK); +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + handle_thunk (cfg, code, target); +#else + guint32 *seq = (guint32*)code; + guint32 *branch_ins; + + /* the trampoline code will try to patch the blrl, blr, bcctr */ + if (ins == 0x4e800021 || ins == 0x4e800020 || ins == 0x4e800420) { + branch_ins = seq; + if (ppc_is_load_op (seq [-3]) || ppc_opcode (seq [-3]) == 31) /* ld || lwz || mr */ + code -= 32; + else + code -= 24; + } else { + if (ppc_is_load_op (seq [5]) +#ifdef PPC_USES_FUNCTION_DESCRIPTOR + /* With function descs we need to do more careful + matches. */ + || ppc_opcode (seq [5]) == 31 /* ld || lwz || mr */ +#endif + ) + branch_ins = seq + 8; + else + branch_ins = seq + 6; + } + + seq = (guint32*)code; + /* this is the lis/ori/sldi/oris/ori/(ld/ld|mr/nop)/mtlr/blrl sequence */ + g_assert (mono_ppc_is_direct_call_sequence (branch_ins)); + + if (ppc_is_load_op (seq [5])) { + g_assert (ppc_is_load_op (seq [6])); + + if (!is_fd) { + guint8 *buf = (guint8*)&seq [5]; + ppc_mr (buf, PPC_CALL_REG, ppc_r12); + ppc_nop (buf); + } + } else { + if (is_fd) + target = (const guchar*)mono_get_addr_from_ftnptr ((gpointer)target); + } + + /* FIXME: make this thread safe */ +#ifdef PPC_USES_FUNCTION_DESCRIPTOR + /* FIXME: we're assuming we're using r12 here */ + ppc_load_ptr_sequence (code, ppc_r12, target); +#else + ppc_load_ptr_sequence (code, PPC_CALL_REG, target); +#endif + mono_arch_flush_icache ((guint8*)seq, 28); +#endif #else guint32 *seq; /* the trampoline code will try to patch the blrl, blr, bcctr */ @@ -3317,10 +3373,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_break)); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); +#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); + cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; +#endif ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); - cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; } else { ppc_bl (code, 0); } @@ -3751,7 +3809,11 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ppc_mr (code, ppc_sp, ppc_r12); mono_add_patch_info (cfg, (guint8*) code - cfg->native_code, MONO_PATCH_INFO_METHOD_JUMP, call->method); +#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; +#else + cfg->thunk_area += THUNK_SIZE; +#endif if (cfg->compile_aot) { /* arch_emit_got_access () patches this */ ppc_load32 (code, ppc_r0, 0); @@ -3764,10 +3826,14 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ppc_mtctr (code, ppc_r0); ppc_bcctr (code, PPC_BR_ALWAYS, 0); } else { - ppc_load_func (code, ppc_r0, 0); - ppc_ldr (code, ppc_r0, 0, ppc_r0); - ppc_mtctr (code, ppc_r0); +#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN + ppc_load_func (code, PPC_CALL_REG, 0); + ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); + ppc_mtctr (code, PPC_CALL_REG); ppc_bcctr (code, PPC_BR_ALWAYS, 0); +#else + ppc_b (code, 0); +#endif } break; } @@ -3796,10 +3862,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) mono_call_add_patch_info (cfg, call, offset); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); +#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); + cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; +#endif ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); - cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; } else { ppc_bl (code, 0); } @@ -3901,10 +3969,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_throw_exception)); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); +#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); + cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; +#endif ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); - cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; } else { ppc_bl (code, 0); } @@ -3917,10 +3987,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_rethrow_exception)); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); +#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); + cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; +#endif ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); - cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; } else { ppc_bl (code, 0); } @@ -4563,10 +4635,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) GUINT_TO_POINTER (MONO_JIT_ICALL_mono_threads_state_poll)); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); +#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); + cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; +#endif ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); - cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; } else { ppc_bl (code, 0); } @@ -5166,10 +5240,12 @@ mono_arch_emit_prolog (MonoCompile *cfg) GUINT_TO_POINTER (MONO_JIT_ICALL_mono_tls_get_lmf_addr_extern)); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); +#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); + cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; +#endif ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); - cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; } else { ppc_bl (code, 0); } @@ -5449,10 +5525,12 @@ mono_arch_emit_exceptions (MonoCompile *cfg) patch_info->ip.i = code - cfg->native_code; if (FORCE_INDIR_CALL || cfg->method->dynamic) { ppc_load_func (code, PPC_CALL_REG, 0); +#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); + cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; +#endif ppc_mtctr (code, PPC_CALL_REG); ppc_bcctr (code, PPC_BR_ALWAYS, 0); - cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; } else { ppc_bl (code, 0); } diff --git a/src/mono/mono/mini/mini-ppc.h b/src/mono/mono/mini/mini-ppc.h index 611e60f93710ef..b47443675e135b 100644 --- a/src/mono/mono/mini/mini-ppc.h +++ b/src/mono/mono/mini/mini-ppc.h @@ -33,20 +33,20 @@ #define MONO_ARCH_CODE_ALIGNMENT 32 #ifdef TARGET_POWERPC64 +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +#define MEMORY_SLOT_THUNK_SIZE 8 +#define GET_MEMORY_SLOT_THUNK_ADDRESS(c) \ + ((guint64)(((guint32*)(c)) [0] & 0x0000ffff) << 48) \ + + ((guint64)(((guint32*)(c + 4)) [0] & 0x0000ffff) << 32) \ + + ((guint64)(((guint32*)(c + 12)) [0] & 0x0000ffff) << 16) \ + + (guint64)(((guint32*)(c + 16)) [0] & 0x0000ffff) +#else #define THUNK_SIZE ((2 + 5) * 4) +#endif #else #define THUNK_SIZE ((2 + 2) * 4) #endif -#ifdef TARGET_POWERPC64 -#define MEMORY_SLOT_THUNK_SIZE 8 -#define MEMORY_SLOT_THUNK 1 -#define CODE_SEQUENCE_THUNK 0 - -#define GET_MEMORY_SLOT_ADDR_PART(v, o) ((v & 0x0000FFFF) << o) - -#endif - void ppc_patch (guchar *code, const guchar *target); struct MonoLMF { diff --git a/src/mono/mono/mini/tramp-ppc.c b/src/mono/mono/mini/tramp-ppc.c index baae30a0899fdb..4814fe5eb66c7c 100644 --- a/src/mono/mono/mini/tramp-ppc.c +++ b/src/mono/mono/mini/tramp-ppc.c @@ -669,15 +669,17 @@ mono_arch_get_call_target (guint8 *code) guint8 *target = code - 4 + (disp * 4); return target; - } else if (((guint32*)(code - 32)) [0] >> 26 == 15) { - - guint8 *thunk = GET_MEMORY_SLOT_ADDR_PART(((guint64*)(code - 32)) [0], 48) - + GET_MEMORY_SLOT_ADDR_PART(((guint64*)(code - 28)) [0], 32) - + GET_MEMORY_SLOT_ADDR_PART(((guint64*)(code - 20)) [0], 16) - + GET_MEMORY_SLOT_ADDR_PART(((guint64*)(code - 16)) [0], 0); - + } +#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN + else if (((guint32*)(code - 32)) [0] >> 26 == 15) { + guint8 *thunk = GET_MEMORY_SLOT_THUNK_ADDRESS((code - 32)); return thunk; - } else { + } else if (((guint32*)(code - 4)) [0] >> 26 == 15) { + guint8 *thunk = GET_MEMORY_SLOT_THUNK_ADDRESS((code - 4)); + return thunk; + } +#endif + else { return NULL; } } From 509e6d577e241127c9948d06db5bf47ce1de1750 Mon Sep 17 00:00:00 2001 From: Alhad Deshpande Date: Tue, 9 Aug 2022 12:12:18 +0000 Subject: [PATCH 4/6] [ppc64le] Enabled g_assert for code sequence check and removed white spaces --- src/mono/mono/mini/mini-ppc.c | 21 +++++++++++++-------- src/mono/mono/mini/tramp-ppc.c | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/mono/mono/mini/mini-ppc.c b/src/mono/mono/mini/mini-ppc.c index 133dd9b19ea63d..27fa5b766d9e7c 100644 --- a/src/mono/mono/mini/mini-ppc.c +++ b/src/mono/mono/mini/mini-ppc.c @@ -311,7 +311,12 @@ mono_ppc_is_direct_call_sequence (guint32 *code) if (ppc_opcode (code [-2]) == 24 && ppc_opcode (code [-3]) == 31) /* mr/nop */ return is_load_sequence (&code [-8]); else +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + /* the memory patch thunk sequence for ppc64le is: lis/ori/sldi/oris/ori/ld/mtlr/blrl */ + return is_load_sequence (&code [-7]); +#else return is_load_sequence (&code [-6]); +#endif } return FALSE; #else @@ -2693,18 +2698,18 @@ static void emit_thunk (guint8 *code, gconstpointer target) { #if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN - *(guint64*)code = (guint64)target; - code += sizeof (guint64); + *(guint64*)code = (guint64)target; + code += sizeof (guint64); #else - guint8 *p = code; + guint8 *p = code; - /* 2 bytes on 32bit, 5 bytes on 64bit */ - ppc_load_sequence (code, ppc_r0, target); + /* 2 bytes on 32bit, 5 bytes on 64bit */ + ppc_load_sequence (code, ppc_r0, target); - ppc_mtctr (code, ppc_r0); - ppc_bcctr (code, PPC_BR_ALWAYS, 0); + ppc_mtctr (code, ppc_r0); + ppc_bcctr (code, PPC_BR_ALWAYS, 0); - mono_arch_flush_icache (p, code - p); + mono_arch_flush_icache (p, code - p); #endif } diff --git a/src/mono/mono/mini/tramp-ppc.c b/src/mono/mono/mini/tramp-ppc.c index 4814fe5eb66c7c..9cf61118061575 100644 --- a/src/mono/mono/mini/tramp-ppc.c +++ b/src/mono/mono/mini/tramp-ppc.c @@ -178,7 +178,7 @@ mono_arch_patch_callsite (guint8 *method_start, guint8 *code_ptr, guint8 *addr) } /* Sanity check */ - //g_assert (mono_ppc_is_direct_call_sequence (code)); + g_assert (mono_ppc_is_direct_call_sequence (code)); ppc_patch ((guint8*)code, addr); } From 9c1aa137d4c5e71776f89ae380163c9858fe1a3d Mon Sep 17 00:00:00 2001 From: Alhad Deshpande Date: Tue, 9 Aug 2022 12:47:14 +0000 Subject: [PATCH 5/6] [ppc64le] Fixed build issue in mini-ppc.h --- src/mono/mono/mini/mini-ppc.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mono/mono/mini/mini-ppc.h b/src/mono/mono/mini/mini-ppc.h index 1f6b080fc7c2ec..703a7133139e7e 100644 --- a/src/mono/mono/mini/mini-ppc.h +++ b/src/mono/mono/mini/mini-ppc.h @@ -127,8 +127,7 @@ typedef struct MonoCompileArch { #else #define MONO_ARCH_CALLEE_FREGS (0xff << ppc_f1) #endif -#define MONO_ARCH_CALLEE_SAVED_FREGS (~(MONO_ARCH_CALLEE_FRE -GS | 1)) +#define MONO_ARCH_CALLEE_SAVED_FREGS (~(MONO_ARCH_CALLEE_FREGS | 1)) #ifdef TARGET_POWERPC64 #define MONO_ARCH_INST_FIXED_REG(desc) (((desc) == 'a')? ppc_r3: \ From a199280248de091ad74ad67b386fd6b097feae80 Mon Sep 17 00:00:00 2001 From: Alhad Deshpande Date: Wed, 10 Aug 2022 08:12:20 +0000 Subject: [PATCH 6/6] [ppc64le] Incorporated code review comments --- src/mono/mono/mini/mini-ppc.c | 56 ++++++++++++++-------------------- src/mono/mono/mini/mini-ppc.h | 12 ++++---- src/mono/mono/mini/tramp-ppc.c | 6 ++-- 3 files changed, 32 insertions(+), 42 deletions(-) diff --git a/src/mono/mono/mini/mini-ppc.c b/src/mono/mono/mini/mini-ppc.c index 27fa5b766d9e7c..93abd63562ff53 100644 --- a/src/mono/mono/mini/mini-ppc.c +++ b/src/mono/mono/mini/mini-ppc.c @@ -311,7 +311,7 @@ mono_ppc_is_direct_call_sequence (guint32 *code) if (ppc_opcode (code [-2]) == 24 && ppc_opcode (code [-3]) == 31) /* mr/nop */ return is_load_sequence (&code [-8]); else -#if G_BYTE_ORDER == G_LITTLE_ENDIAN +#if !defined(PPC_USES_FUNCTION_DESCRIPTOR) /* the memory patch thunk sequence for ppc64le is: lis/ori/sldi/oris/ori/ld/mtlr/blrl */ return is_load_sequence (&code [-7]); #else @@ -2697,7 +2697,7 @@ emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size, static void emit_thunk (guint8 *code, gconstpointer target) { -#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN +#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR) *(guint64*)code = (guint64)target; code += sizeof (guint64); #else @@ -2742,21 +2742,15 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target) g_assert (*(guint32*)thunks == 0); -#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN - // memory patching + emit_thunk (thunks, target); - // code patching +#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR) ppc_load_ptr_sequence (code, PPC_CALL_REG, thunks); - - cfg->arch.thunks += MEMORY_SLOT_THUNK_SIZE; - cfg->arch.thunks_size -= MEMORY_SLOT_THUNK_SIZE; #else - emit_thunk (thunks, target); ppc_patch (code, thunks); - +#endif cfg->arch.thunks += THUNK_SIZE; cfg->arch.thunks_size -= THUNK_SIZE; -#endif } else { ji = mini_jit_info_table_find (code); g_assert (ji); @@ -2775,7 +2769,7 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target) /* The call already points to a thunk, because of trampolines etc. */ target_thunk = orig_target; } -#if (defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_BIG_ENDIAN) || !defined(TARGET_POWERPC64) +#if (defined(TARGET_POWERPC64) && defined(PPC_USES_FUNCTION_DESCRIPTOR)) || !defined(TARGET_POWERPC64) else { for (p = thunks; p < thunks + thunks_size; p += THUNK_SIZE) { if (((guint32 *) p) [0] == 0) { @@ -2810,7 +2804,7 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target) } emit_thunk (target_thunk, target); -#if (defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_BIG_ENDIAN) || !defined(TARGET_POWERPC64) +#if (defined(TARGET_POWERPC64) && defined(PPC_USES_FUNCTION_DESCRIPTOR)) || !defined(TARGET_POWERPC64) ppc_patch (code, target_thunk); #endif @@ -2900,7 +2894,7 @@ ppc_patch_full (MonoCompile *cfg, guchar *code, const guchar *target, gboolean i if (prim == 15 || ins == 0x4e800021 || ins == 0x4e800020 || ins == 0x4e800420) { #ifdef TARGET_POWERPC64 -#if G_BYTE_ORDER == G_LITTLE_ENDIAN +#if !defined(PPC_USES_FUNCTION_DESCRIPTOR) handle_thunk (cfg, code, target); #else guint32 *seq = (guint32*)code; @@ -3378,9 +3372,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_break)); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); -#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN +#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR) ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); - cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; + cfg->thunk_area += THUNK_SIZE; #endif ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); @@ -3814,11 +3808,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ppc_mr (code, ppc_sp, ppc_r12); mono_add_patch_info (cfg, (guint8*) code - cfg->native_code, MONO_PATCH_INFO_METHOD_JUMP, call->method); -#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN - cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; -#else cfg->thunk_area += THUNK_SIZE; -#endif if (cfg->compile_aot) { /* arch_emit_got_access () patches this */ ppc_load32 (code, ppc_r0, 0); @@ -3831,7 +3821,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ppc_mtctr (code, ppc_r0); ppc_bcctr (code, PPC_BR_ALWAYS, 0); } else { -#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN +#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR) ppc_load_func (code, PPC_CALL_REG, 0); ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); ppc_mtctr (code, PPC_CALL_REG); @@ -3867,9 +3857,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) mono_call_add_patch_info (cfg, call, offset); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); -#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN +#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR) ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); - cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; + cfg->thunk_area += THUNK_SIZE; #endif ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); @@ -3974,9 +3964,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_JIT_ICALL_ID, GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_throw_exception)); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); -#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN +#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR) ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); - cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; + cfg->thunk_area += THUNK_SIZE; #endif ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); @@ -3992,9 +3982,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) GUINT_TO_POINTER (MONO_JIT_ICALL_mono_arch_rethrow_exception)); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); -#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN +#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR) ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); - cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; + cfg->thunk_area += THUNK_SIZE; #endif ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); @@ -4640,9 +4630,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) GUINT_TO_POINTER (MONO_JIT_ICALL_mono_threads_state_poll)); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); -#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN +#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR) ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); - cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; + cfg->thunk_area += THUNK_SIZE; #endif ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); @@ -5245,9 +5235,9 @@ mono_arch_emit_prolog (MonoCompile *cfg) GUINT_TO_POINTER (MONO_JIT_ICALL_mono_tls_get_lmf_addr_extern)); if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) { ppc_load_func (code, PPC_CALL_REG, 0); -#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN +#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR) ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); - cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; + cfg->thunk_area += THUNK_SIZE; #endif ppc_mtlr (code, PPC_CALL_REG); ppc_blrl (code); @@ -5530,9 +5520,9 @@ mono_arch_emit_exceptions (MonoCompile *cfg) patch_info->ip.i = code - cfg->native_code; if (FORCE_INDIR_CALL || cfg->method->dynamic) { ppc_load_func (code, PPC_CALL_REG, 0); -#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN +#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR) ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG); - cfg->thunk_area += MEMORY_SLOT_THUNK_SIZE; + cfg->thunk_area += THUNK_SIZE; #endif ppc_mtctr (code, PPC_CALL_REG); ppc_bcctr (code, PPC_BR_ALWAYS, 0); diff --git a/src/mono/mono/mini/mini-ppc.h b/src/mono/mono/mini/mini-ppc.h index 703a7133139e7e..0b962aac233d24 100644 --- a/src/mono/mono/mini/mini-ppc.h +++ b/src/mono/mono/mini/mini-ppc.h @@ -33,13 +33,13 @@ #define MONO_ARCH_CODE_ALIGNMENT 32 #ifdef TARGET_POWERPC64 -#if G_BYTE_ORDER == G_LITTLE_ENDIAN -#define MEMORY_SLOT_THUNK_SIZE 8 +#if !defined(PPC_USES_FUNCTION_DESCRIPTOR) +#define THUNK_SIZE 8 #define GET_MEMORY_SLOT_THUNK_ADDRESS(c) \ - ((guint64)(((guint32*)(c)) [0] & 0x0000ffff) << 48) \ - + ((guint64)(((guint32*)(c + 4)) [0] & 0x0000ffff) << 32) \ - + ((guint64)(((guint32*)(c + 12)) [0] & 0x0000ffff) << 16) \ - + (guint64)(((guint32*)(c + 16)) [0] & 0x0000ffff) + ((guint64)(((c)) [0] & 0x0000ffff) << 48) \ + + ((guint64)(((c)) [1] & 0x0000ffff) << 32) \ + + ((guint64)(((c)) [3] & 0x0000ffff) << 16) \ + + (guint64)(((c)) [4] & 0x0000ffff) #else #define THUNK_SIZE ((2 + 5) * 4) #endif diff --git a/src/mono/mono/mini/tramp-ppc.c b/src/mono/mono/mini/tramp-ppc.c index 9cf61118061575..59bcb275a48609 100644 --- a/src/mono/mono/mini/tramp-ppc.c +++ b/src/mono/mono/mini/tramp-ppc.c @@ -670,12 +670,12 @@ mono_arch_get_call_target (guint8 *code) return target; } -#if defined(TARGET_POWERPC64) && G_BYTE_ORDER == G_LITTLE_ENDIAN +#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR) else if (((guint32*)(code - 32)) [0] >> 26 == 15) { - guint8 *thunk = GET_MEMORY_SLOT_THUNK_ADDRESS((code - 32)); + guint8 *thunk = GET_MEMORY_SLOT_THUNK_ADDRESS((guint32*)(code - 32)); return thunk; } else if (((guint32*)(code - 4)) [0] >> 26 == 15) { - guint8 *thunk = GET_MEMORY_SLOT_THUNK_ADDRESS((code - 4)); + guint8 *thunk = GET_MEMORY_SLOT_THUNK_ADDRESS((guint32*)(code - 4)); return thunk; } #endif