00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00026 #include "libavutil/x86_cpu.h"
00027 #include "libavcodec/dsputil.h"
00028 #include "dsputil_mmx.h"
00029
00030 extern const uint16_t ff_vp3_idct_data[];
00031
00032
00033
00034
00035 #define VP3_LOOP_FILTER(flim) \
00036 "movq %%mm6, %%mm7 \n\t" \
00037 "pand "MANGLE(ff_pb_7 )", %%mm6 \n\t" \
00038 "psrlw $3, %%mm7 \n\t" \
00039 "pand "MANGLE(ff_pb_1F)", %%mm7 \n\t" \
00040 "movq %%mm2, %%mm3 \n\t" \
00041 "pxor %%mm4, %%mm2 \n\t" \
00042 "pand "MANGLE(ff_pb_1 )", %%mm2 \n\t" \
00043 "movq %%mm2, %%mm5 \n\t" \
00044 "paddb %%mm2, %%mm2 \n\t" \
00045 "paddb %%mm5, %%mm2 \n\t" \
00046 "paddb %%mm6, %%mm2 \n\t" \
00047 "pcmpeqb %%mm0, %%mm0 \n\t" \
00048 "pxor %%mm0, %%mm1 \n\t" \
00049 "pavgb %%mm2, %%mm1 \n\t" \
00050 "pxor %%mm4, %%mm0 \n\t" \
00051 "pavgb %%mm3, %%mm0 \n\t" \
00052 "paddb "MANGLE(ff_pb_3 )", %%mm1 \n\t" \
00053 "pavgb %%mm0, %%mm1 \n\t" \
00054 "pavgb %%mm0, %%mm1 \n\t" \
00055 "paddusb %%mm1, %%mm7 \n\t" \
00056 "movq "MANGLE(ff_pb_81)", %%mm6 \n\t" \
00057 "psubusb %%mm7, %%mm6 \n\t" \
00058 "psubusb "MANGLE(ff_pb_81)", %%mm7 \n\t" \
00059 \
00060 "movq "#flim", %%mm5 \n\t" \
00061 "pminub %%mm5, %%mm6 \n\t" \
00062 "pminub %%mm5, %%mm7 \n\t" \
00063 "movq %%mm6, %%mm0 \n\t" \
00064 "movq %%mm7, %%mm1 \n\t" \
00065 "paddb %%mm6, %%mm6 \n\t" \
00066 "paddb %%mm7, %%mm7 \n\t" \
00067 "pminub %%mm5, %%mm6 \n\t" \
00068 "pminub %%mm5, %%mm7 \n\t" \
00069 "psubb %%mm0, %%mm6 \n\t" \
00070 "psubb %%mm1, %%mm7 \n\t" \
00071 "paddusb %%mm7, %%mm4 \n\t" \
00072 "psubusb %%mm6, %%mm4 \n\t" \
00073 "psubusb %%mm7, %%mm3 \n\t" \
00074 "paddusb %%mm6, %%mm3 \n\t"
00075
00076 #define STORE_4_WORDS(dst0, dst1, dst2, dst3, mm) \
00077 "movd "#mm", %0 \n\t" \
00078 "movw %w0, -1"#dst0" \n\t" \
00079 "psrlq $32, "#mm" \n\t" \
00080 "shr $16, %0 \n\t" \
00081 "movw %w0, -1"#dst1" \n\t" \
00082 "movd "#mm", %0 \n\t" \
00083 "movw %w0, -1"#dst2" \n\t" \
00084 "shr $16, %0 \n\t" \
00085 "movw %w0, -1"#dst3" \n\t"
00086
00087 void ff_vp3_v_loop_filter_mmx2(uint8_t *src, int stride, int *bounding_values)
00088 {
00089 __asm__ volatile(
00090 "movq %0, %%mm6 \n\t"
00091 "movq %1, %%mm4 \n\t"
00092 "movq %2, %%mm2 \n\t"
00093 "movq %3, %%mm1 \n\t"
00094
00095 VP3_LOOP_FILTER(%4)
00096
00097 "movq %%mm4, %1 \n\t"
00098 "movq %%mm3, %2 \n\t"
00099
00100 : "+m" (*(uint64_t*)(src - 2*stride)),
00101 "+m" (*(uint64_t*)(src - 1*stride)),
00102 "+m" (*(uint64_t*)(src + 0*stride)),
00103 "+m" (*(uint64_t*)(src + 1*stride))
00104 : "m"(*(uint64_t*)(bounding_values+129))
00105 );
00106 }
00107
00108 void ff_vp3_h_loop_filter_mmx2(uint8_t *src, int stride, int *bounding_values)
00109 {
00110 x86_reg tmp;
00111
00112 __asm__ volatile(
00113 "movd -2(%1), %%mm6 \n\t"
00114 "movd -2(%1,%3), %%mm0 \n\t"
00115 "movd -2(%1,%3,2), %%mm1 \n\t"
00116 "movd -2(%1,%4), %%mm4 \n\t"
00117
00118 TRANSPOSE8x4(%%mm6, %%mm0, %%mm1, %%mm4, -2(%2), -2(%2,%3), -2(%2,%3,2), -2(%2,%4), %%mm2)
00119 VP3_LOOP_FILTER(%5)
00120 SBUTTERFLY(%%mm4, %%mm3, %%mm5, bw, q)
00121
00122 STORE_4_WORDS((%1), (%1,%3), (%1,%3,2), (%1,%4), %%mm4)
00123 STORE_4_WORDS((%2), (%2,%3), (%2,%3,2), (%2,%4), %%mm5)
00124
00125 : "=&r"(tmp)
00126 : "r"(src), "r"(src+4*stride), "r"((x86_reg)stride), "r"((x86_reg)3*stride),
00127 "m"(*(uint64_t*)(bounding_values+129))
00128 : "memory"
00129 );
00130 }
00131
00132
00133 #define BeginIDCT() \
00134 "movq "I(3)", %%mm2 \n\t" \
00135 "movq "C(3)", %%mm6 \n\t" \
00136 "movq %%mm2, %%mm4 \n\t" \
00137 "movq "J(5)", %%mm7 \n\t" \
00138 "pmulhw %%mm6, %%mm4 \n\t" \
00139 "movq "C(5)", %%mm1 \n\t" \
00140 "pmulhw %%mm7, %%mm6 \n\t" \
00141 "movq %%mm1, %%mm5 \n\t" \
00142 "pmulhw %%mm2, %%mm1 \n\t" \
00143 "movq "I(1)", %%mm3 \n\t" \
00144 "pmulhw %%mm7, %%mm5 \n\t" \
00145 "movq "C(1)", %%mm0 \n\t" \
00146 "paddw %%mm2, %%mm4 \n\t" \
00147 "paddw %%mm7, %%mm6 \n\t" \
00148 "paddw %%mm1, %%mm2 \n\t" \
00149 "movq "J(7)", %%mm1 \n\t" \
00150 "paddw %%mm5, %%mm7 \n\t" \
00151 "movq %%mm0, %%mm5 \n\t" \
00152 "pmulhw %%mm3, %%mm0 \n\t" \
00153 "paddsw %%mm7, %%mm4 \n\t" \
00154 "pmulhw %%mm1, %%mm5 \n\t" \
00155 "movq "C(7)", %%mm7 \n\t" \
00156 "psubsw %%mm2, %%mm6 \n\t" \
00157 "paddw %%mm3, %%mm0 \n\t" \
00158 "pmulhw %%mm7, %%mm3 \n\t" \
00159 "movq "I(2)", %%mm2 \n\t" \
00160 "pmulhw %%mm1, %%mm7 \n\t" \
00161 "paddw %%mm1, %%mm5 \n\t" \
00162 "movq %%mm2, %%mm1 \n\t" \
00163 "pmulhw "C(2)", %%mm2 \n\t" \
00164 "psubsw %%mm5, %%mm3 \n\t" \
00165 "movq "J(6)", %%mm5 \n\t" \
00166 "paddsw %%mm7, %%mm0 \n\t" \
00167 "movq %%mm5, %%mm7 \n\t" \
00168 "psubsw %%mm4, %%mm0 \n\t" \
00169 "pmulhw "C(2)", %%mm5 \n\t" \
00170 "paddw %%mm1, %%mm2 \n\t" \
00171 "pmulhw "C(6)", %%mm1 \n\t" \
00172 "paddsw %%mm4, %%mm4 \n\t" \
00173 "paddsw %%mm0, %%mm4 \n\t" \
00174 "psubsw %%mm6, %%mm3 \n\t" \
00175 "paddw %%mm7, %%mm5 \n\t" \
00176 "paddsw %%mm6, %%mm6 \n\t" \
00177 "pmulhw "C(6)", %%mm7 \n\t" \
00178 "paddsw %%mm3, %%mm6 \n\t" \
00179 "movq %%mm4, "I(1)"\n\t" \
00180 "psubsw %%mm5, %%mm1 \n\t" \
00181 "movq "C(4)", %%mm4 \n\t" \
00182 "movq %%mm3, %%mm5 \n\t" \
00183 "pmulhw %%mm4, %%mm3 \n\t" \
00184 "paddsw %%mm2, %%mm7 \n\t" \
00185 "movq %%mm6, "I(2)"\n\t" \
00186 "movq %%mm0, %%mm2 \n\t" \
00187 "movq "I(0)", %%mm6 \n\t" \
00188 "pmulhw %%mm4, %%mm0 \n\t" \
00189 "paddw %%mm3, %%mm5 \n\t" \
00190 "movq "J(4)", %%mm3 \n\t" \
00191 "psubsw %%mm1, %%mm5 \n\t" \
00192 "paddw %%mm0, %%mm2 \n\t" \
00193 "psubsw %%mm3, %%mm6 \n\t" \
00194 "movq %%mm6, %%mm0 \n\t" \
00195 "pmulhw %%mm4, %%mm6 \n\t" \
00196 "paddsw %%mm3, %%mm3 \n\t" \
00197 "paddsw %%mm1, %%mm1 \n\t" \
00198 "paddsw %%mm0, %%mm3 \n\t" \
00199 "paddsw %%mm5, %%mm1 \n\t" \
00200 "pmulhw %%mm3, %%mm4 \n\t" \
00201 "paddsw %%mm0, %%mm6 \n\t" \
00202 "psubsw %%mm2, %%mm6 \n\t" \
00203 "paddsw %%mm2, %%mm2 \n\t" \
00204 "movq "I(1)", %%mm0 \n\t" \
00205 "paddsw %%mm6, %%mm2 \n\t" \
00206 "paddw %%mm3, %%mm4 \n\t" \
00207 "psubsw %%mm1, %%mm2 \n\t"
00208
00209
00210 #define RowIDCT() \
00211 BeginIDCT() \
00212 "movq "I(2)", %%mm3 \n\t" \
00213 "psubsw %%mm7, %%mm4 \n\t" \
00214 "paddsw %%mm1, %%mm1 \n\t" \
00215 "paddsw %%mm7, %%mm7 \n\t" \
00216 "paddsw %%mm2, %%mm1 \n\t" \
00217 "paddsw %%mm4, %%mm7 \n\t" \
00218 "psubsw %%mm3, %%mm4 \n\t" \
00219 "paddsw %%mm3, %%mm3 \n\t" \
00220 "psubsw %%mm5, %%mm6 \n\t" \
00221 "paddsw %%mm5, %%mm5 \n\t" \
00222 "paddsw %%mm4, %%mm3 \n\t" \
00223 "paddsw %%mm6, %%mm5 \n\t" \
00224 "psubsw %%mm0, %%mm7 \n\t" \
00225 "paddsw %%mm0, %%mm0 \n\t" \
00226 "movq %%mm1, "I(1)"\n\t" \
00227 "paddsw %%mm7, %%mm0 \n\t"
00228
00229
00230 #define ColumnIDCT() \
00231 BeginIDCT() \
00232 "paddsw "OC_8", %%mm2 \n\t" \
00233 "paddsw %%mm1, %%mm1 \n\t" \
00234 "paddsw %%mm2, %%mm1 \n\t" \
00235 "psraw $4, %%mm2 \n\t" \
00236 "psubsw %%mm7, %%mm4 \n\t" \
00237 "psraw $4, %%mm1 \n\t" \
00238 "movq "I(2)", %%mm3 \n\t" \
00239 "paddsw %%mm7, %%mm7 \n\t" \
00240 "movq %%mm2, "I(2)"\n\t" \
00241 "paddsw %%mm4, %%mm7 \n\t" \
00242 "movq %%mm1, "I(1)"\n\t" \
00243 "psubsw %%mm3, %%mm4 \n\t" \
00244 "paddsw "OC_8", %%mm4 \n\t" \
00245 "paddsw %%mm3, %%mm3 \n\t" \
00246 "paddsw %%mm4, %%mm3 \n\t" \
00247 "psraw $4, %%mm4 \n\t" \
00248 "psubsw %%mm5, %%mm6 \n\t" \
00249 "psraw $4, %%mm3 \n\t" \
00250 "paddsw "OC_8", %%mm6 \n\t" \
00251 "paddsw %%mm5, %%mm5 \n\t" \
00252 "paddsw %%mm6, %%mm5 \n\t" \
00253 "psraw $4, %%mm6 \n\t" \
00254 "movq %%mm4, "J(4)"\n\t" \
00255 "psraw $4, %%mm5 \n\t" \
00256 "movq %%mm3, "I(3)"\n\t" \
00257 "psubsw %%mm0, %%mm7 \n\t" \
00258 "paddsw "OC_8", %%mm7 \n\t" \
00259 "paddsw %%mm0, %%mm0 \n\t" \
00260 "paddsw %%mm7, %%mm0 \n\t" \
00261 "psraw $4, %%mm7 \n\t" \
00262 "movq %%mm6, "J(6)"\n\t" \
00263 "psraw $4, %%mm0 \n\t" \
00264 "movq %%mm5, "J(5)"\n\t" \
00265 "movq %%mm7, "J(7)"\n\t" \
00266 "movq %%mm0, "I(0)"\n\t"
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 #define Transpose() \
00299 "movq %%mm4, %%mm1 \n\t" \
00300 "punpcklwd %%mm5, %%mm4 \n\t" \
00301 "movq %%mm0, "I(0)"\n\t" \
00302 "punpckhwd %%mm5, %%mm1 \n\t" \
00303 "movq %%mm6, %%mm0 \n\t" \
00304 "punpcklwd %%mm7, %%mm6 \n\t" \
00305 "movq %%mm4, %%mm5 \n\t" \
00306 "punpckldq %%mm6, %%mm4 \n\t" \
00307 "punpckhdq %%mm6, %%mm5 \n\t" \
00308 "movq %%mm1, %%mm6 \n\t" \
00309 "movq %%mm4, "J(4)"\n\t" \
00310 "punpckhwd %%mm7, %%mm0 \n\t" \
00311 "movq %%mm5, "J(5)"\n\t" \
00312 "punpckhdq %%mm0, %%mm6 \n\t" \
00313 "movq "I(0)", %%mm4 \n\t" \
00314 "punpckldq %%mm0, %%mm1 \n\t" \
00315 "movq "I(1)", %%mm5 \n\t" \
00316 "movq %%mm4, %%mm0 \n\t" \
00317 "movq %%mm6, "J(7)"\n\t" \
00318 "punpcklwd %%mm5, %%mm0 \n\t" \
00319 "movq %%mm1, "J(6)"\n\t" \
00320 "punpckhwd %%mm5, %%mm4 \n\t" \
00321 "movq %%mm2, %%mm5 \n\t" \
00322 "punpcklwd %%mm3, %%mm2 \n\t" \
00323 "movq %%mm0, %%mm1 \n\t" \
00324 "punpckldq %%mm2, %%mm0 \n\t" \
00325 "punpckhdq %%mm2, %%mm1 \n\t" \
00326 "movq %%mm4, %%mm2 \n\t" \
00327 "movq %%mm0, "I(0)"\n\t" \
00328 "punpckhwd %%mm3, %%mm5 \n\t" \
00329 "movq %%mm1, "I(1)"\n\t" \
00330 "punpckhdq %%mm5, %%mm4 \n\t" \
00331 "punpckldq %%mm5, %%mm2 \n\t" \
00332 "movq %%mm4, "I(3)"\n\t" \
00333 "movq %%mm2, "I(2)"\n\t"
00334
00335 void ff_vp3_idct_mmx(int16_t *output_data)
00336 {
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 #define C(x) AV_STRINGIFY(16*(x-1))"(%1)"
00347 #define OC_8 "%2"
00348
00349
00350
00351 #define I(x) AV_STRINGIFY(16* x )"(%0)"
00352 #define J(x) AV_STRINGIFY(16*(x-4) + 8)"(%0)"
00353
00354 __asm__ volatile (
00355 RowIDCT()
00356 Transpose()
00357
00358 #undef I
00359 #undef J
00360 #define I(x) AV_STRINGIFY(16* x + 64)"(%0)"
00361 #define J(x) AV_STRINGIFY(16*(x-4) + 72)"(%0)"
00362
00363 RowIDCT()
00364 Transpose()
00365
00366 #undef I
00367 #undef J
00368 #define I(x) AV_STRINGIFY(16*x)"(%0)"
00369 #define J(x) AV_STRINGIFY(16*x)"(%0)"
00370
00371 ColumnIDCT()
00372
00373 #undef I
00374 #undef J
00375 #define I(x) AV_STRINGIFY(16*x + 8)"(%0)"
00376 #define J(x) AV_STRINGIFY(16*x + 8)"(%0)"
00377
00378 ColumnIDCT()
00379 :: "r"(output_data), "r"(ff_vp3_idct_data), "m"(ff_pw_8)
00380 );
00381 #undef I
00382 #undef J
00383
00384 }
00385
00386 void ff_vp3_idct_put_mmx(uint8_t *dest, int line_size, DCTELEM *block)
00387 {
00388 ff_vp3_idct_mmx(block);
00389 put_signed_pixels_clamped_mmx(block, dest, line_size);
00390 }
00391
00392 void ff_vp3_idct_add_mmx(uint8_t *dest, int line_size, DCTELEM *block)
00393 {
00394 ff_vp3_idct_mmx(block);
00395 add_pixels_clamped_mmx(block, dest, line_size);
00396 }