Skip to content

PPC32 support #25

@NattyNarwhal

Description

@NattyNarwhal

Would provide a possibly faster, memory lighter at runtime, use PPC32 libraries in P/Invoke, and a good way for upstream to ensure their PPC32 support works. However, AIX uses function descriptors and its strange calling convention on 32 bit, which violates many of Mono's assumptions about PPC32. (This is why right now, the runtime is 64-bit only.)

Requires

  • Allow configurability for 32/64-bit build (we don't need to propagate an env var; maybe we would if we compiled with xlc) with a cleanup in configure.ac

  • Find all function descriptor handling code and ensure it works on PPC32

  • Find code size assumptions (function descriptor loading code bumps up code size by eight bytes (two ppc32 opcodes) per use of ppc_load_func) and resolve patching issues

  • Other issues like calling conventions

Patch:

Currently bombs out at mini-ppc.c:3080 - PPC32 patching logic I assume has no clue how to deal with function descriptors. Won't send upstream until I can get a program executing.

diff --git a/configure.ac b/configure.ac
index f881417..1babe78 100644
--- a/configure.ac
+++ b/configure.ac
@@ -377,15 +377,32 @@ case "$host" in
 		use_sigposix=yes
 		;;
 	*-*-aix*|*-*-os400*)
-		dnl Set up a 64-bit build
-		CPPFLAGS="$CPPFLAGS -maix64 -DGC_AIX_THREADS -D_ALL_SOURCE -D_THREAD_SAFE -D_LARGE_FILES -D_REENTRANT"
-		LDFLAGS="-maix64"
 		libmono_cflags="-D_THREAD_SAFE -D_REENTRANT"
-		dnl Would you believe GNU nm doesn't know how to process AIX libraries?
-		dnl Hardcode IBM binutils in case GNU ones end up on our path. Also
-		dnl specifiy 64-bit mode for tools.
-		AR="/usr/bin/ar -X64"
-		NM="/usr/bin/nm -X64"
+		dnl This environment variable controls if our build is 32 or 64-bit.
+		AC_ARG_VAR(OBJECT_MODE, [Specifies the bitness type output of IBM binutils])
+		dnl Specify the IBM binutils in case GNU ones end up on our path.
+		dnl OBJECT_MODE sets the bitness of IBM binutils; but this is a pain to 
+		dnl propagate to makefiles; so specify a tool's 64-bit mode manually for now.
+		if test "$OBJECT_MODE" = "64"; then
+			AR="/usr/bin/ar -X64"
+			NM="/usr/bin/nm -X64"
+		else
+			AR="/usr/bin/ar"
+			NM="/usr/bin/nm"
+		fi
+		dnl Check for GCC vs. XL C; GCC doesn't respect OBJECT_MODE, FWIW
+		if test "$GCC" != "yes"; then
+			if test "$OBJECT_MODE" = "64"; then
+				CPPFLAGS="$CPPFLAGS -maix64 -DGC_AIX_THREADS -D_ALL_SOURCE -D_THREAD_SAFE -D_LARGE_FILES -D_REENTRANT"
+				LDFLAGS="-maix64"
+			else
+				echo " ** No OBJECT_MODE ** "
+				CPPFLAGS="$CPPFLAGS -DGC_AIX_THREADS -D_ALL_SOURCE -D_THREAD_SAFE -D_LARGE_FILES -D_REENTRANT"
+			fi
+		else
+			dnl TODO: XL C support
+			CPPFLAGS="$CPPFLAGS -DGC_AIX_THREADS -D_ALL_SOURCE -D_THREAD_SAFE -D_LARGE_FILES -D_REENTRANT"
+		fi
 		dnl SGen is the future (changes to Boehm support code would be
 		dnl required if you wish to re-enable Boehm)
 		support_boehm=no
@@ -3979,8 +3996,11 @@ case "$host" in
 			BTLS_PLATFORM=powerpc
 			dnl on AIX/PASE, shared libraries can be inside archives
 			dnl if they are, we specify them by lib.a(lib.so)
