~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to ffmpeg/libavcodec/i386/motion_est_mmx.c

  • Committer: Bazaar Package Importer
  • Author(s): Christian Marillat
  • Date: 2004-08-29 10:53:42 UTC
  • Revision ID: james.westby@ubuntu.com-20040829105342-qgmnry37eadfkoxx
Tags: upstream-1.1.3
ImportĀ upstreamĀ versionĀ 1.1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * MMX optimized motion estimation
 
3
 * Copyright (c) 2001 Fabrice Bellard.
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU Lesser General Public
 
7
 * License as published by the Free Software Foundation; either
 
8
 * version 2 of the License, or (at your option) any later version.
 
9
 *
 
10
 * This library is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * Lesser General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU Lesser General Public
 
16
 * License along with this library; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 *
 
19
 * mostly by Michael Niedermayer <michaelni@gmx.at>
 
20
 */
 
21
#include "../dsputil.h"
 
22
 
 
23
static const __attribute__ ((aligned(8))) uint64_t round_tab[3]={
 
24
0x0000000000000000,
 
25
0x0001000100010001,
 
26
0x0002000200020002,
 
27
};
 
28
 
 
29
static __attribute__ ((aligned(8), unused)) uint64_t bone= 0x0101010101010101LL;
 
30
 
 
31
static inline void sad8_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h)
 
32
{
 
33
    int len= -(stride<<h);
 
34
    asm volatile(
 
35
        ".balign 16                     \n\t"
 
36
        "1:                             \n\t"
 
37
        "movq (%1, %%eax), %%mm0        \n\t"
 
38
        "movq (%2, %%eax), %%mm2        \n\t"
 
39
        "movq (%2, %%eax), %%mm4        \n\t"
 
40
        "addl %3, %%eax                 \n\t"
 
41
        "psubusb %%mm0, %%mm2           \n\t"
 
42
        "psubusb %%mm4, %%mm0           \n\t"
 
43
        "movq (%1, %%eax), %%mm1        \n\t"
 
44
        "movq (%2, %%eax), %%mm3        \n\t"
 
45
        "movq (%2, %%eax), %%mm5        \n\t"
 
46
        "psubusb %%mm1, %%mm3           \n\t"
 
47
        "psubusb %%mm5, %%mm1           \n\t"
 
48
        "por %%mm2, %%mm0               \n\t"
 
49
        "por %%mm1, %%mm3               \n\t"
 
50
        "movq %%mm0, %%mm1              \n\t"
 
51
        "movq %%mm3, %%mm2              \n\t"
 
52
        "punpcklbw %%mm7, %%mm0         \n\t"
 
53
        "punpckhbw %%mm7, %%mm1         \n\t"
 
54
        "punpcklbw %%mm7, %%mm3         \n\t"
 
55
        "punpckhbw %%mm7, %%mm2         \n\t"
 
56
        "paddw %%mm1, %%mm0             \n\t"
 
57
        "paddw %%mm3, %%mm2             \n\t"
 
58
        "paddw %%mm2, %%mm0             \n\t"
 
59
        "paddw %%mm0, %%mm6             \n\t"
 
60
        "addl %3, %%eax                 \n\t"
 
61
        " js 1b                         \n\t"
 
62
        : "+a" (len)
 
63
        : "r" (blk1 - len), "r" (blk2 - len), "r" (stride)
 
64
    );
 
65
}
 
66
 
 
67
static inline void sad8_mmx2(uint8_t *blk1, uint8_t *blk2, int stride, int h)
 
