This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: Is the a GCC or GAS issue (or no issue at all)?
- From: "Richard Earnshaw (lists)" <Richard dot Earnshaw at arm dot com>
- To: noloader at gmail dot com, "gcc-help at gcc dot gnu dot org" <gcc-help at gcc dot gnu dot org>
- Date: Wed, 3 May 2017 10:38:18 +0100
- Subject: Re: Is the a GCC or GAS issue (or no issue at all)?
- Authentication-results: sourceware.org; auth=none
- References: <CAH8yC8=CAmXJnzry9kzyiNC1vPrYQQd0GLEAHxuQ3NvnVm9Q6g@mail.gmail.com>
On 19/04/17 16:38, Jeffrey Walton wrote:
> On Intel hardware, we can assemble inline assembly instructions as
> long as the assembler supports it. For example, I can use inline
> assembly to provide AES, CRC, CLMUL and SHA even when compiling with
> just -march=x86_64.
>
> I'm trying to do the same on ARM, but it results in an error. The
> hardware is a LeMaker HiKey. It has an ARMv8/Aarch64 A-53 with CRC and
> Crypto:
>
> $ cat /proc/cpuinfo
> Processor : AArch64 Processor rev 3 (aarch64)
> processor : 0
> ...
> processor : 7
> Features : fp asimd evtstrm aes pmull sha1 sha2 crc32
> CPU implementer : 0x41
> CPU architecture: AArch64
>
> And:
>
> $ g++ --save-temps test.cxx -c
> test.s: Assembler messages:
> test.s:24: Error: selected processor does not support `crc32b w1,w0,w0'
>
> I'm guessing the different behaviors are unintended. My first question
> is, is this expected behavior?
>
> If its unintended, then my second question is, is this a GCC or GAS issue?
>
This is expected behaviour. The CRC instructions are not part of the
base instruction set (ARM-v8), so the assembler is diagnosing that
you've used instructions that are incompatible with
.cpu generic+fp+simd
If you want to fine-tune the instructions available, you'll need to
invoke GCC with either an specific cpu where the instructions exist (eg
cortex-a53) or with a -march directive that enables the additional
instructions (eg -march=armv8+crc).
R.
> ***********
>
> hikey: $ cat test.s
> .cpu generic+fp+simd
> .file "test.cxx"
> .text
> .align 2
> .global main
> .type main, %function
> main:
> .LFB2948:
> .cfi_startproc
> sub sp, sp, #32
> .cfi_def_cfa_offset 32
> str w0, [sp, 12]
> str x1, [sp]
> ldr w0, [sp, 12]
> ldr w1, [sp, 12]
> uxtb w1, w1
> str w0, [sp, 28]
> mov w0, w1
> strb w0, [sp, 27]
> ldr w0, [sp, 28]
> ldrb w1, [sp, 27]
> #APP
> // 10 "test.cxx" 1
> crc32b w1, w0, w0
> // 0 "" 2
> #NO_APP
> str w0, [sp, 20]
> ldr w0, [sp, 20]
> add sp, sp, 32
> .cfi_def_cfa_offset 0
> ret
> .cfi_endproc
> .LFE2948:
> .size main, .-main
> .ident "GCC: (Debian/Linaro 4.9.2-10) 4.9.2"
> .section .note.GNU-stack,"",%progbits
>
> ***********
>
> hikey: $ cat test.cxx
> #include <arm_neon.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 ("crc32b %w2, %w1, %w0" : "=r"(r) : "r"(crc), "r"(v));
> return r;
> }
> #else
> # define CRC32B (a,b) __crc32b(a,b)
> #endif
>
> int main(int argc, char* argv[])
> {
> return CRC32B(argc, argc);
> }
>