-			dnl we may hardcode 64-bit names at times, but we don't do 32-bit AIX, so
-			LIBC="libc.a(shr_64.o)"
+			if test "$OBJECT_MODE" = "64"; then
+				LIBC="libc.a(shr_64.o)"
+			else
+				LIBC="libc.a(shr.o)"
+			fi
 			INTL="libintl.a(libintl.so.8)"
 			;;
 		  linux*)
@@ -5135,8 +5155,25 @@ if test "x$enable_btls" = "xyes"; then
 		btls_arch=powerpc
 		case $host_os in
 			aix*|os400*)
-				btls_cflags="$btls_cflags -maix64 -mminimal-toc -pthread -D_ALL_SOURCE -D_THREAD_SAFE -D_REENTRANT"
-				BTLS_CMAKE_ARGS="-DCMAKE_AR=/usr/bin/ar -DCMAKE_C_ARCHIVE_CREATE=\"<CMAKE_AR> -X64 cr <TARGET> <LINK_FLAGS> <OBJECTS>\""
+				dnl Test for GCC vs. XL C
+				if test "$GCC" != "yes"; then
+					if test "$OBJECT_MODE" = "64"; then
+						btls_cflags="$btls_cflags -maix64 -mminimal-toc -pthread -D_ALL_SOURCE -D_THREAD_SAFE -D_REENTRANT"
+						BTLS_CMAKE_ARGS="-DCMAKE_AR=/usr/bin/ar -DCMAKE_C_ARCHIVE_CREATE=\"<CMAKE_AR> -X64 cr <TARGET> <LINK_FLAGS> <OBJECTS>\""
+					else
+						btls_cflags="$btls_cflags -mminimal-toc -pthread -D_ALL_SOURCE -D_THREAD_SAFE -D_REENTRANT"
+						BTLS_CMAKE_ARGS="-DCMAKE_AR=/usr/bin/ar -DCMAKE_C_ARCHIVE_CREATE=\"<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>\""
+					fi
+				else
+					dnl TODO: Verify this for XL C support
+					if test "$OBJECT_MODE" = "64"; then
+						btls_cflags="$btls_cflags -maix64 -mminimal-toc -pthread -D_ALL_SOURCE -D_THREAD_SAFE -D_REENTRANT"
+						BTLS_CMAKE_ARGS="-DCMAKE_AR=/usr/bin/ar -DCMAKE_C_ARCHIVE_CREATE=\"<CMAKE_AR> -X64 cr <TARGET> <LINK_FLAGS> <OBJECTS>\""
+					else
+						btls_cflags="$btls_cflags -mminimal-toc -pthread -D_ALL_SOURCE -D_THREAD_SAFE -D_REENTRANT"
+						BTLS_CMAKE_ARGS="-DCMAKE_AR=/usr/bin/ar -DCMAKE_C_ARCHIVE_CREATE=\"<CMAKE_AR> cr <TARGET> <LINK_FLAGS> <OBJECTS>\""
+					fi
+				fi
 		esac
 		;;
 	android-armv5)
diff --git a/external/boringssl b/external/boringssl
--- a/external/boringssl
+++ b/external/boringssl
@@ -1 +1 @@
-Subproject commit 4e95a6c97494a0c5e9d1f7b6f49c0ff4102908e8
+Subproject commit 4e95a6c97494a0c5e9d1f7b6f49c0ff4102908e8-dirty
diff --git a/external/corefx b/external/corefx
--- a/external/corefx
+++ b/external/corefx
@@ -1 +1 @@
-Subproject commit d2aaa5450b5481c2392a3a5656d353f28e5e3bbd
+Subproject commit d2aaa5450b5481c2392a3a5656d353f28e5e3bbd-dirty
diff --git a/mono/arch/ppc/ppc-codegen.h b/mono/arch/ppc/ppc-codegen.h
index 98fed75..da1a139 100644
--- a/mono/arch/ppc/ppc-codegen.h
+++ b/mono/arch/ppc/ppc-codegen.h
@@ -205,7 +205,15 @@ enum {
 		}	\
 	} G_STMT_END
 