68
{
 
69
    int len= -(stride<<h);
 
70
    asm volatile(
 
71
        ".balign 16                     \n\t"
 
72
        "1:                             \n\t"
 
73
        "movq (%1, %%eax), %%mm0        \n\t"
 
74
        "movq (%2, %%eax), %%mm2        \n\t"
 
75
        "psadbw %%mm2, %%mm0            \n\t"
 
76
        "addl %3, %%eax                 \n\t"
 
77
        "movq (%1, %%eax), %%mm1        \n\t"
 
78
        "movq (%2, %%eax), %%mm3        \n\t"
 
79
        "psadbw %%mm1, %%mm3            \n\t"
 
80
        "paddw %%mm3, %%mm0             \n\t"
 
81
        "paddw %%mm0, %%mm6             \n\t"
 
82
        "addl %3, %%eax                 \n\t"
 
83
        " js 1b                         \n\t"
 
84
        : "+a" (len)
 
85
        : "r" (blk1 - len), "r" (blk2 - len), "r" (stride)
 
86
    );
 
87
}
 
88
 
 
89
static inline void sad8_2_mmx2(uint8_t *blk1a, uint8_t *blk1b, uint8_t *blk2, int stride, int h)
 
90
{
 
91
    int len= -(stride<<h);
 
92
    asm volatile(
 
93
        ".balign 16                     \n\t"
 
94
        "1:                             \n\t"
 
95
        "movq (%1, %%eax), %%mm0        \n\t"
 
96
        "movq (%2, %%eax), %%mm2        \n\t"
 
97
        "pavgb %%mm2, %%mm0             \n\t"
 
98
        "movq (%3, %%eax), %%mm2        \n\t"
 
99
        "psadbw %%mm2, %%mm0            \n\t"
 
100
        "addl %4, %%eax                 \n\t"
 
101
        "movq (%1, %%eax), %%mm1        \n\t"
 
102
        "movq (%2, %%eax), %%mm3        \n\t"
 
103
        "pavgb %%mm1, %%mm3             \n\t"
 
104
        "movq (%3, %%eax), %%mm1        \n\t"
 
105
        "psadbw %%mm1, %%mm3            \n\t"
 
106
        "paddw %%mm3, %%mm0             \n\t"
 
107
        "paddw %%mm0, %%mm6             \n\t"
 
108
        "addl %4, %%eax                 \n\t"
 
109
        " js 1b                         \n\t"
 
110
        : "+a" (len)
 
111
        : "r" (blk1a - len), "r" (blk1b -len), "r" (blk2 - len), "r" (stride)
 
112
    );
 
113
}
 
114
 
 
115
static inline void sad8_4_mmx2(uint8_t *blk1, uint8_t *blk2, int stride, int h)
 
116
{ //FIXME reuse src
 
117
    int len= -(stride<<h);
 
118
    asm volatile(
 
119
        ".balign 16                     \n\t"
 
120
        "movq "MANGLE(bone)", %%mm5     \n\t"
 
121
        "1:                             \n\t"
 
122
        "movq (%1, %%eax), %%mm0        \n\t"
 
123
        "movq (%2, %%eax), %%mm2        \n\t"
 
124
        "movq 1(%1, %%eax), %%mm1       \n\t"
 
125
        "movq 1(%2, %%eax), %%mm3       \n\t"
 
126
        "pavgb %%mm2, %%mm0             \n\t"
 
127
        "pavgb %%mm1, %%mm3             \n\t"
 
128
        "psubusb %%mm5, %%mm3           \n\t"
 
129
        "pavgb %%mm3, %%mm0             \n\t"
 
130
        "movq (%3, %%eax), %%mm2        \n\t"
 
131
        "psadbw %%mm2, %%mm0            \n\t"
 
132
        "addl %4, %%eax                 \n\t"
 
133
        "movq (%1, %%eax), %%mm1        \n\t"
 
134
        "movq (%2, %%eax), %%mm3        \n\t"
 
135
        "movq 1(%1, %%eax), %%mm2       \n\t"
 
136
        "movq 1(%2, %%eax), %%mm4       \n\t"
 
137
        "pavgb %%mm3, %%mm1             \n\t"
 
138
        "pavgb %%mm4, %%mm2             \n\t"
 
139
        "psubusb %%mm5, %%mm2           \n\t"
 
140
        "pavgb %%mm1, %%mm2             \n\t"
 
141
        "movq (%3, %%eax), %%mm1        \n\t"
 
142
        "psadbw %%mm1, %%mm2            \n\t"
 
143
        "paddw %%mm2, %%mm0             \n\t"
 
144
        "paddw %%mm0, %%mm6             \n\t"
 
145
        "addl %4, %%eax                 \n\t"
 
146
        " js 1b                         \n\t"
 
147
        : "+a" (len)
 
148
        : "r" (blk1 - len), "r" (blk1 - len + stride), "r" (blk2 - len), "r" (stride)
 
149
    );
 
150
}
 
