~ubuntu-branches/ubuntu/feisty/avidemux/feisty

« back to all changes in this revision

Viewing changes to avidemux/mpeg2enc/mblock_sad_mmx.cc

  • Committer: Bazaar Package Importer
  • Author(s): Christian Marillat
  • Date: 2005-05-25 13:02:29 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20050525130229-jw94cav0yhmg7vjw
Tags: 1:2.0.40-0.0
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 *   mblock_sad_mmxe.s:  
 
3
 *
 
4
 *
 
5
 *     Enhanced MMX optimized Sum Absolute Differences routines for macroblocks
 
6
 *     (interpolated, 1-pel, 2*2 sub-sampled pel and 4*4 sub-sampled pel)
 
7
 * 
 
8
 *   sad_* Original Copyright (C) 2000 Chris Atenasio <chris@crud.net>
 
9
 *   Enhancements and rest Copyright (C) 2000 Andrew Stevens <as@comlab.ox.ac.uk>
 
10
 * 
 
11
 * 
 
12
 *   This program is free software; you can redistribute it and/or
 
13
 *   modify it under the terms of the GNU General Public License
 
14
 *   as published by the Free Software Foundation; either version 2
 
15
 *   of the License, or (at your option) any later version.
 
16
 * 
 
17
 *   This program is distributed in the hope that it will be useful,
 
18
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
20
 *   GNU General Public License for more details.
 
21
 * 
 
22
 *   You should have received a copy of the GNU General Public License
 
23
 *   along with this program; if not, write to the Free Software
 
24
 *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
25
 */
 
26
 
 
27
#include <config.h>
 
28
#include "mjpeg_types.h"
 
29
#if defined( ARCH_X86)  || defined(ARCH_X86_64)
 
30
#include "mmx.h"
 
31
 
 
32
 
 
33
int sad_00_mmx(uint8_t *blk1,uint8_t *blk2,int lx,int h, int distlim)
 
34
{
 
35
        int rv;
 
36
/*
 
37
 *  N.b. distlim is *ignored* as testing for it is more expensive than the
 
38
 *  occasional saving by aborting the computionation early...
 
39
 * 
 
40
 *  mm0 = distance accumulators (4 words)
 
41
 *  mm1 = temp 
 
42
 *  mm2 = temp 
 
43
 *  mm3 = temp
 
44
 *  mm4 = temp
 
45
 *  mm5 = temp 
 
46
 *  mm6 = 0
 
47
 *  mm7 = temp
 
48
 */
 
49
 
 
50
        pxor_r2r(mm0, mm0);
 
51
        pxor_r2r(mm6, mm6);
 
52
        
 
53
        do {
 
54
                movq_m2r(blk1[0], mm4); /* load first 8 bytes of p1 row  */
 
55
                movq_m2r(blk2[0], mm5); /* load first 8 bytes of p2 row  */
 
56
                
 
57
                movq_r2r(mm4, mm7);     /*  mm5 = abs(mm4-mm5) */
 
58
                psubusb_r2r(mm5, mm7);
 
59
                psubusb_r2r(mm4, mm5);
 
60
                paddb_r2r(mm7, mm5);
 
61
                
 
62
                /* Add the abs(mm4-mm5) bytes to the accumulators */
 
63
                movq_m2r(blk1[8], mm2); /* load second 8 bytes of p1 row (interleaved) */
 
64
                movq_r2r(mm5, mm7);     /* mm7 := [i :  B0..3, mm1]W */
 
65
                punpcklbw_r2r(mm6, mm7);
 
66
                movq_m2r(blk2[8], mm3);
 
67
                paddw_r2r(mm7, mm0);
 
68
                punpckhbw_r2r(mm6, mm5);
 
69
                paddw_r2r(mm5, mm0);
 
70
                
 
71
                        /* This is logically where the mm2, mm3 loads would go... */
 
72
                
 
73
                movq_r2r(mm2, mm7);     /* mm3 = abs(mm2-mm3) */
 
74
                psubusb_r2r(mm3, mm7);
 
75
                psubusb_r2r(mm2, mm3);
 
76
                paddb_r2r(mm7, mm3);
 
77
                
 
78
                /* Add the abs(mm4-mm5) bytes to the accumulators */
 
79
                movq_r2r(mm3, mm7);
 
80
                punpcklbw_r2r(mm6, mm7);
 
81
                punpckhbw_r2r(mm6, mm3);
 
82
                paddw_r2r(mm7, mm0);
 
83
                
 
84
                blk1 += lx; /* update pointers to next row */
 
85
                blk2 += lx;
 
86
                
 
87
                paddw_r2r(mm3, mm0);
 
88
                
 
89
                h--;
 
90
        } while(h);
 
91
        
 
92
        /* Sum the Accumulators */
 
93
        movq_r2r(mm0, mm5);     /*  mm5 := [W0+W2,W1+W3, mm0 */
 
94
        psrlq_i2r(32, mm5);
 
95
        movq_r2r(mm0, mm4);
 
96
        paddw_r2r(mm5, mm4);
 
97
        
 
98
        movq_r2r(mm4, mm7);     /* mm6 := [W0+W2+W1+W3, mm0] */
 
99
        psrlq_i2r(16, mm7);
 
100
        paddw_r2r(mm7, mm4);
 
101
        movd_r2g(mm4, rv);      /* store return value */
 
102
        rv &= 0xffff;
 
103
 
 
104
        emms();
 
105
 
 
106
        return rv;
 
107
}
 
