我一直在研究這個問題一段時間了,我希望有人能指出我的錯誤。我想我無法再通過樹木看到森林了。爲什麼編譯器沒有定義__ARM_FEATURE_CRC32?
我有一個用於測試的LeMaker HiKey開發板。它AArch64,所以其具有NEON和其他CPU的功能,如AES,SHA和CRC32:
$ cat /proc/cpuinfo
Processor : AArch64 Processor rev 3 (aarch64)
...
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
...
當我嘗試編譯的程序:
$ cat test.cxx
#if (defined(__ARM_NEON__) || defined(__ARM_NEON))
# define NEON_INTRINSICS_AVAILABLE 1
#else
# define NEON_INTRINSICS_AVAILABLE 0
#endif
#if BOOL_NEON_INTRINSICS_AVAILABLE
# include <arm_neon.h>
# if defined(__ARM_FEATURE_CRC32) || (__ARM_ACLE >= 200)
# include <arm_acle.h>
# endif
#endif
#include <stdint.h>
int main(int argc, char* argv[])
{
uint32_t crc = 0;
crc = __crc32b(crc, (uint8_t)0);
return 0
}
這將導致以下:
$ g++ test.cxx -o test.exe
test.cxx: In function ‘int main(int, char**)’:
test.cxx:20:33: error: ‘__crc32b’ was not declared in this scope
crc = __crc32b(crc, (uint8_t)0);
^
test.cxx:22:1: error: expected ‘;’ before ‘}’ token
}
^
$ clang++ test.cxx -o test.exe
test.cxx:20:9: error: use of undeclared identifier '__crc32b'
crc = __crc32b(crc, (uint8_t)0);
^
test.cxx:21:11: error: expected ';' after return statement
return 0
^
;
2 errors generated.
文件系統的的grep揭示arm_acle.h
實際上頭:
$ grep -IR '__crc32' /usr/lib
/usr/lib/gcc/.../include/arm_acle.h:__crc32b (uint32_t __a, uint8_t __b)
...
並根據ARM® C Language Extensions,第9.7節CRC32本質,當定義__ARM_FEATURE_CRC32
時,假設缺失的符號存在。檢查arm_acle.h
證實了它。
爲了完整起見,我試着用-march=native
編譯,但編譯器拒絕了它。
爲什麼__ARM_FEATURE_CRC32
未被編譯器定義?
我能做些什麼來讓程序編譯時使用板上的本地特性?
$ gcc --version
gcc (Debian/Linaro 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ clang --version
Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)
Target: aarch64-unknown-linux-gnu
Thread model: posix
$ g++ -dM -E - </dev/null | egrep -i '(arm|neon|acle)'
#define __ARM_NEON 1
$ clang++ -dM -E - </dev/null | egrep -i '(arm|neon|acle)'
#define __ARM_64BIT_STATE 1
#define __ARM_ACLE 200
#define __ARM_ALIGN_MAX_STACK_PWR 4
#define __ARM_ARCH 8
#define __ARM_ARCH_ISA_A64 1
#define __ARM_ARCH_PROFILE 'A'
#define __ARM_FEATURE_CLZ 1
#define __ARM_FEATURE_DIV 1
#define __ARM_FEATURE_FMA 1
#define __ARM_FEATURE_UNALIGNED 1
#define __ARM_FP 0xe
#define __ARM_FP16_FORMAT_IEEE 1
#define __ARM_FP_FENV_ROUNDING 1
#define __ARM_NEON 1
#define __ARM_NEON_FP 0xe
#define __ARM_PCS_AAPCS64 1
#define __ARM_SIZEOF_MINIMAL_ENUM 4
#define __ARM_SIZEOF_WCHAR_T 4
謝謝@mstorsjo。這對我來說很重要。再次感謝。我怎樣才能得到應該存在的其他定義,比如其他缺失的特性'__ARM_ARCH'和'__ARM_ACLE'? '__ARM_ACLE'很重要,因爲Linaro提供了4.9編譯器,所以'has_include(x)'不可用。 – jww
Wrt'__ARM_ARCH',顯然gcc已經選擇不包含它爲aarch64;如果定義了__AARCH64__,它應該與'__ARM_ARCH> = 8'幾乎等價。 至於'__ARM_ACLE',顯然gcc並沒有設置。我猜你可以假設如果設置了__ARM_FEATURE_CRC32,你可以包含arm_acle。h'(至少如果你使用gcc/clang,並且版本高於添加'__ARM_FEATURE_CRC32'的版本,無論哪一個 - 我都不知道)。 – mstorsjo
噢,這裏我們繼續... [GCC Bug 57989 - ARM的gcc定義了__ARM_FEATURE_SIMD32,但確實提供了SIMD32(ARMv6)內部函數](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57989) 。從錯誤:*「實現ACLE正在進行中。不幸的是,這個定義是在內部函數被添加之前添加的。」*。看起來他們抽出了所有與ARM相關的定義。 – jww