151
 
 
152
static inline void sad8_2_mmx(uint8_t *blk1a, uint8_t *blk1b, uint8_t *blk2, int stride, int h)
 
153
{
 
154
    int len= -(stride<<h);
 
155
    asm volatile(
 
156
        ".balign 16                     \n\t"
 
157
        "1:                             \n\t"
 
158
        "movq (%1, %%eax), %%mm0        \n\t"
 
159
        "movq (%2, %%eax), %%mm1        \n\t"
 
160
        "movq (%1, %%eax), %%mm2        \n\t"
 
161
        "movq (%2, %%eax), %%mm3        \n\t"
 
162
        "punpcklbw %%mm7, %%mm0         \n\t"
 
163
        "punpcklbw %%mm7, %%mm1         \n\t"
 
164
        "punpckhbw %%mm7, %%mm2         \n\t"
 
165
        "punpckhbw %%mm7, %%mm3         \n\t"
 
166
        "paddw %%mm0, %%mm1             \n\t"
 
167
        "paddw %%mm2, %%mm3             \n\t"
 
168
        "movq (%3, %%eax), %%mm4        \n\t"
 
169
        "movq (%3, %%eax), %%mm2        \n\t"
 
170
        "paddw %%mm5, %%mm1             \n\t"
 
171
        "paddw %%mm5, %%mm3             \n\t"
 
172
        "psrlw $1, %%mm1                \n\t"
 
173
        "psrlw $1, %%mm3                \n\t"
 
174
        "packuswb %%mm3, %%mm1          \n\t"
 
175
        "psubusb %%mm1, %%mm4           \n\t"
 
176
        "psubusb %%mm2, %%mm1           \n\t"
 
177
        "por %%mm4, %%mm1               \n\t"
 
178
        "movq %%mm1, %%mm0              \n\t"
 
179
        "punpcklbw %%mm7, %%mm0         \n\t"
 
180
        "punpckhbw %%mm7, %%mm1         \n\t"
 
181
        "paddw %%mm1, %%mm0             \n\t"
 
182
        "paddw %%mm0, %%mm6             \n\t"
 
183
        "addl %4, %%eax                 \n\t"
 
184
        " js 1b                         \n\t"
 
185
        : "+a" (len)
 
186
        : "r" (blk1a - len), "r" (blk1b -len), "r" (blk2 - len), "r" (stride)
 
187
    );
 
188
}
 
189
 
 
190
static inline void sad8_4_mmx(uint8_t *blk1, uint8_t *blk2, int stride, int h)
 
