为什么 __ARM_FEATURE_CRC32 没有被编译器定义?
Why is __ARM_FEATURE_CRC32 not being defined by the compiler?
我一直在研究这个问题,希望有人能指出我的错误。我想我再也见不到森林了。
我有一块 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
实际上是 header:
$ 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 Intrinsics,假设在定义 __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
至于为什么默认不启用此功能;这是您的编译器所针对的基线 ABI 中不存在的可选功能,即您的编译器生成的二进制文件预计能够 运行 在缺少 CRC 功能的设备上。
至少对于 gcc,您可以使用 -march
修饰符 crc
启用此功能,如下所示:
$ gcc -dM -E - -march=armv8-a+crc < /dev/null | egrep -i '(arm|neon|acle|crc)'
#define __ARM_FEATURE_CRC32 1
#define __ARM_NEON 1
请参阅 https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/AArch64-Options.html(或旧 gcc 版本的同一页面)以获取有关如何设置此设置的更多文档。
我猜想 -march=native
会做同样的事情,但该选项目前似乎只针对 x86 架构实现。
我一直在研究这个问题,希望有人能指出我的错误。我想我再也见不到森林了。
我有一块 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
实际上是 header:
$ 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 Intrinsics,假设在定义 __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
至于为什么默认不启用此功能;这是您的编译器所针对的基线 ABI 中不存在的可选功能,即您的编译器生成的二进制文件预计能够 运行 在缺少 CRC 功能的设备上。
至少对于 gcc,您可以使用 -march
修饰符 crc
启用此功能,如下所示:
$ gcc -dM -E - -march=armv8-a+crc < /dev/null | egrep -i '(arm|neon|acle|crc)'
#define __ARM_FEATURE_CRC32 1
#define __ARM_NEON 1
请参阅 https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/AArch64-Options.html(或旧 gcc 版本的同一页面)以获取有关如何设置此设置的更多文档。
我猜想 -march=native
会做同样的事情,但该选项目前似乎只针对 x86 架构实现。