History

yadif sse2/ssse3 optimizations

Originally committed as revision 25874 to svn://svn.ffmpeg.org/ffmpeg/trunk

Baptiste Coudurier committed 15 years ago

Commit 1ef64491 parent 23b83423 files · +294 −212Browse files

Unified · Split

3 files
  1. libavfilter/vf_yadif.c +5 −1
  2. libavfilter/x86/yadif.c +21 −211
  3. libavfilter/x86/yadif_template.c +268 −0
libavfilter/vf_yadif.c+5−1
@@ -304,7 +304,11 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) · 303 unmodified lines
304 if (args) sscanf(args, "%d:%d", &yadif->mode, &yadif->parity);304 if (args) sscanf(args, "%d:%d", &yadif->mode, &yadif->parity);
305 305
306 yadif->filter_line = filter_line_c;306 yadif->filter_line = filter_line_c;
307 if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX)307 if (HAVE_SSSE3 && cpu_flags & AV_CPU_FLAG_SSSE3)
308 yadif->filter_line = ff_yadif_filter_line_ssse3;
309 else if (HAVE_SSE && cpu_flags & AV_CPU_FLAG_SSE2)
310 yadif->filter_line = ff_yadif_filter_line_sse2;
311 else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX)
308 yadif->filter_line = ff_yadif_filter_line_mmx;312 yadif->filter_line = ff_yadif_filter_line_mmx;
309 313
310 av_log(ctx, AV_LOG_INFO, "mode:%d parity:%d\n", yadif->mode, yadif->parity);314 av_log(ctx, AV_LOG_INFO, "mode:%d parity:%d\n", yadif->mode, yadif->parity);
libavfilter/x86/yadif.c+21−211
@@ -22,214 +22,24 @@ · 21 unmodified lines
22#include "libavutil/x86_cpu.h"22#include "libavutil/x86_cpu.h"
23#include "libavfilter/yadif.h"23#include "libavfilter/yadif.h"
24 24
25#define LOAD4(mem,dst) \25#if HAVE_SSSE3
26 "movd "mem", "#dst" \n\t"\26#define COMPILE_TEMPLATE_SSE 1
27 "punpcklbw %%mm7, "#dst" \n\t"27#define COMPILE_TEMPLATE_SSSE3 1
28 28#undef RENAME
29#define PABS(tmp,dst) \29#define RENAME(a) a ## _ssse3
30 "pxor "#tmp", "#tmp" \n\t"\30#include "yadif_template.c"
31 "psubw "#dst", "#tmp" \n\t"\31#undef COMPILE_TEMPLATE_SSSE3
32 "pmaxsw "#tmp", "#dst" \n\t"32#endif
33 33
34#define CHECK(pj,mj) \34#if HAVE_SSE
35 "movq "#pj"(%[cur],%[mrefs]), %%mm2 \n\t" /* cur[x-refs-1+j] */\35#undef RENAME
36 "movq "#mj"(%[cur],%[prefs]), %%mm3 \n\t" /* cur[x+refs-1-j] */\36#define RENAME(a) a ## _sse2
37 "movq %%mm2, %%mm4 \n\t"\37#include "yadif_template.c"
38 "movq %%mm2, %%mm5 \n\t"\38#undef COMPILE_TEMPLATE_SSE
39 "pxor %%mm3, %%mm4 \n\t"\39#endif
40 "pavgb %%mm3, %%mm5 \n\t"\40
41 "pand "MANGLE(pb_1)", %%mm4 \n\t"\41#if HAVE_MMX
42 "psubusb %%mm4, %%mm5 \n\t"\42#undef RENAME
43 "psrlq $8, %%mm5 \n\t"\43#define RENAME(a) a ## _mmx
44 "punpcklbw %%mm7, %%mm5 \n\t" /* (cur[x-refs+j] + cur[x+refs-j])>>1 */\44#include "yadif_template.c"
45 "movq %%mm2, %%mm4 \n\t"\45#endif
46 "psubusb %%mm3, %%mm2 \n\t"\
47 "psubusb %%mm4, %%mm3 \n\t"\
48 "pmaxub %%mm3, %%mm2 \n\t"\
49 "movq %%mm2, %%mm3 \n\t"\
50 "movq %%mm2, %%mm4 \n\t" /* ABS(cur[x-refs-1+j] - cur[x+refs-1-j]) */\
51 "psrlq $8, %%mm3 \n\t" /* ABS(cur[x-refs +j] - cur[x+refs -j]) */\
52 "psrlq $16, %%mm4 \n\t" /* ABS(cur[x-refs+1+j] - cur[x+refs+1-j]) */\
53 "punpcklbw %%mm7, %%mm2 \n\t"\
54 "punpcklbw %%mm7, %%mm3 \n\t"\
55 "punpcklbw %%mm7, %%mm4 \n\t"\
56 "paddw %%mm3, %%mm2 \n\t"\
57 "paddw %%mm4, %%mm2 \n\t" /* score */
58
59#define CHECK1 \
60 "movq %%mm0, %%mm3 \n\t"\
61 "pcmpgtw %%mm2, %%mm3 \n\t" /* if(score < spatial_score) */\
62 "pminsw %%mm2, %%mm0 \n\t" /* spatial_score= score; */\
63 "movq %%mm3, %%mm6 \n\t"\
64 "pand %%mm3, %%mm5 \n\t"\
65 "pandn %%mm1, %%mm3 \n\t"\
66 "por %%mm5, %%mm3 \n\t"\
67 "movq %%mm3, %%mm1 \n\t" /* spatial_pred= (cur[x-refs+j] + cur[x+refs-j])>>1; */
68
69#define CHECK2 /* pretend not to have checked dir=2 if dir=1 was bad.\
70 hurts both quality and speed, but matches the C version. */\
71 "paddw "MANGLE(pw_1)", %%mm6 \n\t"\
72 "psllw $14, %%mm6 \n\t"\
73 "paddsw %%mm6, %%mm2 \n\t"\
74 "movq %%mm0, %%mm3 \n\t"\
75 "pcmpgtw %%mm2, %%mm3 \n\t"\
76 "pminsw %%mm2, %%mm0 \n\t"\
77 "pand %%mm3, %%mm5 \n\t"\
78 "pandn %%mm1, %%mm3 \n\t"\
79 "por %%mm5, %%mm3 \n\t"\
80 "movq %%mm3, %%mm1 \n\t"
81
82DECLARE_ASM_CONST(16, uint64_t, pw_1) = 0x0001000100010001ULL;
83DECLARE_ASM_CONST(16, uint64_t, pb_1) = 0x0101010101010101ULL;
84
85void ff_yadif_filter_line_mmx(uint8_t *dst,
86 uint8_t *prev, uint8_t *cur, uint8_t *next,
87 int w, int refs, int parity, int mode)
88{
89 uint64_t tmp0, tmp1, tmp2, tmp3;
90 int x;
91
92#define FILTER\
93 for(x=0; x<w; x+=4){\
94 __asm__ volatile(\
95 "pxor %%mm7, %%mm7 \n\t"\
96 LOAD4("(%[cur],%[mrefs])", %%mm0) /* c = cur[x-refs] */\
97 LOAD4("(%[cur],%[prefs])", %%mm1) /* e = cur[x+refs] */\
98 LOAD4("(%["prev2"])", %%mm2) /* prev2[x] */\
99 LOAD4("(%["next2"])", %%mm3) /* next2[x] */\
100 "movq %%mm3, %%mm4 \n\t"\
101 "paddw %%mm2, %%mm3 \n\t"\
102 "psraw $1, %%mm3 \n\t" /* d = (prev2[x] + next2[x])>>1 */\
103 "movq %%mm0, %[tmp0] \n\t" /* c */\
104 "movq %%mm3, %[tmp1] \n\t" /* d */\
105 "movq %%mm1, %[tmp2] \n\t" /* e */\
106 "psubw %%mm4, %%mm2 \n\t"\
107 PABS( %%mm4, %%mm2) /* temporal_diff0 */\
108 LOAD4("(%[prev],%[mrefs])", %%mm3) /* prev[x-refs] */\
109 LOAD4("(%[prev],%[prefs])", %%mm4) /* prev[x+refs] */\
110 "psubw %%mm0, %%mm3 \n\t"\
111 "psubw %%mm1, %%mm4 \n\t"\
112 PABS( %%mm5, %%mm3)\
113 PABS( %%mm5, %%mm4)\
114 "paddw %%mm4, %%mm3 \n\t" /* temporal_diff1 */\
115 "psrlw $1, %%mm2 \n\t"\
116 "psrlw $1, %%mm3 \n\t"\
117 "pmaxsw %%mm3, %%mm2 \n\t"\
118 LOAD4("(%[next],%[mrefs])", %%mm3) /* next[x-refs] */\
119 LOAD4("(%[next],%[prefs])", %%mm4) /* next[x+refs] */\
120 "psubw %%mm0, %%mm3 \n\t"\
121 "psubw %%mm1, %%mm4 \n\t"\
122 PABS( %%mm5, %%mm3)\
123 PABS( %%mm5, %%mm4)\
124 "paddw %%mm4, %%mm3 \n\t" /* temporal_diff2 */\
125 "psrlw $1, %%mm3 \n\t"\
126 "pmaxsw %%mm3, %%mm2 \n\t"\
127 "movq %%mm2, %[tmp3] \n\t" /* diff */\
128\
129 "paddw %%mm0, %%mm1 \n\t"\
130 "paddw %%mm0, %%mm0 \n\t"\
131 "psubw %%mm1, %%mm0 \n\t"\
132 "psrlw $1, %%mm1 \n\t" /* spatial_pred */\
133 PABS( %%mm2, %%mm0) /* ABS(c-e) */\
134\
135 "movq -1(%[cur],%[mrefs]), %%mm2 \n\t" /* cur[x-refs-1] */\
136 "movq -1(%[cur],%[prefs]), %%mm3 \n\t" /* cur[x+refs-1] */\
137 "movq %%mm2, %%mm4 \n\t"\
138 "psubusb %%mm3, %%mm2 \n\t"\
139 "psubusb %%mm4, %%mm3 \n\t"\
140 "pmaxub %%mm3, %%mm2 \n\t"\
141 "pshufw $9,%%mm2, %%mm3 \n\t"\
142 "punpcklbw %%mm7, %%mm2 \n\t" /* ABS(cur[x-refs-1] - cur[x+refs-1]) */\
143 "punpcklbw %%mm7, %%mm3 \n\t" /* ABS(cur[x-refs+1] - cur[x+refs+1]) */\
144 "paddw %%mm2, %%mm0 \n\t"\
145 "paddw %%mm3, %%mm0 \n\t"\
146 "psubw "MANGLE(pw_1)", %%mm0 \n\t" /* spatial_score */\
147\
148 CHECK(-2,0)\
149 CHECK1\
150 CHECK(-3,1)\
151 CHECK2\
152 CHECK(0,-2)\
153 CHECK1\
154 CHECK(1,-3)\
155 CHECK2\
156\
157 /* if(p->mode<2) ... */\
158 "movq %[tmp3], %%mm6 \n\t" /* diff */\
159 "cmpl $2, %[mode] \n\t"\
160 "jge 1f \n\t"\
161 LOAD4("(%["prev2"],%[mrefs],2)", %%mm2) /* prev2[x-2*refs] */\
162 LOAD4("(%["next2"],%[mrefs],2)", %%mm4) /* next2[x-2*refs] */\
163 LOAD4("(%["prev2"],%[prefs],2)", %%mm3) /* prev2[x+2*refs] */\
164 LOAD4("(%["next2"],%[prefs],2)", %%mm5) /* next2[x+2*refs] */\
165 "paddw %%mm4, %%mm2 \n\t"\
166 "paddw %%mm5, %%mm3 \n\t"\
167 "psrlw $1, %%mm2 \n\t" /* b */\
168 "psrlw $1, %%mm3 \n\t" /* f */\
169 "movq %[tmp0], %%mm4 \n\t" /* c */\
170 "movq %[tmp1], %%mm5 \n\t" /* d */\
171 "movq %[tmp2], %%mm7 \n\t" /* e */\
172 "psubw %%mm4, %%mm2 \n\t" /* b-c */\
173 "psubw %%mm7, %%mm3 \n\t" /* f-e */\
174 "movq %%mm5, %%mm0 \n\t"\
175 "psubw %%mm4, %%mm5 \n\t" /* d-c */\
176 "psubw %%mm7, %%mm0 \n\t" /* d-e */\
177 "movq %%mm2, %%mm4 \n\t"\
178 "pminsw %%mm3, %%mm2 \n\t"\
179 "pmaxsw %%mm4, %%mm3 \n\t"\
180 "pmaxsw %%mm5, %%mm2 \n\t"\
181 "pminsw %%mm5, %%mm3 \n\t"\
182 "pmaxsw %%mm0, %%mm2 \n\t" /* max */\
183 "pminsw %%mm0, %%mm3 \n\t" /* min */\
184 "pxor %%mm4, %%mm4 \n\t"\
185 "pmaxsw %%mm3, %%mm6 \n\t"\
186 "psubw %%mm2, %%mm4 \n\t" /* -max */\
187 "pmaxsw %%mm4, %%mm6 \n\t" /* diff= MAX3(diff, min, -max); */\
188 "1: \n\t"\
189\
190 "movq %[tmp1], %%mm2 \n\t" /* d */\
191 "movq %%mm2, %%mm3 \n\t"\
192 "psubw %%mm6, %%mm2 \n\t" /* d-diff */\
193 "paddw %%mm6, %%mm3 \n\t" /* d+diff */\
194 "pmaxsw %%mm2, %%mm1 \n\t"\
195 "pminsw %%mm3, %%mm1 \n\t" /* d = clip(spatial_pred, d-diff, d+diff); */\
196 "packuswb %%mm1, %%mm1 \n\t"\
197\
198 :[tmp0]"=m"(tmp0),\
199 [tmp1]"=m"(tmp1),\
200 [tmp2]"=m"(tmp2),\
201 [tmp3]"=m"(tmp3)\
202 :[prev] "r"(prev),\
203 [cur] "r"(cur),\
204 [next] "r"(next),\
205 [prefs]"r"((x86_reg)refs),\
206 [mrefs]"r"((x86_reg)-refs),\
207 [mode] "g"(mode)\
208 );\
209 __asm__ volatile("movd %%mm1, %0" :"=m"(*dst));\
210 dst += 4;\
211 prev+= 4;\
212 cur += 4;\
213 next+= 4;\
214 }
215
216 if (parity) {
217#define prev2 "prev"
218#define next2 "cur"
219 FILTER
220#undef prev2
221#undef next2
222 } else {
223#define prev2 "cur"
224#define next2 "next"
225 FILTER
226#undef prev2
227#undef next2
228 }
229}
230#undef LOAD4
231#undef PABS
232#undef CHECK
233#undef CHECK1
234#undef CHECK2
235#undef FILTER
libavfilter/x86/yadif_template.c+268−0
@@ -0,0 +1,268 @@
1/*
2 * Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#ifdef COMPILE_TEMPLATE_SSE
22#define MM "%%xmm"
23#define MOV "movq"
24#define MOVQ "movdqa"
25#define MOVQU "movdqu"
26#define STEP 8
27#define LOAD(mem,dst) \
28 MOV" "mem", "dst" \n\t"\
29 "punpcklbw "MM"7, "dst" \n\t"
30#define PSRL1(reg) "psrldq $1, "reg" \n\t"
31#define PSRL2(reg) "psrldq $2, "reg" \n\t"
32#define PSHUF(src,dst) "movdqa "dst", "src" \n\t"\
33 "psrldq $2, "src" \n\t"
34#else
35#define MM "%%mm"
36#define MOV "movd"
37#define MOVQ "movq"
38#define MOVQU "movq"
39#define STEP 4
40#define LOAD(mem,dst) \
41 MOV" "mem", "dst" \n\t"\
42 "punpcklbw "MM"7, "dst" \n\t"
43#define PSRL1(reg) "psrlq $8, "reg" \n\t"
44#define PSRL2(reg) "psrlq $16, "reg" \n\t"
45#define PSHUF(src,dst) "pshufw $9, "dst", "src" \n\t"
46#endif
47
48#ifdef COMPILE_TEMPLATE_SSSE3
49#define PABS(tmp,dst) \
50 "pabsw "dst", "dst" \n\t"
51#else
52#define PABS(tmp,dst) \
53 "pxor "tmp", "tmp" \n\t"\
54 "psubw "dst", "tmp" \n\t"\
55 "pmaxsw "tmp", "dst" \n\t"
56#endif
57
58#define CHECK(pj,mj) \
59 MOVQU" "#pj"(%[cur],%[mrefs]), "MM"2 \n\t" /* cur[x-refs-1+j] */\
60 MOVQU" "#mj"(%[cur],%[prefs]), "MM"3 \n\t" /* cur[x+refs-1-j] */\
61 MOVQ" "MM"2, "MM"4 \n\t"\
62 MOVQ" "MM"2, "MM"5 \n\t"\
63 "pxor "MM"3, "MM"4 \n\t"\
64 "pavgb "MM"3, "MM"5 \n\t"\
65 "pand "MANGLE(ff_pb_1)", "MM"4 \n\t"\
66 "psubusb "MM"4, "MM"5 \n\t"\
67 PSRL1(MM"5") \
68 "punpcklbw "MM"7, "MM"5 \n\t" /* (cur[x-refs+j] + cur[x+refs-j])>>1 */\
69 MOVQ" "MM"2, "MM"4 \n\t"\
70 "psubusb "MM"3, "MM"2 \n\t"\
71 "psubusb "MM"4, "MM"3 \n\t"\
72 "pmaxub "MM"3, "MM"2 \n\t"\
73 MOVQ" "MM"2, "MM"3 \n\t"\
74 MOVQ" "MM"2, "MM"4 \n\t" /* ABS(cur[x-refs-1+j] - cur[x+refs-1-j]) */\
75 PSRL1(MM"3") /* ABS(cur[x-refs +j] - cur[x+refs -j]) */\
76 PSRL2(MM"4") /* ABS(cur[x-refs+1+j] - cur[x+refs+1-j]) */\
77 "punpcklbw "MM"7, "MM"2 \n\t"\
78 "punpcklbw "MM"7, "MM"3 \n\t"\
79 "punpcklbw "MM"7, "MM"4 \n\t"\
80 "paddw "MM"3, "MM"2 \n\t"\
81 "paddw "MM"4, "MM"2 \n\t" /* score */
82
83#define CHECK1 \
84 MOVQ" "MM"0, "MM"3 \n\t"\
85 "pcmpgtw "MM"2, "MM"3 \n\t" /* if(score < spatial_score) */\
86 "pminsw "MM"2, "MM"0 \n\t" /* spatial_score= score; */\
87 MOVQ" "MM"3, "MM"6 \n\t"\
88 "pand "MM"3, "MM"5 \n\t"\
89 "pandn "MM"1, "MM"3 \n\t"\
90 "por "MM"5, "MM"3 \n\t"\
91 MOVQ" "MM"3, "MM"1 \n\t" /* spatial_pred= (cur[x-refs+j] + cur[x+refs-j])>>1; */
92
93#define CHECK2 /* pretend not to have checked dir=2 if dir=1 was bad.\
94 hurts both quality and speed, but matches the C version. */\
95 "paddw "MANGLE(ff_pw_1)", "MM"6 \n\t"\
96 "psllw $14, "MM"6 \n\t"\
97 "paddsw "MM"6, "MM"2 \n\t"\
98 MOVQ" "MM"0, "MM"3 \n\t"\
99 "pcmpgtw "MM"2, "MM"3 \n\t"\
100 "pminsw "MM"2, "MM"0 \n\t"\
101 "pand "MM"3, "MM"5 \n\t"\
102 "pandn "MM"1, "MM"3 \n\t"\
103 "por "MM"5, "MM"3 \n\t"\
104 MOVQ" "MM"3, "MM"1 \n\t"
105
106void RENAME(ff_yadif_filter_line)(uint8_t *dst,
107 uint8_t *prev, uint8_t *cur, uint8_t *next,
108 int w, int refs, int parity, int mode)
109{
110 DECLARE_ALIGNED(16, uint8_t, tmp0[16]);
111 DECLARE_ALIGNED(16, uint8_t, tmp1[16]);
112 DECLARE_ALIGNED(16, uint8_t, tmp2[16]);
113 DECLARE_ALIGNED(16, uint8_t, tmp3[16]);
114 int x;
115
116#define FILTER\
117 for(x=0; x<w; x+=STEP){\
118 __asm__ volatile(\
119 "pxor "MM"7, "MM"7 \n\t"\
120 LOAD("(%[cur],%[mrefs])", MM"0") /* c = cur[x-refs] */\
121 LOAD("(%[cur],%[prefs])", MM"1") /* e = cur[x+refs] */\
122 LOAD("(%["prev2"])", MM"2") /* prev2[x] */\
123 LOAD("(%["next2"])", MM"3") /* next2[x] */\
124 MOVQ" "MM"3, "MM"4 \n\t"\
125 "paddw "MM"2, "MM"3 \n\t"\
126 "psraw $1, "MM"3 \n\t" /* d = (prev2[x] + next2[x])>>1 */\
127 MOVQ" "MM"0, %[tmp0] \n\t" /* c */\
128 MOVQ" "MM"3, %[tmp1] \n\t" /* d */\
129 MOVQ" "MM"1, %[tmp2] \n\t" /* e */\
130 "psubw "MM"4, "MM"2 \n\t"\
131 PABS( MM"4", MM"2") /* temporal_diff0 */\
132 LOAD("(%[prev],%[mrefs])", MM"3") /* prev[x-refs] */\
133 LOAD("(%[prev],%[prefs])", MM"4") /* prev[x+refs] */\
134 "psubw "MM"0, "MM"3 \n\t"\
135 "psubw "MM"1, "MM"4 \n\t"\
136 PABS( MM"5", MM"3")\
137 PABS( MM"5", MM"4")\
138 "paddw "MM"4, "MM"3 \n\t" /* temporal_diff1 */\
139 "psrlw $1, "MM"2 \n\t"\
140 "psrlw $1, "MM"3 \n\t"\
141 "pmaxsw "MM"3, "MM"2 \n\t"\
142 LOAD("(%[next],%[mrefs])", MM"3") /* next[x-refs] */\
143 LOAD("(%[next],%[prefs])", MM"4") /* next[x+refs] */\
144 "psubw "MM"0, "MM"3 \n\t"\
145 "psubw "MM"1, "MM"4 \n\t"\
146 PABS( MM"5", MM"3")\
147 PABS( MM"5", MM"4")\
148 "paddw "MM"4, "MM"3 \n\t" /* temporal_diff2 */\
149 "psrlw $1, "MM"3 \n\t"\
150 "pmaxsw "MM"3, "MM"2 \n\t"\
151 MOVQ" "MM"2, %[tmp3] \n\t" /* diff */\
152\
153 "paddw "MM"0, "MM"1 \n\t"\
154 "paddw "MM"0, "MM"0 \n\t"\
155 "psubw "MM"1, "MM"0 \n\t"\
156 "psrlw $1, "MM"1 \n\t" /* spatial_pred */\
157 PABS( MM"2", MM"0") /* ABS(c-e) */\
158\
159 MOVQU" -1(%[cur],%[mrefs]), "MM"2 \n\t" /* cur[x-refs-1] */\
160 MOVQU" -1(%[cur],%[prefs]), "MM"3 \n\t" /* cur[x+refs-1] */\
161 MOVQ" "MM"2, "MM"4 \n\t"\
162 "psubusb "MM"3, "MM"2 \n\t"\
163 "psubusb "MM"4, "MM"3 \n\t"\
164 "pmaxub "MM"3, "MM"2 \n\t"\
165 PSHUF(MM"3", MM"2") \
166 "punpcklbw "MM"7, "MM"2 \n\t" /* ABS(cur[x-refs-1] - cur[x+refs-1]) */\
167 "punpcklbw "MM"7, "MM"3 \n\t" /* ABS(cur[x-refs+1] - cur[x+refs+1]) */\
168 "paddw "MM"2, "MM"0 \n\t"\
169 "paddw "MM"3, "MM"0 \n\t"\
170 "psubw "MANGLE(ff_pw_1)", "MM"0 \n\t" /* spatial_score */\
171\
172 CHECK(-2,0)\
173 CHECK1\
174 CHECK(-3,1)\
175 CHECK2\
176 CHECK(0,-2)\
177 CHECK1\
178 CHECK(1,-3)\
179 CHECK2\
180\
181 /* if(p->mode<2) ... */\
182 MOVQ" %[tmp3], "MM"6 \n\t" /* diff */\
183 "cmpl $2, %[mode] \n\t"\
184 "jge 1f \n\t"\
185 LOAD("(%["prev2"],%[mrefs],2)", MM"2") /* prev2[x-2*refs] */\
186 LOAD("(%["next2"],%[mrefs],2)", MM"4") /* next2[x-2*refs] */\
187 LOAD("(%["prev2"],%[prefs],2)", MM"3") /* prev2[x+2*refs] */\
188 LOAD("(%["next2"],%[prefs],2)", MM"5") /* next2[x+2*refs] */\
189 "paddw "MM"4, "MM"2 \n\t"\
190 "paddw "MM"5, "MM"3 \n\t"\
191 "psrlw $1, "MM"2 \n\t" /* b */\
192 "psrlw $1, "MM"3 \n\t" /* f */\
193 MOVQ" %[tmp0], "MM"4 \n\t" /* c */\
194 MOVQ" %[tmp1], "MM"5 \n\t" /* d */\
195 MOVQ" %[tmp2], "MM"7 \n\t" /* e */\
196 "psubw "MM"4, "MM"2 \n\t" /* b-c */\
197 "psubw "MM"7, "MM"3 \n\t" /* f-e */\
198 MOVQ" "MM"5, "MM"0 \n\t"\
199 "psubw "MM"4, "MM"5 \n\t" /* d-c */\
200 "psubw "MM"7, "MM"0 \n\t" /* d-e */\
201 MOVQ" "MM"2, "MM"4 \n\t"\
202 "pminsw "MM"3, "MM"2 \n\t"\
203 "pmaxsw "MM"4, "MM"3 \n\t"\
204 "pmaxsw "MM"5, "MM"2 \n\t"\
205 "pminsw "MM"5, "MM"3 \n\t"\
206 "pmaxsw "MM"0, "MM"2 \n\t" /* max */\
207 "pminsw "MM"0, "MM"3 \n\t" /* min */\
208 "pxor "MM"4, "MM"4 \n\t"\
209 "pmaxsw "MM"3, "MM"6 \n\t"\
210 "psubw "MM"2, "MM"4 \n\t" /* -max */\
211 "pmaxsw "MM"4, "MM"6 \n\t" /* diff= MAX3(diff, min, -max); */\
212 "1: \n\t"\
213\
214 MOVQ" %[tmp1], "MM"2 \n\t" /* d */\
215 MOVQ" "MM"2, "MM"3 \n\t"\
216 "psubw "MM"6, "MM"2 \n\t" /* d-diff */\
217 "paddw "MM"6, "MM"3 \n\t" /* d+diff */\
218 "pmaxsw "MM"2, "MM"1 \n\t"\
219 "pminsw "MM"3, "MM"1 \n\t" /* d = clip(spatial_pred, d-diff, d+diff); */\
220 "packuswb "MM"1, "MM"1 \n\t"\
221\
222 :[tmp0]"=m"(tmp0),\
223 [tmp1]"=m"(tmp1),\
224 [tmp2]"=m"(tmp2),\
225 [tmp3]"=m"(tmp3)\
226 :[prev] "r"(prev),\
227 [cur] "r"(cur),\
228 [next] "r"(next),\
229 [prefs]"r"((x86_reg)refs),\
230 [mrefs]"r"((x86_reg)-refs),\
231 [mode] "g"(mode)\
232 );\
233 __asm__ volatile(MOV" "MM"1, %0" :"=m"(*dst));\
234 dst += STEP;\
235 prev+= STEP;\
236 cur += STEP;\
237 next+= STEP;\
238 }
239
240 if (parity) {
241#define prev2 "prev"
242#define next2 "cur"
243 FILTER
244#undef prev2
245#undef next2
246 } else {
247#define prev2 "cur"
248#define next2 "next"
249 FILTER
250#undef prev2
251#undef next2
252 }
253}
254#undef STEP
255#undef MM
256#undef MOV
257#undef MOVQ
258#undef MOVQU
259#undef PSHUF
260#undef PSRL1
261#undef PSRL2
262#undef LOAD
263#undef PABS
264#undef CHECK
265#undef CHECK1
266#undef CHECK2
267#undef FILTER
268

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t