191
{
 
192
    int len= -(stride<<h);
 
193
    asm volatile(
 
194
        ".balign 16                     \n\t"
 
195
        "1:                             \n\t"
 
196
        "movq (%1, %%eax), %%mm0        \n\t"
 
197
        "movq (%2, %%eax), %%mm1        \n\t"
 
198
        "movq %%mm0, %%mm4              \n\t"
 
199
        "movq %%mm1, %%mm2              \n\t"
 
200
        "punpcklbw %%mm7, %%mm0         \n\t"
 
201
        "punpcklbw %%mm7, %%mm1         \n\t"
 
202
        "punpckhbw %%mm7, %%mm4         \n\t"
 
203
        "punpckhbw %%mm7, %%mm2         \n\t"
 
204
        "paddw %%mm1, %%mm0             \n\t"
 
205
        "paddw %%mm2, %%mm4             \n\t"
 
206
        "movq 1(%1, %%eax), %%mm2       \n\t"
 
207
        "movq 1(%2, %%eax), %%mm3       \n\t"
 
208
        "movq %%mm2, %%mm1              \n\t"
 
209
        "punpcklbw %%mm7, %%mm2         \n\t"
 
210
        "punpckhbw %%mm7, %%mm1         \n\t"
 
211
        "paddw %%mm0, %%mm2             \n\t"
 
212
        "paddw %%mm4, %%mm1             \n\t"
 
213
        "movq %%mm3, %%mm4              \n\t"
 
214
        "punpcklbw %%mm7, %%mm3         \n\t"
 
215
        "punpckhbw %%mm7, %%mm4         \n\t"
 
216
        "paddw %%mm3, %%mm2             \n\t"
 
217
        "paddw %%mm4, %%mm1             \n\t"
 
218
        "movq (%3, %%eax), %%mm3        \n\t"
 
219
        "movq (%3, %%eax), %%mm4        \n\t"
 
220
        "paddw %%mm5, %%mm2             \n\t"
 
221
        "paddw %%mm5, %%mm1             \n\t"
 
222
        "psrlw $2, %%mm2                \n\t"
 
223
        "psrlw $2, %%mm1                \n\t"
 
224
        "packuswb %%mm1, %%mm2          \n\t"
 
225
        "psubusb %%mm2, %%mm3           \n\t"
 
226
        "psubusb %%mm4, %%mm2           \n\t"
 
227
        "por %%mm3, %%mm2               \n\t"
 
228
        "movq %%mm2, %%mm0              \n\t"
 
229
        "punpcklbw %%mm7, %%mm0         \n\t"
 
230
        "punpckhbw %%mm7, %%mm2         \n\t"
 
231
        "paddw %%mm2, %%mm0             \n\t"
 
232
        "paddw %%mm0, %%mm6             \n\t"
 
233
        "addl %4, %%eax                 \n\t"
 
234
        " js 1b                         \n\t"
 
235
        : "+a" (len)
 
236
        : "r" (blk1 - len), "r" (blk1 -len + stride), "r" (blk2 - len), "r" (stride)
 
237
    );
 
238
}
 
239
 
 
240
static inline int sum_mmx(void)
 
241
{
 
242
    int ret;
 
243
    asm volatile(
 
244
        "movq %%mm6, %%mm0              \n\t"
 
245
        "psrlq $32, %%mm6               \n\t"
 
246
        "paddw %%mm0, %%mm6             \n\t"
 
247
        "movq %%mm6, %%mm0              \n\t"
 
248
        "psrlq $16, %%mm6               \n\t"
 
249
        "paddw %%mm0, %%mm6             \n\t"
 
250
        "movd %%mm6, %0                 \n\t"
 
251
        : "=r" (ret)
 
252
    );
 
253
    return ret&0xFFFF;
 
254
}
 
255
 
 
256
static inline int sum_mmx2(void)
 
257
{
 
258
    int ret;
 
259
    asm volatile(
 
260
        "movd %%mm6, %0                 \n\t"
 
261
        : "=r" (ret)
 
262
    );
 
263
    return ret;
 
264
}
 
265
 
 
266
 
 
267
#define PIX_SAD(suf)\
 
268
static int pix_abs8x8_ ## suf(uint8_t *blk2, uint8_t *blk1, int stride)\
 
269
{\
 
270
    asm volatile("pxor %%mm7, %%mm7             \n\t"\
 
271
                 "pxor %%mm6, %%mm6             \n\t":);\
 
272
\
 
273
    sad8_ ## suf(blk1, blk2, stride, 3);\
 
274
\
 
275
    return sum_ ## suf();\
 
276
}\
 
277
static int sad8x8_ ## suf(void *s, uint8_t *blk2, uint8_t *blk1, int stride)\
 