108
 
 
109
 
 
110
 
 
111
/*
 
112
 *        sad_01_mmx.s:  mmx1 optimised 7bit*8 word absolute difference sum
 
113
 *        We're reduce to seven bits as otherwise we also have to mess
 
114
 *        horribly with carries and signed only comparisons make the code
 
115
 *        simply enormous (and probably barely faster than a simple loop).
 
116
 *        Since signals with a bona-fide 8bit res will be rare we simply
 
117
 *        take the precision hit...
 
118
 *        Actually we don't worry about carries from the low-order bits
 
119
 *        either so 1/4 of the time we'll be 1 too low...
 
120
 *  
 
121
 *   Copyright (C) 2000 Andrew Stevens <as@comlab.ox.ac.uk>
 
122
 * 
 
123
 * 
 
124
 *   This program is free software; you can redistribute it and/or
 
125
 *   modify it under the terms of the GNU General Public License
 
126
 *   as published by the Free Software Foundation; either version 2
 
127
 *   of the License, or (at your option) any later version.
 
128
 * 
 
129
 *   This program is distributed in the hope that it will be useful,
 
130
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
131
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
132
 *   GNU General Public License for more details.
 
133
 * 
 
134
 *   You should have received a copy of the GNU General Public License
 
135
 *   along with this program; if not, write to the Free Software
 
136
 *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
137
 */
 
138
 
 
139
int sad_01_mmx(uint8_t *p1, uint8_t *p2, int lx, int h)
 
