From 663c599b0a43d0ae254a1f4e7c662f8aad7d3baa Mon Sep 17 00:00:00 2001 From: Josh Coalson Date: Fri, 21 Jan 2005 01:53:02 +0000 Subject: [PATCH] merged patches from Chris Csanady and John Steele Scott, better checking for altivec and ppc64 on ppc --- src/libFLAC/Makefile.am | 13 ++++++- src/libFLAC/cpu.c | 80 ++++++++++++++++++++++++++++++++++----- src/libFLAC/include/private/cpu.h | 1 + 3 files changed, 84 insertions(+), 10 deletions(-) diff --git a/src/libFLAC/Makefile.am b/src/libFLAC/Makefile.am index 724e881..9c44d21 100644 --- a/src/libFLAC/Makefile.am +++ b/src/libFLAC/Makefile.am @@ -29,10 +29,21 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. lib_LTLIBRARIES = libFLAC.la +DEBUGCFLAGS = +CPUCFLAGS = if DEBUG DEBUGCFLAGS = -DFLAC__OVERFLOW_DETECT endif -CFLAGS = @CFLAGS@ $(DEBUGCFLAGS) +if FLaC__CPU_PPC +# The -force_cpusubtype_ALL is needed to insert a ppc64 instruction +# into cpu.c with an asm(). +if FLaC__SYS_DARWIN +CPUCFLAGS= -faltivec -force_cpusubtype_ALL +else +CPUCFLAGS= -maltivec -mabi=altivec -force_cpusubtype_ALL +endif +endif +CFLAGS = @CFLAGS@ $(DEBUGCFLAGS) $(CPUCFLAGS) if FLaC__NO_ASM else diff --git a/src/libFLAC/cpu.c b/src/libFLAC/cpu.c index 63ce05e..0dacd23 100644 --- a/src/libFLAC/cpu.c +++ b/src/libFLAC/cpu.c @@ -30,8 +30,8 @@ */ #include "private/cpu.h" -#include -#include +#include +#include #ifdef HAVE_CONFIG_H #include @@ -39,9 +39,32 @@ #if defined FLAC__CPU_PPC #if !defined FLAC__NO_ASM -#if defined __APPLE__ && defined __MACH__ +#if defined FLAC__SYS_DARWIN #include -#endif /* __APPLE__ && __MACH__ */ +#include +#include +#include +#include +#ifndef CPU_SUBTYPE_POWERPC_970 +#define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100) +#endif +#else /* FLAC__SYS_DARWIN */ +#include +#include + +static sigjmp_buf jmpbuf; +static volatile sig_atomic_t canjump = 0; + +static void sigill_handler (int sig) +{ + if (!canjump) { + signal (sig, SIG_DFL); + raise (sig); + } + canjump = 0; + siglongjmp (jmpbuf, 1); +} +#endif /* FLAC__SYS_DARWIN */ #endif /* FLAC__NO_ASM */ #endif /* FLAC__CPU_PPC */ @@ -91,7 +114,7 @@ void FLAC__cpu_info(FLAC__CPUInfo *info) #if !defined FLAC__NO_ASM info->use_asm = true; #ifdef FLAC__USE_ALTIVEC -#if defined __APPLE__ && defined __MACH__ +#if defined FLAC__SYS_DARWIN { int selectors[2] = { CTL_HW, HW_VECTORUNIT }; int result = 0; @@ -100,12 +123,51 @@ void FLAC__cpu_info(FLAC__CPUInfo *info) info->data.ppc.altivec = error==0 ? result!=0 : 0; } -#else /* __APPLE__ && __MACH__ */ - /* don't know of any other thread-safe way to check */ - info->data.ppc.altivec = 0; -#endif /* __APPLE__ && __MACH__ */ + { + host_basic_info_data_t hostInfo; + mach_msg_type_number_t infoCount; + + infoCount = HOST_BASIC_INFO_COUNT; + host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo, &infoCount); + + info->data.ppc.ppc64 = (hostInfo.cpu_type == CPU_TYPE_POWERPC) && (hostInfo.cpu_subtype == CPU_SUBTYPE_POWERPC_970); + } +#else /* FLAC__SYS_DARWIN */ + { + /* no Darwin, do it the brute-force way */ + /* this is borrowed from MPlayer from the libmpeg2 library */ + info->data.ppc.altivec = 0; + info->data.ppc.ppc64 = 0; + + signal (SIGILL, sigill_handler); + if (!sigsetjmp (jmpbuf, 1)) { + canjump = 1; + + asm volatile ( + "mtspr 256, %0\n\t" + "vand %%v0, %%v0, %%v0" + : + : "r" (-1) + ); + + info->data.ppc.altivec = 1; + } + canjump = 0; + if (!sigsetjmp (jmpbuf, 1)) { + int x = 0; + canjump = 1; + + /* PPC64 hardware implements the cntlzd instruction */ + asm volatile ("cntlzd %0, %1" : "=r" (x) : "r" (x) ); + + info->data.ppc.ppc64 = 1; + } + signal (SIGILL, SIG_DFL); + } +#endif /* FLAC__SYS_DARWIN */ #else /* FLAC__USE_ALTIVEC */ info->data.ppc.altivec = 0; + info->data.ppc.ppc64 = 0; #endif /* FLAC__USE_ALTIVEC */ #else /* FLAC__NO_ASM */ info->use_asm = false; diff --git a/src/libFLAC/include/private/cpu.h b/src/libFLAC/include/private/cpu.h index b8c001a..37a9285 100644 --- a/src/libFLAC/include/private/cpu.h +++ b/src/libFLAC/include/private/cpu.h @@ -57,6 +57,7 @@ typedef struct { typedef struct { FLAC__bool altivec; + FLAC__bool ppc64; } FLAC__CPUInfo_PPC; extern const unsigned FLAC__CPUINFO_IA32_CPUID_CMOV; -- 2.7.4