bool CPU_ProbeCRC32() { #if defined(CRYPTOPP_NO_CPU_FEATURE_PROBES) return false; #elif (CRYPTOPP_ARM_CRC32_AVAILABLE) # if defined(CRYPTOPP_MS_STYLE_INLINE_ASSEMBLY) volatile bool result = true; __try { word32 w=0, x=1; word16 y=2; byte z=3; w = __crc32w(w,x); w = __crc32h(w,y); w = __crc32b(w,z); w = __crc32cw(w,x); w = __crc32ch(w,y); w = __crc32cb(w,z); result = !!w; } __except (EXCEPTION_EXECUTE_HANDLER) { return false; } return result; #else // longjmp and clobber warnings. Volatile is required. // http://github.com/weidai11/cryptopp/issues/24 and http://stackoverflow.com/q/7721854 volatile bool result = true; volatile SigHandler oldHandler = signal(SIGILL, SigIllHandler); if (oldHandler == SIG_ERR) return false; volatile sigset_t oldMask; if (sigprocmask(0, NULLPTR, (sigset_t*)&oldMask)) return false; if (setjmp(s_jmpSIGILL)) result = false; else { word32 w=0, x=1; word16 y=2; byte z=3; w = __crc32w(w,x); w = __crc32h(w,y); w = __crc32b(w,z); w = __crc32cw(w,x); w = __crc32ch(w,y); w = __crc32cb(w,z); // Hack... GCC optimizes away the code and returns true result = !!w; } sigprocmask(SIG_SETMASK, (sigset_t*)&oldMask, NULLPTR); signal(SIGILL, oldHandler); return result; # endif #else return false; #endif // CRYPTOPP_ARM_CRC32_AVAILABLE }
// ARM-LABEL: test_crc32h // AArch32: call i32 @llvm.arm.crc32h // AArch64: call i32 @llvm.aarch64.crc32h uint32_t test_crc32h(uint32_t a, uint16_t b) { return __crc32h(a, b); }