J'essaye d'assembler un fichier qui utilise l'instruction CRC d'ARM. L'assembleur produit une erreur Error: selected processor does not support 'crc32b w1,w0,w0'
.Le GAS génère-t-il des instructions à partir de l'assemblage en ligne?
Des contrôles d'exécution sont en place, nous sommes donc en sécurité avec l'instruction. La technique fonctionne bien sur i686 et x86_64. Par exemple, je peux assembler un fichier qui utilise Intel CRC intrinsics ou SHA Intrinsics sans -mcrc
ou -msha
(et sur une machine sans les fonctionnalités).
Voici le cas de test:
$ 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"((unsigned int)v));
return r;
}
#else
// Use the intrinsic
# define CRC32B(a,b) __crc32b(a,b)
#endif
int main(int argc, char* argv[])
{
return CRC32B(argc, argc);
}
Et voici le résultat:
$ g++ test.cxx -c
/tmp/ccqHBPUf.s: Assembler messages:
/tmp/ccqHBPUf.s:23: Error: selected processor does not support `crc32b w1,w0,w0'
Mise en place du code ASM dans un fichier source et la compilation avec différentes options est impossible, car CRC32B
sera utilisé dans les fichiers d'en-tête C++, aussi.
Comment puis-je obtenir le GAS pour assembler l'instruction?
La configuration et les options de GCC sont la raison pour laquelle nous essayons de faire les choses de cette façon. L'utilisateur ne lit pas les manuels, donc ils n'ajouteront pas -march=armv8-a+crc+crypto -mtune=cortex-a53
à CFLAGS
et CXXFLAGS
.
En outre, les distributions sont compilées sur une machine "moins performante", nous voulons donc que les routines d'accélération matérielle soient disponibles. Lorsque la bibliothèque est fournie par une distribution comme Linaro, les deux chemins de code (CRC logiciel et CRC accéléré par le matériel) seront disponibles.
La machine est un LeMaker HiKey, qui est ARMv8/Aarch64. Il dispose d'un processeur A53 avec CRC et Crypto (CRC et Crypto est facultative dans l'architecture):
$ 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
GCC n'a pas plus de l'habituel définit l'on attend d'être présent par défaut:
$ g++ -dM -E - </dev/null | sort | egrep -i '(arm|neon|aarch|asimd)'
#define __aarch64__ 1
#define __AARCH64_CMODEL_SMALL__ 1
#define __AARCH64EL__ 1
aide GCC -march=native
ne fonctionne pas sur ARM:
$ g++ -march=native -dM -E - </dev/null | sort | egrep -i '(arm|neon|aarch|asimd)'
cc1: error: unknown value ‘native’ for -march
Et Clang:
$ clang++ -dM -E - </dev/null | sort | egrep -i '(arm|neon|aarch|asimd)'
#define __AARCH64EL__ 1
#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
#define __aarch64__ 1
version GCC:
$ gcc -v
...
gcc version 4.9.2 (Debian/Linaro 4.9.2-10)
version GAZ:
$ as -v
GNU assembler version 2.24 (aarch64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.24
Je n'ai pas un environnement pour le tester, mais il semble que ce que vous avez besoin est '.arch_extension name'. Peut-être ajouté directement à cette instruction ASM. Selon [docs] (https://sourceware.org/binutils/docs/as/ARM-Directives.html), cela vous permet * d'ajouter ou de supprimer des extensions de façon incrémentielle à l'architecture compilée pour *. A défaut, peut-être ajouter un '.arch name' comme un bit de 'bas niveau' de 'basic' asm? –
Ou y a-t-il d'autres contraintes ici qui me manquent? L'ajout de directives aux instructions ASM comme ceci n'est pas nouveau. Les gens l'ont utilisé pour mettre l'assembleur de style Intel dans des instructions asm depuis toujours. –
@David - Merci. J'ai pensé dans le même sens. Hélas, A-32, Aarch32 et Aarch64 ne sont pas IA32. J'ai essayé '.arch_extension' hier, mais cela a entraîné des erreurs. '.arch_extension' a besoin de Binutils 2.26 à partir de 2016. 2.26 supporte Aarch32 et Aarch64. Voir aussi [Erreur: pseudo-op: '.arch_extension'] (https://lists.linaro.org/pipermail/linaro-toolchain/2017-April/006112.html) dans la liste de diffusion Linaro Toolchain. – jww