140
{
 
141
        int rv;
 
142
 
 
143
/*
 
144
 *  mm0 = distance accumulators (4 words)
 
145
 *  mm1 = bytes p2
 
146
 *  mm2 = bytes p1
 
147
 *  mm3 = bytes p1+1
 
148
 *  mm4 = temp 4 bytes in words interpolating p1, p1+1
 
149
 *  mm5 = temp 4 bytes in words from p2
 
150
 *  mm6 = temp comparison bit mask p1,p2
 
151
 *  mm7 = temp comparison bit mask p2,p1
 
152
 */
 
153
        pxor_r2r(mm0, mm0);
 
154
 
 
155
 
 
156
        do {
 
157
                /* First 8 bytes of row */
 
158
                
 
159
                /* First 4 bytes of 8 */
 
160
                
 
161
                movq_m2r(p1[0], mm4);           /* mm4 := first 4 bytes p1 */
 
162
                pxor_r2r(mm7, mm7);
 
163
                movq_r2r(mm4, mm2);             /* mm2 records all 8 bytes */
 
164
                punpcklbw_r2r(mm7, mm4);        /* First 4 bytes p1 in Words... */
 
165
                
 
166
                movq_m2r(p1[1], mm6);           /* mm6 := first 4 bytes p1+1 */
 
167
                movq_r2r(mm6, mm3);             /* mm3 records all 8 bytes */
 
168
                punpcklbw_r2r(mm7, mm6);
 
169
                paddw_r2r(mm6, mm4);            /* mm4 := First 4 bytes interpolated in words */
 
170
                psrlw_i2r(1, mm4);
 
171
                
 
172
                movq_m2r(p2[0], mm5);           /* mm5:=first 4 bytes of p2 in words */
 
173
                movq_r2r(mm5, mm1);
 
174
                punpcklbw_r2r(mm7, mm5);
 
175
                
 
176
                movq_r2r(mm4, mm7);
 
177
                pcmpgtw_r2r(mm5, mm7);          /* mm7 := [i : W0..3,mm4>mm5] */
 
178
                
 
179
                movq_r2r(mm4, mm6);             /* mm6 := [i : W0..3, (mm4-mm5)*(mm4-mm5 > 0)] */
 
180
                psubw_r2r(mm5, mm6);
 
181
                pand_r2r(mm7, mm6);
 
182
                
 
183
                paddw_r2r(mm6, mm0);            /*  Add to accumulator */
 
184
                
 
185
                movq_r2r(mm5, mm6);             /* mm6 := [i : W0..3,mm5>mm4] */
 
186
                pcmpgtw_r2r(mm4, mm6);
 
187
                psubw_r2r(mm4, mm5);            /*  mm5 := [i : B0..7, (mm5-mm4)*(mm5-mm4 > 0)] */
 
188
                pand_r2r(mm6, mm5);
 
189
                
 
190
                paddw_r2r(mm5, mm0);            /*  Add to accumulator */
 
191
        
 
192
                /* Second 4 bytes of 8 */
 
193
                
 
194
                movq_r2r(mm2, mm4);             /* mm4 := Second 4 bytes p1 in words */
 
195
                pxor_r2r(mm7, mm7);
 
196
                punpckhbw_r2r(mm7, mm4);
 
197
                movq_r2r(mm3, mm6);             /*  mm6 := Second 4 bytes p1+1 in words */
 
198
                punpckhbw_r2r(mm7, mm6);
 
199
                
 
200
                paddw_r2r(mm6, mm4);            /* mm4 := First 4 Interpolated bytes in words */
 
201
                psrlw_i2r(1, mm4);
 
202
                
 
203
                movq_r2r(mm1, mm5);             /* mm5:= second 4 bytes of p2 in words */
 
204
                punpckhbw_r2r(mm7, mm5);
 
205
                
 
206
                movq_r2r(mm4, mm7);
 
207
                pcmpgtw_r2r(mm5, mm7);          /* mm7 := [i : W0..3,mm4>mm5] */
 
208
                
 
209
                movq_r2r(mm4, mm6);             /* mm6 := [i : W0..3, (mm4-mm5)*(mm4-mm5 > 0)] */
 
210
                psubw_r2r(mm5, mm6);
 
211
                pand_r2r(mm7, mm6);
 
212
                
 
213
                paddw_r2r(mm6, mm0);            /*  Add to accumulator */
 
214
                
 
215
                movq_r2r(mm5, mm6);             /* mm6 := [i : W0..3,mm5>mm4] */
 
216
                pcmpgtw_r2r(mm4, mm6);
 
217
                psubw_r2r(mm4, mm5);            /*  mm5 := [i : B0..7, (mm5-mm4)*(mm5-mm4 > 0)] */
 
218
                pand_r2r(mm6, mm5);
 
219
                
 
220
                paddw_r2r(mm5, mm0);            /* Add to accumulator */
 
221
                
 
222
 
 
223
                /* Second 8 bytes of row */
 
224
                
 
225
                /* First 4 bytes of 8 */
 
226
                
 
227
                movq_m2r(p1[8], mm4);           /* mm4 := first 4 bytes p1+8 */
 
228
                pxor_r2r(mm7, mm7);
 
229
                movq_r2r(mm4, mm2);             /* mm2 records all 8 bytes */
 
230
                punpcklbw_r2r(mm7, mm4);        /* First 4 bytes p1 in Words... */
 
231
                
 
232
                movq_m2r(p1[9], mm6);           /* mm6 := first 4 bytes p1+9 */
 
233
                movq_r2r(mm6, mm3);             /* mm3 records all 8 bytes */
 
234
                punpcklbw_r2r(mm7, mm6);
 
235
                paddw_r2r(mm6, mm4);            /* mm4 := First 4 bytes interpolated in words */
 
236
                psrlw_i2r(1, mm4);
 
237
                
 
238
                movq_m2r(p2[8], mm5);           /* mm5:=first 4 bytes of p2+8 in words */
 
239
                movq_r2r(mm5, mm1);
 
240
                punpcklbw_r2r(mm7, mm5);
 
241
                
 
242
                movq_r2r(mm4, mm7);
 
243
                pcmpgtw_r2r(mm5, mm7);          /* mm7 := [i : W0..3,mm4>mm5] */
 
244
                
 
245
                movq_r2r(mm4, mm6);             /* mm6 := [i : W0..3, (mm4-mm5)*(mm4-mm5 > 0)] */
 
246
                psubw_r2r(mm5, mm6);
 
247
                pand_r2r(mm7, mm6);
 
248
                
 
249
                paddw_r2r(mm6, mm0);            /*  Add to accumulator */
 
250
                
 
251
                movq_r2r(mm5, mm6);             /* mm6 := [i : W0..3,mm5>mm4] */
 
252
                pcmpgtw_r2r(mm4, mm6);
 
253
                psubw_r2r(mm4, mm5);            /*  mm5 := [i : B0..7, (mm5-mm4)*(mm5-mm4 > 0)] */
 
254
                pand_r2r(mm6, mm5);
 
255
                
 
256
                paddw_r2r(mm5, mm0);            /*  Add to accumulator */
 
257
        
 
258
                /* Second 4 bytes of 8 */
 
259
                
 
260
                movq_r2r(mm2, mm4);             /* mm4 := Second 4 bytes p1 in words */
 
261
                pxor_r2r(mm7, mm7);
 
262
                punpckhbw_r2r(mm7, mm4);
 
263
                movq_r2r(mm3, mm6);             /*  mm6 := Second 4 bytes p1+1 in words */
 
264
                punpckhbw_r2r(mm7, mm6);
 
265
                
 
266
                paddw_r2r(mm6, mm4);            /* mm4 := First 4 Interpolated bytes in words */
 
267
                psrlw_i2r(1, mm4);
 
268
                
 
269
                movq_r2r(mm1, mm5);             /* mm5:= second 4 bytes of p2 in words */
 
270
                punpckhbw_r2r(mm7, mm5);
 
271
                
 
272
                movq_r2r(mm4, mm7);
 
273
                pcmpgtw_r2r(mm5, mm7);          /* mm7 := [i : W0..3,mm4>mm5] */
 
274
                
 
275
                movq_r2r(mm4, mm6);             /* mm6 := [i : W0..3, (mm4-mm5)*(mm4-mm5 > 0)] */
 
276
                psubw_r2r(mm5, mm6);
 
277
                pand_r2r(mm7, mm6);
 
278
                
 
279
                paddw_r2r(mm6, mm0);            /*  Add to accumulator */
 
280
                
 
281
                movq_r2r(mm5, mm6);             /* mm6 := [i : W0..3,mm5>mm4] */
 
282
                pcmpgtw_r2r(mm4, mm6);
 
283
                psubw_r2r(mm4, mm5);            /*  mm5 := [i : B0..7, (mm5-mm4)*(mm5-mm4 > 0)] */
 
284
                pand_r2r(mm6, mm5);
 
285
                
 
286
                paddw_r2r(mm5, mm0);            /* Add to accumulator */
 
287
                
 
288
                
 
289
                p1 += lx; /* update pointers to next row */
 
290
                p2 += lx;
 
291
 
 
292
                h--;
 
293
        } while (h);
 
294
 
 
295
        /* Sum the Accumulators */
 
296
        movq_r2r(mm0, mm4);
 
297
        psrlq_i2r(32, mm4);
 
298
        paddw_r2r(mm4, mm0);
 
299
        movq_r2r(mm0, mm6);
 
300
        psrlq_i2r(16, mm6);
 
301
        paddw_r2r(mm6, mm0);
 
302
        movd_r2g(mm0, rv);      /* store return value */
 
303
        rv &= 0xffff;
 
304
 
 
305
        emms();
 
306
 
 
307
        return rv;
 
308
}
 
309
 
 
310
 
 
311
/*
 
312
 *     sad_01_mmx.s:  mmx1 optimised 7bit*8 word absolute difference sum
 
313
 *        We're reduce to seven bits as otherwise we also have to mess
 
314
 *        horribly with carries and signed only comparisons make the code
 
315
 *        simply enormous (and probably barely faster than a simple loop).
 
316
 *        Since signals with a bona-fide 8bit res will be rare we simply
 
317
 *        take the precision hit...
 
318
 *        Actually we don't worry about carries from the low-order bits
 
319
 *        either so 1/4 of the time we'll be 1 too low...
 
320
 *  
 
321
 *   Copyright (C) 2000 Andrew Stevens <as@comlab.ox.ac.uk>
 
322
 * 
 
323
 * 
 
324
 *   This program is free software; you can redistribute it and/or
 
325
 *   modify it under the terms of the GNU General Public License
 
326
 *   as published by the Free Software Foundation; either version 2
 
327
 *   of the License, or (at your option) any later version.
 
328
 * 
 
329
 *   This program is distributed in the hope that it will be useful,
 
330
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
331
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
332
 *   GNU General Public License for more details.
 
333
 * 
 
334
 *   You should have received a copy of the GNU General Public License
 
335
 *   along with this program; if not, write to the Free Software
 
336
 *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
337
 */
 
