chiark / gitweb /
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 8745ea43cd02a136f43fbe3c5c43c78228daecae..0af9cb58fbf58d07659a157610837f3338a0d1e2 100644 (file)
@@ -148,6 +148,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.
 
index 10ae404466344586068eb90e3cef93d6239722df..1b0ab2b138884a2190f1d933892d61ded1370353 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 bbb81f30c8615e080e8290db60bcb7ec34b355a1..1e463bdc36b32360e9b6a3e8af55809b06c6c341 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 dcf7028140273b292c9e80fa687ce93eb6433123..e3e5c21a8f385e3421cc43fdf1ac3f32bf3a2047 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.