Я одалживаю некоторый код из VLC для моего видеопроигрывателя, написанный на MSVC ++ 2010, и не могу найти эквивалент его встроенным ассамам, связанным с извлечением декодированного видеокадра из памяти графического процессора в обычную память.В частности, я не знаю, как перевести эту инструкцию:
movq %%xmm1, 8(%[dst1])
, которую можно увидеть в функции SplitUV
в файле vlc/modules/codec/avcodec/copy.c
.
Согласно MSDN, встроенные функциидля movq
есть _mm_move_epi64
, _mm_loadl_epi64
и _mm_storel_epi64
.Тем не менее, они требуют __m128i
аргументов, и если я добавлю 1 к указателю к __m128i
, я получу смещение 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.
Буду очень признателен за комментарии и предложения.
Спасибо.