338
 
 
339
int sad_10_mmx(uint8_t *p1, uint8_t *p2, int lx, int h)
 
340
{
 
341
        int rv;
 
342
        
 
343
/*
 
344
 *  mm0 = distance accumulators (4 words)
 
345
 *  mm1 = bytes p2
 
346
 *  mm2 = bytes p1
 
347
 *  mm3 = bytes p1+1
 
348
 *  mm4 = temp 4 bytes in words interpolating p1, p1+1
 
349
 *  mm5 = temp 4 bytes in words from p2
 
350
 *  mm6 = temp comparison bit mask p1,p2
 
351
 *  mm7 = temp comparison bit mask p2,p1
 
352
 */
 
353
        
 
354
        pxor_r2r(mm0, mm0);
 
355
        
 
356
        do {
 
357
                /* First 8 bytes of row */
 
358
                
 
359
                /* First 4 bytes of 8 */
 
360
                
 
361
                movq_m2r(p1[0], mm4);           /* mm4 := first 4 bytes p1 */
 
362
                pxor_r2r(mm7, mm7);
 
363
                movq_r2r(mm4, mm2);             /* mm2 records all 8 bytes */
 
364
                punpcklbw_r2r(mm7, mm4);        /* First 4 bytes p1 in Words... */
 
365
                
 
366
                movq_m2r(p1[lx], mm6);          /* mm6 := first 4 bytes p1+lx */
 
367
                movq_r2r(mm6, mm3);             /* mm3 records all 8 bytes */
 
368
                punpcklbw_r2r(mm7, mm6);
 
369
                paddw_r2r(mm6, mm4);            /* mm4 := First 4 bytes interpolated in words */
 
370
                psrlw_i2r(1, mm4);
 
371
                
 
372
                movq_m2r(p2[0], mm5);           /* mm5:=first 4 bytes of p2 in words */
 
373
                movq_r2r(mm5, mm1);
 
374
                punpcklbw_r2r(mm7, mm5);
 
375
                
 
376
                movq_r2r(mm4, mm7);
 
377
                pcmpgtw_r2r(mm5, mm7);          /* mm7 := [i : W0..3,mm4>mm5] */
 
378
                
 
379
                movq_r2r(mm4, mm6);             /* mm6 := [i : W0..3, (mm4-mm5)*(mm4-mm5 > 0)] */
 
380
                psubw_r2r(mm5, mm6);
 
381
                pand_r2r(mm7, mm6);
 
382
                
 
383
                paddw_r2r(mm6, mm0);            /* Add to accumulator */
 
384
                        
 
385
                movq_r2r(mm5, mm6);             /* mm6 := [i : W0..3,mm5>mm4] */
 
386
                pcmpgtw_r2r(mm4, mm6);
 
387
                psubw_r2r(mm4, mm5);            /* mm5 := [i : B0..7, (mm5-mm4)*(mm5-mm4 > 0)] */
 
388
                pand_r2r(mm6, mm5);
 
389
                
 
390
                paddw_r2r(mm5, mm0);            /* Add to accumulator */
 
391
 
 
392
                        
 
393
                /* Second 4 bytes of 8 */
 
394
        
 
395
                movq_r2r(mm2, mm4);             /* mm4 := Second 4 bytes p1 in words */
 
396
                pxor_r2r(mm7, mm7);
 
397
                punpckhbw_r2r(mm7, mm4);
 
398
                movq_r2r(mm3, mm6);             /* mm6 := Second 4 bytes p1+lx in words  */
 
399
                punpckhbw_r2r(mm7, mm6);
 
400
                
 
401
                paddw_r2r(mm6, mm4);            /* mm4 := First 4 Interpolated bytes in words */
 
402
                psrlw_i2r(1, mm4);
 
403
                
 
404
                movq_r2r(mm1, mm5);             /* mm5:= second 4 bytes of p2 in words */
 
405
                punpckhbw_r2r(mm7, mm5);
 
406
                
 
407
                movq_r2r(mm4, mm7);
 
408
                pcmpgtw_r2r(mm5, mm7);          /* mm7 := [i : W0..3,mm4>mm5] */
 
409
                
 
410
                movq_r2r(mm4, mm6);             /* mm6 := [i : W0..3, (mm4-mm5)*(mm4-mm5 > 0)] */
 
411
                psubw_r2r(mm5, mm6);
 
412
                pand_r2r(mm7, mm6);
 
413
                
 
414
                paddw_r2r(mm6, mm0);            /* Add to accumulator */
 
415
                
 
416
                movq_r2r(mm5, mm6);             /* mm6 := [i : W0..3,mm5>mm4] */
 
417
                pcmpgtw_r2r(mm4, mm6);
 
418
                psubw_r2r(mm4, mm5);            /* mm5 := [i : B0..7, (mm5-mm4)*(mm5-mm4 > 0)] */
 
419
                pand_r2r(mm6, mm5);
 
420
                
 
421
                paddw_r2r(mm5, mm0);            /* Add to accumulator */
 
422
                
 
423
                
 
424
                /* Second 8 bytes of row */
 
425
 
 
426
                /* First 4 bytes of 8 */
 
427
                
 
428
                movq_m2r(p1[8], mm4);           /* mm4 := first 4 bytes p1+8 */
 
429
                pxor_r2r(mm7, mm7);
 
430
                movq_r2r(mm4, mm2);             /* mm2 records all 8 bytes */
 
431
                punpcklbw_r2r(mm7, mm4);        /* First 4 bytes p1 in Words... */
 
432
                
 
433
                movq_m2r(p1[lx+8], mm6);        /* mm6 := first 4 bytes p1+lx+8 */
 
434
                movq_r2r(mm6, mm3);             /* mm3 records all 8 bytes */
 
435
                punpcklbw_r2r(mm7, mm6);
 
436
                paddw_r2r(mm6, mm4);            /* mm4 := First 4 bytes interpolated in words */
 
437
                psrlw_i2r(1, mm4);
 
438
                
 
439
                movq_m2r(p2[8], mm5);           /* mm5:=first 4 bytes of p2+8 in words */
 
440
                movq_r2r(mm5, mm1);
 
441
                punpcklbw_r2r(mm7, mm5);
 
442
                
 
443
                movq_r2r(mm4, mm7);
 
444
                pcmpgtw_r2r(mm5, mm7);          /* mm7 := [i : W0..3,mm4>mm5] */
 
445
                
 
446
                movq_r2r(mm4, mm6);             /* mm6 := [i : W0..3, (mm4-mm5)*(mm4-mm5 > 0)] */
 
447
                psubw_r2r(mm5, mm6);
 
448
                pand_r2r(mm7, mm6);
 
449
                
 
450
                paddw_r2r(mm6, mm0);            /* Add to accumulator */
 
451
 
 
452
                movq_r2r(mm5, mm6);             /* mm6 := [i : W0..3,mm5>mm4] */
 
453
                pcmpgtw_r2r(mm4, mm6);
 
454
                psubw_r2r(mm4, mm5);            /* mm5 := [i : B0..7, (mm5-mm4)*(mm5-mm4 > 0)] */
 
455
                pand_r2r(mm6, mm5);
 
456
                
 
457
                paddw_r2r(mm5, mm0);            /* Add to accumulator */
 
458
                        
 
459
                /* Second 4 bytes of 8 */
 
460
        
 
461
                movq_r2r(mm2, mm4);             /* mm4 := Second 4 bytes p1 in words */
 
462
                pxor_r2r(mm7, mm7);
 
463
                punpckhbw_r2r(mm7, mm4);
 
464
                movq_r2r(mm3, mm6);             /* mm6 := Second 4 bytes p1+lx in words  */
 
465
                punpckhbw_r2r(mm7, mm6);
 
466
                
 
467
                paddw_r2r(mm6, mm4);            /* mm4 := First 4 Interpolated bytes in words */
 
468
                psrlw_i2r(1, mm4);
 
469
                
 
470
                movq_r2r(mm1, mm5);             /* mm5:= second 4 bytes of p2 in words */
 
471
                punpckhbw_r2r(mm7, mm5);
 
472
                
 
473
                movq_r2r(mm4, mm7);
 
474
                pcmpgtw_r2r(mm5, mm7);          /* mm7 := [i : W0..3,mm4>mm5] */
 
475
                
 
476
                movq_r2r(mm4, mm6);             /* mm6 := [i : W0..3, (mm4-mm5)*(mm4-mm5 > 0)] */
 
477
                psubw_r2r(mm5, mm6);
 
478
                pand_r2r(mm7, mm6);
 
479
                
 
480
                paddw_r2r(mm6, mm0);            /* Add to accumulator */
 
481
                
 
482
                movq_r2r(mm5, mm6);             /* mm6 := [i : W0..3,mm5>mm4] */
 
483
                pcmpgtw_r2r(mm4, mm6);
 
484
                psubw_r2r(mm4, mm5);            /* mm5 := [i : B0..7, (mm5-mm4)*(mm5-mm4 > 0)] */
 
485
                pand_r2r(mm6, mm5);
 
486
                
 
487
                paddw_r2r(mm5, mm0);            /* Add to accumulator */
 
488
                
 
489
                p1 += lx;
 
490
                p2 += lx;
 
491
 
 
492
                h--;
 
493
        } while (h);
 
494
        
 
495
        /* Sum the Accumulators */
 
496
        movq_r2r(mm0, mm4);
 
497
        psrlq_i2r(32, mm4);
 
498
        paddw_r2r(mm4, mm0);
 
499
        movq_r2r(mm0, mm6);
 
500
        psrlq_i2r(16, mm6);
 
501
        paddw_r2r(mm6, mm0);
 
502
        movd_r2g(mm0, rv);      /* store return value */
 
503
        rv &= 0xffff;
 
504
 
 
505
        emms();
 
506
 
 
507
        return rv;
 
508
}
 