278
{\
 
279
    asm volatile("pxor %%mm7, %%mm7             \n\t"\
 
280
                 "pxor %%mm6, %%mm6             \n\t":);\
 
281
\
 
282
    sad8_ ## suf(blk1, blk2, stride, 3);\
 
283
\
 
284
    return sum_ ## suf();\
 
285
}\
 
286
\
 
287
static int pix_abs8x8_x2_ ## suf(uint8_t *blk2, uint8_t *blk1, int stride)\
 
288
{\
 
289
    asm volatile("pxor %%mm7, %%mm7             \n\t"\
 
290
                 "pxor %%mm6, %%mm6             \n\t"\
 
291
                 "movq %0, %%mm5                \n\t"\
 
292
                 :: "m"(round_tab[1]) \
 
293
                 );\
 
294
\
 
295
    sad8_2_ ## suf(blk1, blk1+1, blk2, stride, 3);\
 
296
\
 
297
    return sum_ ## suf();\
 
298
}\
 
299
\
 
300
static int pix_abs8x8_y2_ ## suf(uint8_t *blk2, uint8_t *blk1, int stride)\
 
301
{\
 
302
    asm volatile("pxor %%mm7, %%mm7             \n\t"\
 
303
                 "pxor %%mm6, %%mm6             \n\t"\
 
304
                 "movq %0, %%mm5                \n\t"\
 
305
                 :: "m"(round_tab[1]) \
 
306
                 );\
 
307
\
 
308
    sad8_2_ ## suf(blk1, blk1+stride, blk2, stride, 3);\
 
309
\
 
310
    return sum_ ## suf();\
 
311
}\
 
312
\
 
313
static int pix_abs8x8_xy2_ ## suf(uint8_t *blk2, uint8_t *blk1, int stride)\
 
314
{\
 
315
    asm volatile("pxor %%mm7, %%mm7             \n\t"\
 
316
                 "pxor %%mm6, %%mm6             \n\t"\
 
317
                 "movq %0, %%mm5                \n\t"\
 
318
                 :: "m"(round_tab[2]) \
 
319
                 );\
 
320
\
 
321
    sad8_4_ ## suf(blk1, blk2, stride, 3);\
 
322
\
 
323
    return sum_ ## suf();\
 
324
}\
 
325
\
 
326
static int pix_abs16x16_ ## suf(uint8_t *blk2, uint8_t *blk1, int stride)\
 
327
{\
 
328
    asm volatile("pxor %%mm7, %%mm7             \n\t"\
 
329
                 "pxor %%mm6, %%mm6             \n\t":);\
 
330
\
 
331
    sad8_ ## suf(blk1  , blk2  , stride, 4);\
 
332
    sad8_ ## suf(blk1+8, blk2+8, stride, 4);\
 
333
\
 
334
    return sum_ ## suf();\
 
335
}\
 
336
static int sad16x16_ ## suf(void *s, uint8_t *blk2, uint8_t *blk1, int stride)\
 
337
{\
 
338
    asm volatile("pxor %%mm7, %%mm7             \n\t"\
 
339
                 "pxor %%mm6, %%mm6             \n\t":);\
 
340
\
 
341
    sad8_ ## suf(blk1  , blk2  , stride, 4);\
 
342
    sad8_ ## suf(blk1+8, blk2+8, stride, 4);\
 
343
\
 
344
    return sum_ ## suf();\
 
345
}\
 
346
static int pix_abs16x16_x2_ ## suf(uint8_t *blk2, uint8_t *blk1, int stride)\
 
347
{\
 
348
    asm volatile("pxor %%mm7, %%mm7             \n\t"\
 
349
                 "pxor %%mm6, %%mm6             \n\t"\
 
350
                 "movq %0, %%mm5                \n\t"\
 
351
                 :: "m"(round_tab[1]) \
 
352
                 );\
 
353
\
 
354
    sad8_2_ ## suf(blk1  , blk1+1, blk2  , stride, 4);\
 
355
    sad8_2_ ## suf(blk1+8, blk1+9, blk2+8, stride, 4);\
 
356
\
 
357
    return sum_ ## suf();\
 
358
}\
 
