Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
424 views
in Technique[技术] by (71.8m points)

c++ - Why is __ARM_FEATURE_CRC32 not being defined by the compiler?

I've been working on this issue for some time now, and I hope someone can point out my mistake. I guess I can no longer see the forest through the trees.

I have a LeMaker HiKey dev board I use for testing. Its AArch64, so its has NEON and the other cpu features like AES, SHA and CRC32:

$ cat /proc/cpuinfo 
Processor   : AArch64 Processor rev 3 (aarch64)
...
Features    : fp asimd evtstrm aes pmull sha1 sha2 crc32 
...

When I attempt to compile a program:

$ 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
}

It results in the following:

$ 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.

A grep of the file system reveals arm_acle.h is in fact the header:

$ grep -IR '__crc32' /usr/lib
/usr/lib/gcc/.../include/arm_acle.h:__crc32b (uint32_t __a, uint8_t __b)
...

And according to ARM? C Language Extensions, Section 9.7 CRC32 Intrinsics, the missing symbols are suppose be present when __ARM_FEATURE_CRC32 is defined. Inspecting arm_acle.h confirms it.

For completeness, I tried compiling with -march=native, but the compiler rejected it.

Why is __ARM_FEATURE_CRC32 not being defined by the compiler?

What can I do to get the program to compile with the native features available on the board?


$ 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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

As for why this feature isn't enabled by default; this is an optional feature not present in the baseline ABI that your compiler targets, i.e. the binaries that your compiler produces are expected to be able to run on devices lacking the CRC feature.

At least for gcc, you can enable this feature with the -march modifier crc, like this:

$ gcc -dM -E - -march=armv8-a+crc < /dev/null | egrep -i '(arm|neon|acle|crc)'
#define __ARM_FEATURE_CRC32 1
#define __ARM_NEON 1

See https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/AArch64-Options.html (or the same page for older gcc versions) for more docs on how to set this.

I guess one could expect -march=native to do the same, but that option currently only seems to be implemented for x86 architectures.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...