509
 
 
510
 
 
511
 
 
512
/*
 
513
 *     sad_01_mmx.s:  
 
514
 *  
 
515
 *   Copyright (C) 2000 Andrew Stevens <as@comlab.ox.ac.uk>
 
516
 * 
 
517
 * 
 
518
 *   This program is free software; you can redistribute it and/or
 
519
 *   modify it under the terms of the GNU General Public License
 
520
 *   as published by the Free Software Foundation; either version 2
 
521
 *   of the License, or (at your option) any later version.
 
522
 * 
 
523
 *   This program is distributed in the hope that it will be useful,
 
524
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
525
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
526
 *   GNU General Public License for more details.
 
527
 * 
 
528
 *   You should have received a copy of the GNU General Public License
 
529
 *   along with this program; if not, write to the Free Software
 
530
 *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
531
 */
 
532
 
 
533
int sad_11_mmx(uint8_t *p1, uint8_t *p2, int lx, int h)
 
534
{
 
535
        int rv;
 
536
 
 
537
/*
 
538
 *  mm0 = distance accumulators (4 words)
 
539
 *  mm1 = bytes p2
 
540
 *  mm2 = bytes p1
 
541
 *  mm3 = bytes p1+lx
 
542
 *  I'd love to find someplace to stash p1+1 and p1+lx+1's bytes
 
543
 *  but I don't think thats going to happen in iA32-land...
 
544
 *  mm4 = temp 4 bytes in words interpolating p1, p1+1
 
545
 *  mm5 = temp 4 bytes in words from p2
 
546
 *  mm6 = temp comparison bit mask p1,p2
 
547
 *  mm7 = temp comparison bit mask p2,p1
 
548
 */
 
549
 
 
550
        pxor_r2r(mm0, mm0);
 
551
        
 
552
        do {
 
553
        
 
554
                /*  First 8 bytes of row */
 
555
                
 
556
                /*  First 4 bytes of 8 */
 
557
        
 
558
                movq_m2r(p1[0], mm4);           /* mm4 := first 4 bytes p1 */
 
559
                pxor_r2r(mm7, mm7);
 
560
                movq_r2r(mm4, mm2);             /* mm2 records all 8 bytes */
 
561
                punpcklbw_r2r(mm7, mm4);        /* First 4 bytes p1 in Words... */
 
562
                
 
563
                movq_m2r(p1[lx], mm6);          /* mm6 := first 4 bytes p1+lx */
 
564
                movq_r2r(mm6, mm3);             /*  mm3 records all 8 bytes */
 
565
                punpcklbw_r2r(mm7, mm6);
 
566
                paddw_r2r(mm6, mm4);
 
567
                
 
568
                movq_m2r(p1[1], mm5);           /* mm5 := first 4 bytes p1+1 */
 
569
                punpcklbw_r2r(mm7, mm5);        /* First 4 bytes p1 in Words... */
 
570
                paddw_r2r(mm5, mm4);
 
571
                movq_m2r(p1[lx+1], mm6);        /* mm6 := first 4 bytes p1+lx+1 */
 
572
                punpcklbw_r2r(mm7, mm6);
 
573
                paddw_r2r(mm6, mm4);
 
574
                
 
575
                psrlw_i2r(2, mm4);              /*  mm4 := First 4 bytes interpolated in words */
 
576
                
 
577
                movq_m2r(p2[0], mm5);           /* mm5:=first 4 bytes of p2 in words */
 
578
                movq_r2r(mm5, mm1);
 
579
                punpcklbw_r2r(mm7, mm5);
 
580
 
 
581
                movq_r2r(mm4, mm7);
 
582
                pcmpgtw_r2r(mm5, mm7);          /* mm7 := [i : W0..3,mm4>mm5] */
 
583
                
 
584
                movq_r2r(mm4, mm6);             /* mm6 := [i : W0..3, (mm4-mm5)*(mm4-mm5 > 0)] */
 
585
                psubw_r2r(mm5, mm6);
 
586
                pand_r2r(mm7, mm6);
 
587
 
 
588
                paddw_r2r(mm6, mm0);            /* Add to accumulator */
 
589
 
 
590
                movq_r2r(mm5, mm6);             /* mm6 := [i : W0..3,mm5>mm4] */
 
591
                pcmpgtw_r2r(mm4, mm6);
 
592
                psubw_r2r(mm4, mm5);            /* mm5 := [i : B0..7, (mm5-mm4)*(mm5-mm4 > 0)] */
 
593
                pand_r2r(mm6, mm5);
 
594
                
 
595
                paddw_r2r(mm5, mm0);            /* Add to accumulator */
 
596
                
 
597
                /* Second 4 bytes of 8 */
 
598
                
 
599
                movq_r2r(mm2, mm4);             /* mm4 := Second 4 bytes p1 in words */
 
600
                pxor_r2r(mm7, mm7);
 
601
                punpckhbw_r2r(mm7, mm4);
 
602
                movq_r2r(mm3, mm6);             /*  mm6 := Second 4 bytes p1+1 in words */
 
603
                punpckhbw_r2r(mm7, mm6);
 
604
                paddw_r2r(mm6, mm4);
 
605
                
 
606
                movq_m2r(p1[1], mm5);           /*  mm5 := first 4 bytes p1+1 */
 
607
                punpckhbw_r2r(mm7, mm5);        /* First 4 bytes p1 in Words... */
 
608
                paddw_r2r(mm5, mm4);
 
609
                movq_m2r(p1[lx+1], mm6);        /* mm6 := first 4 bytes p1+lx+1 */
 
610
                punpckhbw_r2r(mm7, mm6);
 
611
                paddw_r2r(mm6, mm4);
 
612
                
 
613
                psrlw_i2r(2, mm4);              /* mm4 := First 4 bytes interpolated in words */
 
614
                
 
615
                movq_r2r(mm1, mm5);             /* mm5:= second 4 bytes of p2 in words */
 
616
                punpckhbw_r2r(mm7, mm5);
 
617
                
 
618
                movq_r2r(mm4, mm7);
 
619
                pcmpgtw_r2r(mm5, mm7);          /* mm7 := [i : W0..3,mm4>mm5] */
 
620
                
 
621
                movq_r2r(mm4, mm6);             /* mm6 := [i : W0..3, (mm4-mm5)*(mm4-mm5 > 0)] */
 
622
                psubw_r2r(mm5, mm6);            
 
623
                pand_r2r(mm7, mm6);
 
624
                
 
625
                paddw_r2r(mm6, mm0);            /* Add to accumulator */
 
626
                
 
627
                movq_r2r(mm5, mm6);             /* mm6 := [i : W0..3,mm5>mm4] */
 
628
                pcmpgtw_r2r(mm4, mm6);
 
629
                psubw_r2r(mm4, mm5);            /*  mm5 := [i : B0..7, (mm5-mm4)*(mm5-mm4 > 0)] */
 
630
                pand_r2r(mm6, mm5);
 
631
                
 
632
                paddw_r2r(mm5, mm0);            /* Add to accumulator */
 
633
                
 
634
                
 
635
                /* Second 8 bytes of row */
 
636
 
 
637
                /*  First 4 bytes of 8 */
 
638
        
 
639
                movq_m2r(p1[8], mm4);           /* mm4 := first 4 bytes p1+8 */
 
640
                pxor_r2r(mm7, mm7);
 
641
                movq_r2r(mm4, mm2);             /* mm2 records all 8 bytes */
 
642
                punpcklbw_r2r(mm7, mm4);        /* First 4 bytes p1 in Words... */
 
643
                
 
644
                movq_m2r(p1[lx+8], mm6);        /* mm6 := first 4 bytes p1+lx+8 */
 
645
                movq_r2r(mm6, mm3);             /*  mm3 records all 8 bytes */
 
646
                punpcklbw_r2r(mm7, mm6);
 
647
                paddw_r2r(mm6, mm4);
 
648
                
 
649
                movq_m2r(p1[9], mm5);           /* mm5 := first 4 bytes p1+9 */
 
650
                punpcklbw_r2r(mm7, mm5);        /* First 4 bytes p1 in Words... */
 
651
                paddw_r2r(mm5, mm4);
 
652
                movq_m2r(p1[lx+9], mm6);        /* mm6 := first 4 bytes p1+lx+9 */
 
653
                punpcklbw_r2r(mm7, mm6);
 
654
                paddw_r2r(mm6, mm4);
 
655
                
 
656
                psrlw_i2r(2, mm4);              /*  mm4 := First 4 bytes interpolated in words */
 
657
                
 
658
                movq_m2r(p2[8], mm5);           /* mm5:=first 4 bytes of p2+8 in words */
 
659
                movq_r2r(mm5, mm1);
 
660
                punpcklbw_r2r(mm7, mm5);
 
661
 
 
662
                movq_r2r(mm4, mm7);
 
663
                pcmpgtw_r2r(mm5, mm7);          /* mm7 := [i : W0..3,mm4>mm5] */
 
664
                
 
665
                movq_r2r(mm4, mm6);             /* mm6 := [i : W0..3, (mm4-mm5)*(mm4-mm5 > 0)] */
 
666
                psubw_r2r(mm5, mm6);
 
667
                pand_r2r(mm7, mm6);
 
668
 
 
669
                paddw_r2r(mm6, mm0);            /* Add to accumulator */
 
670
 
 
671
                movq_r2r(mm5, mm6);             /* mm6 := [i : W0..3,mm5>mm4] */
 
672
                pcmpgtw_r2r(mm4, mm6);
 
673
                psubw_r2r(mm4, mm5);            /* mm5 := [i : B0..7, (mm5-mm4)*(mm5-mm4 > 0)] */
 
674
                pand_r2r(mm6, mm5);
 
675
                
 
676
                paddw_r2r(mm5, mm0);            /* Add to accumulator */
 
677
                
 
678
                /* Second 4 bytes of 8 */
 
679
                
 
680
                movq_r2r(mm2, mm4);             /* mm4 := Second 4 bytes p1 in words */
 
681
                pxor_r2r(mm7, mm7);
 
682
                punpckhbw_r2r(mm7, mm4);
 
683
                movq_r2r(mm3, mm6);             /*  mm6 := Second 4 bytes p1+1 in words */
 
684
                punpckhbw_r2r(mm7, mm6);
 
685
                paddw_r2r(mm6, mm4);
 
686
                
 
687
                movq_m2r(p1[9], mm5);           /*  mm5 := first 4 bytes p1+9 */
 
688
                punpckhbw_r2r(mm7, mm5);        /* First 4 bytes p1 in Words... */
 
689
                paddw_r2r(mm5, mm4);
 
690
                movq_m2r(p1[lx+9], mm6);        /* mm6 := first 4 bytes p1+lx+9 */
 
691
                punpckhbw_r2r(mm7, mm6);
 
692
                paddw_r2r(mm6, mm4);
 
693
                
 
694
                psrlw_i2r(2, mm4);              /* mm4 := First 4 bytes interpolated in words */
 
695
                
 
696
                movq_r2r(mm1, mm5);             /* mm5:= second 4 bytes of p2 in words */
 
697
                punpckhbw_r2r(mm7, mm5);
 
698
                
 
699
                movq_r2r(mm4, mm7);
 
700
                pcmpgtw_r2r(mm5, mm7);          /* mm7 := [i : W0..3,mm4>mm5] */
 
701
                
 
702
                movq_r2r(mm4, mm6);             /* mm6 := [i : W0..3, (mm4-mm5)*(mm4-mm5 > 0)] */
 
703
                psubw_r2r(mm5, mm6);            
 
704
                pand_r2r(mm7, mm6);
 
705
                
 
706
                paddw_r2r(mm6, mm0);            /* Add to accumulator */
 
707
                
 
708
                movq_r2r(mm5, mm6);             /* mm6 := [i : W0..3,mm5>mm4] */
 
709
                pcmpgtw_r2r(mm4, mm6);
 
710
                psubw_r2r(mm4, mm5);            /*  mm5 := [i : B0..7, (mm5-mm4)*(mm5-mm4 > 0)] */
 
711
                pand_r2r(mm6, mm5);
 
712
                
 
713
                paddw_r2r(mm5, mm0);            /* Add to accumulator */                        
 
714
                
 
715
                p1 += lx;       /* update pointers to next row */
 
716
                p2 += lx;
 
717
        
 
718
                h--;
 
719
        } while (h);
 
720
 
 
721
        /* Sum the Accumulators */
 
722
        movq_r2r(mm0, mm4);
 
723
        psrlq_i2r(32, mm4);
 
724
        paddw_r2r(mm4, mm0);
 
725
        movq_r2r(mm0, mm6);
 
726
        psrlq_i2r(16, mm6);
 
727
        paddw_r2r(mm6, mm0);
 
728
        movd_r2g(mm0, rv);      /* store return value */
 
729
        rv &= 0xffff;
 
730
 
 
731
        return rv;
 
732
}
 