+#if defined(_AIX)
+#define ppc_load_func(c,D,v) G_STMT_START { \
+		ppc_load_sequence ((c), ppc_r12, (gpointer)(gsize)(v));	\
+		ppc_ldptr ((c), ppc_r2, sizeof (gpointer), ppc_r12);	\
+		ppc_ldptr ((c), (D), 0, ppc_r12);	\
+	} G_STMT_END
+#else
 #define ppc_load_func(c,D,V)	      ppc_load_sequence ((c), (D), (V))
+#endif
 
 #define ppc_load_multiple_regs(c,D,d,A)      ppc_lmw   ((c), (D), (d), (A))
 
diff --git a/mono/mini/cpu-ppc.md b/mono/mini/cpu-ppc.md
index 5eea6e3..d251798 100644
--- a/mono/mini/cpu-ppc.md
+++ b/mono/mini/cpu-ppc.md
@@ -80,7 +80,7 @@ fcompare: src1:f src2:f len:12
 oparglist: src1:i len:12
 setlret: src1:i src2:i len:12
 checkthis: src1:b len:4
-voidcall: len:16 clob:c
+voidcall: len:24 clob:c
 voidcall_reg: src1:i len:16 clob:c
 voidcall_membase: src1:b len:16 clob:c
 fcall: dest:g len:16 clob:c
