Apple Clang在Xcdoe 10下是否缺少针对ARMv8/Aarch64的CRC32?

Apple Clang在Xcdoe 10下是否缺少针对ARMv8/Aarch64的CRC32?

问题描述:

我正在尝试为我们的Xcode交叉编译设置配置项。交叉编译测试ARMv7和ARMv8。事情看起来当谈到时间链接以ARMv8除了良好:Apple Clang在Xcdoe 10下是否缺少针对ARMv8/Aarch64的CRC32?

clang++ -DNDEBUG -g2 -O3 -fPIC -pipe -Wall -miphoneos-version-min=7 -arch arm64 \ 
    -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk \ 
    -stdlib=libc++ -c cryptlib.cpp 
clang++ -DNDEBUG -g2 -O3 -fPIC -pipe -Wall -miphoneos-version-min=7 -arch arm64 \ 
    -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk \ 
    -stdlib=libc++ -c cpu.cpp 
... 

clang++ -o cryptest.exe -DNDEBUG -g2 -O3 -fPIC -pipe -Wall -miphoneos-version-min=7 -arch arm64 \ 
    -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.2.sdk \ 
    -stdlib=libc++ test.o bench1.o bench2.o ... ./libcryptopp.a 

Undefined symbols for architecture arm64: 

    "CryptoPP::CRC32_Update_ARMV8(unsigned char const*, unsigned long, unsigned int&)", referenced from: 

     CryptoPP::CRC32::Update(unsigned char const*, unsigned long) in libcryptopp.a(crc.o) 

    "CryptoPP::CRC32C_Update_ARMV8(unsigned char const*, unsigned long, unsigned int&)", referenced from: 

     CryptoPP::CRC32C::Update(unsigned char const*, unsigned long) in libcryptopp.a(crc.o) 

ld: symbol(s) not found for architecture arm64 

clang: error: linker command failed with exit code 1 (use -v to see invocation) 

make: *** [cryptest.exe] Error 1 

我们显然不运行输出神器cryptest.exe。我们只是编译并链接到测试的东西。

该代码已经在LLVM Clang下正常测试。所有ARMv8/Aarch64机器都具有CRC-32和CRC-32C;所有ARMv8/Aarch64机器都具有CRC-32和CRC-32C;所有ARMv8/Aarch64机器都具有CRC-32和CRC-32C;但Crypto扩展是可选的。错误没有多大意义。

Apple Clang在Xcode 10下是否缺少针对ARMv8/Aarch64的CRC32?


下面是导致错误的代码。

#if defined(__ARM_FEATURE_CRC32) 

void CRC32_Update_ARMV8(const uint8_t *s, size_t n, uint32_t& c) 
{ 
    for(; !IsAligned<uint32_t>(s) && n > 0; s++, n--) 
     c = __crc32b(c, *s); 

    for(; n > 4; s+=4, n-=4) 
     c = __crc32w(c, *s); 

    for(; n > 0; s++, n--) 
     c = __crc32b(c, *s); 
} 

#endif 

在Xcode 8.3.3下,我遇到了__crc32 *()的编译错误。然后我添加了命令行开关

-march=armv8-a+crc 

this链接处找到,那么代码编译的很好。我使用iphone7 +/iOS10.3.1进行测试,结果正常。

根据ARM's document( “ARM®架构参考手册 ARMv8,为ARMv8-A架构概况” DDI0487B_a_armv8_arm.pdf:页A1-58)注意,CRC32指令是可选的V8和强制V8.1。当我在iphone6 +/iOS9.3.3上运行相同的程序时,它在__crc32 *()处崩溃。我还用内联汇编器对它进行了验证。因此,为了避免崩溃,需要进行某种运行时检查。我不完全了解如何,但作为最后的手段,我们可以使用模型名称。

+0

谢谢@beshio。 *“为避免崩溃,因此需要进行某种运行时检查......” - 请参阅[如何确定iOS上运行时的ARMv8功能?](https://*.com/q/45637888/ 608639) – jww

+0

@jww,感谢您的信息。我会检查链接并研究它。 – beshio