2016-07-24 9 views
1

64 비트 Aarch64 장치에서 ARM에서 GCC 인라인 어셈블러를 배우고 있습니다. 내가 이해하지 못하는 오류 메시지가 나타납니다. GCC의 인라인 어셈블러에서의 오류 메시지가 :Error : 피연산자 1에서 벡터 레지스터를 잘못 사용했습니다.

$ cat test.cc 
#include <arm_neon.h> 
int main(int argc, char* argv[]) 
{ 
    uint64x2_t r = {0,0}, a = {2,4}; 
    __asm__ __volatile__ 
    (
     "pmull %0, %1, %1;" 
     : "=w" (r) 
     : "w" (a), "w" (a) 
     : "cc" 
    ); 

    return (int)r[0]; 
} 

"w"Aarch64 machine constraint입니다 :

$ gcc -DNDEBUG -g3 -O1 -march=armv8-a+crc+crypto test.cc -o test.exe 
/tmp/ccCHOWrn.s: Assembler messages: 
/tmp/ccCHOWrn.s:19: Error: invalid use of vector register at operand 1 -- `pmull v0,v0,v0' 

샘플 프로그램은 단순히 다항식 곱셈을 행사하려고합니다. 이 경우 "부동 소수점 또는 SIMD 벡터 레지스터"라고 말하면인데, 이는 내가 원하는 것으로 보인다.

uint64x2_t 유형은 일반적으로 ARM 내장 함수와 함께 사용됩니다. 하지만 그 128 비트 타입과 SIMD 코 프로세서를 위해 정렬, 그래서 그것은 샘플을위한 좋은 선택 같았다.

장치는 Linaro 이미지 및 GCC 4.9.2 컴파일러가있는 LeMaker HiKey입니다. 이 버그는 몇 년 전에 고쳐졌지만, 관련이 있는지 확실하지 않습니다. fbb ftbfs on arm64.

나는 두 가지 질문이 있습니다

  • 오류가 무엇을 의미합니까, 내가 그것을 어떻게 해결할 수 있습니까?
  • pmullpmull2에 내장 함수가 있습니까?

나는 배치 지정자를 추가하는 시도,하지만 난 구문을 알고하지 않기 때문에 그것이 작동하지 않았다 놀랐 아니에요 :


$ gcc -DNDEBUG -g3 -O1 -march=armv8-a+crc+crypto test.cc -o test.exe 
test.cc: In function ‘int main(int, char**)’: 
test.cc:8:15: error: expected ‘)’ before numeric constant 
     : "=w" (r.1q) 
      ^
test.cc:8:15: error: expected ‘)’ before numeric constant 
test.cc:9:6: error: expected ‘;’ before ‘:’ token 
     : "w" (a.1d), "w" (a.1d) 
    ^
test.cc:9:6: error: expected primary-expression before ‘:’ token 
가 나는 또한 더블 추가하는 시도를 어셈블러에서 .att_stntax.intel_syntax :

(으)로 문제가 발생하여 백분율 기호 (예 : %%0%%1) 10
$ gcc -DNDEBUG -g3 -O1 -march=armv8-a+crc+crypto test.cc -o test.exe 
/tmp/ccPpnvUP.s: Assembler messages: 
/tmp/ccPpnvUP.s:19: Error: operand 1 should be a SIMD vector register -- `pmull %0,%1,%1' 

답변

1

What does the error mean, and how can I fix it?

나는 제약 조건 위반이 발생했다는 것을 의미한다고 생각합니다.

$ cat test.cc 
#include <arm_neon.h> 
#include <stdio.h> 
int main(int argc, char* argv[]) 
{ 
    uint64x2_t r = {0,0}, a = {2,4}; 
    __asm__ __volatile__ 
    (
    "pmull %0.1q, %1.1d, %1.1d;" 
    : "=w" (r) 
    : "w" (a[0]), "w" (a[1]) 
    : "cc" 
    ); 

    fprintf(stdout, "%d, %d\n", r[0], r[1]); 
    return 0; 
} 

그리고 :

$ gcc -march=armv8-a+crc+crypto test.cc -o test.exe 
$ ./test.exe 
4, 0 

And : 다음 트릭을 수행 것 같습니다

