ARMv5 compatibility for registerized runtime changes.
authorStephen Blackheath <effusively.proffer.stephen@blacksapphire.com>
Tue, 26 Jul 2011 10:35:17 +0000 (10:35 +0000)
committerManuel M T Chakravarty <chak@cse.unsw.edu.au>
Wed, 10 Aug 2011 12:03:41 +0000 (22:03 +1000)
When the bootstrap compiler does not include this patch, you must add this line
to mk/build.mk, otherwise the ARM architecture cannot be detected due to a
-undef option given to the C pre-processor.
SRC_HC_OPTS = -pgmP 'gcc -E -traditional'

compiler/HsVersions.h
includes/Stg.h
includes/stg/ArchSpecific.h [new file with mode: 0644]
includes/stg/MachRegs.h
includes/stg/SMP.h
mk/config.mk.in
rts/OldARMAtomic.c
rts/StgCRun.c

index b6f92ae..f730c7e 100644 (file)
@@ -15,6 +15,7 @@ you will screw up the layout where they are used in case expressions!
 
 /* Pull in all the platform defines for this build (foo_TARGET_ARCH etc.) */
 #include "ghc_boot_platform.h"
+#include "../includes/stg/ArchSpecific.h"
 
 /* This macro indicates that the target OS supports ELF-like shared libraries */
 #if linux_TARGET_OS || freebsd_TARGET_OS || openbsd_TARGET_OS || solaris2_TARGET_OS
index cae4a3a..5665018 100644 (file)
@@ -225,6 +225,8 @@ typedef StgFunPtr       F_;
    Other Stg stuff...
    -------------------------------------------------------------------------- */
 
+#include "stg/ArchSpecific.h" /* required by MachRegs.h and SMP.h */
+
 #include "stg/DLL.h"
 #include "stg/MachRegs.h"
 #include "stg/Regs.h"
diff --git a/includes/stg/ArchSpecific.h b/includes/stg/ArchSpecific.h
new file mode 100644 (file)
index 0000000..b8815cf
--- /dev/null
@@ -0,0 +1,30 @@
+/* ----------------------------------------------------------------------------
+ *
+ * (c) The GHC Team, 2011
+ *
+ * Architecture-specific defines for ARM
+ *
+ * Do not #include this file directly: #include "Rts.h" instead.
+ *
+ * To understand the structure of the RTS headers, see the wiki:
+ *   http://hackage.haskell.org/trac/ghc/wiki/Commentary/SourceTree/Includes
+ *
+ * -------------------------------------------------------------------------- */
+
+#ifndef ARCH_ARM_H
+#define ARCH_ARM_H
+
+#if defined(__ARM_ARCH_2__) || defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__) || \
+    defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_5__) || \
+    defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__)
+#define arm_HOST_ARCH_PRE_ARMv6
+#endif
+
+#if defined(arm_HOST_ARCH_PRE_ARMv6) || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
+    defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || \
+    defined(__ARM_ARCH_6M__)
+#define arm_HOST_ARCH_PRE_ARMv7
+#endif
+
+#endif
+
index cf00796..64b32e8 100644 (file)
 #define REG_R4          r10
 #define REG_SpLim       r11
 
+#if !defined(arm_HOST_ARCH_PRE_ARMv6)
 /* d8 */
 #define REG_F1    s16
 #define REG_F2    s17
 
 #define REG_D1    d10
 #define REG_D2    d11
+#endif
 
 #endif /* arm */
 
index 4162058..bfd6bbc 100644 (file)
 #ifndef SMP_H
 #define SMP_H
 
-#if defined(__ARM_ARCH_2__) || defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__) || \
-    defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_5__) || \
-    defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__)
-#define PRE_ARMv6
-#endif
-
-#if defined(PRE_ARMv6) || defined(__ARM_ARCH_6__)
-#define PRE_ARMv7
-#endif
-
 #if defined(THREADED_RTS)
 
-#if arm_HOST_ARCH && defined(PRE_ARMv6)
+#if arm_HOST_ARCH && defined(arm_HOST_ARCH_PRE_ARMv6)
 void arm_atomic_spin_lock(void);
 void arm_atomic_spin_unlock(void);
 #endif
