forked from pool/mono-core
dfe1c9a97c
- Cleanup patch numbers - Rebase ppc64 patches based on upstream (commits are 173eaf1dfaf, 7e056cd346c, PR#1479) - 0001-ppc64le-fixes.patch bsc#923558 OBS-URL: https://build.opensuse.org/request/show/292535 OBS-URL: https://build.opensuse.org/package/show/Mono:Factory/mono-core?expand=0&rev=145
1607 lines
66 KiB
Diff
1607 lines
66 KiB
Diff
From efbddc02e76b3a532984de4237f77ba084899175 Mon Sep 17 00:00:00 2001
|
|
From: Dinar Valeev <dvaleev@suse.com>
|
|
Date: Mon, 23 Mar 2015 23:19:48 +0100
|
|
Subject: [PATCH] ppc64le fixes
|
|
|
|
---
|
|
mono/arch/ppc/ppc-codegen.h | 12 +-
|
|
mono/metadata/sgen-archdep.h | 7 +
|
|
mono/metadata/sgen-marksweep.c | 5 +
|
|
mono/mini/aot-compiler.c | 16 +-
|
|
mono/mini/cpu-ppc64.md | 4 +-
|
|
mono/mini/exceptions-ppc.c | 44 ++---
|
|
mono/mini/mini-gc.c | 7 +
|
|
mono/mini/mini-mips.c | 12 +-
|
|
mono/mini/mini-ppc.c | 405 ++++++++++++++++++++++-------------------
|
|
mono/mini/mini-ppc.h | 15 +-
|
|
mono/mini/mini.c | 5 +-
|
|
mono/mini/tramp-ppc.c | 64 +++----
|
|
mono/utils/mono-context.c | 27 +++
|
|
mono/utils/strtod.c | 9 +
|
|
14 files changed, 352 insertions(+), 280 deletions(-)
|
|
|
|
diff --git a/mono/arch/ppc/ppc-codegen.h b/mono/arch/ppc/ppc-codegen.h
|
|
index 55b5060..d4d25a2 100644
|
|
--- a/mono/arch/ppc/ppc-codegen.h
|
|
+++ b/mono/arch/ppc/ppc-codegen.h
|
|
@@ -123,7 +123,7 @@ enum {
|
|
PPC_TRAP_GE_UN = 16 + PPC_TRAP_EQ
|
|
};
|
|
|
|
-#define ppc_emit32(c,x) do { *((guint32 *) (c)) = GUINT32_TO_BE (x); (c) = (gpointer)((guint8 *)(c) + sizeof (guint32));} while (0)
|
|
+#define ppc_emit32(c,x) do { *((guint32 *) (c)) = (guint32) (x); (c) = (gpointer)((guint8 *)(c) + sizeof (guint32));} while (0)
|
|
|
|
#define ppc_is_imm16(val) ((((val)>> 15) == 0) || (((val)>> 15) == -1))
|
|
#define ppc_is_uimm16(val) ((glong)(val) >= 0L && (glong)(val) <= 65535L)
|
|
@@ -806,11 +806,15 @@ my and Ximian's copyright to this code. ;)
|
|
} \
|
|
} G_STMT_END
|
|
|
|
+#if _CALL_ELF == 2
|
|
+#define ppc_load_func(c,D,V) ppc_load_sequence ((c), (D), (V))
|
|
+#else
|
|
#define ppc_load_func(c,D,v) G_STMT_START { \
|
|
- ppc_load_sequence ((c), ppc_r11, (guint64)(gsize)(v)); \
|
|
- ppc_ldptr ((c), ppc_r2, sizeof (gpointer), ppc_r11); \
|
|
- ppc_ldptr ((c), (D), 0, ppc_r11); \
|
|
+ ppc_load_sequence ((c), ppc_r12, (guint64)(gsize)(v)); \
|
|
+ ppc_ldptr ((c), ppc_r2, sizeof (gpointer), ppc_r12); \
|
|
+ ppc_ldptr ((c), (D), 0, ppc_r12); \
|
|
} G_STMT_END
|
|
+#endif
|
|
|
|
#define ppc_load_multiple_regs(c,D,d,A) G_STMT_START { \
|
|
int __i, __o = (d); \
|
|
diff --git a/mono/metadata/sgen-archdep.h b/mono/metadata/sgen-archdep.h
|
|
index 420dc96..410ba6a 100644
|
|
--- a/mono/metadata/sgen-archdep.h
|
|
+++ b/mono/metadata/sgen-archdep.h
|
|
@@ -87,6 +87,13 @@
|
|
((a)[__i]) = (gpointer) UCONTEXT_REG_Rn((ctx), __i); \
|
|
} while (0)
|
|
|
|
+/* MS_BLOCK_SIZE must be a multiple of the system pagesize, which for some
|
|
+ archs is 64k. */
|
|
+#if defined(TARGET_POWERPC64) && _CALL_ELF == 2
|
|
+#define ARCH_MIN_MS_BLOCK_SIZE (64*1024)
|
|
+#define ARCH_MIN_MS_BLOCK_SIZE_SHIFT 16
|
|
+#endif
|
|
+
|
|
#elif defined(TARGET_ARM)
|
|
|
|
#define REDZONE_SIZE 0
|
|
diff --git a/mono/metadata/sgen-marksweep.c b/mono/metadata/sgen-marksweep.c
|
|
index 8980687..a115aad 100644
|
|
--- a/mono/metadata/sgen-marksweep.c
|
|
+++ b/mono/metadata/sgen-marksweep.c
|
|
@@ -44,8 +44,13 @@
|
|
|
|
#define SGEN_HAVE_CONCURRENT_MARK
|
|
|
|
+#if defined(ARCH_MIN_MS_BLOCK_SIZE) && defined(ARCH_MIN_MS_BLOCK_SIZE_SHIFT)
|
|
+#define MS_BLOCK_SIZE ARCH_MIN_MS_BLOCK_SIZE
|
|
+#define MS_BLOCK_SIZE_SHIFT ARCH_MIN_MS_BLOCK_SIZE_SHIFT
|
|
+#else
|
|
#define MS_BLOCK_SIZE (16*1024)
|
|
#define MS_BLOCK_SIZE_SHIFT 14
|
|
+#endif
|
|
#define MAJOR_SECTION_SIZE MS_BLOCK_SIZE
|
|
#define CARDS_PER_BLOCK (MS_BLOCK_SIZE / CARD_SIZE_IN_BYTES)
|
|
|
|
diff --git a/mono/mini/aot-compiler.c b/mono/mini/aot-compiler.c
|
|
index bb3b34a..526ea23 100644
|
|
--- a/mono/mini/aot-compiler.c
|
|
+++ b/mono/mini/aot-compiler.c
|
|
@@ -1941,14 +1941,14 @@ arch_emit_imt_thunk (MonoAotCompile *acfg, int offset, int *tramp_size)
|
|
code = buf;
|
|
|
|
/* Load the mscorlib got address */
|
|
- ppc_ldptr (code, ppc_r11, sizeof (gpointer), ppc_r30);
|
|
+ ppc_ldptr (code, ppc_r12, sizeof (gpointer), ppc_r30);
|
|
/* Load the parameter from the GOT */
|
|
ppc_load (code, ppc_r0, offset * sizeof (gpointer));
|
|
- ppc_ldptr_indexed (code, ppc_r11, ppc_r11, ppc_r0);
|
|
+ ppc_ldptr_indexed (code, ppc_r12, ppc_r12, ppc_r0);
|
|
|
|
/* Load and check key */
|
|
labels [1] = code;
|
|
- ppc_ldptr (code, ppc_r0, 0, ppc_r11);
|
|
+ ppc_ldptr (code, ppc_r0, 0, ppc_r12);
|
|
ppc_cmp (code, 0, sizeof (gpointer) == 8 ? 1 : 0, ppc_r0, MONO_ARCH_IMT_REG);
|
|
labels [2] = code;
|
|
ppc_bc (code, PPC_BR_TRUE, PPC_BR_EQ, 0);
|
|
@@ -1959,18 +1959,18 @@ arch_emit_imt_thunk (MonoAotCompile *acfg, int offset, int *tramp_size)
|
|
ppc_bc (code, PPC_BR_TRUE, PPC_BR_EQ, 0);
|
|
|
|
/* Loop footer */
|
|
- ppc_addi (code, ppc_r11, ppc_r11, 2 * sizeof (gpointer));
|
|
+ ppc_addi (code, ppc_r12, ppc_r12, 2 * sizeof (gpointer));
|
|
labels [4] = code;
|
|
ppc_b (code, 0);
|
|
mono_ppc_patch (labels [4], labels [1]);
|
|
|
|
/* Match */
|
|
mono_ppc_patch (labels [2], code);
|
|
- ppc_ldptr (code, ppc_r11, sizeof (gpointer), ppc_r11);
|
|
- /* r11 now contains the value of the vtable slot */
|
|
+ ppc_ldptr (code, ppc_r12, sizeof (gpointer), ppc_r12);
|
|
+ /* r12 now contains the value of the vtable slot */
|
|
/* this is not a function descriptor on ppc64 */
|
|
- ppc_ldptr (code, ppc_r11, 0, ppc_r11);
|
|
- ppc_mtctr (code, ppc_r11);
|
|
+ ppc_ldptr (code, ppc_r12, 0, ppc_r12);
|
|
+ ppc_mtctr (code, ppc_r12);
|
|
ppc_bcctr (code, PPC_BR_ALWAYS, 0);
|
|
|
|
/* Fail */
|
|
diff --git a/mono/mini/cpu-ppc64.md b/mono/mini/cpu-ppc64.md
|
|
index 114bc3c..c47c6e2 100644
|
|
--- a/mono/mini/cpu-ppc64.md
|
|
+++ b/mono/mini/cpu-ppc64.md
|
|
@@ -380,7 +380,7 @@ vcall2_membase: src1:b len:16 clob:c
|
|
|
|
jump_table: dest:i len:20
|
|
|
|
-atomic_add_i4: src1:b src2:i dest:i len:20
|
|
-atomic_add_i8: src1:b src2:i dest:i len:20
|
|
+atomic_add_i4: src1:b src2:i dest:i len:28
|
|
+atomic_add_i8: src1:b src2:i dest:i len:28
|
|
atomic_cas_i4: src1:b src2:i src3:i dest:i len:38
|
|
atomic_cas_i8: src1:b src2:i src3:i dest:i len:38
|
|
diff --git a/mono/mini/exceptions-ppc.c b/mono/mini/exceptions-ppc.c
|
|
index 6c3878e..8850b75 100644
|
|
--- a/mono/mini/exceptions-ppc.c
|
|
+++ b/mono/mini/exceptions-ppc.c
|
|
@@ -381,18 +381,18 @@ mono_arch_get_throw_exception_generic (int size, MonoTrampInfo **info, int corli
|
|
|
|
if (aot) {
|
|
code = mono_arch_emit_load_aotconst (start, code, &ji, MONO_PATCH_INFO_IMAGE, mono_defaults.corlib);
|
|
- ppc_mr (code, ppc_r3, ppc_r11);
|
|
+ ppc_mr (code, ppc_r3, ppc_r12);
|
|
code = mono_arch_emit_load_aotconst (start, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_exception_from_token");
|
|
#ifdef PPC_USES_FUNCTION_DESCRIPTOR
|
|
- ppc_ldptr (code, ppc_r2, sizeof (gpointer), ppc_r11);
|
|
- ppc_ldptr (code, ppc_r11, 0, ppc_r11);
|
|
+ ppc_ldptr (code, ppc_r2, sizeof (gpointer), ppc_r12);
|
|
+ ppc_ldptr (code, ppc_r12, 0, ppc_r12);
|
|
#endif
|
|
- ppc_mtctr (code, ppc_r11);
|
|
+ ppc_mtctr (code, ppc_r12);
|
|
ppc_bcctrl (code, PPC_BR_ALWAYS, 0);
|
|
} else {
|
|
ppc_load (code, ppc_r3, (gulong)mono_defaults.corlib);
|
|
- ppc_load_func (code, ppc_r0, mono_exception_from_token);
|
|
- ppc_mtctr (code, ppc_r0);
|
|
+ ppc_load_func (code, PPC_CALL_REG, mono_exception_from_token);
|
|
+ ppc_mtctr (code, PPC_CALL_REG);
|
|
ppc_bcctrl (code, PPC_BR_ALWAYS, 0);
|
|
}
|
|
}
|
|
@@ -420,14 +420,14 @@ mono_arch_get_throw_exception_generic (int size, MonoTrampInfo **info, int corli
|
|
code = mono_arch_emit_load_got_addr (start, code, NULL, &ji);
|
|
code = mono_arch_emit_load_aotconst (start, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_ppc_throw_exception");
|
|
#ifdef PPC_USES_FUNCTION_DESCRIPTOR
|
|
- ppc_ldptr (code, ppc_r2, sizeof (gpointer), ppc_r11);
|
|
- ppc_ldptr (code, ppc_r11, 0, ppc_r11);
|
|
+ ppc_ldptr (code, ppc_r2, sizeof (gpointer), ppc_r12);
|
|
+ ppc_ldptr (code, ppc_r12, 0, ppc_r12);
|
|
#endif
|
|
- ppc_mtctr (code, ppc_r11);
|
|
+ ppc_mtctr (code, ppc_r12);
|
|
ppc_bcctrl (code, PPC_BR_ALWAYS, 0);
|
|
} else {
|
|
- ppc_load_func (code, ppc_r0, mono_ppc_throw_exception);
|
|
- ppc_mtctr (code, ppc_r0);
|
|
+ ppc_load_func (code, PPC_CALL_REG, mono_ppc_throw_exception);
|
|
+ ppc_mtctr (code, PPC_CALL_REG);
|
|
ppc_bcctrl (code, PPC_BR_ALWAYS, 0);
|
|
}
|
|
/* we should never reach this breakpoint */
|
|
@@ -600,31 +600,13 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
|
|
void
|
|
mono_arch_sigctx_to_monoctx (void *ctx, MonoContext *mctx)
|
|
{
|
|
-#ifdef MONO_CROSS_COMPILE
|
|
- g_assert_not_reached ();
|
|
-#else
|
|
- os_ucontext *uc = ctx;
|
|
-
|
|
- mctx->sc_ir = UCONTEXT_REG_NIP(uc);
|
|
- mctx->sc_sp = UCONTEXT_REG_Rn(uc, 1);
|
|
- memcpy (&mctx->regs, &UCONTEXT_REG_Rn(uc, 13), sizeof (mgreg_t) * MONO_SAVED_GREGS);
|
|
- memcpy (&mctx->fregs, &UCONTEXT_REG_FPRn(uc, 14), sizeof (double) * MONO_SAVED_FREGS);
|
|
-#endif
|
|
+ return mono_sigctx_to_monoctx (ctx, mctx);
|
|
}
|
|
|
|
void
|
|
mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
|
|
{
|
|
-#ifdef MONO_CROSS_COMPILE
|
|
- g_assert_not_reached ();
|
|
-#else
|
|
- os_ucontext *uc = ctx;
|
|
-
|
|
- UCONTEXT_REG_NIP(uc) = mctx->sc_ir;
|
|
- UCONTEXT_REG_Rn(uc, 1) = mctx->sc_sp;
|
|
- memcpy (&UCONTEXT_REG_Rn(uc, 13), &mctx->regs, sizeof (mgreg_t) * MONO_SAVED_GREGS);
|
|
- memcpy (&UCONTEXT_REG_FPRn(uc, 14), &mctx->fregs, sizeof (double) * MONO_SAVED_FREGS);
|
|
-#endif
|
|
+ return mono_monoctx_to_sigctx (mctx, ctx);
|
|
}
|
|
|
|
gpointer
|
|
diff --git a/mono/mini/mini-gc.c b/mono/mini/mini-gc.c
|
|
index a528b3f..d0004b6 100644
|
|
--- a/mono/mini/mini-gc.c
|
|
+++ b/mono/mini/mini-gc.c
|
|
@@ -436,6 +436,13 @@ static int callee_saved_regs [] = { ARMREG_V1, ARMREG_V2, ARMREG_V3, ARMREG_V4,
|
|
static int callee_saved_regs [] = { };
|
|
#elif defined(TARGET_S390X)
|
|
static int callee_saved_regs [] = { s390_r6, s390_r7, s390_r8, s390_r9, s390_r10, s390_r11, s390_r12, s390_r13, s390_r14 };
|
|
+#elif defined(TARGET_POWERPC64) && _CALL_ELF == 2
|
|
+static int callee_saved_regs [] = {
|
|
+ ppc_r13, ppc_r14, ppc_r15, ppc_r16,
|
|
+ ppc_r17, ppc_r18, ppc_r19, ppc_r20,
|
|
+ ppc_r21, ppc_r22, ppc_r23, ppc_r24,
|
|
+ ppc_r25, ppc_r26, ppc_r27, ppc_r28,
|
|
+ ppc_r29, ppc_r30, ppc_r31 };
|
|
#elif defined(TARGET_POWERPC)
|
|
static int callee_saved_regs [] = { ppc_r6, ppc_r7, ppc_r8, ppc_r9, ppc_r10, ppc_r11, ppc_r12, ppc_r13, ppc_r14 };
|
|
#endif
|
|
diff --git a/mono/mini/mini-mips.c b/mono/mini/mini-mips.c
|
|
index 2aa6bd1..1eb61e9 100644
|
|
--- a/mono/mini/mini-mips.c
|
|
+++ b/mono/mini/mini-mips.c
|
|
@@ -3305,8 +3305,8 @@ emit_reserve_param_area (MonoCompile *cfg, guint8 *code)
|
|
if (ppc_is_imm16 (-size)) {
|
|
ppc_stwu (code, ppc_r0, -size, ppc_sp);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, -size);
|
|
- ppc_stwux (code, ppc_r0, ppc_sp, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, -size);
|
|
+ ppc_stwux (code, ppc_r0, ppc_sp, ppc_r12);
|
|
}
|
|
#endif
|
|
return code;
|
|
@@ -3327,8 +3327,8 @@ emit_unreserve_param_area (MonoCompile *cfg, guint8 *code)
|
|
if (ppc_is_imm16 (size)) {
|
|
ppc_stwu (code, ppc_r0, size, ppc_sp);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, size);
|
|
- ppc_stwux (code, ppc_r0, ppc_sp, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, size);
|
|
+ ppc_stwux (code, ppc_r0, ppc_sp, ppc_r12);
|
|
}
|
|
#endif
|
|
return code;
|
|
@@ -3719,8 +3719,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
case OP_DIV_IMM:
|
|
g_assert_not_reached ();
|
|
#if 0
|
|
- ppc_load (code, ppc_r11, ins->inst_imm);
|
|
- ppc_divwod (code, ins->dreg, ins->sreg1, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, ins->inst_imm);
|
|
+ ppc_divwod (code, ins->dreg, ins->sreg1, ppc_r12);
|
|
ppc_mfspr (code, ppc_r0, ppc_xer);
|
|
ppc_andisd (code, ppc_r0, ppc_r0, (1<<14));
|
|
/* FIXME: use OverflowException for 0x80000000/-1 */
|
|
diff --git a/mono/mini/mini-ppc.c b/mono/mini/mini-ppc.c
|
|
index a7c8398..594a72e 100644
|
|
--- a/mono/mini/mini-ppc.c
|
|
+++ b/mono/mini/mini-ppc.c
|
|
@@ -104,11 +104,11 @@ offsets_from_pthread_key (guint32 key, int *offset2)
|
|
/* FIXME: ensure the sc call preserves all but r3 */
|
|
#define emit_darwing4_tls(code,dreg,key) do {\
|
|
int off1 = 0x48 + key * sizeof (gpointer); \
|
|
- if ((dreg) != ppc_r3) ppc_mr ((code), ppc_r11, ppc_r3); \
|
|
+ if ((dreg) != ppc_r3) ppc_mr ((code), ppc_r12, ppc_r3); \
|
|
ppc_li ((code), ppc_r0, 0x7FF2); \
|
|
ppc_sc ((code)); \
|
|
ppc_lwz ((code), (dreg), off1, ppc_r3); \
|
|
- if ((dreg) != ppc_r3) ppc_mr ((code), ppc_r3, ppc_r11); \
|
|
+ if ((dreg) != ppc_r3) ppc_mr ((code), ppc_r3, ppc_r12); \
|
|
} while (0);
|
|
|
|
#ifdef PPC_THREAD_PTR_REG
|
|
@@ -119,8 +119,8 @@ offsets_from_pthread_key (guint32 key, int *offset2)
|
|
ppc_ldptr ((code), (dreg), off1, PPC_THREAD_PTR_REG); \
|
|
} else { \
|
|
int off3 = (off2 + 1) > 1; \
|
|
- ppc_addis ((code), ppc_r11, PPC_THREAD_PTR_REG, off3); \
|
|
- ppc_ldptr ((code), (dreg), off1, ppc_r11); \
|
|
+ ppc_addis ((code), ppc_r12, PPC_THREAD_PTR_REG, off3); \
|
|
+ ppc_ldptr ((code), (dreg), off1, ppc_r12); \
|
|
} \
|
|
} while (0);
|
|
#else
|
|
@@ -191,29 +191,29 @@ emit_memcpy (guint8 *code, int size, int dreg, int doffset, int sreg, int soffse
|
|
|
|
ppc_load (code, ppc_r0, shifted);
|
|
ppc_mtctr (code, ppc_r0);
|
|
- //g_assert (sreg == ppc_r11);
|
|
- ppc_addi (code, ppc_r12, dreg, (doffset - sizeof (gpointer)));
|
|
- ppc_addi (code, ppc_r11, sreg, (soffset - sizeof (gpointer)));
|
|
+ //g_assert (sreg == ppc_r12);
|
|
+ ppc_addi (code, ppc_r11, dreg, (doffset - sizeof (gpointer)));
|
|
+ ppc_addi (code, ppc_r12, sreg, (soffset - sizeof (gpointer)));
|
|
copy_loop_start = code;
|
|
- ppc_ldptr_update (code, ppc_r0, (unsigned int)sizeof (gpointer), ppc_r11);
|
|
- ppc_stptr_update (code, ppc_r0, (unsigned int)sizeof (gpointer), ppc_r12);
|
|
+ ppc_ldptr_update (code, ppc_r0, (unsigned int)sizeof (gpointer), ppc_r12);
|
|
+ ppc_stptr_update (code, ppc_r0, (unsigned int)sizeof (gpointer), ppc_r11);
|
|
copy_loop_jump = code;
|
|
ppc_bc (code, PPC_BR_DEC_CTR_NONZERO, 0, 0);
|
|
ppc_patch (copy_loop_jump, copy_loop_start);
|
|
size -= shifted * sizeof (gpointer);
|
|
doffset = soffset = 0;
|
|
- dreg = ppc_r12;
|
|
+ dreg = ppc_r11;
|
|
}
|
|
#ifdef __mono_ppc64__
|
|
/* the hardware has multiple load/store units and the move is long
|
|
enough to use more then one regiester, then use load/load/store/store
|
|
to execute 2 instructions per cycle. */
|
|
- if ((cpu_hw_caps & PPC_MULTIPLE_LS_UNITS) && (dreg != ppc_r12) && (sreg != ppc_r12)) {
|
|
+ if ((cpu_hw_caps & PPC_MULTIPLE_LS_UNITS) && (dreg != ppc_r11) && (sreg != ppc_r11)) {
|
|
while (size >= 16) {
|
|
ppc_ldptr (code, ppc_r0, soffset, sreg);
|
|
- ppc_ldptr (code, ppc_r12, soffset+8, sreg);
|
|
+ ppc_ldptr (code, ppc_r11, soffset+8, sreg);
|
|
ppc_stptr (code, ppc_r0, doffset, dreg);
|
|
- ppc_stptr (code, ppc_r12, doffset+8, dreg);
|
|
+ ppc_stptr (code, ppc_r11, doffset+8, dreg);
|
|
size -= 16;
|
|
soffset += 16;
|
|
doffset += 16;
|
|
@@ -227,12 +227,12 @@ emit_memcpy (guint8 *code, int size, int dreg, int doffset, int sreg, int soffse
|
|
doffset += 8;
|
|
}
|
|
#else
|
|
- if ((cpu_hw_caps & PPC_MULTIPLE_LS_UNITS) && (dreg != ppc_r12) && (sreg != ppc_r12)) {
|
|
+ if ((cpu_hw_caps & PPC_MULTIPLE_LS_UNITS) && (dreg != ppc_r11) && (sreg != ppc_r11)) {
|
|
while (size >= 8) {
|
|
ppc_lwz (code, ppc_r0, soffset, sreg);
|
|
- ppc_lwz (code, ppc_r12, soffset+4, sreg);
|
|
+ ppc_lwz (code, ppc_r11, soffset+4, sreg);
|
|
ppc_stw (code, ppc_r0, doffset, dreg);
|
|
- ppc_stw (code, ppc_r12, doffset+4, dreg);
|
|
+ ppc_stw (code, ppc_r11, doffset+4, dreg);
|
|
size -= 8;
|
|
soffset += 8;
|
|
doffset += 8;
|
|
@@ -744,7 +744,7 @@ mono_arch_get_global_int_regs (MonoCompile *cfg)
|
|
for (i = 14; i < top; ++i) {
|
|
/*
|
|
* Reserve r29 for holding the vtable address for virtual calls in AOT mode,
|
|
- * since the trampolines can clobber r11.
|
|
+ * since the trampolines can clobber r12.
|
|
*/
|
|
if (!(cfg->compile_aot && i == 29))
|
|
regs = g_list_prepend (regs, GUINT_TO_POINTER (i));
|
|
@@ -1789,8 +1789,8 @@ mono_arch_instrument_prolog (MonoCompile *cfg, void *func, void *p, gboolean ena
|
|
|
|
ppc_load_ptr (code, ppc_r3, cfg->method);
|
|
ppc_li (code, ppc_r4, 0); /* NULL ebp for now */
|
|
- ppc_load_func (code, ppc_r0, func);
|
|
- ppc_mtlr (code, ppc_r0);
|
|
+ ppc_load_func (code, PPC_CALL_REG, func);
|
|
+ ppc_mtlr (code, PPC_CALL_REG);
|
|
ppc_blrl (code);
|
|
return code;
|
|
}
|
|
@@ -1887,8 +1887,8 @@ mono_arch_instrument_epilog_full (MonoCompile *cfg, void *func, void *p, gboolea
|
|
}
|
|
|
|
ppc_load_ptr (code, ppc_r3, cfg->method);
|
|
- ppc_load_func (code, ppc_r0, func);
|
|
- ppc_mtlr (code, ppc_r0);
|
|
+ ppc_load_func (code, PPC_CALL_REG, func);
|
|
+ ppc_mtlr (code, PPC_CALL_REG);
|
|
ppc_blrl (code);
|
|
|
|
switch (save_mode) {
|
|
@@ -2822,14 +2822,14 @@ handle_thunk (int absolute, guchar *code, const guchar *target) {
|
|
static void
|
|
patch_ins (guint8 *code, guint32 ins)
|
|
{
|
|
- *(guint32*)code = GUINT32_TO_BE (ins);
|
|
+ *(guint32*)code = ins;
|
|
mono_arch_flush_icache (code, 4);
|
|
}
|
|
|
|
void
|
|
ppc_patch_full (guchar *code, const guchar *target, gboolean is_fd)
|
|
{
|
|
- guint32 ins = GUINT32_FROM_BE (*(guint32*)code);
|
|
+ guint32 ins = *(guint32*)code;
|
|
guint32 prim = ins >> 26;
|
|
guint32 ovf;
|
|
|
|
@@ -2912,7 +2912,13 @@ ppc_patch_full (guchar *code, const guchar *target, gboolean is_fd)
|
|
else
|
|
code -= 24;
|
|
} else {
|
|
- if (ppc_is_load_op (seq [5]) || ppc_opcode (seq [5]) == 31) /* ld || lwz || mr */
|
|
+ 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;
|
|
@@ -2927,7 +2933,7 @@ ppc_patch_full (guchar *code, const guchar *target, gboolean is_fd)
|
|
|
|
if (!is_fd) {
|
|
guint8 *buf = (guint8*)&seq [5];
|
|
- ppc_mr (buf, ppc_r0, ppc_r11);
|
|
+ ppc_mr (buf, PPC_CALL_REG, ppc_r12);
|
|
ppc_nop (buf);
|
|
}
|
|
} else {
|
|
@@ -2936,8 +2942,12 @@ ppc_patch_full (guchar *code, const guchar *target, gboolean is_fd)
|
|
}
|
|
|
|
/* FIXME: make this thread safe */
|
|
- /* FIXME: we're assuming we're using r11 here */
|
|
- ppc_load_ptr_sequence (code, ppc_r11, target);
|
|
+#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);
|
|
#else
|
|
guint32 *seq;
|
|
@@ -2952,8 +2962,8 @@ ppc_patch_full (guchar *code, const guchar *target, gboolean is_fd)
|
|
g_assert ((seq [2] >> 26) == 31);
|
|
g_assert (seq [3] == 0x4e800021 || seq [3] == 0x4e800020 || seq [3] == 0x4e800420);
|
|
/* FIXME: make this thread safe */
|
|
- ppc_lis (code, ppc_r0, (guint32)(target) >> 16);
|
|
- ppc_ori (code, ppc_r0, ppc_r0, (guint32)(target) & 0xffff);
|
|
+ ppc_lis (code, PPC_CALL_REG, (guint32)(target) >> 16);
|
|
+ ppc_ori (code, PPC_CALL_REG, PPC_CALL_REG, (guint32)(target) & 0xffff);
|
|
mono_arch_flush_icache (code - 8, 8);
|
|
#endif
|
|
} else {
|
|
@@ -3010,8 +3020,8 @@ emit_reserve_param_area (MonoCompile *cfg, guint8 *code)
|
|
if (ppc_is_imm16 (-size)) {
|
|
ppc_stptr_update (code, ppc_r0, -size, ppc_sp);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, -size);
|
|
- ppc_stptr_update_indexed (code, ppc_r0, ppc_sp, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, -size);
|
|
+ ppc_stptr_update_indexed (code, ppc_r0, ppc_sp, ppc_r12);
|
|
}
|
|
|
|
return code;
|
|
@@ -3032,8 +3042,8 @@ emit_unreserve_param_area (MonoCompile *cfg, guint8 *code)
|
|
if (ppc_is_imm16 (size)) {
|
|
ppc_stptr_update (code, ppc_r0, size, ppc_sp);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, size);
|
|
- ppc_stptr_update_indexed (code, ppc_r0, ppc_sp, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, size);
|
|
+ ppc_stptr_update_indexed (code, ppc_r0, ppc_sp, ppc_r12);
|
|
}
|
|
|
|
return code;
|
|
@@ -3107,8 +3117,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
* a breakpoint is hit will step to the next IL offset.
|
|
*/
|
|
if (ins->flags & MONO_INST_SINGLE_STEP_LOC) {
|
|
- ppc_load (code, ppc_r11, (gsize)ss_trigger_page);
|
|
- ppc_ldptr (code, ppc_r11, 0, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, (gsize)ss_trigger_page);
|
|
+ ppc_ldptr (code, ppc_r12, 0, ppc_r12);
|
|
}
|
|
|
|
mono_add_seq_point (cfg, bb, ins, code - cfg->native_code);
|
|
@@ -3142,8 +3152,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
ppc_stb (code, ins->sreg1, ins->inst_offset, ins->inst_destbasereg);
|
|
} else {
|
|
if (ppc_is_imm32 (ins->inst_offset)) {
|
|
- ppc_addis (code, ppc_r12, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
|
|
- ppc_stb (code, ins->sreg1, ins->inst_offset, ppc_r12);
|
|
+ ppc_addis (code, ppc_r11, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
|
|
+ ppc_stb (code, ins->sreg1, ins->inst_offset, ppc_r11);
|
|
} else {
|
|
ppc_load (code, ppc_r0, ins->inst_offset);
|
|
ppc_stbx (code, ins->sreg1, ins->inst_destbasereg, ppc_r0);
|
|
@@ -3155,8 +3165,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
ppc_sth (code, ins->sreg1, ins->inst_offset, ins->inst_destbasereg);
|
|
} else {
|
|
if (ppc_is_imm32 (ins->inst_offset)) {
|
|
- ppc_addis (code, ppc_r12, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
|
|
- ppc_sth (code, ins->sreg1, ins->inst_offset, ppc_r12);
|
|
+ ppc_addis (code, ppc_r11, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
|
|
+ ppc_sth (code, ins->sreg1, ins->inst_offset, ppc_r11);
|
|
} else {
|
|
ppc_load (code, ppc_r0, ins->inst_offset);
|
|
ppc_sthx (code, ins->sreg1, ins->inst_destbasereg, ppc_r0);
|
|
@@ -3168,8 +3178,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
ppc_stptr (code, ins->sreg1, ins->inst_offset, ins->inst_destbasereg);
|
|
} else {
|
|
if (ppc_is_imm32 (ins->inst_offset)) {
|
|
- ppc_addis (code, ppc_r12, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
|
|
- ppc_stptr (code, ins->sreg1, ins->inst_offset, ppc_r12);
|
|
+ ppc_addis (code, ppc_r11, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
|
|
+ ppc_stptr (code, ins->sreg1, ins->inst_offset, ppc_r11);
|
|
} else {
|
|
ppc_load (code, ppc_r0, ins->inst_offset);
|
|
ppc_stptr_indexed (code, ins->sreg1, ins->inst_destbasereg, ppc_r0);
|
|
@@ -3371,8 +3381,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
|
|
(gpointer)"mono_break");
|
|
if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) {
|
|
- ppc_load_func (code, ppc_r0, 0);
|
|
- ppc_mtlr (code, ppc_r0);
|
|
+ ppc_load_func (code, PPC_CALL_REG, 0);
|
|
+ ppc_mtlr (code, PPC_CALL_REG);
|
|
ppc_blrl (code);
|
|
} else {
|
|
ppc_bl (code, 0);
|
|
@@ -3725,7 +3735,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
*/
|
|
g_assert (!cfg->method->save_lmf);
|
|
/*
|
|
- * Note: we can use ppc_r11 here because it is dead anyway:
|
|
+ * Note: we can use ppc_r12 here because it is dead anyway:
|
|
* we're leaving the method.
|
|
*/
|
|
if (1 || cfg->flags & MONO_CFG_HAS_CALLS) {
|
|
@@ -3733,26 +3743,26 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
if (ppc_is_imm16 (ret_offset)) {
|
|
ppc_ldptr (code, ppc_r0, ret_offset, cfg->frame_reg);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, ret_offset);
|
|
- ppc_ldptr_indexed (code, ppc_r0, cfg->frame_reg, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, ret_offset);
|
|
+ ppc_ldptr_indexed (code, ppc_r0, cfg->frame_reg, ppc_r12);
|
|
}
|
|
ppc_mtlr (code, ppc_r0);
|
|
}
|
|
|
|
if (ppc_is_imm16 (cfg->stack_usage)) {
|
|
- ppc_addi (code, ppc_r11, cfg->frame_reg, cfg->stack_usage);
|
|
+ ppc_addi (code, ppc_r12, cfg->frame_reg, cfg->stack_usage);
|
|
} else {
|
|
/* cfg->stack_usage is an int, so we can use
|
|
* an addis/addi sequence here even in 64-bit. */
|
|
- ppc_addis (code, ppc_r11, cfg->frame_reg, ppc_ha(cfg->stack_usage));
|
|
- ppc_addi (code, ppc_r11, ppc_r11, cfg->stack_usage);
|
|
+ ppc_addis (code, ppc_r12, cfg->frame_reg, ppc_ha(cfg->stack_usage));
|
|
+ ppc_addi (code, ppc_r12, ppc_r12, cfg->stack_usage);
|
|
}
|
|
if (!cfg->method->save_lmf) {
|
|
pos = 0;
|
|
for (i = 31; i >= 13; --i) {
|
|
if (cfg->used_int_regs & (1 << i)) {
|
|
pos += sizeof (gpointer);
|
|
- ppc_ldptr (code, i, -pos, ppc_r11);
|
|
+ ppc_ldptr (code, i, -pos, ppc_r12);
|
|
}
|
|
}
|
|
} else {
|
|
@@ -3761,27 +3771,27 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
|
|
/* Copy arguments on the stack to our argument area */
|
|
if (call->stack_usage) {
|
|
- code = emit_memcpy (code, call->stack_usage, ppc_r11, PPC_STACK_PARAM_OFFSET, ppc_sp, PPC_STACK_PARAM_OFFSET);
|
|
- /* r11 was clobbered */
|
|
+ code = emit_memcpy (code, call->stack_usage, ppc_r12, PPC_STACK_PARAM_OFFSET, ppc_sp, PPC_STACK_PARAM_OFFSET);
|
|
+ /* r12 was clobbered */
|
|
g_assert (cfg->frame_reg == ppc_sp);
|
|
if (ppc_is_imm16 (cfg->stack_usage)) {
|
|
- ppc_addi (code, ppc_r11, cfg->frame_reg, cfg->stack_usage);
|
|
+ ppc_addi (code, ppc_r12, cfg->frame_reg, cfg->stack_usage);
|
|
} else {
|
|
/* cfg->stack_usage is an int, so we can use
|
|
* an addis/addi sequence here even in 64-bit. */
|
|
- ppc_addis (code, ppc_r11, cfg->frame_reg, ppc_ha(cfg->stack_usage));
|
|
- ppc_addi (code, ppc_r11, ppc_r11, cfg->stack_usage);
|
|
+ ppc_addis (code, ppc_r12, cfg->frame_reg, ppc_ha(cfg->stack_usage));
|
|
+ ppc_addi (code, ppc_r12, ppc_r12, cfg->stack_usage);
|
|
}
|
|
}
|
|
|
|
- ppc_mr (code, ppc_sp, ppc_r11);
|
|
+ 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 (cfg->compile_aot) {
|
|
/* arch_emit_got_access () patches this */
|
|
ppc_load32 (code, ppc_r0, 0);
|
|
#ifdef PPC_USES_FUNCTION_DESCRIPTOR
|
|
- ppc_ldptr_indexed (code, ppc_r11, ppc_r30, ppc_r0);
|
|
- ppc_ldptr (code, ppc_r0, 0, ppc_r11);
|
|
+ ppc_ldptr_indexed (code, ppc_r12, ppc_r30, ppc_r0);
|
|
+ ppc_ldptr (code, ppc_r0, 0, ppc_r12);
|
|
#else
|
|
ppc_ldptr_indexed (code, ppc_r0, ppc_r30, ppc_r0);
|
|
#endif
|
|
@@ -3819,8 +3829,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
else
|
|
mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_ABS, call->fptr);
|
|
if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) {
|
|
- ppc_load_func (code, ppc_r0, 0);
|
|
- ppc_mtlr (code, ppc_r0);
|
|
+ ppc_load_func (code, PPC_CALL_REG, 0);
|
|
+ ppc_mtlr (code, PPC_CALL_REG);
|
|
ppc_blrl (code);
|
|
} else {
|
|
ppc_bl (code, 0);
|
|
@@ -3853,7 +3863,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
case OP_VCALL2_MEMBASE:
|
|
case OP_VOIDCALL_MEMBASE:
|
|
case OP_CALL_MEMBASE:
|
|
- if (cfg->compile_aot && ins->sreg1 == ppc_r11) {
|
|
+ if (cfg->compile_aot && ins->sreg1 == ppc_r12) {
|
|
/* The trampolines clobber this */
|
|
ppc_mr (code, ppc_r29, ins->sreg1);
|
|
ppc_ldptr (code, ppc_r0, ins->inst_offset, ppc_r29);
|
|
@@ -3871,9 +3881,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
int alloca_waste = PPC_STACK_PARAM_OFFSET + cfg->param_area + 31;
|
|
int area_offset = alloca_waste;
|
|
area_offset &= ~31;
|
|
- ppc_addi (code, ppc_r11, ins->sreg1, alloca_waste + 31);
|
|
+ ppc_addi (code, ppc_r12, ins->sreg1, alloca_waste + 31);
|
|
/* FIXME: should be calculated from MONO_ARCH_FRAME_ALIGNMENT */
|
|
- ppc_clear_right_imm (code, ppc_r11, ppc_r11, 4);
|
|
+ ppc_clear_right_imm (code, ppc_r12, ppc_r12, 4);
|
|
/* use ctr to store the number of words to 0 if needed */
|
|
if (ins->flags & MONO_INST_INIT) {
|
|
/* we zero 4 bytes at a time:
|
|
@@ -3886,8 +3896,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
ppc_mtctr (code, ppc_r0);
|
|
}
|
|
ppc_ldptr (code, ppc_r0, 0, ppc_sp);
|
|
- ppc_neg (code, ppc_r11, ppc_r11);
|
|
- ppc_stptr_update_indexed (code, ppc_r0, ppc_sp, ppc_r11);
|
|
+ ppc_neg (code, ppc_r12, ppc_r12);
|
|
+ ppc_stptr_update_indexed (code, ppc_r0, ppc_sp, ppc_r12);
|
|
|
|
/* FIXME: make this loop work in 8 byte
|
|
increments on PPC64 */
|
|
@@ -3897,9 +3907,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
* run at least once
|
|
*/
|
|
ppc_addi (code, ins->dreg, ppc_sp, (area_offset - 8));
|
|
- ppc_li (code, ppc_r11, 0);
|
|
+ ppc_li (code, ppc_r12, 0);
|
|
zero_loop_start = code;
|
|
- ppc_stwu (code, ppc_r11, 4, ins->dreg);
|
|
+ ppc_stwu (code, ppc_r12, 4, ins->dreg);
|
|
zero_loop_jump = code;
|
|
ppc_bc (code, PPC_BR_DEC_CTR_NONZERO, 0, 0);
|
|
ppc_patch (zero_loop_jump, zero_loop_start);
|
|
@@ -3913,8 +3923,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
|
|
(gpointer)"mono_arch_throw_exception");
|
|
if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) {
|
|
- ppc_load_func (code, ppc_r0, 0);
|
|
- ppc_mtlr (code, ppc_r0);
|
|
+ ppc_load_func (code, PPC_CALL_REG, 0);
|
|
+ ppc_mtlr (code, PPC_CALL_REG);
|
|
ppc_blrl (code);
|
|
} else {
|
|
ppc_bl (code, 0);
|
|
@@ -3927,8 +3937,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
|
|
(gpointer)"mono_arch_rethrow_exception");
|
|
if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) {
|
|
- ppc_load_func (code, ppc_r0, 0);
|
|
- ppc_mtlr (code, ppc_r0);
|
|
+ ppc_load_func (code, PPC_CALL_REG, 0);
|
|
+ ppc_mtlr (code, PPC_CALL_REG);
|
|
ppc_blrl (code);
|
|
} else {
|
|
ppc_bl (code, 0);
|
|
@@ -3943,8 +3953,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
if (ppc_is_imm16 (spvar->inst_offset)) {
|
|
ppc_stptr (code, ppc_r0, spvar->inst_offset, spvar->inst_basereg);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, spvar->inst_offset);
|
|
- ppc_stptr_indexed (code, ppc_r0, ppc_r11, spvar->inst_basereg);
|
|
+ ppc_load (code, ppc_r12, spvar->inst_offset);
|
|
+ ppc_stptr_indexed (code, ppc_r0, ppc_r12, spvar->inst_basereg);
|
|
}
|
|
break;
|
|
}
|
|
@@ -3957,8 +3967,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
if (ppc_is_imm16 (spvar->inst_offset)) {
|
|
ppc_ldptr (code, ppc_r0, spvar->inst_offset, spvar->inst_basereg);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, spvar->inst_offset);
|
|
- ppc_ldptr_indexed (code, ppc_r0, spvar->inst_basereg, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, spvar->inst_offset);
|
|
+ ppc_ldptr_indexed (code, ppc_r0, spvar->inst_basereg, ppc_r12);
|
|
}
|
|
ppc_mtlr (code, ppc_r0);
|
|
ppc_blr (code);
|
|
@@ -4064,11 +4074,11 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
|
|
/* FIXME: Optimize this */
|
|
ppc_bl (code, 1);
|
|
- ppc_mflr (code, ppc_r11);
|
|
+ ppc_mflr (code, ppc_r12);
|
|
ppc_b (code, 3);
|
|
*(double*)code = *(double*)ins->inst_p0;
|
|
code += 8;
|
|
- ppc_lfd (code, ins->dreg, 8, ppc_r11);
|
|
+ ppc_lfd (code, ins->dreg, 8, ppc_r12);
|
|
break;
|
|
case OP_R4CONST:
|
|
g_assert_not_reached ();
|
|
@@ -4078,8 +4088,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
ppc_stfd (code, ins->sreg1, ins->inst_offset, ins->inst_destbasereg);
|
|
} else {
|
|
if (ppc_is_imm32 (ins->inst_offset)) {
|
|
- ppc_addis (code, ppc_r12, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
|
|
- ppc_stfd (code, ins->sreg1, ins->inst_offset, ppc_r12);
|
|
+ ppc_addis (code, ppc_r11, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
|
|
+ ppc_stfd (code, ins->sreg1, ins->inst_offset, ppc_r11);
|
|
} else {
|
|
ppc_load (code, ppc_r0, ins->inst_offset);
|
|
ppc_stfdx (code, ins->sreg1, ins->inst_destbasereg, ppc_r0);
|
|
@@ -4091,8 +4101,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
ppc_lfd (code, ins->dreg, ins->inst_offset, ins->inst_basereg);
|
|
} else {
|
|
if (ppc_is_imm32 (ins->inst_offset)) {
|
|
- ppc_addis (code, ppc_r12, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
|
|
- ppc_lfd (code, ins->dreg, ins->inst_offset, ppc_r12);
|
|
+ ppc_addis (code, ppc_r11, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
|
|
+ ppc_lfd (code, ins->dreg, ins->inst_offset, ppc_r11);
|
|
} else {
|
|
ppc_load (code, ppc_r0, ins->inst_offset);
|
|
ppc_lfdx (code, ins->dreg, ins->inst_destbasereg, ppc_r0);
|
|
@@ -4105,8 +4115,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
ppc_stfs (code, ins->sreg1, ins->inst_offset, ins->inst_destbasereg);
|
|
} else {
|
|
if (ppc_is_imm32 (ins->inst_offset)) {
|
|
- ppc_addis (code, ppc_r12, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
|
|
- ppc_stfs (code, ins->sreg1, ins->inst_offset, ppc_r12);
|
|
+ ppc_addis (code, ppc_r11, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
|
|
+ ppc_stfs (code, ins->sreg1, ins->inst_offset, ppc_r11);
|
|
} else {
|
|
ppc_load (code, ppc_r0, ins->inst_offset);
|
|
ppc_stfsx (code, ins->sreg1, ins->inst_destbasereg, ppc_r0);
|
|
@@ -4118,8 +4128,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
|
|
ppc_lfs (code, ins->dreg, ins->inst_offset, ins->inst_basereg);
|
|
} else {
|
|
if (ppc_is_imm32 (ins->inst_offset)) {
|
|
- ppc_addis (code, ppc_r12, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
|
|
- ppc_lfs (code, ins->dreg, ins->inst_offset, ppc_r12);
|
|
+ ppc_addis (code, ppc_r11, ins->inst_destbasereg, ppc_ha(ins->inst_offset));
|
|
+ ppc_lfs (code, ins->dreg, ins->inst_offset, ppc_r11);
|
|
} else {
|
|
ppc_load (code, ppc_r0, ins->inst_offset);
|
|
ppc_lfsx (code, ins->dreg, ins->inst_destbasereg, ppc_r0);
|
|
@@ -4509,6 +4519,16 @@ mono_arch_register_lowlevel_calls (void)
|
|
}
|
|
|
|
#ifdef __mono_ppc64__
|
|
+#ifdef _LITTLE_ENDIAN
|
|
+#define patch_load_sequence(ip,val) do {\
|
|
+ guint16 *__load = (guint16*)(ip); \
|
|
+ g_assert (sizeof (val) == sizeof (gsize)); \
|
|
+ __load [0] = (((guint64)(gsize)(val)) >> 48) & 0xffff; \
|
|
+ __load [2] = (((guint64)(gsize)(val)) >> 32) & 0xffff; \
|
|
+ __load [6] = (((guint64)(gsize)(val)) >> 16) & 0xffff; \
|
|
+ __load [8] = ((guint64)(gsize)(val)) & 0xffff; \
|
|
+ } while (0)
|
|
+#elif defined _BIG_ENDIAN
|
|
#define patch_load_sequence(ip,val) do {\
|
|
guint16 *__load = (guint16*)(ip); \
|
|
g_assert (sizeof (val) == sizeof (gsize)); \
|
|
@@ -4518,6 +4538,9 @@ mono_arch_register_lowlevel_calls (void)
|
|
__load [9] = ((guint64)(gsize)(val)) & 0xffff; \
|
|
} while (0)
|
|
#else
|
|
+#error huh? No endianess defined by compiler
|
|
+#endif
|
|
+#else
|
|
#define patch_load_sequence(ip,val) do {\
|
|
guint16 *__lis_ori = (guint16*)(ip); \
|
|
__lis_ori [1] = (((gulong)(val)) >> 16) & 0xffff; \
|
|
@@ -4728,12 +4751,12 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
code = save_registers (cfg, code, alloc_size - pos, ppc_sp, method->save_lmf, cfg->used_int_regs, cfa_offset);
|
|
} else {
|
|
if (pos)
|
|
- ppc_addi (code, ppc_r11, ppc_sp, -pos);
|
|
+ ppc_addi (code, ppc_r12, ppc_sp, -pos);
|
|
ppc_load (code, ppc_r0, -alloc_size);
|
|
ppc_str_update_indexed (code, ppc_sp, ppc_sp, ppc_r0);
|
|
cfa_offset = alloc_size;
|
|
mono_emit_unwind_op_def_cfa_offset (cfg, code, alloc_size);
|
|
- code = save_registers (cfg, code, 0, ppc_r11, method->save_lmf, cfg->used_int_regs, cfa_offset);
|
|
+ code = save_registers (cfg, code, 0, ppc_r12, method->save_lmf, cfg->used_int_regs, cfa_offset);
|
|
}
|
|
}
|
|
if (cfg->frame_reg != ppc_sp) {
|
|
@@ -4779,8 +4802,8 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
if (ppc_is_imm16 (inst->inst_offset)) {
|
|
ppc_stptr (code, ainfo->reg, inst->inst_offset, inst->inst_basereg);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, inst->inst_offset);
|
|
- ppc_stptr_indexed (code, ainfo->reg, ppc_r11, inst->inst_basereg);
|
|
+ ppc_load (code, ppc_r12, inst->inst_offset);
|
|
+ ppc_stptr_indexed (code, ainfo->reg, ppc_r12, inst->inst_basereg);
|
|
}
|
|
}
|
|
|
|
@@ -4797,8 +4820,8 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
else if (ainfo->regtype == RegTypeFP)
|
|
ppc_fmr (code, inst->dreg, ainfo->reg);
|
|
else if (ainfo->regtype == RegTypeBase) {
|
|
- ppc_ldr (code, ppc_r11, 0, ppc_sp);
|
|
- ppc_ldptr (code, inst->dreg, ainfo->offset, ppc_r11);
|
|
+ ppc_ldr (code, ppc_r12, 0, ppc_sp);
|
|
+ ppc_ldptr (code, inst->dreg, ainfo->offset, ppc_r12);
|
|
} else
|
|
g_assert_not_reached ();
|
|
|
|
@@ -4813,11 +4836,11 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
ppc_stb (code, ainfo->reg, inst->inst_offset, inst->inst_basereg);
|
|
} else {
|
|
if (ppc_is_imm32 (inst->inst_offset)) {
|
|
- ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
- ppc_stb (code, ainfo->reg, inst->inst_offset, ppc_r11);
|
|
+ ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
+ ppc_stb (code, ainfo->reg, inst->inst_offset, ppc_r12);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, inst->inst_offset);
|
|
- ppc_stbx (code, ainfo->reg, inst->inst_basereg, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, inst->inst_offset);
|
|
+ ppc_stbx (code, ainfo->reg, inst->inst_basereg, ppc_r12);
|
|
}
|
|
}
|
|
break;
|
|
@@ -4826,11 +4849,11 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
ppc_sth (code, ainfo->reg, inst->inst_offset, inst->inst_basereg);
|
|
} else {
|
|
if (ppc_is_imm32 (inst->inst_offset)) {
|
|
- ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
- ppc_sth (code, ainfo->reg, inst->inst_offset, ppc_r11);
|
|
+ ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
+ ppc_sth (code, ainfo->reg, inst->inst_offset, ppc_r12);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, inst->inst_offset);
|
|
- ppc_sthx (code, ainfo->reg, inst->inst_basereg, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, inst->inst_offset);
|
|
+ ppc_sthx (code, ainfo->reg, inst->inst_basereg, ppc_r12);
|
|
}
|
|
}
|
|
break;
|
|
@@ -4840,11 +4863,11 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
ppc_stw (code, ainfo->reg, inst->inst_offset, inst->inst_basereg);
|
|
} else {
|
|
if (ppc_is_imm32 (inst->inst_offset)) {
|
|
- ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
- ppc_stw (code, ainfo->reg, inst->inst_offset, ppc_r11);
|
|
+ ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
+ ppc_stw (code, ainfo->reg, inst->inst_offset, ppc_r12);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, inst->inst_offset);
|
|
- ppc_stwx (code, ainfo->reg, inst->inst_basereg, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, inst->inst_offset);
|
|
+ ppc_stwx (code, ainfo->reg, inst->inst_basereg, ppc_r12);
|
|
}
|
|
}
|
|
break;
|
|
@@ -4852,8 +4875,8 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
if (ppc_is_imm16 (inst->inst_offset)) {
|
|
ppc_str (code, ainfo->reg, inst->inst_offset, inst->inst_basereg);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, inst->inst_offset);
|
|
- ppc_str_indexed (code, ainfo->reg, ppc_r11, inst->inst_basereg);
|
|
+ ppc_load (code, ppc_r12, inst->inst_offset);
|
|
+ ppc_str_indexed (code, ainfo->reg, ppc_r12, inst->inst_basereg);
|
|
}
|
|
break;
|
|
#else
|
|
@@ -4862,10 +4885,10 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
ppc_stw (code, ainfo->reg, inst->inst_offset, inst->inst_basereg);
|
|
ppc_stw (code, ainfo->reg + 1, inst->inst_offset + 4, inst->inst_basereg);
|
|
} else {
|
|
- ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
- ppc_addi (code, ppc_r11, ppc_r11, inst->inst_offset);
|
|
- ppc_stw (code, ainfo->reg, 0, ppc_r11);
|
|
- ppc_stw (code, ainfo->reg + 1, 4, ppc_r11);
|
|
+ ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
+ ppc_addi (code, ppc_r12, ppc_r12, inst->inst_offset);
|
|
+ ppc_stw (code, ainfo->reg, 0, ppc_r12);
|
|
+ ppc_stw (code, ainfo->reg + 1, 4, ppc_r12);
|
|
}
|
|
break;
|
|
#endif
|
|
@@ -4874,31 +4897,31 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
ppc_stptr (code, ainfo->reg, inst->inst_offset, inst->inst_basereg);
|
|
} else {
|
|
if (ppc_is_imm32 (inst->inst_offset)) {
|
|
- ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
- ppc_stptr (code, ainfo->reg, inst->inst_offset, ppc_r11);
|
|
+ ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
+ ppc_stptr (code, ainfo->reg, inst->inst_offset, ppc_r12);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, inst->inst_offset);
|
|
- ppc_stptr_indexed (code, ainfo->reg, inst->inst_basereg, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, inst->inst_offset);
|
|
+ ppc_stptr_indexed (code, ainfo->reg, inst->inst_basereg, ppc_r12);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
} else if (ainfo->regtype == RegTypeBase) {
|
|
g_assert (ppc_is_imm16 (ainfo->offset));
|
|
- /* load the previous stack pointer in r11 */
|
|
- ppc_ldr (code, ppc_r11, 0, ppc_sp);
|
|
- ppc_ldptr (code, ppc_r0, ainfo->offset, ppc_r11);
|
|
+ /* load the previous stack pointer in r12 */
|
|
+ ppc_ldr (code, ppc_r12, 0, ppc_sp);
|
|
+ ppc_ldptr (code, ppc_r0, ainfo->offset, ppc_r12);
|
|
switch (ainfo->size) {
|
|
case 1:
|
|
if (ppc_is_imm16 (inst->inst_offset)) {
|
|
ppc_stb (code, ppc_r0, inst->inst_offset, inst->inst_basereg);
|
|
} else {
|
|
if (ppc_is_imm32 (inst->inst_offset)) {
|
|
- ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
- ppc_stb (code, ppc_r0, inst->inst_offset, ppc_r11);
|
|
+ ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
+ ppc_stb (code, ppc_r0, inst->inst_offset, ppc_r12);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, inst->inst_offset);
|
|
- ppc_stbx (code, ppc_r0, inst->inst_basereg, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, inst->inst_offset);
|
|
+ ppc_stbx (code, ppc_r0, inst->inst_basereg, ppc_r12);
|
|
}
|
|
}
|
|
break;
|
|
@@ -4907,11 +4930,11 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
ppc_sth (code, ppc_r0, inst->inst_offset, inst->inst_basereg);
|
|
} else {
|
|
if (ppc_is_imm32 (inst->inst_offset)) {
|
|
- ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
- ppc_sth (code, ppc_r0, inst->inst_offset, ppc_r11);
|
|
+ ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
+ ppc_sth (code, ppc_r0, inst->inst_offset, ppc_r12);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, inst->inst_offset);
|
|
- ppc_sthx (code, ppc_r0, inst->inst_basereg, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, inst->inst_offset);
|
|
+ ppc_sthx (code, ppc_r0, inst->inst_basereg, ppc_r12);
|
|
}
|
|
}
|
|
break;
|
|
@@ -4921,11 +4944,11 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
ppc_stw (code, ppc_r0, inst->inst_offset, inst->inst_basereg);
|
|
} else {
|
|
if (ppc_is_imm32 (inst->inst_offset)) {
|
|
- ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
- ppc_stw (code, ppc_r0, inst->inst_offset, ppc_r11);
|
|
+ ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
+ ppc_stw (code, ppc_r0, inst->inst_offset, ppc_r12);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, inst->inst_offset);
|
|
- ppc_stwx (code, ppc_r0, inst->inst_basereg, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, inst->inst_offset);
|
|
+ ppc_stwx (code, ppc_r0, inst->inst_basereg, ppc_r12);
|
|
}
|
|
}
|
|
break;
|
|
@@ -4933,8 +4956,8 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
if (ppc_is_imm16 (inst->inst_offset)) {
|
|
ppc_str (code, ppc_r0, inst->inst_offset, inst->inst_basereg);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, inst->inst_offset);
|
|
- ppc_str_indexed (code, ppc_r0, ppc_r11, inst->inst_basereg);
|
|
+ ppc_load (code, ppc_r12, inst->inst_offset);
|
|
+ ppc_str_indexed (code, ppc_r0, ppc_r12, inst->inst_basereg);
|
|
}
|
|
break;
|
|
#else
|
|
@@ -4942,15 +4965,15 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
g_assert (ppc_is_imm16 (ainfo->offset + 4));
|
|
if (ppc_is_imm16 (inst->inst_offset + 4)) {
|
|
ppc_stw (code, ppc_r0, inst->inst_offset, inst->inst_basereg);
|
|
- ppc_lwz (code, ppc_r0, ainfo->offset + 4, ppc_r11);
|
|
+ ppc_lwz (code, ppc_r0, ainfo->offset + 4, ppc_r12);
|
|
ppc_stw (code, ppc_r0, inst->inst_offset + 4, inst->inst_basereg);
|
|
} else {
|
|
- /* use r12 to load the 2nd half of the long before we clobber r11. */
|
|
- ppc_lwz (code, ppc_r12, ainfo->offset + 4, ppc_r11);
|
|
- ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
- ppc_addi (code, ppc_r11, ppc_r11, inst->inst_offset);
|
|
- ppc_stw (code, ppc_r0, 0, ppc_r11);
|
|
- ppc_stw (code, ppc_r12, 4, ppc_r11);
|
|
+ /* use r11 to load the 2nd half of the long before we clobber r12. */
|
|
+ ppc_lwz (code, ppc_r11, ainfo->offset + 4, ppc_r12);
|
|
+ ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
+ ppc_addi (code, ppc_r12, ppc_r12, inst->inst_offset);
|
|
+ ppc_stw (code, ppc_r0, 0, ppc_r12);
|
|
+ ppc_stw (code, ppc_r11, 4, ppc_r12);
|
|
}
|
|
break;
|
|
#endif
|
|
@@ -4959,11 +4982,11 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
ppc_stptr (code, ppc_r0, inst->inst_offset, inst->inst_basereg);
|
|
} else {
|
|
if (ppc_is_imm32 (inst->inst_offset)) {
|
|
- ppc_addis (code, ppc_r11, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
- ppc_stptr (code, ppc_r0, inst->inst_offset, ppc_r11);
|
|
+ ppc_addis (code, ppc_r12, inst->inst_basereg, ppc_ha(inst->inst_offset));
|
|
+ ppc_stptr (code, ppc_r0, inst->inst_offset, ppc_r12);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, inst->inst_offset);
|
|
- ppc_stptr_indexed (code, ppc_r0, inst->inst_basereg, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, inst->inst_offset);
|
|
+ ppc_stptr_indexed (code, ppc_r0, inst->inst_basereg, ppc_r12);
|
|
}
|
|
}
|
|
break;
|
|
@@ -5022,39 +5045,39 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
/* FIXME: we need to do the shifting here, too */
|
|
if (ainfo->bytes)
|
|
NOT_IMPLEMENTED;
|
|
- /* load the previous stack pointer in r11 (r0 gets overwritten by the memcpy) */
|
|
- ppc_ldr (code, ppc_r11, 0, ppc_sp);
|
|
+ /* load the previous stack pointer in r12 (r0 gets overwritten by the memcpy) */
|
|
+ ppc_ldr (code, ppc_r12, 0, ppc_sp);
|
|
if ((size & MONO_PPC_32_64_CASE (3, 7)) != 0) {
|
|
code = emit_memcpy (code, size - soffset,
|
|
inst->inst_basereg, doffset,
|
|
- ppc_r11, ainfo->offset + soffset);
|
|
+ ppc_r12, ainfo->offset + soffset);
|
|
} else {
|
|
code = emit_memcpy (code, ainfo->vtsize * sizeof (gpointer),
|
|
inst->inst_basereg, doffset,
|
|
- ppc_r11, ainfo->offset + soffset);
|
|
+ ppc_r12, ainfo->offset + soffset);
|
|
}
|
|
}
|
|
} else if (ainfo->regtype == RegTypeStructByAddr) {
|
|
/* if it was originally a RegTypeBase */
|
|
if (ainfo->offset) {
|
|
- /* load the previous stack pointer in r11 */
|
|
- ppc_ldr (code, ppc_r11, 0, ppc_sp);
|
|
- ppc_ldptr (code, ppc_r11, ainfo->offset, ppc_r11);
|
|
+ /* load the previous stack pointer in r12 */
|
|
+ ppc_ldr (code, ppc_r12, 0, ppc_sp);
|
|
+ ppc_ldptr (code, ppc_r12, ainfo->offset, ppc_r12);
|
|
} else {
|
|
- ppc_mr (code, ppc_r11, ainfo->reg);
|
|
+ ppc_mr (code, ppc_r12, ainfo->reg);
|
|
}
|
|
|
|
if (cfg->tailcall_valuetype_addrs) {
|
|
MonoInst *addr = cfg->tailcall_valuetype_addrs [tailcall_struct_index];
|
|
|
|
g_assert (ppc_is_imm16 (addr->inst_offset));
|
|
- ppc_stptr (code, ppc_r11, addr->inst_offset, addr->inst_basereg);
|
|
+ ppc_stptr (code, ppc_r12, addr->inst_offset, addr->inst_basereg);
|
|
|
|
tailcall_struct_index++;
|
|
}
|
|
|
|
g_assert (ppc_is_imm16 (inst->inst_offset));
|
|
- code = emit_memcpy (code, ainfo->vtsize, inst->inst_basereg, inst->inst_offset, ppc_r11, 0);
|
|
+ code = emit_memcpy (code, ainfo->vtsize, inst->inst_basereg, inst->inst_offset, ppc_r12, 0);
|
|
/*g_print ("copy in %s: %d bytes from %d to offset: %d\n", method->name, ainfo->vtsize, ainfo->reg, inst->inst_offset);*/
|
|
} else
|
|
g_assert_not_reached ();
|
|
@@ -5075,8 +5098,8 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
|
|
(gpointer)"mono_get_lmf_addr");
|
|
if ((FORCE_INDIR_CALL || cfg->method->dynamic) && !cfg->compile_aot) {
|
|
- ppc_load_func (code, ppc_r0, 0);
|
|
- ppc_mtlr (code, ppc_r0);
|
|
+ ppc_load_func (code, PPC_CALL_REG, 0);
|
|
+ ppc_mtlr (code, PPC_CALL_REG);
|
|
ppc_blrl (code);
|
|
} else {
|
|
ppc_bl (code, 0);
|
|
@@ -5086,25 +5109,25 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
/* lmf_offset is the offset from the previous stack pointer,
|
|
* alloc_size is the total stack space allocated, so the offset
|
|
* of MonoLMF from the current stack ptr is alloc_size - lmf_offset.
|
|
- * The pointer to the struct is put in ppc_r11 (new_lmf).
|
|
+ * The pointer to the struct is put in ppc_r12 (new_lmf).
|
|
* The callee-saved registers are already in the MonoLMF structure
|
|
*/
|
|
- ppc_addi (code, ppc_r11, ppc_sp, alloc_size - lmf_offset);
|
|
+ ppc_addi (code, ppc_r12, ppc_sp, alloc_size - lmf_offset);
|
|
/* ppc_r3 is the result from mono_get_lmf_addr () */
|
|
- ppc_stptr (code, ppc_r3, G_STRUCT_OFFSET(MonoLMF, lmf_addr), ppc_r11);
|
|
+ ppc_stptr (code, ppc_r3, G_STRUCT_OFFSET(MonoLMF, lmf_addr), ppc_r12);
|
|
/* new_lmf->previous_lmf = *lmf_addr */
|
|
ppc_ldptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r3);
|
|
- ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r11);
|
|
- /* *(lmf_addr) = r11 */
|
|
- ppc_stptr (code, ppc_r11, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r3);
|
|
+ ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r12);
|
|
+ /* *(lmf_addr) = r12 */
|
|
+ ppc_stptr (code, ppc_r12, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r3);
|
|
/* save method info */
|
|
if (cfg->compile_aot)
|
|
// FIXME:
|
|
ppc_load (code, ppc_r0, 0);
|
|
else
|
|
ppc_load_ptr (code, ppc_r0, method);
|
|
- ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, method), ppc_r11);
|
|
- ppc_stptr (code, ppc_sp, G_STRUCT_OFFSET(MonoLMF, ebp), ppc_r11);
|
|
+ ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, method), ppc_r12);
|
|
+ ppc_stptr (code, ppc_sp, G_STRUCT_OFFSET(MonoLMF, ebp), ppc_r12);
|
|
/* save the current IP */
|
|
if (cfg->compile_aot) {
|
|
ppc_bl (code, 1);
|
|
@@ -5117,7 +5140,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
|
|
ppc_load_sequence (code, ppc_r0, (gulong)0x01010101L);
|
|
#endif
|
|
}
|
|
- ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, eip), ppc_r11);
|
|
+ ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, eip), ppc_r12);
|
|
}
|
|
|
|
if (tracing)
|
|
@@ -5169,21 +5192,21 @@ mono_arch_emit_epilog (MonoCompile *cfg)
|
|
lmf_offset = pos;
|
|
/* save the frame reg in r8 */
|
|
ppc_mr (code, ppc_r8, cfg->frame_reg);
|
|
- ppc_addi (code, ppc_r11, cfg->frame_reg, cfg->stack_usage - lmf_offset);
|
|
+ ppc_addi (code, ppc_r12, cfg->frame_reg, cfg->stack_usage - lmf_offset);
|
|
/* r5 = previous_lmf */
|
|
- ppc_ldptr (code, ppc_r5, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r11);
|
|
+ ppc_ldptr (code, ppc_r5, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r12);
|
|
/* r6 = lmf_addr */
|
|
- ppc_ldptr (code, ppc_r6, G_STRUCT_OFFSET(MonoLMF, lmf_addr), ppc_r11);
|
|
+ ppc_ldptr (code, ppc_r6, G_STRUCT_OFFSET(MonoLMF, lmf_addr), ppc_r12);
|
|
/* *(lmf_addr) = previous_lmf */
|
|
ppc_stptr (code, ppc_r5, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r6);
|
|
/* FIXME: speedup: there is no actual need to restore the registers if
|
|
* we didn't actually change them (idea from Zoltan).
|
|
*/
|
|
/* restore iregs */
|
|
- ppc_ldr_multiple (code, ppc_r13, G_STRUCT_OFFSET(MonoLMF, iregs), ppc_r11);
|
|
+ ppc_ldr_multiple (code, ppc_r13, G_STRUCT_OFFSET(MonoLMF, iregs), ppc_r12);
|
|
/* restore fregs */
|
|
/*for (i = 14; i < 32; i++) {
|
|
- ppc_lfd (code, i, G_STRUCT_OFFSET(MonoLMF, fregs) + ((i-14) * sizeof (gdouble)), ppc_r11);
|
|
+ ppc_lfd (code, i, G_STRUCT_OFFSET(MonoLMF, fregs) + ((i-14) * sizeof (gdouble)), ppc_r12);
|
|
}*/
|
|
g_assert (ppc_is_imm16 (cfg->stack_usage + PPC_RET_ADDR_OFFSET));
|
|
/* use the saved copy of the frame reg in r8 */
|
|
@@ -5198,8 +5221,8 @@ mono_arch_emit_epilog (MonoCompile *cfg)
|
|
if (ppc_is_imm16 (return_offset)) {
|
|
ppc_ldr (code, ppc_r0, return_offset, cfg->frame_reg);
|
|
} else {
|
|
- ppc_load (code, ppc_r11, return_offset);
|
|
- ppc_ldr_indexed (code, ppc_r0, cfg->frame_reg, ppc_r11);
|
|
+ ppc_load (code, ppc_r12, return_offset);
|
|
+ ppc_ldr_indexed (code, ppc_r0, cfg->frame_reg, ppc_r12);
|
|
}
|
|
ppc_mtlr (code, ppc_r0);
|
|
}
|
|
@@ -5210,7 +5233,7 @@ mono_arch_emit_epilog (MonoCompile *cfg)
|
|
offset -= sizeof (mgreg_t);
|
|
}
|
|
if (cfg->frame_reg != ppc_sp)
|
|
- ppc_mr (code, ppc_r11, cfg->frame_reg);
|
|
+ ppc_mr (code, ppc_r12, cfg->frame_reg);
|
|
/* note r31 (possibly the frame register) is restored last */
|
|
for (i = 13; i <= 31; i++) {
|
|
if (cfg->used_int_regs & (1 << i)) {
|
|
@@ -5219,22 +5242,22 @@ mono_arch_emit_epilog (MonoCompile *cfg)
|
|
}
|
|
}
|
|
if (cfg->frame_reg != ppc_sp)
|
|
- ppc_addi (code, ppc_sp, ppc_r11, cfg->stack_usage);
|
|
+ ppc_addi (code, ppc_sp, ppc_r12, cfg->stack_usage);
|
|
else
|
|
ppc_addi (code, ppc_sp, ppc_sp, cfg->stack_usage);
|
|
} else {
|
|
- ppc_load32 (code, ppc_r11, cfg->stack_usage);
|
|
+ ppc_load32 (code, ppc_r12, cfg->stack_usage);
|
|
if (cfg->used_int_regs) {
|
|
- ppc_add (code, ppc_r11, cfg->frame_reg, ppc_r11);
|
|
+ ppc_add (code, ppc_r12, cfg->frame_reg, ppc_r12);
|
|
for (i = 31; i >= 13; --i) {
|
|
if (cfg->used_int_regs & (1 << i)) {
|
|
pos += sizeof (mgreg_t);
|
|
- ppc_ldr (code, i, -pos, ppc_r11);
|
|
+ ppc_ldr (code, i, -pos, ppc_r12);
|
|
}
|
|
}
|
|
- ppc_mr (code, ppc_sp, ppc_r11);
|
|
+ ppc_mr (code, ppc_sp, ppc_r12);
|
|
} else {
|
|
- ppc_add (code, ppc_sp, cfg->frame_reg, ppc_r11);
|
|
+ ppc_add (code, ppc_sp, cfg->frame_reg, ppc_r12);
|
|
}
|
|
}
|
|
|
|
@@ -5385,8 +5408,8 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
|
|
patch_info->data.name = "mono_arch_throw_corlib_exception";
|
|
patch_info->ip.i = code - cfg->native_code;
|
|
if (FORCE_INDIR_CALL || cfg->method->dynamic) {
|
|
- ppc_load_func (code, ppc_r0, 0);
|
|
- ppc_mtctr (code, ppc_r0);
|
|
+ ppc_load_func (code, PPC_CALL_REG, 0);
|
|
+ ppc_mtctr (code, PPC_CALL_REG);
|
|
ppc_bcctr (code, PPC_BR_ALWAYS, 0);
|
|
} else {
|
|
ppc_bl (code, 0);
|
|
@@ -5621,15 +5644,15 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
|
|
start = code;
|
|
|
|
/*
|
|
- * We need to save and restore r11 because it might be
|
|
+ * We need to save and restore r12 because it might be
|
|
* used by the caller as the vtable register, so
|
|
* clobbering it will trip up the magic trampoline.
|
|
*
|
|
- * FIXME: Get rid of this by making sure that r11 is
|
|
+ * FIXME: Get rid of this by making sure that r12 is
|
|
* not used as the vtable register in interface calls.
|
|
*/
|
|
- ppc_stptr (code, ppc_r11, PPC_RET_ADDR_OFFSET, ppc_sp);
|
|
- ppc_load (code, ppc_r11, (gsize)(& (vtable->vtable [0])));
|
|
+ ppc_stptr (code, ppc_r12, PPC_RET_ADDR_OFFSET, ppc_sp);
|
|
+ ppc_load (code, ppc_r12, (gsize)(& (vtable->vtable [0])));
|
|
|
|
for (i = 0; i < count; ++i) {
|
|
MonoIMTCheckItem *item = imt_entries [i];
|
|
@@ -5645,8 +5668,8 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
|
|
if (item->has_target_code) {
|
|
ppc_load_ptr (code, ppc_r0, item->value.target_code);
|
|
} else {
|
|
- ppc_ldptr (code, ppc_r0, (sizeof (gpointer) * item->value.vtable_slot), ppc_r11);
|
|
- ppc_ldptr (code, ppc_r11, PPC_RET_ADDR_OFFSET, ppc_sp);
|
|
+ ppc_ldptr (code, ppc_r0, (sizeof (gpointer) * item->value.vtable_slot), ppc_r12);
|
|
+ ppc_ldptr (code, ppc_r12, PPC_RET_ADDR_OFFSET, ppc_sp);
|
|
}
|
|
ppc_mtctr (code, ppc_r0);
|
|
ppc_bcctr (code, PPC_BR_ALWAYS, 0);
|
|
@@ -5678,8 +5701,8 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
|
|
item->jmp_code = code;
|
|
ppc_bc (code, PPC_BR_FALSE, PPC_BR_EQ, 0);
|
|
#endif
|
|
- ppc_ldptr (code, ppc_r0, (sizeof (gpointer) * item->value.vtable_slot), ppc_r11);
|
|
- ppc_ldptr (code, ppc_r11, PPC_RET_ADDR_OFFSET, ppc_sp);
|
|
+ ppc_ldptr (code, ppc_r0, (sizeof (gpointer) * item->value.vtable_slot), ppc_r12);
|
|
+ ppc_ldptr (code, ppc_r12, PPC_RET_ADDR_OFFSET, ppc_sp);
|
|
ppc_mtctr (code, ppc_r0);
|
|
ppc_bcctr (code, PPC_BR_ALWAYS, 0);
|
|
#if ENABLE_WRONG_METHOD_CHECK
|
|
@@ -5804,17 +5827,17 @@ mono_arch_emit_load_got_addr (guint8 *start, guint8 *code, MonoCompile *cfg, Mon
|
|
* Emit code to load the contents of the GOT slot identified by TRAMP_TYPE and
|
|
* TARGET from the mscorlib GOT in full-aot code.
|
|
* On PPC, the GOT address is assumed to be in r30, and the result is placed into
|
|
- * r11.
|
|
+ * r12.
|
|
*/
|
|
guint8*
|
|
mono_arch_emit_load_aotconst (guint8 *start, guint8 *code, MonoJumpInfo **ji, int tramp_type, gconstpointer target)
|
|
{
|
|
/* Load the mscorlib got address */
|
|
- ppc_ldptr (code, ppc_r11, sizeof (gpointer), ppc_r30);
|
|
+ ppc_ldptr (code, ppc_r12, sizeof (gpointer), ppc_r30);
|
|
*ji = mono_patch_info_list_prepend (*ji, code - start, tramp_type, target);
|
|
/* arch_emit_got_access () patches this */
|
|
ppc_load32 (code, ppc_r0, 0);
|
|
- ppc_ldptr_indexed (code, ppc_r11, ppc_r11, ppc_r0);
|
|
+ ppc_ldptr_indexed (code, ppc_r12, ppc_r12, ppc_r0);
|
|
|
|
return code;
|
|
}
|
|
@@ -5837,8 +5860,8 @@ mono_arch_set_breakpoint (MonoJitInfo *ji, guint8 *ip)
|
|
guint8 *code = ip;
|
|
guint8 *orig_code = code;
|
|
|
|
- ppc_load_sequence (code, ppc_r11, (gsize)bp_trigger_page);
|
|
- ppc_ldptr (code, ppc_r11, 0, ppc_r11);
|
|
+ ppc_load_sequence (code, ppc_r12, (gsize)bp_trigger_page);
|
|
+ ppc_ldptr (code, ppc_r12, 0, ppc_r12);
|
|
|
|
g_assert (code - orig_code == BREAKPOINT_SIZE);
|
|
|
|
diff --git a/mono/mini/mini-ppc.h b/mono/mini/mini-ppc.h
|
|
index 4b39b7a..9e5c02e 100644
|
|
--- a/mono/mini/mini-ppc.h
|
|
+++ b/mono/mini/mini-ppc.h
|
|
@@ -4,6 +4,7 @@
|
|
#include <mono/arch/ppc/ppc-codegen.h>
|
|
#include <mono/utils/mono-sigcontext.h>
|
|
#include <mono/utils/mono-context.h>
|
|
+#include <mono/metadata/object.h>
|
|
#include <glib.h>
|
|
|
|
#ifdef __mono_ppc64__
|
|
@@ -68,7 +69,13 @@ typedef struct MonoCompileArch {
|
|
#ifdef __mono_ppc64__
|
|
#define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS
|
|
#define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS
|
|
+
|
|
+/* ELFv2 ABI doesn't use function descriptors. */
|
|
+#if _CALL_ELF == 2
|
|
+#undef PPC_USES_FUNCTION_DESCRIPTOR
|
|
+#else
|
|
#define PPC_USES_FUNCTION_DESCRIPTOR
|
|
+#endif
|
|
|
|
#ifndef __mono_ilp32__
|
|
#define MONO_ARCH_HAVE_TLS_GET 1
|
|
@@ -97,7 +104,7 @@ typedef struct MonoCompileArch {
|
|
#define MONO_ARCH_GC_MAPS_SUPPORTED 1
|
|
|
|
/* Parameters used by the register allocator */
|
|
-#define MONO_ARCH_CALLEE_REGS ((0xff << ppc_r3) | (1 << ppc_r11) | (1 << ppc_r12))
|
|
+#define MONO_ARCH_CALLEE_REGS ((0xff << ppc_r3) | (1 << ppc_r12) | (1 << ppc_r11))
|
|
#define MONO_ARCH_CALLEE_SAVED_REGS (0xfffff << ppc_r13) /* ppc_13 - ppc_31 */
|
|
|
|
#if defined(__APPLE__) || defined(__mono_ppc64__)
|
|
@@ -164,15 +171,17 @@ typedef struct MonoCompileArch {
|
|
#define PPC_FIRST_FPARG_REG ppc_f1
|
|
#endif
|
|
|
|
+#define PPC_CALL_REG ppc_r12
|
|
+
|
|
#if defined(HAVE_WORKING_SIGALTSTACK) && !defined(__APPLE__)
|
|
#define MONO_ARCH_SIGSEGV_ON_ALTSTACK 1
|
|
#define MONO_ARCH_SIGNAL_STACK_SIZE (12 * 1024)
|
|
#endif /* HAVE_WORKING_SIGALTSTACK */
|
|
|
|
#define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE
|
|
-#define MONO_ARCH_IMT_REG ppc_r12
|
|
+#define MONO_ARCH_IMT_REG ppc_r11
|
|
|
|
-#define MONO_ARCH_VTABLE_REG ppc_r12
|
|
+#define MONO_ARCH_VTABLE_REG ppc_r11
|
|
#define MONO_ARCH_RGCTX_REG MONO_ARCH_IMT_REG
|
|
|
|
#define MONO_ARCH_NO_IOV_CHECK 1
|
|
diff --git a/mono/mini/mini.c b/mono/mini/mini.c
|
|
index d7ee5ba..bd3dbb5 100755
|
|
--- a/mono/mini/mini.c
|
|
+++ b/mono/mini/mini.c
|
|
@@ -7085,10 +7085,9 @@ mini_get_debug_options (void)
|
|
static gpointer
|
|
mini_create_ftnptr (MonoDomain *domain, gpointer addr)
|
|
{
|
|
-#if !defined(__ia64__) && !defined(__ppc64__) && !defined(__powerpc64__)
|
|
+#if !defined(__ia64__) && (!defined(__ppc64__) && !defined(__powerpc64__) || _CALL_ELF == 2)
|
|
return addr;
|
|
#else
|
|
-
|
|
gpointer* desc = NULL;
|
|
|
|
if ((desc = g_hash_table_lookup (domain->ftnptrs_hash, addr)))
|
|
@@ -7114,7 +7113,7 @@ mini_create_ftnptr (MonoDomain *domain, gpointer addr)
|
|
static gpointer
|
|
mini_get_addr_from_ftnptr (gpointer descr)
|
|
{
|
|
-#if defined(__ia64__) || defined(__ppc64__) || defined(__powerpc64__)
|
|
+#if defined(__ia64__) || ((defined(__ppc64__) || defined(__powerpc64__)) && _CALL_ELF != 2)
|
|
return *(gpointer*)descr;
|
|
#else
|
|
return descr;
|
|
diff --git a/mono/mini/tramp-ppc.c b/mono/mini/tramp-ppc.c
|
|
index 6fac1a1..1b2cc1d 100644
|
|
--- a/mono/mini/tramp-ppc.c
|
|
+++ b/mono/mini/tramp-ppc.c
|
|
@@ -295,44 +295,44 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
|
|
if (aot) {
|
|
code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_get_lmf_addr");
|
|
#ifdef PPC_USES_FUNCTION_DESCRIPTOR
|
|
- ppc_ldptr (code, ppc_r2, sizeof (gpointer), ppc_r11);
|
|
- ppc_ldptr (code, ppc_r11, 0, ppc_r11);
|
|
+ ppc_ldptr (code, ppc_r2, sizeof (gpointer), ppc_r12);
|
|
+ ppc_ldptr (code, ppc_r12, 0, ppc_r12);
|
|
#endif
|
|
- ppc_mtlr (code, ppc_r11);
|
|
+ ppc_mtlr (code, ppc_r12);
|
|
ppc_blrl (code);
|
|
} else {
|
|
- ppc_load_func (code, ppc_r0, mono_get_lmf_addr);
|
|
- ppc_mtlr (code, ppc_r0);
|
|
+ ppc_load_func (code, PPC_CALL_REG, mono_get_lmf_addr);
|
|
+ ppc_mtlr (code, PPC_CALL_REG);
|
|
ppc_blrl (code);
|
|
}
|
|
/* we build the MonoLMF structure on the stack - see mini-ppc.h
|
|
- * The pointer to the struct is put in ppc_r11.
|
|
+ * The pointer to the struct is put in ppc_r12.
|
|
*/
|
|
- ppc_addi (code, ppc_r11, ppc_sp, STACK - sizeof (MonoLMF));
|
|
- ppc_stptr (code, ppc_r3, G_STRUCT_OFFSET(MonoLMF, lmf_addr), ppc_r11);
|
|
+ ppc_addi (code, ppc_r12, ppc_sp, STACK - sizeof (MonoLMF));
|
|
+ ppc_stptr (code, ppc_r3, G_STRUCT_OFFSET(MonoLMF, lmf_addr), ppc_r12);
|
|
/* new_lmf->previous_lmf = *lmf_addr */
|
|
ppc_ldptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r3);
|
|
- ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r11);
|
|
- /* *(lmf_addr) = r11 */
|
|
- ppc_stptr (code, ppc_r11, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r3);
|
|
+ ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r12);
|
|
+ /* *(lmf_addr) = r12 */
|
|
+ ppc_stptr (code, ppc_r12, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r3);
|
|
/* save method info (it's stored on the stack, so get it first). */
|
|
if ((tramp_type == MONO_TRAMPOLINE_JIT) || (tramp_type == MONO_TRAMPOLINE_JUMP)) {
|
|
ppc_ldr (code, ppc_r0, GREGS_OFFSET, ppc_r1);
|
|
- ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, method), ppc_r11);
|
|
+ ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, method), ppc_r12);
|
|
} else {
|
|
ppc_load (code, ppc_r0, 0);
|
|
- ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, method), ppc_r11);
|
|
+ ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, method), ppc_r12);
|
|
}
|
|
/* store the frame pointer of the calling method */
|
|
ppc_addi (code, ppc_r0, ppc_sp, STACK);
|
|
- ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, ebp), ppc_r11);
|
|
+ ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, ebp), ppc_r12);
|
|
/* save the IP (caller ip) */
|
|
if (tramp_type == MONO_TRAMPOLINE_JUMP) {
|
|
ppc_li (code, ppc_r0, 0);
|
|
} else {
|
|
ppc_ldr (code, ppc_r0, STACK + PPC_RET_ADDR_OFFSET, ppc_r1);
|
|
}
|
|
- ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, eip), ppc_r11);
|
|
+ ppc_stptr (code, ppc_r0, G_STRUCT_OFFSET(MonoLMF, eip), ppc_r12);
|
|
|
|
/*
|
|
* Now we're ready to call trampoline (mgreg_t *regs, guint8 *code, gpointer value, guint8 *tramp)
|
|
@@ -356,15 +356,15 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
|
|
if (aot) {
|
|
code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, g_strdup_printf ("trampoline_func_%d", tramp_type));
|
|
#ifdef PPC_USES_FUNCTION_DESCRIPTOR
|
|
- ppc_ldptr (code, ppc_r2, sizeof (gpointer), ppc_r11);
|
|
- ppc_ldptr (code, ppc_r11, 0, ppc_r11);
|
|
+ ppc_ldptr (code, ppc_r2, sizeof (gpointer), ppc_r12);
|
|
+ ppc_ldptr (code, ppc_r12, 0, ppc_r12);
|
|
#endif
|
|
- ppc_mtlr (code, ppc_r11);
|
|
+ ppc_mtlr (code, ppc_r12);
|
|
ppc_blrl (code);
|
|
} else {
|
|
tramp_handler = mono_get_trampoline_func (tramp_type);
|
|
- ppc_load_func (code, ppc_r0, tramp_handler);
|
|
- ppc_mtlr (code, ppc_r0);
|
|
+ ppc_load_func (code, PPC_CALL_REG, tramp_handler);
|
|
+ ppc_mtlr (code, PPC_CALL_REG);
|
|
ppc_blrl (code);
|
|
}
|
|
|
|
@@ -384,20 +384,20 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
|
|
* Now we restore the MonoLMF (see emit_epilogue in mini-ppc.c)
|
|
* and the rest of the registers, so the method called will see
|
|
* the same state as before we executed.
|
|
- * The pointer to MonoLMF is in ppc_r11.
|
|
+ * The pointer to MonoLMF is in ppc_r12.
|
|
*/
|
|
- ppc_addi (code, ppc_r11, ppc_r1, STACK - sizeof (MonoLMF));
|
|
+ ppc_addi (code, ppc_r12, ppc_r1, STACK - sizeof (MonoLMF));
|
|
/* r5 = previous_lmf */
|
|
- ppc_ldptr (code, ppc_r5, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r11);
|
|
+ ppc_ldptr (code, ppc_r5, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r12);
|
|
/* r6 = lmf_addr */
|
|
- ppc_ldptr (code, ppc_r6, G_STRUCT_OFFSET(MonoLMF, lmf_addr), ppc_r11);
|
|
+ ppc_ldptr (code, ppc_r6, G_STRUCT_OFFSET(MonoLMF, lmf_addr), ppc_r12);
|
|
/* *(lmf_addr) = previous_lmf */
|
|
ppc_stptr (code, ppc_r5, G_STRUCT_OFFSET(MonoLMF, previous_lmf), ppc_r6);
|
|
/* restore iregs */
|
|
- ppc_ldr_multiple (code, ppc_r13, G_STRUCT_OFFSET(MonoLMF, iregs), ppc_r11);
|
|
+ ppc_ldr_multiple (code, ppc_r13, G_STRUCT_OFFSET(MonoLMF, iregs), ppc_r12);
|
|
/* restore fregs */
|
|
for (i = 14; i < 32; i++)
|
|
- ppc_lfd (code, i, G_STRUCT_OFFSET(MonoLMF, fregs) + ((i-14) * sizeof (gdouble)), ppc_r11);
|
|
+ ppc_lfd (code, i, G_STRUCT_OFFSET(MonoLMF, fregs) + ((i-14) * sizeof (gdouble)), ppc_r12);
|
|
|
|
/* restore the volatile registers, we skip r1, of course */
|
|
offset = STACK - sizeof (MonoLMF) - (14 * sizeof (double));
|
|
@@ -419,8 +419,8 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
|
|
*/
|
|
/* Restore stack pointer and LR and jump to the code */
|
|
ppc_ldr (code, ppc_r1, 0, ppc_r1);
|
|
- ppc_ldr (code, ppc_r11, PPC_RET_ADDR_OFFSET, ppc_r1);
|
|
- ppc_mtlr (code, ppc_r11);
|
|
+ ppc_ldr (code, ppc_r12, PPC_RET_ADDR_OFFSET, ppc_r1);
|
|
+ ppc_mtlr (code, ppc_r12);
|
|
if (MONO_TRAMPOLINE_TYPE_MUST_RETURN (tramp_type))
|
|
ppc_blr (code);
|
|
else
|
|
@@ -591,9 +591,9 @@ mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info
|
|
code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, g_strdup_printf ("specific_trampoline_lazy_fetch_%u", slot));
|
|
/* Branch to the trampoline */
|
|
#ifdef PPC_USES_FUNCTION_DESCRIPTOR
|
|
- ppc_ldptr (code, ppc_r11, 0, ppc_r11);
|
|
+ ppc_ldptr (code, ppc_r12, 0, ppc_r12);
|
|
#endif
|
|
- ppc_mtctr (code, ppc_r11);
|
|
+ ppc_mtctr (code, ppc_r12);
|
|
ppc_bcctr (code, PPC_BR_ALWAYS, 0);
|
|
} else {
|
|
tramp = mono_arch_create_specific_trampoline (GUINT_TO_POINTER (slot),
|
|
@@ -653,9 +653,9 @@ mono_arch_create_generic_class_init_trampoline (MonoTrampInfo **info, gboolean a
|
|
code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "specific_trampoline_generic_class_init");
|
|
/* Branch to the trampoline */
|
|
#ifdef PPC_USES_FUNCTION_DESCRIPTOR
|
|
- ppc_ldptr (code, ppc_r11, 0, ppc_r11);
|
|
+ ppc_ldptr (code, ppc_r12, 0, ppc_r12);
|
|
#endif
|
|
- ppc_mtctr (code, ppc_r11);
|
|
+ ppc_mtctr (code, ppc_r12);
|
|
ppc_bcctr (code, PPC_BR_ALWAYS, 0);
|
|
} else {
|
|
tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_GENERIC_CLASS_INIT,
|
|
diff --git a/mono/utils/mono-context.c b/mono/utils/mono-context.c
|
|
index c52d044..0db9dce 100644
|
|
--- a/mono/utils/mono-context.c
|
|
+++ b/mono/utils/mono-context.c
|
|
@@ -421,4 +421,31 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
|
|
}
|
|
}
|
|
|
|
+#elif (((defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__)) && !defined(MONO_CROSS_COMPILE))) || (defined(TARGET_POWERPC))
|
|
+
|
|
+#include <mono/utils/mono-context.h>
|
|
+#include <mono/mini/mini-ppc.h>
|
|
+
|
|
+void
|
|
+mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
|
|
+{
|
|
+ os_ucontext *uc = sigctx;
|
|
+
|
|
+ mctx->sc_ir = UCONTEXT_REG_NIP(uc);
|
|
+ mctx->sc_sp = UCONTEXT_REG_Rn(uc, 1);
|
|
+ memcpy (&mctx->regs, &UCONTEXT_REG_Rn(uc, 13), sizeof (mgreg_t) * MONO_SAVED_GREGS);
|
|
+ memcpy (&mctx->fregs, &UCONTEXT_REG_FPRn(uc, 14), sizeof (double) * MONO_SAVED_FREGS);
|
|
+}
|
|
+
|
|
+void
|
|
+mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
|
|
+{
|
|
+ os_ucontext *uc = sigctx;
|
|
+
|
|
+ UCONTEXT_REG_NIP(uc) = mctx->sc_ir;
|
|
+ UCONTEXT_REG_Rn(uc, 1) = mctx->sc_sp;
|
|
+ memcpy (&UCONTEXT_REG_Rn(uc, 13), &mctx->regs, sizeof (mgreg_t) * MONO_SAVED_GREGS);
|
|
+ memcpy (&UCONTEXT_REG_FPRn(uc, 14), &mctx->fregs, sizeof (double) * MONO_SAVED_FREGS);
|
|
+}
|
|
+
|
|
#endif /* #if defined(__i386__) */
|
|
diff --git a/mono/utils/strtod.c b/mono/utils/strtod.c
|
|
index f20acdc..1ba4b72 100644
|
|
--- a/mono/utils/strtod.c
|
|
+++ b/mono/utils/strtod.c
|
|
@@ -173,6 +173,12 @@
|
|
* #define NO_ERRNO if strtod should not assign errno = ERANGE when
|
|
* the result overflows to +-Infinity or underflows to 0.
|
|
*/
|
|
+#if defined __BIG_ENDIAN__ || defined _BIG_ENDIAN
|
|
+# define IEEE_MC68k
|
|
+#elif defined __LITTLE_ENDIAN__ || defined _LITTLE_ENDIAN
|
|
+# define IEEE_8087
|
|
+#else
|
|
+
|
|
#if defined(TARGET_X86) || defined(mips) && defined(MIPSEL) || defined (__arm__) || defined(__aarch64__)
|
|
|
|
# define IEEE_8087
|
|
@@ -194,9 +200,12 @@
|
|
# define IEEE_MC68k
|
|
|
|
#else
|
|
+#warning byte order unknown, assuming big endian
|
|
#define IEEE_MC68k
|
|
#endif
|
|
|
|
+#endif
|
|
+
|
|
#define Long gint32
|
|
#define ULong guint32
|
|
|
|
--
|
|
1.8.5.2
|
|
|