diff --git a/mono/mini/exceptions-ppc.c b/mono/mini/exceptions-ppc.c
index 3483ba8..43113b6 100644
--- a/mono/mini/exceptions-ppc.c
+++ b/mono/mini/exceptions-ppc.c
@@ -463,7 +463,7 @@ mono_arch_get_throw_exception_generic (int size, MonoTrampInfo **info, int corli
 gpointer
 mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot)
 {
-	int size = MONO_PPC_32_64_CASE (132, 224) + PPC_FTNPTR_SIZE;
+	int size = MONO_PPC_32_64_CASE (140, 224) + PPC_FTNPTR_SIZE;
 
 	if (aot)
 		size += 64;
@@ -485,7 +485,7 @@ mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot)
 gpointer
 mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot)
 {
-	int size = MONO_PPC_32_64_CASE (132, 224) + PPC_FTNPTR_SIZE;
+	int size = MONO_PPC_32_64_CASE (140, 224) + PPC_FTNPTR_SIZE;
 
 	if (aot)
 		size += 64;
@@ -502,7 +502,7 @@ mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot)
 gpointer
 mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot)
 {
-	int size = MONO_PPC_32_64_CASE (168, 304) + PPC_FTNPTR_SIZE;
+	int size = MONO_PPC_32_64_CASE (176, 304) + PPC_FTNPTR_SIZE;
 
 	if (aot)
 		size += 64;
@@ -679,8 +679,8 @@ mono_arch_handle_altstack_exception (void *sigctx, MONO_SIG_HANDLER_INFO_TYPE *s
 	{
 		MonoPPCFunctionDescriptor *handler_ftnptr = (MonoPPCFunctionDescriptor*)altstack_handle_and_restore;
 
-		UCONTEXT_REG_NIP(uc) = (gulong)handler_ftnptr->code;
-		UCONTEXT_REG_Rn(uc, 2) = (gulong)handler_ftnptr->toc;
+		UCONTEXT_REG_NIP(uc) = (gpointer)handler_ftnptr->code;
+		UCONTEXT_REG_Rn(uc, 2) = (gpointer)handler_ftnptr->toc;
 	}
 #else
 	UCONTEXT_REG_NIP(uc) = (unsigned long)altstack_handle_and_restore;
@@ -726,8 +726,8 @@ setup_ucontext_return (void *uc, gpointer func)
 	{
 		MonoPPCFunctionDescriptor *handler_ftnptr = (MonoPPCFunctionDescriptor*)func;
 
-		UCONTEXT_REG_NIP(uc) = (gulong)handler_ftnptr->code;
-		UCONTEXT_REG_Rn(uc, 2) = (gulong)handler_ftnptr->toc;
+		UCONTEXT_REG_NIP(uc) = (gpointer)handler_ftnptr->code;
+		UCONTEXT_REG_Rn(uc, 2) = (gpointer)handler_ftnptr->toc;
 	}
 #else
 	UCONTEXT_REG_NIP(uc) = (unsigned long)func;
@@ -794,9 +794,9 @@ mono_arch_setup_async_callback (MonoContext *ctx, void (*async_cb)(void *fun), g
 	uintptr_t sp = (uintptr_t) MONO_CONTEXT_GET_SP(ctx);
 	ctx->regs [PPC_FIRST_ARG_REG] = user_data;
 	sp -= PPC_MINIMAL_STACK_SIZE;
-	*(unsigned long *)sp = MONO_CONTEXT_GET_SP(ctx);
+	*(gpointer *)sp = MONO_CONTEXT_GET_SP(ctx);
 	MONO_CONTEXT_SET_BP(ctx, sp);
-	mono_arch_setup_resume_sighandler_ctx(ctx, (unsigned long) async_cb);
+	mono_arch_setup_resume_sighandler_ctx(ctx, (gpointer) async_cb);
 }
 
 void
@@ -804,9 +804,9 @@ mono_arch_setup_resume_sighandler_ctx (MonoContext *ctx, gpointer func)
 {
 #ifdef PPC_USES_FUNCTION_DESCRIPTOR
 	MonoPPCFunctionDescriptor *handler_ftnptr = (MonoPPCFunctionDescriptor*)func;
-	MONO_CONTEXT_SET_IP(ctx, (gulong)handler_ftnptr->code);
-	ctx->regs[2] = (gulong)handler_ftnptr->toc;
+	MONO_CONTEXT_SET_IP(ctx, (gpointer)handler_ftnptr->code);
+	ctx->regs[2] = (gpointer)handler_ftnptr->toc;
 #else
-	MONO_CONTEXT_SET_IP(ctx, (unsigned long) func);
+	MONO_CONTEXT_SET_IP(ctx, (gpointer) func);
 #endif
 }
diff --git a/mono/mini/mini-ppc.c b/mono/mini/mini-ppc.c
index 282868e..a20f622 100644
--- a/mono/mini/mini-ppc.c
+++ b/mono/mini/mini-ppc.c
@@ -2951,7 +2951,7 @@ ppc_patch_full (MonoCompile *cfg, MonoDomain *domain, guchar *code, const guchar
 	guint32 prim = ins >> 26;
 	guint32 ovf;
 
-	//g_print ("patching 0x%08x (0x%08x) to point to 0x%08x\n", code, ins, target);
+	g_print ("patching 0x%08x (0x%08x) to point to 0x%08x\n", code, ins, target);
 	if (prim == 18) {
 		// prefer relative branches, they are more position independent (e.g. for AOT compilation).
 		gint diff = target - code;
@@ -3087,7 +3087,7 @@ ppc_patch_full (MonoCompile *cfg, MonoDomain *domain, guchar *code, const guchar
 	} else {
 		g_assert_not_reached ();
 	}
-//	g_print ("patched with 0x%08x\n", ins);
+	g_print ("patched with 0x%08x\n", ins);
 }
 
 void
diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c
index 2f16279..bc406b9 100644
--- a/mono/mini/mini-runtime.c
+++ b/mono/mini/mini-runtime.c
@@ -3812,7 +3812,7 @@ mini_create_ftnptr (MonoDomain *domain, gpointer addr)
 
 	if ((desc = g_hash_table_lookup (domain->ftnptrs_hash, addr)))
 		return desc;
-#if defined(__mono_ppc64__)
+#if defined(PPC_USES_FUNCTION_DESCRIPTOR)
 	desc = mono_domain_alloc0 (domain, 3 * sizeof (gpointer));
 
 	desc [0] = addr;

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: JITThis issue affects the Mono JITos: aixThis issue affects AIXos: iThis issue affects ipriority; lowThis issue isn't too importanttype: enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions