Index: src/OFSystemInfo.h ================================================================== --- src/OFSystemInfo.h +++ src/OFSystemInfo.h @@ -182,8 +182,21 @@ * * @return Whether the CPU supports AVX2 */ + (bool)supportsAVX2; #endif + +#ifdef OF_PPC_ASM +/*! + * @brief Returns whether the CPU supports AltiVec. + * + * @warning This method only checks CPU support and assumes OS support! + * + * @note This method is only available on PowerPC. + * + * @return Whether the CPU supports AltiVec + */ ++ (bool)supportsAltiVec; +#endif @end OF_ASSUME_NONNULL_END Index: src/OFSystemInfo.m ================================================================== --- src/OFSystemInfo.m +++ src/OFSystemInfo.m @@ -44,19 +44,26 @@ # include #endif #ifdef __QNX__ # include #endif +#ifdef OF_PPC_ASM +# include +#endif #if defined(OF_X86_64_ASM) || defined(OF_X86_ASM) struct x86_regs { uint32_t eax, ebx, ecx, edx; }; #endif static size_t pageSize; static size_t numberOfCPUs; +#ifdef OF_PPC_ASM +static sig_atomic_t altiVecSupported; +static sigjmp_buf altiVecJumpBuffer; +#endif #if defined(OF_X86_64_ASM) static OF_INLINE struct x86_regs OF_CONST_FUNC x86_cpuid(uint32_t eax, uint32_t ecx) { @@ -92,12 +99,35 @@ ); return regs; } #endif + +#ifdef OF_PPC_ASM +static void +altiVecSIGILLHandler(int signal) +{ + altiVecSupported = 0; + siglongjmp(altiVecJumpBuffer, 1); +} +#endif @implementation OFSystemInfo +#ifdef OF_PPC_ASM ++ (void)load +{ + altiVecSupported = 1; + if (sigsetjmp(altiVecJumpBuffer, 1) == 0) { + signal(SIGILL, altiVecSIGILLHandler); + __asm__ __volatile__ ( + "vor v0, v0, v0" + ); + } + signal(SIGILL, SIG_DFL); +} +#endif + + (void)initialize { if (self != [OFSystemInfo class]) return; @@ -369,6 +399,13 @@ + (bool)supportsAVX2 { return x86_cpuid(0, 0).eax >= 7 && (x86_cpuid(7, 0).ebx & (1 << 5)); } #endif + +#ifdef OF_PPC_ASM ++ (bool)supportsAltiVec +{ + return altiVecSupported; +} +#endif @end