컴파일러가 내 C 코드에서 인라인 어셈블리를 매개 변수화하여 레지스터를 자동으로 선택하도록하고 싶습니다.하지만 몇 가지 문제가 있습니다. 누구가 잘못 될지 말해 줄 수 있습니까? 내가 주석 처리 한 코드를 사용하면 (% xmm0과의 제휴를 강요 함) 컴파일하여 예상 결과를 얻습니다.(SSE4) gcc에서 인라인 어셈블리로 blendvpd 사용 시도
또한/tmp/ccJxmSbm.s: Assembler messages:
/tmp/ccJxmSbm.s:81: Error: the first operand of `blendvpd' must be `%xmm0'
나는의 printf 문을 제거 이외의 아무것도 할 경우, 코드 블록이 성공적으로 너무 컴파일 : 내가 떠날 경우 그것은 여기에 기록 된대로, 내가 컴파일러 오류가 밖으로 댓글을 달았습니다. 따라서 printf 호출을 준비하기 위해 매개 변수를 움직이는 것과 관련이 있습니다. 나는 명시 적으로 % xmm0을 사용하도록되어있는 "Yz"제약 조건을 넣었지만, 그것이 존중되지 않는 것처럼 보입니다.
#include <stdio.h>
const unsigned long long myConst[2] = {0x0000000000000000,0xffffffffffffffff};
const unsigned long long myConst2[2] = {0x0000000000000000,0x1111111111111111};
const unsigned long long myConst3[2] = {0xabcdef,0x0000000000000000};
#define ASSIGN_CONST128(val, const) \
val = *((__uint128_t *)const);
int main(void)
{
register __uint128_t regVal1 /* asm("%xmm0") */ ;
register __uint128_t regVal2;
register __uint128_t regVal3;
ASSIGN_CONST128(regVal1, myConst);
ASSIGN_CONST128(regVal2, myConst2);
ASSIGN_CONST128(regVal3, myConst3);
asm("blendvpd %[mask], %[val1], %[val2]" :
[val2] "+x" (regVal3) :
[mask] "Yz" (regVal1),
[val1] "x" (regVal2));
printf("REGVAL1: %016llx%016llx (original=%016llx%016llx)\n"
"REGVAL2: %016llx%016llx (original=%016llx%016llx)\n"
"REGVAL3: %016llx%016llx (original=%016llx%016llx)\n",
(unsigned long long)(regVal1>>64), (unsigned long long)regVal1,
myConst[1], myConst[0],
(unsigned long long)(regVal2>>64), (unsigned long long)regVal2,
myConst2[1], myConst2[0],
(unsigned long long)(regVal3>>64), (unsigned long long)regVal3,
myConst3[1], myConst3[0]);
// Expected result:
// REGVAL1: ffffffffffffffff0000000000000000 (original=ffffffffffffffff0000000000000000)
// REGVAL2: 11111111111111110000000000000000 (original=11111111111111110000000000000000)
// REGVAL3: 1111111111111111abcdef (original=0000000000000000abcdef)
}
내가 어떤 생각을 주셔서 감사합니다 : 여기
문제의 코드입니다.
'__uint128_t'는'__m128d'와 다릅니다. 참고로,이 코드에서는'icc'가 충돌하고'clang'은 컴파일을 거부합니다. –
내 부분에 순수한 무지. __m128i로 변경했을 때 (실제로 정수형이 필요하다면 차이가 생깁니다.) 컴파일러에서 손을 덜 잡는 것에 눈이.니다. 이 유형의 객체와의 모든 상호 작용이 현재 어셈블리에서 완료되어야하는 것처럼 보입니다. 반드시 문제는 아니지만 그것을 파악하는 것은 어려웠습니다. – Marty
그래서 이제는 두 개의 "부호없는 long long"임시 변수를 만들고 movlpd/movhpd를 사용하여 xmmX 레지스터 내용을 이동시킵니다. 그리고 나서 "unsigned long long"변수에 대해 printf를 할 수 있습니다. – Marty