Add support machinery for ARM hosts.
authorMark Wooding <mdw@distorted.org.uk>
Sat, 21 May 2016 13:33:28 +0000 (14:33 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 21 May 2016 16:17:27 +0000 (17:17 +0100)
There's currently no ARM code here, but we can probe for the
features (and it seems to work).

base/asm-common.h
base/dispatch.c
base/dispatch.h
configure.ac

index 8745ea4..0af9cb5 100644 (file)
@@ -149,6 +149,50 @@ _where_am_i.\got :
 #endif
 
 ///--------------------------------------------------------------------------
+/// ARM-specific hacking.
+
+#if CPUFAM_ARM
+
+// Set the function hooks.
+#define FUNC_PREHOOK(_) .balign 4
+#define ENDFUNC_HOOK(name) .ltorg
+
+// Call external subroutine at ADDR, possibly via PLT.
+       .macro  callext addr, cond=
+#if WANT_PIC
+       bl\cond \addr(PLT)
+#else
+       bl\cond \addr
+#endif
+       .endm
+
+// Do I need to arrange a spare GOT register?
+#if WANT_PIC
+#  define NEED_GOT 1
+#endif
+#define GOTREG r9
+
+// Maybe load GOT address into GOT.
+       .macro  ldgot   got=r9
+#if WANT_PIC
+       ldr     \got, =_GLOBAL_OFFSET_TABLE_ - . - 12
+       add     \got, pc, \got
+#endif
+       .endm
+
+// Load address of external symbol ADDR into REG, maybe using GOT.
+       .macro  leaext  reg, addr, cond=, got=GOTREG
+#if WANT_PIC
+       ldr     \reg, =\addr(GOT)
+       ldr     \reg, [\got, \reg]
+#else
+       ldr     \reg, =\addr
+#endif
+       .endm
+
+#endif
+
+///--------------------------------------------------------------------------
 /// Final stuff.
 
 // Default values for the various hooks.
index 10ae404..1b0ab2b 100644 (file)
@@ -224,6 +224,10 @@ struct auxentry { unsigned long type; union auxval value; };
  * that the necessary entry types are defined.  This is primarily ordered by
  * entry type to minimize duplication.
  */
+#if defined(AT_HWCAP) && CPUFAM_ARMEL
+#  define WANT_ANY 1
+#  define WANT_AT_HWCAP(_) _(AT_HWCAP, u, hwcap)
+#endif
 
 /* If we couldn't find any interesting entries then we can switch all of this
  * machinery off.  Also do that if we have no means for atomic updates.
@@ -255,6 +259,15 @@ static unsigned hwcaps = 0;
  *     intends to satisfy from the auxiliary vector.  Each entry contains a
  *     feature name suffix, and the token name (for `check_env').
  */
+#if CPUFAM_ARMEL
+#  define WANTAUX(_)                                                   \
+       WANT_AT_HWCAP(_)
+#  define CAPMAP(_)                                                    \
+       _(ARM_VFP, "arm:vfp")                                           \
+       _(ARM_NEON, "arm:neon")                                         \
+       _(ARM_V4, "arm:v4")                                             \
+       _(ARM_D32, "arm:d32")
+#endif
 
 /* Build the bitmask for `hwcaps' from the `CAPMAP' list. */
 enum {
@@ -358,6 +371,12 @@ static void probe_hwcaps(void)
   /* Each CPU family now has to pick through what was found and stashed in
    * `probed', and set the appropriate flag bits in `hw'.
    */
+#if CPUFAM_ARMEL
+  if (probed.hwcap & HWCAP_VFPv3) hw |= HF_ARM_VFP;
+  if (probed.hwcap & HWCAP_NEON) hw |= HF_ARM_NEON;
+  if (probed.hwcap & HWCAP_VFPD32) hw |= HF_ARM_D32;
+  if (probed.hwcap & HWCAP_VFPv4) hw |= HF_ARM_V4;
+#endif
 
   /* Store the bitmask of features we probed for everyone to see. */
   DISPATCH_STORE(hwcaps, hw);
index bbb81f3..1e463bd 100644 (file)
@@ -175,7 +175,11 @@ extern void dispatch_debug(const char */*fmt*/, ...);
 
 enum {
   CPUFEAT_X86_SSE2,                    /* Streaming SIMD Extensions 2 */
-  CPUFEAT_X86_AESNI                    /* AES Native Instructions */
+  CPUFEAT_X86_AESNI,                   /* AES Native Instructions */
+  CPUFEAT_ARM_VFP,                     /* VFP floating-point (v3 or v4) */
+  CPUFEAT_ARM_NEON,                    /* Advanced SIMD (v1 or v2) */
+  CPUFEAT_ARM_V4,                      /* VFPv4 and/or SIMD v2 */
+  CPUFEAT_ARM_D32                      /* 32 double registers, not 16 */
 };
 
 extern int cpu_feature_p(int /*feat*/);
index dcf7028..e3e5c21 100644 (file)
@@ -58,7 +58,8 @@ AC_DEFUN([catacomb_CPU_FAMILIES],
   [$1([i[[3-6]]86,cygwin], [x86], [win])
    $1([i[[3-6]]86,*], [x86], [sysv])
    $1([x86_64,cygwin], [amd64], [win])
-   $1([x86_64,*], [amd64], [sysv])])
+   $1([x86_64,*], [amd64], [sysv])
+   $1([armv*,*-gnueabi | armv*,*-gnueabihf], [armel], [gnueabi])])
 
 dnl A utility to clear the `seen' flags, used so as to process each CPU or
 dnl ABI once.