359
static int pix_abs16x16_y2_ ## suf(uint8_t *blk2, uint8_t *blk1, int stride)\
 
360
{\
 
361
    asm volatile("pxor %%mm7, %%mm7             \n\t"\
 
362
                 "pxor %%mm6, %%mm6             \n\t"\
 
363
                 "movq %0, %%mm5                \n\t"\
 
364
                 :: "m"(round_tab[1]) \
 
365
                 );\
 
366
\
 
367
    sad8_2_ ## suf(blk1  , blk1+stride,  blk2  , stride, 4);\
 
368
    sad8_2_ ## suf(blk1+8, blk1+stride+8,blk2+8, stride, 4);\
 
369
\
 
370
    return sum_ ## suf();\
 
371
}\
 
372
static int pix_abs16x16_xy2_ ## suf(uint8_t *blk2, uint8_t *blk1, int stride)\
 
373
{\
 
374
    asm volatile("pxor %%mm7, %%mm7             \n\t"\
 
375
                 "pxor %%mm6, %%mm6             \n\t"\
 
376
                 "movq %0, %%mm5                \n\t"\
 
377
                 :: "m"(round_tab[2]) \
 
378
                 );\
 
379
\
 
380
    sad8_4_ ## suf(blk1  , blk2  , stride, 4);\
 
381
    sad8_4_ ## suf(blk1+8, blk2+8, stride, 4);\
 
382
\
 
383
    return sum_ ## suf();\
 
384
}\
 
385
 
 
386
PIX_SAD(mmx)
 
387
PIX_SAD(mmx2)
 
388
 
 
389
void dsputil_init_pix_mmx(DSPContext* c, AVCodecContext *avctx)
 
390
{
 
391
    if (mm_flags & MM_MMX) {
 
392
        c->pix_abs16x16     = pix_abs16x16_mmx;
 
393
        c->pix_abs16x16_x2  = pix_abs16x16_x2_mmx;
 
394
        c->pix_abs16x16_y2  = pix_abs16x16_y2_mmx;
 
395
        c->pix_abs16x16_xy2 = pix_abs16x16_xy2_mmx;
 
396
        c->pix_abs8x8     = pix_abs8x8_mmx;
 
397
        c->pix_abs8x8_x2  = pix_abs8x8_x2_mmx;
 
398
        c->pix_abs8x8_y2  = pix_abs8x8_y2_mmx;
 
399
        c->pix_abs8x8_xy2 = pix_abs8x8_xy2_mmx;
 
400
 
 
401
        c->sad[0]= sad16x16_mmx;
 
402
        c->sad[1]= sad8x8_mmx;
 
403
    }
 
404
    if (mm_flags & MM_MMXEXT) {
 
405
        c->pix_abs16x16     = pix_abs16x16_mmx2;
 
406
        c->pix_abs8x8     = pix_abs8x8_mmx2;
 
407
 
 
408
        c->sad[0]= sad16x16_mmx2;
 
409
        c->sad[1]= sad8x8_mmx2;
 
410
        
 
411
        if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
 
412
            c->pix_abs16x16_x2  = pix_abs16x16_x2_mmx2;
 
413
            c->pix_abs16x16_y2  = pix_abs16x16_y2_mmx2;
 
414
            c->pix_abs16x16_xy2 = pix_abs16x16_xy2_mmx2;
 
415
            c->pix_abs8x8_x2  = pix_abs8x8_x2_mmx2;
 
416
            c->pix_abs8x8_y2  = pix_abs8x8_y2_mmx2;
 
417
            c->pix_abs8x8_xy2 = pix_abs8x8_xy2_mmx2;
 
418
        }
 
419
    }
 
420
}