diff --git a/coregrind/m_initimg/initimg-linux.c b/coregrind/m_initimg/initimg-linux.c index 19535039d..ad7dedd21 100644 --- a/coregrind/m_initimg/initimg-linux.c +++ b/coregrind/m_initimg/initimg-linux.c @@ -672,6 +672,14 @@ Addr setup_client_stack( void* init_sp, break; case AT_HWCAP: +# if defined(VGP_arm_linux) + { Bool has_neon = (auxv->u.a_val & VKI_HWCAP_NEON) > 0; + VG_(debugLog)(2, "initimg", + "ARM has-neon from-auxv: %s\n", + has_neon ? "YES" : "NO"); + VG_(machine_arm_set_has_NEON)( has_neon ); + } +# endif break; case AT_DCACHEBSIZE: diff --git a/coregrind/m_machine.c b/coregrind/m_machine.c index fdd2ce803..5f3bc927b 100644 --- a/coregrind/m_machine.c +++ b/coregrind/m_machine.c @@ -983,6 +983,22 @@ void VG_(machine_ppc64_set_clszB)( Int szB ) #endif +/* Notify host's ability to handle NEON instructions. */ +#if defined(VGA_arm) +void VG_(machine_arm_set_has_NEON)( Bool has_neon ) +{ + vg_assert(hwcaps_done); + /* There's nothing else we can sanity check. */ + + if (has_neon) { + vai.hwcaps |= VEX_HWCAPS_ARM_NEON; + } else { + vai.hwcaps &= ~VEX_HWCAPS_ARM_NEON; + } +} +#endif + + /* Fetch host cpu info, once established. */ void VG_(machine_get_VexArchInfo)( /*OUT*/VexArch* pVa, /*OUT*/VexArchInfo* pVai ) diff --git a/coregrind/pub_core_machine.h b/coregrind/pub_core_machine.h index 91d048aab..ea32dc83d 100644 --- a/coregrind/pub_core_machine.h +++ b/coregrind/pub_core_machine.h @@ -158,6 +158,11 @@ void VG_(get_UnwindStartRegs) ( /*OUT*/UnwindStartRegs* regs, then safe to use VG_(machine_get_VexArchInfo) and VG_(machine_ppc64_has_VMX) + ------------- + arm: initially: call VG_(machine_get_hwcaps) + call VG_(machine_arm_set_has_NEON) + + then safe to use VG_(machine_get_VexArchInfo) VG_(machine_get_hwcaps) may use signals (although it attempts to leave signal state unchanged) and therefore should only be @@ -182,6 +187,10 @@ extern void VG_(machine_ppc32_set_clszB)( Int ); extern void VG_(machine_ppc64_set_clszB)( Int ); #endif +#if defined(VGA_arm) +extern void VG_(machine_arm_set_has_NEON)( Bool ); +#endif + /* X86: set to 1 if the host is able to do {ld,st}mxcsr (load/store the SSE control/status register), else zero. Is referenced from assembly code, so do not change from a 32-bit int. */ diff --git a/include/vki/vki-arm-linux.h b/include/vki/vki-arm-linux.h index 65da4e037..9e6ff1ea7 100644 --- a/include/vki/vki-arm-linux.h +++ b/include/vki/vki-arm-linux.h @@ -871,6 +871,12 @@ struct vki_vm86plus_struct { struct vki_vm86plus_info_struct vm86plus; }; +//---------------------------------------------------------------------- +// From linux-2.6.35.4/arch/arm/include/asm/hwcap.h +//---------------------------------------------------------------------- + +#define VKI_HWCAP_NEON 4096 + //---------------------------------------------------------------------- // And that's it! //----------------------------------------------------------------------