SHA256
1
0
forked from pool/mono-core
mono-core/mono-core-ppc64le.diff

257 lines
8.8 KiB
Diff
Raw Normal View History

Basic ppc64le support
This adds initial support for ppc64le to the ppc64 port. That is:
* little endian aware (also in strtod),
* and ELFv2 aware (not using function descriptors)
* adjust various block sizes to be multiple of 64k, the default
pagesize on ppc64le. The sources should have used the system function
to ensure alignment on pagesize, so this is just a stop-gap
It also corrects the list of registers for the precise GC, but that isn't
used in mini at all on any architecture currently.
Index: mono-3.4.0/mono/arch/ppc/ppc-codegen.h
===================================================================
--- mono-3.4.0.orig/mono/arch/ppc/ppc-codegen.h
+++ mono-3.4.0/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); \
} G_STMT_END
+#endif
#define ppc_load_multiple_regs(c,D,d,A) G_STMT_START { \
int __i, __o = (d); \
Index: mono-3.4.0/mono/metadata/sgen-marksweep.c
===================================================================
--- mono-3.4.0.orig/mono/metadata/sgen-marksweep.c
+++ mono-3.4.0/mono/metadata/sgen-marksweep.c
@@ -45,8 +45,10 @@
#define SGEN_HAVE_CONCURRENT_MARK
#endif
-#define MS_BLOCK_SIZE (16*1024)
-#define MS_BLOCK_SIZE_SHIFT 14
+/* MS_BLOCK_SIZE must be a multiple of the system pagesize, which for some
+ archs is 64k. */
+#define MS_BLOCK_SIZE (64*1024)
+#define MS_BLOCK_SIZE_SHIFT 16
#define MAJOR_SECTION_SIZE MS_BLOCK_SIZE
#define CARDS_PER_BLOCK (MS_BLOCK_SIZE / CARD_SIZE_IN_BYTES)
Index: mono-3.4.0/mono/mini/mini-gc.c
===================================================================
--- mono-3.4.0.orig/mono/mini/mini-gc.c
+++ mono-3.4.0/mono/mini/mini-gc.c
@@ -439,7 +439,12 @@ static int callee_saved_regs [] = { ARMR
#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_POWERPC)
-static int callee_saved_regs [] = { ppc_r6, ppc_r7, ppc_r8, ppc_r9, ppc_r10, ppc_r11, ppc_r12, ppc_r13, ppc_r14 };
+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 };
#endif
static guint32
Index: mono-3.4.0/mono/mini/mini-ppc.c
===================================================================
--- mono-3.4.0.orig/mono/mini/mini-ppc.c
+++ mono-3.4.0/mono/mini/mini-ppc.c
@@ -2811,14 +2811,14 @@ handle_thunk (int absolute, guchar *code
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;
@@ -2901,7 +2901,13 @@ ppc_patch_full (guchar *code, const guch
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;
@@ -2925,8 +2931,12 @@ ppc_patch_full (guchar *code, const guch
}
/* FIXME: make this thread safe */
+#ifdef PPC_USES_FUNCTION_DESCRIPTOR
/* FIXME: we're assuming we're using r11 here */
ppc_load_ptr_sequence (code, ppc_r11, target);
+#else
+ ppc_load_ptr_sequence (code, ppc_r0, target);
+#endif
mono_arch_flush_icache ((guint8*)seq, 28);
#else
guint32 *seq;
@@ -4481,6 +4491,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)); \
@@ -4490,6 +4510,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; \
Index: mono-3.4.0/mono/mini/mini-ppc.h
===================================================================
--- mono-3.4.0.orig/mono/mini/mini-ppc.h
+++ mono-3.4.0/mono/mini/mini-ppc.h
@@ -69,7 +69,13 @@ typedef struct MonoCompileArch {
#define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS
#define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS
#define MONO_ARCH_HAVE_ATOMIC_ADD 1
+
+/* 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
Index: mono-3.4.0/mono/mini/mini.c
===================================================================
--- mono-3.4.0.orig/mono/mini/mini.c
+++ mono-3.4.0/mono/mini/mini.c
@@ -7004,10 +7004,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)))
@@ -7033,7 +7032,7 @@ mini_create_ftnptr (MonoDomain *domain,
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;
Index: mono-3.4.0/mono/utils/lock-free-alloc.c
===================================================================
--- mono-3.4.0.orig/mono/utils/lock-free-alloc.c
+++ mono-3.4.0/mono/utils/lock-free-alloc.c
@@ -123,7 +123,9 @@ struct _MonoLockFreeAllocDescriptor {
#define NUM_DESC_BATCH 64
-#define SB_SIZE 16384
+/* SB_SIZE must be a multiple of the system pagesize, which for some
+ archs is 64k. */
+#define SB_SIZE 65536
#define SB_HEADER_SIZE 16
#define SB_USABLE_SIZE (SB_SIZE - SB_HEADER_SIZE)
Index: mono-3.4.0/mono/utils/mono-mmap.c
===================================================================
--- mono-3.4.0.orig/mono/utils/mono-mmap.c
+++ mono-3.4.0/mono/utils/mono-mmap.c
@@ -332,6 +332,11 @@ mono_valloc (void *addr, size_t length,
int
mono_vfree (void *addr, size_t length)
{
+/*if ( (length & (mono_pagesize () - 1)) != 0)
+ printf ("XXXX vfree: length not multiple of pagesize\n");
+if ( aligned_address (addr, length, mono_pagesize()) != addr)
+ printf ("XXXX vfree: addr not aligned to pagesize\n");*/
+
return munmap (addr, length);
}
Index: mono-3.4.0/mono/utils/strtod.c
===================================================================
--- mono-3.4.0.orig/mono/utils/strtod.c
+++ mono-3.4.0/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__)
# 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