mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-26 01:02:33 +00:00
swscale: MMX optim of hscale16()
code is based on existing 8bit MMX code Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
895b616146
commit
d9d56036f3
@ -2246,6 +2246,149 @@ static inline void RENAME(hScale16)(int16_t *dst, int dstW, const uint16_t *src,
|
||||
const int16_t *filter, const int16_t *filterPos, long filterSize, int shift)
|
||||
{
|
||||
int i, j;
|
||||
#if COMPILE_TEMPLATE_MMX
|
||||
assert(filterSize % 4 == 0 && filterSize>0);
|
||||
if (filterSize==4 && shift<15) { // Always true for upscaling, sometimes for down, too.
|
||||
x86_reg counter= -2*dstW;
|
||||
filter-= counter*2;
|
||||
filterPos-= counter/2;
|
||||
dst-= counter/2;
|
||||
__asm__ volatile(
|
||||
"movd %5, %%mm7 \n\t"
|
||||
#if defined(PIC)
|
||||
"push %%"REG_b" \n\t"
|
||||
#endif
|
||||
"push %%"REG_BP" \n\t" // we use 7 regs here ...
|
||||
"mov %%"REG_a", %%"REG_BP" \n\t"
|
||||
".p2align 4 \n\t"
|
||||
"1: \n\t"
|
||||
"movzwl (%2, %%"REG_BP"), %%eax \n\t"
|
||||
"movzwl 2(%2, %%"REG_BP"), %%ebx \n\t"
|
||||
"movq (%1, %%"REG_BP", 4), %%mm1 \n\t"
|
||||
"movq 8(%1, %%"REG_BP", 4), %%mm3 \n\t"
|
||||
"movq (%3, %%"REG_a", 2), %%mm0 \n\t"
|
||||
"movq (%3, %%"REG_b", 2), %%mm2 \n\t"
|
||||
"pmaddwd %%mm1, %%mm0 \n\t"
|
||||
"pmaddwd %%mm2, %%mm3 \n\t"
|
||||
"movq %%mm0, %%mm4 \n\t"
|
||||
"punpckldq %%mm3, %%mm0 \n\t"
|
||||
"punpckhdq %%mm3, %%mm4 \n\t"
|
||||
"paddd %%mm4, %%mm0 \n\t"
|
||||
"psrad %%mm7, %%mm0 \n\t"
|
||||
"packssdw %%mm0, %%mm0 \n\t"
|
||||
"movd %%mm0, (%4, %%"REG_BP") \n\t"
|
||||
"add $4, %%"REG_BP" \n\t"
|
||||
" jnc 1b \n\t"
|
||||
|
||||
"pop %%"REG_BP" \n\t"
|
||||
#if defined(PIC)
|
||||
"pop %%"REG_b" \n\t"
|
||||
#endif
|
||||
: "+a" (counter)
|
||||
: "c" (filter), "d" (filterPos), "S" (src), "D" (dst), "m"(shift)
|
||||
#if !defined(PIC)
|
||||
: "%"REG_b
|
||||
#endif
|
||||
);
|
||||
} else if (filterSize==8 && shift<15) {
|
||||
x86_reg counter= -2*dstW;
|
||||
filter-= counter*4;
|
||||
filterPos-= counter/2;
|
||||
dst-= counter/2;
|
||||
__asm__ volatile(
|
||||
"movd %5, %%mm7 \n\t"
|
||||
#if defined(PIC)
|
||||
"push %%"REG_b" \n\t"
|
||||
#endif
|
||||
"push %%"REG_BP" \n\t" // we use 7 regs here ...
|
||||
"mov %%"REG_a", %%"REG_BP" \n\t"
|
||||
".p2align 4 \n\t"
|
||||
"1: \n\t"
|
||||
"movzwl (%2, %%"REG_BP"), %%eax \n\t"
|
||||
"movzwl 2(%2, %%"REG_BP"), %%ebx \n\t"
|
||||
"movq (%1, %%"REG_BP", 8), %%mm1 \n\t"
|
||||
"movq 16(%1, %%"REG_BP", 8), %%mm3 \n\t"
|
||||
"movq (%3, %%"REG_a", 2), %%mm0 \n\t"
|
||||
"movq (%3, %%"REG_b", 2), %%mm2 \n\t"
|
||||
"pmaddwd %%mm1, %%mm0 \n\t"
|
||||
"pmaddwd %%mm2, %%mm3 \n\t"
|
||||
|
||||
"movq 8(%1, %%"REG_BP", 8), %%mm1 \n\t"
|
||||
"movq 24(%1, %%"REG_BP", 8), %%mm5 \n\t"
|
||||
"movq 8(%3, %%"REG_a", 2), %%mm4 \n\t"
|
||||
"movq 8(%3, %%"REG_b", 2), %%mm2 \n\t"
|
||||
"pmaddwd %%mm1, %%mm4 \n\t"
|
||||
"pmaddwd %%mm2, %%mm5 \n\t"
|
||||
"paddd %%mm4, %%mm0 \n\t"
|
||||
"paddd %%mm5, %%mm3 \n\t"
|
||||
"movq %%mm0, %%mm4 \n\t"
|
||||
"punpckldq %%mm3, %%mm0 \n\t"
|
||||
"punpckhdq %%mm3, %%mm4 \n\t"
|
||||
"paddd %%mm4, %%mm0 \n\t"
|
||||
"psrad %%mm7, %%mm0 \n\t"
|
||||
"packssdw %%mm0, %%mm0 \n\t"
|
||||
"movd %%mm0, (%4, %%"REG_BP") \n\t"
|
||||
"add $4, %%"REG_BP" \n\t"
|
||||
" jnc 1b \n\t"
|
||||
|
||||
"pop %%"REG_BP" \n\t"
|
||||
#if defined(PIC)
|
||||
"pop %%"REG_b" \n\t"
|
||||
#endif
|
||||
: "+a" (counter)
|
||||
: "c" (filter), "d" (filterPos), "S" (src), "D" (dst), "m"(shift)
|
||||
#if !defined(PIC)
|
||||
: "%"REG_b
|
||||
#endif
|
||||
);
|
||||
} else if (shift<15){
|
||||
const uint16_t *offset = src+filterSize;
|
||||
x86_reg counter= -2*dstW;
|
||||
//filter-= counter*filterSize/2;
|
||||
filterPos-= counter/2;
|
||||
dst-= counter/2;
|
||||
__asm__ volatile(
|
||||
"movd %7, %%mm7 \n\t"
|
||||
".p2align 4 \n\t"
|
||||
"1: \n\t"
|
||||
"mov %2, %%"REG_c" \n\t"
|
||||
"movzwl (%%"REG_c", %0), %%eax \n\t"
|
||||
"movzwl 2(%%"REG_c", %0), %%edx \n\t"
|
||||
"mov %5, %%"REG_c" \n\t"
|
||||
"pxor %%mm4, %%mm4 \n\t"
|
||||
"pxor %%mm5, %%mm5 \n\t"
|
||||
"2: \n\t"
|
||||
"movq (%1), %%mm1 \n\t"
|
||||
"movq (%1, %6), %%mm3 \n\t"
|
||||
"movq (%%"REG_c", %%"REG_a", 2), %%mm0 \n\t"
|
||||
"movq (%%"REG_c", %%"REG_d", 2), %%mm2 \n\t"
|
||||
"pmaddwd %%mm1, %%mm0 \n\t"
|
||||
"pmaddwd %%mm2, %%mm3 \n\t"
|
||||
"paddd %%mm3, %%mm5 \n\t"
|
||||
"paddd %%mm0, %%mm4 \n\t"
|
||||
"add $8, %1 \n\t"
|
||||
"add $8, %%"REG_c" \n\t"
|
||||
"cmp %4, %%"REG_c" \n\t"
|
||||
" jb 2b \n\t"
|
||||
"add %6, %1 \n\t"
|
||||
"movq %%mm4, %%mm0 \n\t"
|
||||
"punpckldq %%mm5, %%mm4 \n\t"
|
||||
"punpckhdq %%mm5, %%mm0 \n\t"
|
||||
"paddd %%mm0, %%mm4 \n\t"
|
||||
"psrad %%mm7, %%mm4 \n\t"
|
||||
"packssdw %%mm4, %%mm4 \n\t"
|
||||
"mov %3, %%"REG_a" \n\t"
|
||||
"movd %%mm4, (%%"REG_a", %0) \n\t"
|
||||
"add $4, %0 \n\t"
|
||||
" jnc 1b \n\t"
|
||||
|
||||
: "+r" (counter), "+r" (filter)
|
||||
: "m" (filterPos), "m" (dst), "m"(offset),
|
||||
"m" (src), "r" ((x86_reg)filterSize*2), "m"(shift)
|
||||
: "%"REG_a, "%"REG_c, "%"REG_d
|
||||
);
|
||||
} else
|
||||
#endif
|
||||
for (i=0; i<dstW; i++) {
|
||||
int srcPos= filterPos[i];
|
||||
int val=0;
|
||||
|
Loading…
Reference in New Issue
Block a user