2012-01-11 5 views
1

VLC에서 비디오 변환기로 일부 코드를 빌려 왔는데 MSVC++ 2010로 작성되었으며 디코딩 된 비디오 프레임을 추출하는 것과 관련하여 인라인 asms와 같은 것을 찾을 수 없습니다. GPU 메모리를 기본 메모리에 연결합니다. 특히, 내가이 명령을 번역하는 방법을 모른다 : 파일 vlc/modules/codec/avcodec/copy.c의 기능 SplitUV에서 볼 수 있습니다GCC 인라인 asm (SSE2, SSSE3)을 MSVC 내장 함수로 변환

movq %%xmm1, 8(%[dst1]) 

.

MSDN에 따르면 movq에 대한 내장 함수는 _mm_move_epi64, _mm_loadl_epi64_mm_storel_epi64입니다. 그러나 그들은 __m128i 인수가 필요하며, __m128i에 대한 포인터에 1을 더하면 8 바이트가 필요한 반면 16 바이트의 오프셋을 가져옵니다.

전체 어셈블러 코드는 다음과 같다 :

__m128i x0, x1, x2, x3, x7; 
__m128i *pshuffle128 = (__m128i *)shuffle; 
__m128i *pSrc = (__m128i *)src; 

for (x = 0; x < (width & ~31); x += 32) { 
    __m128i *dst1 = (__m128i *)dstu + x; 
    __m128i *dst2 = (__m128i *)dstv + x; 
    x7 = _mm_loadu_si128(pshuffle128); // "movdqu (%[shuffle]), %%xmm7\n" 
    x0 = _mm_load_si128(pSrc + 0);  // "movdqa 0(%[src]), %%xmm0\n" 
    x1 = _mm_load_si128(pSrc + 1);  // "movdqa 16(%[src]), %%xmm1\n" 
    x2 = _mm_load_si128(pSrc + 2);  // "movdqa 32(%[src]), %%xmm2\n" 
    x3 = _mm_load_si128(pSrc + 3);  // "movdqa 48(%[src]), %%xmm3\n" 
    x0 = _mm_shuffle_epi8(x0, x7);  // "pshufb %%xmm7, %%xmm0\n" 
    x1 = _mm_shuffle_epi8(x1, x7);  // "pshufb %%xmm7, %%xmm1\n" 
    x2 = _mm_shuffle_epi8(x2, x7);  // "pshufb %%xmm7, %%xmm2\n" 
    x3 = _mm_shuffle_epi8(x3, x7);  // "pshufb %%xmm7, %%xmm3\n" 
    _mm_storel_epi64(dst1 + 0, x0);  // "movq %%xmm0, 0(%[dst1])\n" 

다음 명령 : 라인으로

for (x = 0; x < (width & ~31); x += 32) { 
    asm volatile (
    "movdqu (%[shuffle]), %%xmm7\n" 
    "movdqa 0(%[src]), %%xmm0\n" 
    "movdqa 16(%[src]), %%xmm1\n" 
    "movdqa 32(%[src]), %%xmm2\n" 
    "movdqa 48(%[src]), %%xmm3\n" 
    "pshufb %%xmm7, %%xmm0\n" 
    "pshufb %%xmm7, %%xmm1\n" 
    "pshufb %%xmm7, %%xmm2\n" 
    "pshufb %%xmm7, %%xmm3\n" 
    "movq %%xmm0, 0(%[dst1])\n" 
    "movq %%xmm1, 8(%[dst1])\n" 
    "movhpd %%xmm0, 0(%[dst2])\n" 
    "movhpd %%xmm1, 8(%[dst2])\n" 
    "movq %%xmm2, 16(%[dst1])\n" 
    "movq %%xmm3, 24(%[dst1])\n" 
    "movhpd %%xmm2, 16(%[dst2])\n" 
    "movhpd %%xmm3, 24(%[dst2])\n" 
    : : [dst1]"r"(&dstu[x]), [dst2]"r"(&dstv[x]), [src]"r"(&src[2*x]), 
     [shuffle]"r"(shuffle) 
    : "memory" 
); 
... 
} 

내가 번역을 시작했습니다, 선, 이제 (불완전) 다음 코드가에 의해 그 될 것입니다

movq %%xmm1, 8(%[dst1]) 

및 8 바이트의 오프셋을 지정하는 방법을 모르겠습니다. 또한 PSHUFB를 올바르게 번역했다고 의심합니다.

의견과 제안에 매우 감사드립니다.

감사합니다.

+0

저는이 물건에 대한 전문가가 아니지만, 두 컴파일러가 공유하는 내장 함수가 있다고 생각합니다.이 두 가지 컴파일러를 사용하는 것이 좋습니다. –

+0

아니, 그런 건 없어. x86 용 MSVC는 인라인 asm을 사용할 수도 있지만 x64 용 MSVC는 사용할 수 없습니다. – wl2776

+0

한편, 2 개의 오류가 있습니다. (1) dstu와 dstv (2)를 전환했습니다. pSrc는 값 (__m128i *) (src + 2 * x)에 사이클 본문에 지정되어야합니다. – wl2776

답변

2

은 단순히 당신이 8 씩 증가하고이 here (해당 페이지의 "_mm_storel_epi64"에 대한 검색)을 어떻게하는지 유사 _mm_storel_epi64에 호출 __m128i*로 전송할 수 있습니다 dst에 대한 char* 포인터를 사용합니다.

+0

감사합니다. – wl2776

관련 문제