733
 
 
734
 
 
735
 
 
736
int sad_sub22_mmx(uint8_t *blk1,uint8_t *blk2,int lx,int h)
 
737
{
 
738
        int rv;
 
739
 
 
740
/*
 
741
 *  mm0 = distance accumulators (4 words)
 
742
 *  mm1 = temp 
 
743
 *  mm2 = temp 
 
744
 *  mm3 = temp
 
745
 *  mm4 = temp
 
746
 *  mm5 = temp 
 
747
 *  mm6 = 0
 
748
 *  mm7 = temp
 
749
 */
 
750
 
 
751
        pxor_r2r(mm0, mm0);
 
752
        pxor_r2r(mm6, mm6);
 
753
 
 
754
        do {
 
755
                movq_m2r(blk1[0], mm4);         /* load 8 bytes of p1 */
 
756
                movq_m2r(blk2[0], mm5);         /* load 8 bytes of p2 */
 
757
                
 
758
                movq_r2r(mm4, mm7);             /* mm5 = abs(*p1-*p2) */
 
759
                psubusb_r2r(mm5, mm7);
 
760
                psubusb_r2r(mm4, mm5);
 
761
                blk1 += lx;                     /* update pointer to next row */
 
762
                paddb_r2r(mm7, mm5);
 
763
                
 
764
                        /* Add the mm5 bytes to the accumulatores */
 
765
                movq_r2r(mm5, mm7);
 
766
                punpcklbw_r2r(mm6, mm7);
 
767
                paddw_r2r(mm7, mm0);
 
768
                punpckhbw_r2r(mm6, mm5);
 
769
                blk2 += lx;                     /* update pointer to next row */
 
770
                paddw_r2r(mm5, mm0);
 
771
                
 
772
                movq_m2r(blk1[0], mm4);         /* load 8 bytes of p1 (next row) */
 
773
                movq_m2r(blk2[0], mm5);         /* load 8 bytes of p2 (next row) */
 
774
                
 
775
                movq_r2r(mm4, mm7);             /* mm5 = abs(*p1-*p2) */
 
776
                psubusb_r2r(mm5, mm7);
 
777
                psubusb_r2r(mm4, mm5);
 
778
                blk1 += lx;                     /* update pointer to next row */
 
779
                paddb_r2r(mm7, mm5);
 
780
                
 
781
                        /* Add the mm5 bytes to the accumulatores */
 
782
                movq_r2r(mm5, mm7);
 
783
                punpcklbw_r2r(mm6, mm7);
 
784
                blk2 += lx;                     /* update pointer to next row */
 
785
                paddw_r2r(mm7, mm0);
 
786
                punpckhbw_r2r(mm6, mm5);
 
787
                h -= 2;
 
788
                paddw_r2r(mm5, mm0);
 
789
        } while (h);
 
790
 
 
791
        /* Sum the Accumulators */
 
792
        movq_r2r(mm0, mm1);
 
793
        psrlq_i2r(16, mm1);
 
794
        movq_r2r(mm0, mm2);
 
795
        psrlq_i2r(32, mm2);
 
796
        movq_r2r(mm0, mm3);
 
797
        psrlq_i2r(48, mm3);
 
798
        paddw_r2r(mm1, mm0);
 
799
        paddw_r2r(mm3, mm2);
 
800
        paddw_r2r(mm2, mm0);
 
801
                
 
802
        movd_r2g(mm0, rv);      /* store return value */
 
803
        rv &= 0xffff;
 
804
 
 
805
        emms();
 
806
 
 
807
        return rv;
 
808
}
 
