Gcc 是否有来自内联汇编的GAS生成指令?

Gcc 是否有来自内联汇编的GAS生成指令?,gcc,inline-assembly,gnu-assembler,arm64,Gcc,Inline Assembly,Gnu Assembler,Arm64,我正在尝试汇编一个使用ARM的CRC指令的文件。汇编程序正在生成错误错误:所选处理器不支持“crc32b w1,w0,w0” 有运行时检查,所以我们使用指令是安全的。该技术在i686和x86_64上运行良好。例如,我可以汇编一个使用英特尔或不使用-mcrc或-msha的文件(在没有这些功能的机器上) 以下是测试用例: $ cat test.cxx #include <arm_neon.h> #define GCC_INLINE_ATTRIB __attribute__((__gnu

我正在尝试汇编一个使用ARM的CRC指令的文件。汇编程序正在生成错误
错误:所选处理器不支持“crc32b w1,w0,w0”

有运行时检查,所以我们使用指令是安全的。该技术在i686和x86_64上运行良好。例如,我可以汇编一个使用英特尔或不使用
-mcrc
-msha
的文件(在没有这些功能的机器上)

以下是测试用例:

$ 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);
}
< >将ASM代码放置在源文件中,并用不同的选项编译是不可行的,因为头文件中也使用了<代码> CRC32 b <代码>。 如何获取气体来组装说明书


GCC的配置和选项是我们尝试这样做的原因。用户不阅读手册,因此他们不会将
-march=armv8-a+crc+crypto-mtune=cortex-a53
添加到
CFLAGS
cxflags

此外,发行版编译到“能力最低”的机器上,因此我们希望硬件加速例程可用。当库由像Linaro这样的发行版提供时,两种代码路径(软件CRC和硬件加速CRC)都将可用


这台机器是一台LeMaker HiKey,它是ARMv8/Aarch64。它有一个带CRC和Crypto的A53处理器(CRC和Crypto在架构下是可选的):

GCC缺少默认情况下预期出现的大多数常用定义:

$ g++ -dM -E - </dev/null | sort | egrep -i '(arm|neon|aarch|asimd)'
#define __aarch64__ 1
#define __AARCH64_CMODEL_SMALL__ 1
#define __AARCH64EL__ 1
和叮当声:

$ 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
气体版本:

$ as -v
GNU assembler version 2.24 (aarch64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.24

这个答案来自王炯的电话。它绕过了GAS的架构要求,与GCC配合良好:

\uuuuuuu内联无符号整数GCC\uuinline\uattrib
CRC32W(无符号整数crc,无符号整数val)
{
#如果1
易失性无符号整数;
asm(“\n”
“\t”“。设置注册表\u x0,0\n”
\t“”。设置注册表项x1,1\n
“\t”“。设置注册表项x2,2\n”
“\t”“。设置注册表项x3,3\n”
“\t”“。设置注册表项x4,4\n”
“\t”“。设置注册表项x5,5\n”
“\t”“。设置注册表项x6,6\n”
“\t”“。设置注册表项x7,7\n”
“\t”“#crc32w%w0,%w1,%w2\n”

“\t”。安装0x1ac04800|(reg_u%2我没有环境来测试这一点,但听起来您需要的是
.arch\u扩展名
。可能直接添加到此asm指令中。根据,这允许您向正在编译的体系结构中增量添加或删除扩展名。如果失败,可能需要添加
.arch名
“顶级"有点“基本”asm?或者我缺少了更多约束?向asm指令中添加这样的指令并不是什么新鲜事。人们从永远以来都在使用它将英特尔风格的汇编程序放入asm指令中。@David-谢谢。我也这么想。唉,A-32、Aarch32和Aarch64不是IA32。我尝试了
.arch\u extension昨天发布了,但它导致了错误。
。arch_extension
需要从2016年开始使用Binutils 2.26。2.26同时支持AARC32和AARC64。另请参见Linaro工具链邮件列表。听起来
#pragma GCC target
比使用(潜在冲突)更合适
.arch
asm在文件范围内。但要记住一些东西。@David-谢谢。
#pragma GCC target
需要GCC 6用于AARC64。还有一个更正:Binutils 2.26是从2014年开始的,而不是2016年。
$ g++ -march=native -dM -E - </dev/null | sort | egrep -i '(arm|neon|aarch|asimd)'
cc1: error: unknown value ‘native’ for -march
$ 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
$ gcc -v
...
gcc version 4.9.2 (Debian/Linaro 4.9.2-10)
$ as -v
GNU assembler version 2.24 (aarch64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.24