@@ -140,12 +130,12 @@ xchg(StgPtr p, StgWord w)
        : "+r" (result), "+m" (*p)
        : /* no input-only operands */
       );
-#elif arm_HOST_ARCH && defined(PRE_ARMv6)
+#elif arm_HOST_ARCH && defined(arm_HOST_ARCH_PRE_ARMv6)
     __asm__ __volatile__ ("swp %0, %1, [%2]"
                          : "=&r" (result)
                          : "r" (w), "r" (p) : "memory");
-#elif arm_HOST_ARCH && !defined(PRE_ARMv6)
-    // swp instruction which is used in PRE_ARMv6 code above
+#elif arm_HOST_ARCH && !defined(arm_HOST_ARCH_PRE_ARMv6)
+    // swp instruction which is used in pre-ARMv6 code above
     // is deprecated in AMRv6 and later. ARM, Ltd. *highly* recommends
     // to use ldrex/strex instruction pair for the same purpose
     // see chapter: Synchronization and semaphores in ARM Architecture
@@ -156,7 +146,7 @@ xchg(StgPtr p, StgWord w)
                           "      strex  %1, %2, [%3]\n"
                           "      teq    %1, #1\n"
                           "      beq    1b\n"
-#if !defined(PRE_ARMv7)
+#if !defined(arm_HOST_ARCH_PRE_ARMv7)
                           "      dmb\n"
 #endif
                           : "=&r" (result), "=&r" (tmp)
@@ -164,7 +154,6 @@ xchg(StgPtr p, StgWord w)
                           : "memory"
                           );
 #elif !defined(WITHSMP)
-#error xchg() unimplemented on this architecture
     result = *p;
     *p = w;
 #else
@@ -208,15 +197,14 @@ cas(StgVolatilePtr p, StgWord o, StgWord n)
        : "memory"
     );
     return n;
-#elif arm_HOST_ARCH
-#if defined(PRE_ARMv6)
+#elif arm_HOST_ARCH && defined(arm_HOST_ARCH_PRE_ARMv6)
     StgWord r;
     arm_atomic_spin_lock();
     r  = *p; 
     if (r == o) { *p = n; } 
     arm_atomic_spin_unlock();
     return r;
-#else
+#elif arm_HOST_ARCH && !defined(arm_HOST_ARCH_PRE_ARMv6)
     StgWord result,tmp;
 
     __asm__ __volatile__(
@@ -228,7 +216,7 @@ cas(StgVolatilePtr p, StgWord o, StgWord n)
         "       teq     %0, #1\n"
         "       it      eq\n"
         "       beq     1b\n"
-#if !defined(PRE_ARMv7)
+#if !defined(arm_HOST_ARCH_PRE_ARMv7)
         "       dmb\n"
 #endif
                 : "=&r"(tmp), "=&r"(result)
@@ -236,9 +224,7 @@ cas(StgVolatilePtr p, StgWord o, StgWord n)
                 : "cc","memory");
 
     return result;
-#endif
 #elif !defined(WITHSMP)
