일부 어셈블리 코드를 c99 코드베이스에 소개하고자합니다. ARM CPU의 UMULL 명령어를 사용하여 2 개의 uint32_t를 곱하고 결과를 즉시 uint64_t로 가져 오려고합니다.ARM MULL 명령어를 통해 gcc의 uint64_t에서 출력을 생성하려면 어떻게해야합니까?
이제 uint64_t에는 2 개의 레지스터가 필요하므로 출력 및 asm 블록의 제약 조건을 어떻게 지정합니까?
일부 어셈블리 코드를 c99 코드베이스에 소개하고자합니다. ARM CPU의 UMULL 명령어를 사용하여 2 개의 uint32_t를 곱하고 결과를 즉시 uint64_t로 가져 오려고합니다.ARM MULL 명령어를 통해 gcc의 uint64_t에서 출력을 생성하려면 어떻게해야합니까?
이제 uint64_t에는 2 개의 레지스터가 필요하므로 출력 및 asm 블록의 제약 조건을 어떻게 지정합니까?
좋은 질문입니다! 가
uint32_t a, b; uint64_t c; ... c = (uint64_t)a * (uint64_t)b;또는 당신은 당신이 기계 별 ASM을 사용해야 느낀다면, 당신은 갈 수 있습니다 :
다음 코드는 어셈블러에 의지하지 않고는 GCC -O
이상을 사용하여 원하는 출력
uint32_t a, b; uint64_t c;asm ("umull %Q0, %R0, %1, %2" : "=r"(c) : "r"(a), "r"(b));
c
'는의 이름을 등록 처음이다 % Q와 % R은 레지스터 쌍의 하위 32 비트 레지스터와 상위 32 비트 레지스터를 선택합니다. 예제는 gcc/config/arm/arm.md -> umulsidi3을 참조하십시오.
그러나 C로 머물러 있으면 옵티마이 저가 더 많은 일을 할 수있는 기회를 주며 프로그램 독자에게는 더 친절합니다.
umull
명령어는 두 개의 32 비트 레지스터로 결과를 생성합니다.
/* assuming the 64-bit result was stored in "hi" (upper
half) and "lo" (lower half) */
uint64_t v = ((uint64_t)hi << 32) | (uint64_t)lo;
컴파일러 최적화가 왼쪽 시프트는 순수 데이터 라우팅 것을주의해야하고, 결과 코드는 괜찮을 것 : 나는 명시 적으로 그런 일에 64 비트 값을 재 조립하는 것이 좋습니다. 컴파일러 출력을 확인하려면 -S
을 사용하십시오.
답변 해 주셔서 감사합니다. 실제로 C 버전은 내가하고 싶은 일을합니다. % Q 및 % R 구문에 대해 많은 감사를드립니다. 처음에는이를 찾고있었습니다. – user265429