2014-03-10 20:10:59 +01:00
|
|
|
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.
|
|
|
|
|
2014-05-29 08:10:29 +02:00
|
|
|
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
|
2014-03-10 20:10:59 +01:00
|
|
|
@@ -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); \
|
2014-05-29 08:10:29 +02:00
|
|
|
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
|
2014-03-10 20:10:59 +01:00
|
|
|
@@ -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)
|
|
|
|
|
2014-05-29 08:10:29 +02:00
|
|
|
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
|
2014-03-10 20:10:59 +01:00
|
|
|
@@ -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
|
2014-05-29 08:10:29 +02:00
|
|
|
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
|
2014-03-10 20:10:59 +01:00
|
|
|
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;
|
|
|
|
|
2014-05-29 08:10:29 +02:00
|
|
|
@@ -2901,7 +2901,13 @@ ppc_patch_full (guchar *code, const guch
|
2014-03-10 20:10:59 +01:00
|
|
|
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;
|
2014-05-29 08:10:29 +02:00
|
|
|
@@ -2925,8 +2931,12 @@ ppc_patch_full (guchar *code, const guch
|
2014-03-10 20:10:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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;
|
2014-05-29 08:10:29 +02:00
|
|
|
@@ -4481,6 +4491,16 @@ mono_arch_register_lowlevel_calls (void)
|
2014-03-10 20:10:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#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)); \
|
2014-05-29 08:10:29 +02:00
|
|
|
@@ -4490,6 +4510,9 @@ mono_arch_register_lowlevel_calls (void)
|
2014-03-10 20:10:59 +01:00
|
|
|
__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; \
|
2014-05-29 08:10:29 +02:00
|
|
|
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
|
2014-03-10 20:10:59 +01:00
|
|
|
@@ -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
|
2014-05-29 08:10:29 +02:00
|
|
|
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)
|
2014-03-10 20:10:59 +01:00
|
|
|
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)))
|
2014-05-29 08:10:29 +02:00
|
|
|
@@ -7033,7 +7032,7 @@ mini_create_ftnptr (MonoDomain *domain,
|
2014-03-10 20:10:59 +01:00
|
|
|
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;
|
2014-05-29 08:10:29 +02:00
|
|
|
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
|
2014-03-10 20:10:59 +01:00
|
|
|
@@ -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)
|
|
|
|
|
2014-05-29 08:10:29 +02:00
|
|
|
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
|
2014-03-10 20:10:59 +01:00
|
|
|
@@ -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);
|
|
|
|
}
|
|
|
|
|
2014-05-29 08:10:29 +02:00
|
|
|
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
|
2014-03-10 20:10:59 +01:00
|
|
|
@@ -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
|
|
|
|
|