将GCC内联asm(SSE2,SSSE3)转换为MSVC内在函数

时间:2012-01-11 15:14:29

标签: visual-c++ gcc inline-assembly sse2

我正在从VLC借用一些代码到我的视频播放器,用MSVC ++ 2010编写,并且找不到与其内联asms相同的内容,与从GPU内存中提取解码视频帧到常规内存有关。 特别是,我不知道如何翻译这条指令:

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

可以在文件SplitUV中的函数vlc/modules/codec/avcodec/copy.c中看到。

根据MSDN,movq的内在函数为_mm_move_epi64_mm_loadl_epi64_mm_storel_epi64。 但是,它们需要__m128i个参数,如果我向指向__m128i的指针添加1,我将获得16个字节的偏移量,而我需要8个字节。

整个汇编程序代码如下:

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"
 );
 ...
}

我已经开始逐行翻译,现在有了以下代码(不完整):

__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"

下一条指令就是

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

我不知道如何指定8个字节的偏移量。 另外,我有一些疑问,我已经正确翻译了PSHUFB。

非常感谢您的意见和建议。

感谢。

1 个答案:

答案 0 :(得分:2)

只需使用char*的{​​{1}}指针即可增加8,并在调用dst时将其投放到__m128i*,类似于完成_mm_storel_epi64 {{1}} (在该页面上搜索“_mm_storel_epi64”)。