-#error cas() unimplemented on this architecture
     StgWord result;
     result = *p;
     if (result == o) {
@@ -320,9 +306,9 @@ write_barrier(void) {
 #elif sparc_HOST_ARCH
     /* Sparc in TSO mode does not require store/store barriers. */
     __asm__ __volatile__ ("" : : : "memory");
-#elif arm_HOST_ARCH && PRE_ARMv7
+#elif arm_HOST_ARCH && defined(arm_HOST_ARCH_PRE_ARMv7)
     __asm__ __volatile__ ("" : : : "memory");
-#elif arm_HOST_ARCH && !PRE_ARMv7
+#elif arm_HOST_ARCH && !defined(arm_HOST_ARCH_PRE_ARMv7)
     __asm__ __volatile__ ("dmb  st" : : : "memory");
 #elif !defined(WITHSMP)
     return;
@@ -341,7 +327,7 @@ store_load_barrier(void) {
     __asm__ __volatile__ ("sync" : : : "memory");
 #elif sparc_HOST_ARCH
     __asm__ __volatile__ ("membar #StoreLoad" : : : "memory");
-#elif arm_HOST_ARCH && !PRE_ARMv7
+#elif arm_HOST_ARCH && !defined(arm_HOST_ARCH_PRE_ARMv7)
     __asm__ __volatile__ ("dmb" : : : "memory");
 #elif !defined(WITHSMP)
     return;
@@ -361,7 +347,7 @@ load_load_barrier(void) {
 #elif sparc_HOST_ARCH
     /* Sparc in TSO mode does not require load/load barriers. */
     __asm__ __volatile__ ("" : : : "memory");
-#elif arm_HOST_ARCH && !PRE_ARMv7
+#elif arm_HOST_ARCH && !defined(arm_HOST_ARCH_PRE_ARMv7)
     __asm__ __volatile__ ("dmb" : : : "memory");
 #elif !defined(WITHSMP)
     return;
index e8ded39..873205c 100644 (file)
@@ -174,7 +174,7 @@ GhcWithSMP=$(strip $(if $(filter YESNO, $(ArchSupportsSMP)$(GhcUnregisterised)),
 # has support for this OS/ARCH combination.
 
 OsSupportsGHCi=$(strip $(patsubst $(HostOS_CPP), YES, $(findstring $(HostOS_CPP), mingw32 cygwin32 linux solaris2 freebsd dragonfly netbsd openbsd darwin)))
-ArchSupportsGHCi=$(strip $(patsubst $(HostArch_CPP), YES, $(findstring $(HostArch_CPP), i386 x86_64 powerpc sparc sparc64 arm)))
+ArchSupportsGHCi=$(strip $(patsubst $(HostArch_CPP), YES, $(findstring $(HostArch_CPP), i386 x86_64 powerpc sparc sparc64)))
 
 ifeq "$(OsSupportsGHCi)$(ArchSupportsGHCi)" "YESYES"
 GhcWithInterpreter=YES
index 2a3c6c6..5c51cc0 100644 (file)
@@ -1,3 +1,12 @@
+/* -----------------------------------------------------------------------------
+ *
+ * (c) The GHC Team, 2011
+ *
+ * Inefficient but necessary atomic locks used for implementing atomic
+ * operations on ARM architectures pre-ARMv6.
+ *
+ * -------------------------------------------------------------------------- */
+
 #include "PosixSource.h"
 #include "Stg.h"
 
@@ -7,7 +16,7 @@
 
 #if defined(THREADED_RTS)
 
-#if arm_HOST_ARCH && defined(PRE_ARMv6)
+#if arm_HOST_ARCH && defined(arm_HOST_ARCH_PRE_ARMv6)
 
 static volatile int atomic_spin = 0;
 
@@ -41,7 +50,7 @@ void arm_atomic_spin_unlock()
   atomic_spin = 0;
 } 
 
-#endif  /* arm_HOST_ARCH && defined(PRE_ARMv6) */
+#endif  /* arm_HOST_ARCH && defined(arm_HOST_ARCH_PRE_ARMv6) */
 
 #endif  /* defined(THREADED_RTS) */
 
index 58db832..7251e64 100644 (file)
@@ -997,7 +997,9 @@ StgRun(StgFunPtr f, StgRegTable *basereg) {
         * save callee-saves registers on behalf of the STG code.
         */
        "stmfd sp!, {r4-r10, fp, ip, lr}\n\t"
+#if !defined(arm_HOST_ARCH_PRE_ARMv6)
         "vstmdb sp!, {d8-d11}\n\t"
+#endif
         /*
          * allocate some space for Stg machine's temporary storage.
          * Note: RESERVER_C_STACK_BYTES has to be a round number here or
@@ -1028,7 +1030,9 @@ StgRun(StgFunPtr f, StgRegTable *basereg) {
        /*
         * restore callee-saves registers.
         */
+#if !defined(arm_HOST_ARCH_PRE_ARMv6)
         "vldmia sp!, {d8-d11}\n\t"
+#endif
        "ldmfd sp!, {r4-r10, fp, ip, lr}\n\t"
       : "=r" (r)
       : "r" (f), "r" (basereg), "i" (RESERVED_C_STACK_BYTES)