$ gdb -batch -ex 'disassemble main' ./test.exe 
Dump of assembler code for function main: 
    0x00000000004005f0 <+0>: stp x29, x30, [sp,#-64]! 
    0x00000000004005f4 <+4>: mov x29, sp 
    0x00000000004005f8 <+8>: str w0, [x29,#28] 
    0x00000000004005fc <+12>: str x1, [x29,#16] 
    0x0000000000400600 <+16>: movi v0.4s, #0x0 
    0x0000000000400604 <+20>: mov x0, v0.d[0] 
    0x0000000000400608 <+24>: mov x1, v0.d[1] 
    0x000000000040060c <+28>: fmov d0, x0 
    0x0000000000400610 <+32>: mov v0.d[1], x1 
    0x0000000000400614 <+36>: str q0, [x29,#48] 
    0x0000000000400618 <+40>: ldr q0, 0x4006a0 
    0x000000000040061c <+44>: mov x0, v0.d[0] 
    0x0000000000400620 <+48>: mov x1, v0.d[1] 
    0x0000000000400624 <+52>: fmov d0, x0 
    0x0000000000400628 <+56>: mov v0.d[1], x1 
    0x000000000040062c <+60>: str q0, [x29,#32] 
    0x0000000000400630 <+64>: ldr x0, [x29,#32] 
    0x0000000000400634 <+68>: ldr x1, [x29,#40] 
    0x0000000000400638 <+72>: fmov d0, x0 
    0x000000000040063c <+76>: fmov d1, x1 
    0x0000000000400640 <+80>: pmull v0.1q, v0.1d, v0.1d 
    0x0000000000400644 <+84>: mov x0, v0.d[0] 
    0x0000000000400648 <+88>: mov x1, v0.d[1] 
    0x000000000040064c <+92>: fmov d0, x0 
    0x0000000000400650 <+96>: mov v0.d[1], x1 
    0x0000000000400654 <+100>: str q0, [x29,#48] 
    0x0000000000400658 <+104>: adrp x0, 0x410000 
    0x000000000040065c <+108>: add x0, x0, #0x9f0 
    0x0000000000400660 <+112>: ldr x4, [x0] 
    0x0000000000400664 <+116>: ldr x1, [x29,#48] 
    0x0000000000400668 <+120>: ldr x2, [x29,#56] 
    0x000000000040066c <+124>: adrp x0, 0x400000 
    0x0000000000400670 <+128>: add x0, x0, #0x748 
    0x0000000000400674 <+132>: mov x3, x2 
    0x0000000000400678 <+136>: mov x2, x1 
    0x000000000040067c <+140>: mov x1, x0 
    0x0000000000400680 <+144>: mov x0, x4 
    0x0000000000400684 <+148>: bl 0x4004a0 <[email protected]> 
    0x0000000000400688 <+152>: mov w0, #0x0     // #0 
    0x000000000040068c <+156>: ldp x29, x30, [sp],#64 
    0x0000000000400690 <+160>: ret 
End of assembler dump. 

Is there an intrinsic for pmull and pmull2?

일부 내장 함수가있는 것 같습니다 :

$ gcc -march=armv8-a+crc+crypto -E test.cc | grep -B 4 pmull 
__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) 
vmull_high_p8 (poly8x16_t a, poly8x16_t b) 
{ 
    poly16x8_t result; 
    __asm__ ("pmull2 %0.8h,%1.16b,%2.16b" 
-- 
__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__)) 
vmull_p8 (poly8x8_t a, poly8x8_t b) 
{ 
    poly16x8_t result; 
    __asm__ ("pmull %0.8h, %1.8b, %2.8b" 
-- 
static __inline poly128_t 
vmull_p64 (poly64_t a, poly64_t b) 
{ 
    return 
    __builtin_aarch64_crypto_pmulldi_ppp (a, b); 
-- 

static __inline poly128_t 
vmull_high_p64 (poly64x2_t a, poly64x2_t b) 
{ 
    return __builtin_aarch64_crypto_pmullv2di_ppp (a, b); 
+0

즉, 컴파일러에게 SIMD 레지스터를 요청하면 SIMD 레지스터가 제공됩니다. 명령어의 _rest_를 적절하게 지정해야합니다. 구문이 확실히 분명하지는 않습니다. 데이터 유형이 사용자가 아닌 모든 피연산자에 대해 지정해야하는 명령어의 고유 한 부분입니다. 당신이 상상할 수있는 니모닉 (나는 초기 애플 어셈블러가 후자의 형식을 사용하는 자신의 구문을 구현하여 많은 혼란을 겪었던 것을 기억한다). – Notlikethat