Я уже давно занимаюсь этой проблемой, и я надеюсь, что кто-то может указать на мою ошибку. Наверное, я больше не могу видеть лес через деревья.Почему __ARM_FEATURE_CRC32 не определяется компилятором?
У меня есть плата LeMaker HiKey, которую я использую для тестирования. Его AArch64, поэтому его имеет неон и другие функции центрального процессора, как 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 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
Спасибо @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 - gcc для ARM определяет __ARM_FEATURE_SIMD32, но обеспечивает встроенные свойства SIMD32 (ARMv6)] (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57989) , Из ошибки: * «Внедрение ACLE - это незавершенное производство. К сожалению, этот параметр был добавлен до того, как были встроены функции ...» *. Похоже, что они дергали все связанные с ARM определения. – jww