809
 
 
810
 
 
811
int sad_sub44_mmx(uint8_t *blk1, uint8_t *blk2, int qlx, int qh)
 
812
{
 
813
        int rv;
 
814
 
 
815
/*
 
816
 *  mm0 = distance accumulator left block p1
 
817
 *  mm1 = distance accumulator right block p1
 
818
 *  mm2 = 0
 
819
 *  mm3 = right block of p1
 
820
 *  mm4 = left block of p1
 
821
 *  mm5 = p2
 
822
 *  mm6 = temp
 
823
 *  mm7 = temp
 
824
 */
 
825
 
 
826
        pxor_r2r(mm0, mm0);
 
827
        pxor_r2r(mm1, mm1);
 
828
        pxor_r2r(mm2, mm2);
 
829
        
 
830
        do {
 
831
 
 
832
                /*
 
833
                 *  Beware loop obfuscated by interleaving to try to
 
834
                 *  hide latencies...
 
835
                 */
 
836
 
 
837
                movq_m2r(blk1[0], mm4);         /* mm4 =  first 4 bytes of p1 in words */
 
838
                movq_m2r(blk2[0], mm5);         /* mm5 = 4 bytes of p2 in words */
 
839
                movq_r2r(mm4, mm3);
 
840
                punpcklbw_r2r(mm2, mm4);
 
841
                punpcklbw_r2r(mm2, mm5);
 
842
 
 
843
                movq_r2r(mm4, mm7);
 
844
                movq_r2r(mm5, mm6);
 
845
                psubusw_r2r(mm5, mm7);
 
846
                psubusw_r2r(mm4, mm6);
 
847
                
 
848
                blk1 += qlx;    /* update a pointer to next row */
 
849
                
 
850
                paddw_r2r(mm6, mm7);
 
851
                paddw_r2r(mm7, mm0);    /* Add absolute differences to left block accumulators */
 
852
                        
 
853
                blk2 += qlx;
 
854
                qh--;
 
855
                        
 
856
        } while (qh);
 
857
        
 
858
        
 
859
        /* Sum the accumulators */
 
860
        movq_r2r(mm0, mm4);
 
861
        psrlq_i2r(32, mm4);
 
862
        paddw_r2r(mm4, mm0);
 
863
        movq_r2r(mm0, mm6);
 
864
        psrlq_i2r(16, mm6);
 
865
        paddw_r2r(mm6, mm0);
 
866
        movd_r2g(mm0, rv);
 
867
        rv &= 0xffff;
 
868
        
 
869
        emms();
 
870
 
 
871
        return rv;
 
872
}
 
873
#endif
 
874