Skip to content
2 changes: 1 addition & 1 deletion src/mono/mono/mini/cpu-ppc.mdesc
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion src/mono/mono/mini/cpu-ppc64.mdesc
Original file line number Diff line number Diff line change
Expand Up @@ -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
64 changes: 61 additions & 3 deletions src/mono/mono/mini/mini-ppc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 !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
return is_load_sequence (&code [-6]);
#endif
}
return FALSE;
#else
Expand Down Expand Up @@ -2692,6 +2697,10 @@ 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) && !defined(PPC_USES_FUNCTION_DESCRIPTOR)
*(guint64*)code = (guint64)target;
code += sizeof (guint64);
#else
guint8 *p = code;

/* 2 bytes on 32bit, 5 bytes on 64bit */
Expand All @@ -2701,6 +2710,7 @@ emit_thunk (guint8 *code, gconstpointer target)
ppc_bcctr (code, PPC_BR_ALWAYS, 0);

mono_arch_flush_icache (p, code - p);
#endif
}

static void
Expand Down Expand Up @@ -2731,9 +2741,14 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target)
}

g_assert (*(guint32*)thunks == 0);


emit_thunk (thunks, target);
#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR)
ppc_load_ptr_sequence (code, PPC_CALL_REG, thunks);
#else
ppc_patch (code, thunks);

#endif
cfg->arch.thunks += THUNK_SIZE;
cfg->arch.thunks_size -= THUNK_SIZE;
} else {
Expand All @@ -2753,7 +2768,9 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target)
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 {
}
#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) {
/* Free entry */
Expand All @@ -2777,7 +2794,7 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target)
}
}
}

#endif
// g_print ("THUNK: %p %p %p\n", code, target, target_thunk);

if (!target_thunk) {
Expand All @@ -2787,7 +2804,9 @@ handle_thunk (MonoCompile *cfg, guchar *code, const guchar *target)
}

emit_thunk (target_thunk, target);
#if (defined(TARGET_POWERPC64) && defined(PPC_USES_FUNCTION_DESCRIPTOR)) || !defined(TARGET_POWERPC64)
ppc_patch (code, target_thunk);
#endif

mono_mini_arch_unlock ();
}
Expand Down Expand Up @@ -2875,6 +2894,9 @@ 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 !defined(PPC_USES_FUNCTION_DESCRIPTOR)
handle_thunk (cfg, code, target);
#else
guint32 *seq = (guint32*)code;
guint32 *branch_ins;

Expand Down Expand Up @@ -2923,6 +2945,7 @@ ppc_patch_full (MonoCompile *cfg, guchar *code, const guchar *target, gboolean i
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 */
Expand Down Expand Up @@ -3349,6 +3372,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);
#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR)
ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG);
cfg->thunk_area += THUNK_SIZE;
#endif
ppc_mtlr (code, PPC_CALL_REG);
ppc_blrl (code);
} else {
Expand Down Expand Up @@ -3794,7 +3821,14 @@ 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) && !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);
ppc_bcctr (code, PPC_BR_ALWAYS, 0);
#else
ppc_b (code, 0);
#endif
}
break;
}
Expand Down Expand Up @@ -3823,6 +3857,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);
#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR)
ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG);
cfg->thunk_area += THUNK_SIZE;
#endif
ppc_mtlr (code, PPC_CALL_REG);
ppc_blrl (code);
} else {
Expand Down Expand Up @@ -3926,6 +3964,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);
#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR)
ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG);
cfg->thunk_area += THUNK_SIZE;
#endif
ppc_mtlr (code, PPC_CALL_REG);
ppc_blrl (code);
} else {
Expand All @@ -3940,6 +3982,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);
#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR)
ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG);
cfg->thunk_area += THUNK_SIZE;
#endif
ppc_mtlr (code, PPC_CALL_REG);
ppc_blrl (code);
} else {
Expand Down Expand Up @@ -4584,6 +4630,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);
#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR)
ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG);
cfg->thunk_area += THUNK_SIZE;
#endif
ppc_mtlr (code, PPC_CALL_REG);
ppc_blrl (code);
} else {
Expand Down Expand Up @@ -5185,6 +5235,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);
#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR)
ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG);
cfg->thunk_area += THUNK_SIZE;
#endif
ppc_mtlr (code, PPC_CALL_REG);
ppc_blrl (code);
} else {
Expand Down Expand Up @@ -5466,6 +5520,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);
#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR)
ppc_ldr (code, PPC_CALL_REG, 0, PPC_CALL_REG);
cfg->thunk_area += THUNK_SIZE;
#endif
ppc_mtctr (code, PPC_CALL_REG);
ppc_bcctr (code, PPC_BR_ALWAYS, 0);
} else {
Expand Down
12 changes: 10 additions & 2 deletions src/mono/mono/mini/mini-ppc.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,16 @@
#define MONO_ARCH_CODE_ALIGNMENT 32

#ifdef TARGET_POWERPC64
#if !defined(PPC_USES_FUNCTION_DESCRIPTOR)
#define THUNK_SIZE 8
#define GET_MEMORY_SLOT_THUNK_ADDRESS(c) \
((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
#else
#define THUNK_SIZE ((2 + 2) * 4)
#endif
Expand Down Expand Up @@ -118,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: \
Expand Down
12 changes: 11 additions & 1 deletion src/mono/mono/mini/tramp-ppc.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,17 @@ mono_arch_get_call_target (guint8 *code)
guint8 *target = code - 4 + (disp * 4);

return target;
} else {
}
#if defined(TARGET_POWERPC64) && !defined(PPC_USES_FUNCTION_DESCRIPTOR)
else if (((guint32*)(code - 32)) [0] >> 26 == 15) {
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((guint32*)(code - 4));
return thunk;
}
#endif
else {
return NULL;
}
}
Expand Down