ARM의 CRC 명령어를 사용하는 파일을 어셈블하려고합니다. 어셈블러에서 Error: selected processor does not support 'crc32b w1,w0,w0'
이라는 오류가 발생합니다.GAS가 인라인 어셈블리에서 명령어를 생성합니까?
런타임 검사가 있으므로 실행시 안전합니다. 이 기술은 i686 및 x86_64에서 정상적으로 작동합니다. 예를 들어 또는 SHA Intrinsics을 사용하는 파일을 -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);
}
을 그리고 여기 결과입니다 CRC32B
이되기 때문에 가능한
$ g++ test.cxx -c
/tmp/ccqHBPUf.s: Assembler messages:
/tmp/ccqHBPUf.s:23: Error: selected processor does not support `crc32b w1,w0,w0'
소스 파일에 ASM 코드를 배치하고 다른 옵션과 함께 컴파일되지 않는다 C++ 헤더 파일에도 사용됩니다.
GAS로 명령어를 어셈블하려면 어떻게해야합니까?
GCC의 구성 및 옵션이 이러한 방식으로 작업을 수행하는 이유입니다. 사용자는 설명서를 읽지 않으므로 -march=armv8-a+crc+crypto -mtune=cortex-a53
을 CFLAGS
및 CXXFLAGS
에 추가하지 않습니다.
또한 배포판은 "성능이 가장 낮은"컴퓨터로 컴파일되므로 하드웨어 가속 루틴을 사용할 수 있기를 원합니다. 라이브러리가 Linaro와 같은 배포판에서 제공되면 두 코드 경로 (소프트웨어 CRC 및 하드웨어 가속 CRC)를 사용할 수 있습니다.
기계는 LeMaker HiKey이며 ARMv8/Aarch64입니다. 그것은 CRC 및 암호화를 가진 A53 프로세서가 (CRC 및 암호화는 아키텍처에 따라 선택 사항입니다) :
$ g++ -dM -E - </dev/null | sort | egrep -i '(arm|neon|aarch|asimd)'
#define __aarch64__ 1
#define __AARCH64_CMODEL_SMALL__ 1
#define __AARCH64EL__ 1
사용 :
$ 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는 평소의 대부분은 하나가 기본적으로 존재하는 것으로 예상하고 정의합니다 부족 GCC의 -march=native
ARM에서 작동하지 않습니다 :
$ 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 버전 :
$ 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
나는이를 테스트 할 수있는 환경을 가지고 있지 않지만, 그것은 당신이 필요 같은 소리는 .arch_extension의 name''이다. 아마도이 asm 명령에 직접 추가되었을 것입니다. [docs] (https://sourceware.org/bin/tools/docs/as/ARM-Directives.html)에 따르면, *를 위해 컴파일되는 아키텍처에 확장을 추가하거나 제거 할 수 있습니다. 아마도'.arch name'을 '기본'asm의 "최상위 레벨"비트로 추가하는 것에 실패했을 것입니다. –
여기에 더 많은 제약이 있습니까? 이와 같이 asm 명령에 지시문을 추가하는 것은 새로운 것이 아닙니다. 사람들은 인텔 스타일 어셈블러를 영원히 asm 명령어에 넣기 위해이 명령어를 사용 해왔다. –
@David - 감사합니다. 나는 같은 줄로 생각했다. Alas, A-32, Aarch32 및 Aarch64는 IA32가 아닙니다. 어제'.arch_extension'을 시도했지만 오류가 발생했습니다. '.arch_extension'은 2016 년부터 Binutils 2.26을 필요로합니다. 2.26은 Aarch32와 Aarch64를 모두 지원합니다. Linaro Toolchain 메일 링리스트의 [Error : unknown pseudo-op :'.arch_extension '] (https://lists.linaro.org/pipermail/linaro-toolchain/2017-April/006112.html)도 참조하십시오. – jww