On Wed, Apr 19, 2017 at 9:57 PM, Jim Wilson jim.wilson@linaro.org wrote:
On Wed, Apr 19, 2017 at 12:38 PM, Jeffrey Walton noloader@gmail.com wrote:
According to [1], I can use ".arch_extension" to enable it. According to [2], ".arch_extension" is available in GCC 4.6 and GAS 2.21. My version of Linaro provides GCC 4.9.2 and GAS 2.25.90. I can also duplicate the issue on GCC113 (compiel farm), which provides GCC 4.8 and GAS 2.24.
ARM is a little ambiguous. It turns out that arch_extension was added to the arm (32-bit) port in 2010, but wasn't added to the aarch64 (64-bit) port until 2014. So you need binutils-2.26 in order to use arch_extension pseudo-op with the aarch64 toolchain.
Meanwhile, you might try looking at the arm_neon.h header file for your gcc version. Though it apperas in gcc-4.9.2 there is only a predefined macro __ARM_FEATURE_CRYPTO that you can use, and nothing for CRC. GCC 5.x adds a __ARM_FEATURE_CRC32 predefined macro that you could use.
With gcc 6, the arm_neon.h file uses #pragma GCC push_options #pragma GCC target ("+nothing+crypto") ... #pragma GCC pop_options to enable crypto support. You can do something similar with crc, you probably want to use "+onthing+crc" if you only want crc support enalbed, or "+simd+crc" if you want both simd and crc support enabled for instance.
The GCC aarch64 port does not use the arch64_extension support in binutils.
I think the linux kernel just puts functions that need crc support in different files, so that those files can be compiled with crc support enabled via -mcpu=generic+crc.
Ah, thanks Jim. That would have taken me a long time to discover.
I've had some success with something similar to the kernel method. The program below works with GCC 4.8, 4.9 and later.
The thing I am not sure about is saving and restoring the cpu. The AS manual states "Specifying .cpu clears any previously selected architecture extensions". But arch_extensions does not seem to work, so I guess its a moot point. Also, the manual only discusses '.set' in the context of MIPS. The program below does not produce a warning or error. I am not sure if its doing what's expected.
I'm trying to avoid adding an additional source file for each source file that uses NEON, CRC or CRYPTO. We are a C++ project, and it means moving functions out of headers and into source files. Additionally, we have 175 source files (plus headers), and the strategy could double the counts.
Our choices are kind of crummy at this point...
Jeff
$ cat test.cxx #include <arm_neon.h> #include <arm_acle.h>
#define GCC_INLINE_ATTRIB __attribute__((__gnu_inline__, __always_inline__, __artificial__))
#if defined(__GNUC__) && !defined(__ARM_FEATURE_CRC32) __inline unsigned int GCC_INLINE_ATTRIB CRC32B(unsigned int crc, unsigned char v) { unsigned int r; asm (".set push, .cpu \n" ".cpu generic+crc \n" "crc32w %w2, %w1, %w0 \n" ".set pop, .cpu \n" : "=r"(r) : "r"(crc), "r"((unsigned int)v)); return r; } #else // just use the intrinsic # define CRC32B(a,b) __crc32b(a,b) #endif
int main(int argc, char* argv[]) { return CRC32B(argc, argc); }