[svn] / trunk / xvidcore / src / image / x86_asm / interpolate8x8_xmm.asm Repository:
ViewVC logotype

Annotation of /trunk/xvidcore/src/image/x86_asm/interpolate8x8_xmm.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1877 - (view) (download)

1 : edgomez 1382 ;/*****************************************************************************
2 : Isibaar 262 ; *
3 : edgomez 1382 ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * - mmx 8x8 block-based halfpel interpolation -
5 : Isibaar 262 ; *
6 : Isibaar 1795 ; * Copyright(C) 2002-2008 Michael Militzer <michael@xvid.org>
7 : edgomez 1382 ; * 2002 Pascal Massimino <skal@planet-d.net>
8 : Isibaar 262 ; *
9 : edgomez 1382 ; * This program is free software ; you can redistribute it and/or modify
10 :     ; * it under the terms of the GNU General Public License as published by
11 :     ; * the Free Software Foundation ; either version 2 of the License, or
12 :     ; * (at your option) any later version.
13 : Isibaar 262 ; *
14 : edgomez 1382 ; * This program is distributed in the hope that it will be useful,
15 :     ; * but WITHOUT ANY WARRANTY ; without even the implied warranty of
16 :     ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 :     ; * GNU General Public License for more details.
18 : Isibaar 262 ; *
19 : edgomez 1382 ; * You should have received a copy of the GNU General Public License
20 :     ; * along with this program ; if not, write to the Free Software
21 :     ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 : Isibaar 262 ; *
23 : edgomez 1382 ; ****************************************************************************/
24 : Isibaar 262
25 : Isibaar 1795 %include "nasm.inc"
26 : edgomez 851
27 : edgomez 1382 ;=============================================================================
28 :     ; Read only data
29 :     ;=============================================================================
30 : Isibaar 262
31 : Isibaar 1795 DATA
32 : Isibaar 262
33 : Isibaar 1795 ALIGN SECTION_ALIGN
34 : edgomez 1382 mmx_one:
35 :     times 8 db 1
36 : Isibaar 262
37 : Isibaar 1844 TEXT
38 : Isibaar 262
39 :     cglobal interpolate8x8_halfpel_h_xmm
40 :     cglobal interpolate8x8_halfpel_v_xmm
41 :     cglobal interpolate8x8_halfpel_hv_xmm
42 :    
43 : suxen_drol 1632 cglobal interpolate8x4_halfpel_h_xmm
44 :     cglobal interpolate8x4_halfpel_v_xmm
45 :     cglobal interpolate8x4_halfpel_hv_xmm
46 :    
47 : edgomez 1530 cglobal interpolate8x8_halfpel_add_xmm
48 :     cglobal interpolate8x8_halfpel_h_add_xmm
49 :     cglobal interpolate8x8_halfpel_v_add_xmm
50 :     cglobal interpolate8x8_halfpel_hv_add_xmm
51 :    
52 : Isibaar 262 ;===========================================================================
53 :     ;
54 :     ; void interpolate8x8_halfpel_h_xmm(uint8_t * const dst,
55 :     ; const uint8_t * const src,
56 :     ; const uint32_t stride,
57 :     ; const uint32_t rounding);
58 :     ;
59 :     ;===========================================================================
60 :    
61 :     %macro COPY_H_SSE_RND0 0
62 : Isibaar 1795 movq mm0, [_EAX]
63 :     pavgb mm0, [_EAX+1]
64 :     movq mm1, [_EAX+TMP1]
65 :     pavgb mm1, [_EAX+TMP1+1]
66 :     lea _EAX,[_EAX+2*TMP1]
67 :     movq [TMP0],mm0
68 :     movq [TMP0+TMP1],mm1
69 : Isibaar 262 %endmacro
70 :    
71 :     %macro COPY_H_SSE_RND1 0
72 : Isibaar 1795 movq mm0, [_EAX]
73 :     movq mm1, [_EAX+TMP1]
74 : Isibaar 262 movq mm4, mm0
75 :     movq mm5, mm1
76 : Isibaar 1795 movq mm2, [_EAX+1]
77 :     movq mm3, [_EAX+TMP1+1]
78 : Isibaar 262 pavgb mm0, mm2
79 :     pxor mm2, mm4
80 :     pavgb mm1, mm3
81 : Isibaar 1795 lea _EAX, [_EAX+2*TMP1]
82 : Isibaar 262 pxor mm3, mm5
83 :     pand mm2, mm7
84 :     pand mm3, mm7
85 :     psubb mm0, mm2
86 : Isibaar 1795 movq [TMP0], mm0
87 : Isibaar 262 psubb mm1, mm3
88 : Isibaar 1795 movq [TMP0+TMP1], mm1
89 : Isibaar 262 %endmacro
90 :    
91 : Isibaar 1795 ALIGN SECTION_ALIGN
92 : Isibaar 262 interpolate8x8_halfpel_h_xmm:
93 :    
94 : Isibaar 1795 mov _EAX, prm4 ; rounding
95 :     mov TMP0, prm1 ; Dst
96 :     test _EAX,_EAX
97 :     mov _EAX, prm2 ; Src
98 :     mov TMP1, prm3 ; stride
99 : Isibaar 262
100 :     jnz near .rounding1
101 :    
102 :     COPY_H_SSE_RND0
103 : Isibaar 1795 lea TMP0,[TMP0+2*TMP1]
104 : Isibaar 262 COPY_H_SSE_RND0
105 : Isibaar 1795 lea TMP0,[TMP0+2*TMP1]
106 : Isibaar 262 COPY_H_SSE_RND0
107 : Isibaar 1795 lea TMP0,[TMP0+2*TMP1]
108 : Isibaar 262 COPY_H_SSE_RND0
109 :     ret
110 :    
111 : Isibaar 1793 .rounding1:
112 : edgomez 1382 ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
113 : Isibaar 262 movq mm7, [mmx_one]
114 :     COPY_H_SSE_RND1
115 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
116 : Isibaar 262 COPY_H_SSE_RND1
117 : Isibaar 1795 lea TMP0,[TMP0+2*TMP1]
118 : Isibaar 262 COPY_H_SSE_RND1
119 : Isibaar 1795 lea TMP0,[TMP0+2*TMP1]
120 : Isibaar 262 COPY_H_SSE_RND1
121 :     ret
122 : Isibaar 1793 ENDFUNC
123 : Isibaar 262
124 :     ;===========================================================================
125 :     ;
126 :     ; void interpolate8x8_halfpel_v_xmm(uint8_t * const dst,
127 : edgomez 1382 ; const uint8_t * const src,
128 :     ; const uint32_t stride,
129 :     ; const uint32_t rounding);
130 : Isibaar 262 ;
131 :     ;===========================================================================
132 :    
133 :     %macro COPY_V_SSE_RND0 0
134 : Isibaar 1795 movq mm0, [_EAX]
135 :     movq mm1, [_EAX+TMP1]
136 : Isibaar 262 pavgb mm0, mm1
137 : Isibaar 1795 pavgb mm1, [_EAX+2*TMP1]
138 :     lea _EAX, [_EAX+2*TMP1]
139 :     movq [TMP0], mm0
140 :     movq [TMP0+TMP1],mm1
141 : Isibaar 262 %endmacro
142 :    
143 :     %macro COPY_V_SSE_RND1 0
144 :     movq mm0, mm2
145 : Isibaar 1795 movq mm1, [_EAX]
146 :     movq mm2, [_EAX+TMP1]
147 :     lea _EAX,[_EAX+2*TMP1]
148 : Isibaar 262 movq mm4, mm0
149 :     movq mm5, mm1
150 :     pavgb mm0, mm1
151 : edgomez 1382 pxor mm4, mm1
152 : Isibaar 262 pavgb mm1, mm2
153 :     pxor mm5, mm2
154 : edgomez 1382 pand mm4, mm7 ; lsb's of (i^j)...
155 :     pand mm5, mm7 ; lsb's of (i^j)...
156 :     psubb mm0, mm4 ; ...are substracted from result of pavgb
157 : Isibaar 1795 movq [TMP0], mm0
158 : edgomez 1382 psubb mm1, mm5 ; ...are substracted from result of pavgb
159 : Isibaar 1795 movq [TMP0+TMP1], mm1
160 : Isibaar 262 %endmacro
161 :    
162 : Isibaar 1795 ALIGN SECTION_ALIGN
163 : Isibaar 262 interpolate8x8_halfpel_v_xmm:
164 :    
165 : Isibaar 1795 mov _EAX, prm4 ; rounding
166 :     mov TMP0, prm1 ; Dst
167 :     test _EAX,_EAX
168 :     mov _EAX, prm2 ; Src
169 :     mov TMP1, prm3 ; stride
170 : Isibaar 262
171 : edgomez 1382 ; we process 2 line at a time
172 : Isibaar 262 jnz near .rounding1
173 :    
174 :     COPY_V_SSE_RND0
175 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
176 : Isibaar 262 COPY_V_SSE_RND0
177 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
178 : Isibaar 262 COPY_V_SSE_RND0
179 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
180 : Isibaar 262 COPY_V_SSE_RND0
181 :     ret
182 :    
183 : Isibaar 1793 .rounding1:
184 : edgomez 1382 ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
185 : Isibaar 262 movq mm7, [mmx_one]
186 : Isibaar 1795 movq mm2, [_EAX] ; loop invariant
187 :     add _EAX, TMP1
188 : Isibaar 262
189 :     COPY_V_SSE_RND1
190 : Isibaar 1795 lea TMP0,[TMP0+2*TMP1]
191 : Isibaar 262 COPY_V_SSE_RND1
192 : Isibaar 1795 lea TMP0,[TMP0+2*TMP1]
193 : Isibaar 262 COPY_V_SSE_RND1
194 : Isibaar 1795 lea TMP0,[TMP0+2*TMP1]
195 : Isibaar 262 COPY_V_SSE_RND1
196 :     ret
197 : Isibaar 1793 ENDFUNC
198 : Isibaar 262
199 :     ;===========================================================================
200 :     ;
201 :     ; void interpolate8x8_halfpel_hv_xmm(uint8_t * const dst,
202 : edgomez 1382 ; const uint8_t * const src,
203 :     ; const uint32_t stride,
204 :     ; const uint32_t rounding);
205 : Isibaar 262 ;
206 :     ;
207 :     ;===========================================================================
208 :    
209 :     ; The trick is to correct the result of 'pavgb' with some combination of the
210 :     ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
211 :     ; The boolean relations are:
212 : edgomez 1382 ; (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
213 : Isibaar 262 ; (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
214 :     ; (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
215 :     ; (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
216 :     ; with s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
217 :    
218 :     ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
219 :    
220 :     %macro COPY_HV_SSE_RND0 0
221 : Isibaar 1795 lea _EAX, [_EAX+TMP1]
222 : Isibaar 262
223 : Isibaar 1795 movq mm0, [_EAX]
224 :     movq mm1, [_EAX+1]
225 : Isibaar 262
226 : edgomez 1382 movq mm6, mm0
227 :     pavgb mm0, mm1 ; mm0=(j+k+1)/2. preserved for next step
228 : Isibaar 1795 lea _EAX, [_EAX+TMP1]
229 : edgomez 1382 pxor mm1, mm6 ; mm1=(j^k). preserved for next step
230 : Isibaar 262
231 : edgomez 1382 por mm3, mm1 ; ij |= jk
232 :     movq mm6, mm2
233 :     pxor mm6, mm0 ; mm6 = s^t
234 :     pand mm3, mm6 ; (ij|jk) &= st
235 :     pavgb mm2, mm0 ; mm2 = (s+t+1)/2
236 :     pand mm3, mm7 ; mask lsb
237 :     psubb mm2, mm3 ; apply.
238 : Isibaar 262
239 : Isibaar 1795 movq [TMP0], mm2
240 : Isibaar 262
241 : Isibaar 1795 movq mm2, [_EAX]
242 :     movq mm3, [_EAX+1]
243 : edgomez 1382 movq mm6, mm2
244 :     pavgb mm2, mm3 ; preserved for next iteration
245 : Isibaar 1795 lea TMP0,[TMP0+TMP1]
246 : edgomez 1382 pxor mm3, mm6 ; preserved for next iteration
247 : Isibaar 262
248 : edgomez 1382 por mm1, mm3
249 :     movq mm6, mm0
250 :     pxor mm6, mm2
251 :     pand mm1, mm6
252 :     pavgb mm0, mm2
253 : Isibaar 262
254 : edgomez 1382 pand mm1, mm7
255 :     psubb mm0, mm1
256 : Isibaar 262
257 : Isibaar 1795 movq [TMP0], mm0
258 : Isibaar 262 %endmacro
259 :    
260 :     %macro COPY_HV_SSE_RND1 0
261 : Isibaar 1795 lea _EAX, [_EAX+TMP1]
262 : Isibaar 262
263 : Isibaar 1795 movq mm0, [_EAX]
264 :     movq mm1, [_EAX+1]
265 : Isibaar 262
266 : edgomez 1382 movq mm6, mm0
267 :     pavgb mm0, mm1 ; mm0=(j+k+1)/2. preserved for next step
268 : Isibaar 1795 lea _EAX, [_EAX+TMP1]
269 : edgomez 1382 pxor mm1, mm6 ; mm1=(j^k). preserved for next step
270 : Isibaar 262
271 : edgomez 1382 pand mm3, mm1
272 :     movq mm6, mm2
273 :     pxor mm6, mm0
274 :     por mm3, mm6
275 :     pavgb mm2, mm0
276 :     pand mm3, mm7
277 :     psubb mm2, mm3
278 : Isibaar 262
279 : Isibaar 1795 movq [TMP0], mm2
280 : Isibaar 262
281 : Isibaar 1795 movq mm2, [_EAX]
282 :     movq mm3, [_EAX+1]
283 : edgomez 1382 movq mm6, mm2
284 :     pavgb mm2, mm3 ; preserved for next iteration
285 : Isibaar 1795 lea TMP0,[TMP0+TMP1]
286 : edgomez 1382 pxor mm3, mm6 ; preserved for next iteration
287 : Isibaar 262
288 : edgomez 1382 pand mm1, mm3
289 :     movq mm6, mm0
290 :     pxor mm6, mm2
291 :     por mm1, mm6
292 :     pavgb mm0, mm2
293 :     pand mm1, mm7
294 :     psubb mm0, mm1
295 : Isibaar 262
296 : Isibaar 1795 movq [TMP0], mm0
297 : Isibaar 262 %endmacro
298 :    
299 : Isibaar 1795 ALIGN SECTION_ALIGN
300 : Isibaar 262 interpolate8x8_halfpel_hv_xmm:
301 : Isibaar 1795 mov _EAX, prm4 ; rounding
302 :     mov TMP0, prm1 ; Dst
303 :     test _EAX, _EAX
304 :     mov _EAX, prm2 ; Src
305 :     mov TMP1, prm3 ; stride
306 : Isibaar 262
307 :     movq mm7, [mmx_one]
308 :    
309 :     ; loop invariants: mm2=(i+j+1)/2 and mm3= i^j
310 : Isibaar 1795 movq mm2, [_EAX]
311 :     movq mm3, [_EAX+1]
312 : Isibaar 262 movq mm6, mm2
313 :     pavgb mm2, mm3
314 : edgomez 1382 pxor mm3, mm6 ; mm2/mm3 ready
315 : Isibaar 262
316 :     jnz near .rounding1
317 :    
318 :     COPY_HV_SSE_RND0
319 : Isibaar 1795 add TMP0, TMP1
320 : Isibaar 262 COPY_HV_SSE_RND0
321 : Isibaar 1795 add TMP0, TMP1
322 : Isibaar 262 COPY_HV_SSE_RND0
323 : Isibaar 1795 add TMP0, TMP1
324 : Isibaar 262 COPY_HV_SSE_RND0
325 :     ret
326 :    
327 : Isibaar 1793 .rounding1:
328 : Isibaar 262 COPY_HV_SSE_RND1
329 : Isibaar 1795 add TMP0, TMP1
330 : Isibaar 262 COPY_HV_SSE_RND1
331 : Isibaar 1795 add TMP0, TMP1
332 : Isibaar 262 COPY_HV_SSE_RND1
333 : Isibaar 1795 add TMP0, TMP1
334 : Isibaar 262 COPY_HV_SSE_RND1
335 : edgomez 1382 ret
336 : Isibaar 1793 ENDFUNC
337 : edgomez 1530
338 :     ;===========================================================================
339 :     ;
340 : suxen_drol 1632 ; void interpolate8x4_halfpel_h_xmm(uint8_t * const dst,
341 :     ; const uint8_t * const src,
342 :     ; const uint32_t stride,
343 :     ; const uint32_t rounding);
344 :     ;
345 :     ;===========================================================================
346 :    
347 : Isibaar 1795 ALIGN SECTION_ALIGN
348 : suxen_drol 1632 interpolate8x4_halfpel_h_xmm:
349 :    
350 : Isibaar 1795 mov _EAX, prm4 ; rounding
351 :     mov TMP0, prm1 ; Dst
352 :     test _EAX,_EAX
353 :     mov _EAX, prm2 ; Src
354 :     mov TMP1, prm3 ; stride
355 : suxen_drol 1632
356 :     jnz near .rounding1
357 :    
358 :     COPY_H_SSE_RND0
359 : Isibaar 1795 lea TMP0,[TMP0+2*TMP1]
360 : suxen_drol 1632 COPY_H_SSE_RND0
361 :     ret
362 :    
363 : Isibaar 1793 .rounding1:
364 : suxen_drol 1632 ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
365 :     movq mm7, [mmx_one]
366 :     COPY_H_SSE_RND1
367 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
368 : suxen_drol 1632 COPY_H_SSE_RND1
369 :     ret
370 : Isibaar 1793 ENDFUNC
371 : suxen_drol 1632
372 :     ;===========================================================================
373 :     ;
374 :     ; void interpolate8x4_halfpel_v_xmm(uint8_t * const dst,
375 :     ; const uint8_t * const src,
376 :     ; const uint32_t stride,
377 :     ; const uint32_t rounding);
378 :     ;
379 :     ;===========================================================================
380 :    
381 : Isibaar 1795 ALIGN SECTION_ALIGN
382 : suxen_drol 1632 interpolate8x4_halfpel_v_xmm:
383 :    
384 : Isibaar 1795 mov _EAX, prm4 ; rounding
385 :     mov TMP0, prm1 ; Dst
386 :     test _EAX,_EAX
387 :     mov _EAX, prm2 ; Src
388 :     mov TMP1, prm3 ; stride
389 : suxen_drol 1632
390 :     ; we process 2 line at a time
391 :     jnz near .rounding1
392 :    
393 :     COPY_V_SSE_RND0
394 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
395 : suxen_drol 1632 COPY_V_SSE_RND0
396 :     ret
397 :    
398 : Isibaar 1793 .rounding1:
399 : suxen_drol 1632 ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
400 :     movq mm7, [mmx_one]
401 : Isibaar 1795 movq mm2, [_EAX] ; loop invariant
402 :     add _EAX, TMP1
403 : suxen_drol 1632
404 :     COPY_V_SSE_RND1
405 : Isibaar 1795 lea TMP0,[TMP0+2*TMP1]
406 : suxen_drol 1632 COPY_V_SSE_RND1
407 :     ret
408 : Isibaar 1793 ENDFUNC
409 : suxen_drol 1632
410 :     ;===========================================================================
411 :     ;
412 :     ; void interpolate8x4_halfpel_hv_xmm(uint8_t * const dst,
413 :     ; const uint8_t * const src,
414 :     ; const uint32_t stride,
415 :     ; const uint32_t rounding);
416 :     ;
417 :     ;
418 :     ;===========================================================================
419 :    
420 :     ; The trick is to correct the result of 'pavgb' with some combination of the
421 :     ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
422 :     ; The boolean relations are:
423 :     ; (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
424 :     ; (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
425 :     ; (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
426 :     ; (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
427 :     ; with s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
428 :    
429 :     ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
430 :    
431 : Isibaar 1795 ALIGN SECTION_ALIGN
432 : suxen_drol 1632 interpolate8x4_halfpel_hv_xmm:
433 : Isibaar 1795 mov _EAX, prm4 ; rounding
434 :     mov TMP0, prm1 ; Dst
435 :     test _EAX, _EAX
436 :     mov _EAX, prm2 ; Src
437 :     mov TMP1, prm3 ; stride
438 : suxen_drol 1632
439 :     movq mm7, [mmx_one]
440 :    
441 :     ; loop invariants: mm2=(i+j+1)/2 and mm3= i^j
442 : Isibaar 1795 movq mm2, [_EAX]
443 :     movq mm3, [_EAX+1]
444 : suxen_drol 1632 movq mm6, mm2
445 :     pavgb mm2, mm3
446 :     pxor mm3, mm6 ; mm2/mm3 ready
447 :    
448 :     jnz near .rounding1
449 :    
450 :     COPY_HV_SSE_RND0
451 : Isibaar 1795 add TMP0, TMP1
452 : suxen_drol 1632 COPY_HV_SSE_RND0
453 :     ret
454 :    
455 : Isibaar 1793 .rounding1:
456 : suxen_drol 1632 COPY_HV_SSE_RND1
457 : Isibaar 1795 add TMP0, TMP1
458 : suxen_drol 1632 COPY_HV_SSE_RND1
459 :     ret
460 : Isibaar 1793 ENDFUNC
461 : suxen_drol 1632
462 :     ;===========================================================================
463 :     ;
464 : edgomez 1530 ; The next functions combine both source halfpel interpolation step and the
465 :     ; averaging (with rouding) step to avoid wasting memory bandwidth computing
466 :     ; intermediate halfpel images and then averaging them.
467 :     ;
468 :     ;===========================================================================
469 :    
470 :     %macro PROLOG0 0
471 : Isibaar 1795 mov TMP0, prm1 ; Dst
472 :     mov _EAX, prm2 ; Src
473 :     mov TMP1, prm3 ; BpS
474 : edgomez 1530 %endmacro
475 :     %macro PROLOG1 0
476 :     PROLOG0
477 : Isibaar 1795 test prm4d, 1; Rounding?
478 : edgomez 1530 %endmacro
479 :     %macro EPILOG 0
480 :     ret
481 :     %endmacro
482 :    
483 :     ;===========================================================================
484 :     ;
485 :     ; void interpolate8x8_halfpel_add_xmm(uint8_t * const dst,
486 :     ; const uint8_t * const src,
487 :     ; const uint32_t stride,
488 :     ; const uint32_t rounding);
489 :     ;
490 :     ;
491 :     ;===========================================================================
492 :    
493 :     %macro ADD_FF 2
494 : Isibaar 1795 movq mm0, [_EAX+%1]
495 :     movq mm1, [_EAX+%2]
496 : edgomez 1530 ;;---
497 :     ;; movq mm2, mm0
498 :     ;; movq mm3, mm1
499 :     ;;---
500 : Isibaar 1795 pavgb mm0, [TMP0+%1]
501 :     pavgb mm1, [TMP0+%2]
502 : edgomez 1530 ;;--
503 : Isibaar 1795 ;; por mm2, [TMP0+%1]
504 :     ;; por mm3, [TMP0+%2]
505 : edgomez 1530 ;; pand mm2, [mmx_one]
506 :     ;; pand mm3, [mmx_one]
507 :     ;; psubsb mm0, mm2
508 :     ;; psubsb mm1, mm3
509 :     ;;--
510 : Isibaar 1795 movq [TMP0+%1], mm0
511 :     movq [TMP0+%2], mm1
512 : edgomez 1530 %endmacro
513 :    
514 : Isibaar 1795 ALIGN SECTION_ALIGN
515 : edgomez 1530 interpolate8x8_halfpel_add_xmm: ; 23c
516 :     PROLOG1
517 : Isibaar 1795 ADD_FF 0, TMP1
518 :     lea _EAX,[_EAX+2*TMP1]
519 :     lea TMP0,[TMP0+2*TMP1]
520 :     ADD_FF 0, TMP1
521 :     lea _EAX,[_EAX+2*TMP1]
522 :     lea TMP0,[TMP0+2*TMP1]
523 :     ADD_FF 0, TMP1
524 :     lea _EAX,[_EAX+2*TMP1]
525 :     lea TMP0,[TMP0+2*TMP1]
526 :     ADD_FF 0, TMP1
527 : edgomez 1530 EPILOG
528 : Isibaar 1793 ENDFUNC
529 : edgomez 1530
530 :     ;===========================================================================
531 :     ;
532 :     ; void interpolate8x8_halfpel_h_add_xmm(uint8_t * const dst,
533 :     ; const uint8_t * const src,
534 :     ; const uint32_t stride,
535 :     ; const uint32_t rounding);
536 :     ;
537 :     ;
538 :     ;===========================================================================
539 :    
540 :    
541 :     %macro ADD_FH_RND0 2
542 : Isibaar 1795 movq mm0, [_EAX+%1]
543 :     movq mm1, [_EAX+%2]
544 :     pavgb mm0, [_EAX+%1+1]
545 :     pavgb mm1, [_EAX+%2+1]
546 :     pavgb mm0, [TMP0+%1]
547 :     pavgb mm1, [TMP0+%2]
548 :     movq [TMP0+%1],mm0
549 :     movq [TMP0+%2],mm1
550 : edgomez 1530 %endmacro
551 :    
552 :     %macro ADD_FH_RND1 2
553 : Isibaar 1795 movq mm0, [_EAX+%1]
554 :     movq mm1, [_EAX+%2]
555 : edgomez 1530 movq mm4, mm0
556 :     movq mm5, mm1
557 : Isibaar 1795 movq mm2, [_EAX+%1+1]
558 :     movq mm3, [_EAX+%2+1]
559 : edgomez 1530 pavgb mm0, mm2
560 :     ; lea ??
561 :     pxor mm2, mm4
562 :     pavgb mm1, mm3
563 :     pxor mm3, mm5
564 :     pand mm2, [mmx_one]
565 :     pand mm3, [mmx_one]
566 :     psubb mm0, mm2
567 :     psubb mm1, mm3
568 : Isibaar 1795 pavgb mm0, [TMP0+%1]
569 :     pavgb mm1, [TMP0+%2]
570 :     movq [TMP0+%1],mm0
571 :     movq [TMP0+%2],mm1
572 : edgomez 1530 %endmacro
573 :    
574 : Isibaar 1795 ALIGN SECTION_ALIGN
575 : edgomez 1530 interpolate8x8_halfpel_h_add_xmm: ; 32c
576 :     PROLOG1
577 :     jnz near .Loop1
578 : Isibaar 1795 ADD_FH_RND0 0, TMP1
579 :     lea _EAX,[_EAX+2*TMP1]
580 :     lea TMP0,[TMP0+2*TMP1]
581 :     ADD_FH_RND0 0, TMP1
582 :     lea _EAX,[_EAX+2*TMP1]
583 :     lea TMP0,[TMP0+2*TMP1]
584 :     ADD_FH_RND0 0, TMP1
585 :     lea _EAX,[_EAX+2*TMP1]
586 :     lea TMP0,[TMP0+2*TMP1]
587 :     ADD_FH_RND0 0, TMP1
588 : edgomez 1530 EPILOG
589 :    
590 : Isibaar 1793 .Loop1:
591 : edgomez 1530 ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
592 :     ; movq mm7, [mmx_one]
593 : Isibaar 1795 ADD_FH_RND1 0, TMP1
594 :     lea _EAX,[_EAX+2*TMP1]
595 :     lea TMP0,[TMP0+2*TMP1]
596 :     ADD_FH_RND1 0, TMP1
597 :     lea _EAX,[_EAX+2*TMP1]
598 :     lea TMP0,[TMP0+2*TMP1]
599 :     ADD_FH_RND1 0, TMP1
600 :     lea _EAX,[_EAX+2*TMP1]
601 :     lea TMP0,[TMP0+2*TMP1]
602 :     ADD_FH_RND1 0, TMP1
603 : edgomez 1530 EPILOG
604 : Isibaar 1793 ENDFUNC
605 : edgomez 1530
606 :    
607 :     ;===========================================================================
608 :     ;
609 :     ; void interpolate8x8_halfpel_v_add_xmm(uint8_t * const dst,
610 :     ; const uint8_t * const src,
611 :     ; const uint32_t stride,
612 :     ; const uint32_t rounding);
613 :     ;
614 :     ;
615 :     ;===========================================================================
616 :    
617 :     %macro ADD_8_HF_RND0 0
618 : Isibaar 1795 movq mm0, [_EAX]
619 :     movq mm1, [_EAX+TMP1]
620 : edgomez 1530 pavgb mm0, mm1
621 : Isibaar 1795 pavgb mm1, [_EAX+2*TMP1]
622 :     lea _EAX,[_EAX+2*TMP1]
623 :     pavgb mm0, [TMP0]
624 :     pavgb mm1, [TMP0+TMP1]
625 :     movq [TMP0],mm0
626 :     movq [TMP0+TMP1],mm1
627 : edgomez 1530 %endmacro
628 :    
629 :     %macro ADD_8_HF_RND1 0
630 : Isibaar 1795 movq mm1, [_EAX+TMP1]
631 :     movq mm2, [_EAX+2*TMP1]
632 :     lea _EAX,[_EAX+2*TMP1]
633 : edgomez 1530 movq mm4, mm0
634 :     movq mm5, mm1
635 :     pavgb mm0, mm1
636 :     pxor mm4, mm1
637 :     pavgb mm1, mm2
638 :     pxor mm5, mm2
639 :     pand mm4, mm7 ; lsb's of (i^j)...
640 :     pand mm5, mm7 ; lsb's of (i^j)...
641 :     psubb mm0, mm4 ; ...are substracted from result of pavgb
642 : Isibaar 1795 pavgb mm0, [TMP0]
643 :     movq [TMP0], mm0
644 : edgomez 1530 psubb mm1, mm5 ; ...are substracted from result of pavgb
645 : Isibaar 1795 pavgb mm1, [TMP0+TMP1]
646 :     movq [TMP0+TMP1], mm1
647 : edgomez 1530 %endmacro
648 :    
649 : Isibaar 1795 ALIGN SECTION_ALIGN
650 : edgomez 1530 interpolate8x8_halfpel_v_add_xmm:
651 :     PROLOG1
652 :    
653 :     jnz near .Loop1
654 :     pxor mm7, mm7 ; this is a NOP
655 :    
656 :     ADD_8_HF_RND0
657 : Isibaar 1795 lea TMP0,[TMP0+2*TMP1]
658 : edgomez 1530 ADD_8_HF_RND0
659 : Isibaar 1795 lea TMP0,[TMP0+2*TMP1]
660 : edgomez 1530 ADD_8_HF_RND0
661 : Isibaar 1795 lea TMP0,[TMP0+2*TMP1]
662 : edgomez 1530 ADD_8_HF_RND0
663 :     EPILOG
664 :    
665 : Isibaar 1793 .Loop1:
666 : Isibaar 1795 movq mm0, [_EAX] ; loop invariant
667 : edgomez 1530 movq mm7, [mmx_one]
668 :    
669 :     ADD_8_HF_RND1
670 :     movq mm0, mm2
671 : Isibaar 1795 lea TMP0,[TMP0+2*TMP1]
672 : edgomez 1530 ADD_8_HF_RND1
673 :     movq mm0, mm2
674 : Isibaar 1795 lea TMP0,[TMP0+2*TMP1]
675 : edgomez 1530 ADD_8_HF_RND1
676 :     movq mm0, mm2
677 : Isibaar 1795 lea TMP0,[TMP0+2*TMP1]
678 : edgomez 1530 ADD_8_HF_RND1
679 :     EPILOG
680 : Isibaar 1793 ENDFUNC
681 : edgomez 1530
682 :     ; The trick is to correct the result of 'pavgb' with some combination of the
683 :     ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
684 :     ; The boolean relations are:
685 :     ; (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
686 :     ; (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
687 :     ; (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
688 :     ; (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
689 :     ; with s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
690 :    
691 :     ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
692 :    
693 :     ;===========================================================================
694 :     ;
695 :     ; void interpolate8x8_halfpel_hv_add_xmm(uint8_t * const dst,
696 :     ; const uint8_t * const src,
697 :     ; const uint32_t stride,
698 :     ; const uint32_t rounding);
699 :     ;
700 :     ;
701 :     ;===========================================================================
702 :    
703 :     %macro ADD_HH_RND0 0
704 : Isibaar 1795 lea _EAX,[_EAX+TMP1]
705 : edgomez 1530
706 : Isibaar 1795 movq mm0, [_EAX]
707 :     movq mm1, [_EAX+1]
708 : edgomez 1530
709 :     movq mm6, mm0
710 :     pavgb mm0, mm1 ; mm0=(j+k+1)/2. preserved for next step
711 : Isibaar 1795 lea _EAX,[_EAX+TMP1]
712 : edgomez 1530 pxor mm1, mm6 ; mm1=(j^k). preserved for next step
713 :    
714 :     por mm3, mm1 ; ij |= jk
715 :     movq mm6, mm2
716 :     pxor mm6, mm0 ; mm6 = s^t
717 :     pand mm3, mm6 ; (ij|jk) &= st
718 :     pavgb mm2, mm0 ; mm2 = (s+t+1)/2
719 :     pand mm3, mm7 ; mask lsb
720 :     psubb mm2, mm3 ; apply.
721 :    
722 : Isibaar 1795 pavgb mm2, [TMP0]
723 :     movq [TMP0], mm2
724 : edgomez 1530
725 : Isibaar 1795 movq mm2, [_EAX]
726 :     movq mm3, [_EAX+1]
727 : edgomez 1530 movq mm6, mm2
728 :     pavgb mm2, mm3 ; preserved for next iteration
729 : Isibaar 1795 lea TMP0,[TMP0+TMP1]
730 : edgomez 1530 pxor mm3, mm6 ; preserved for next iteration
731 :    
732 :     por mm1, mm3
733 :     movq mm6, mm0
734 :     pxor mm6, mm2
735 :     pand mm1, mm6
736 :     pavgb mm0, mm2
737 :    
738 :     pand mm1, mm7
739 :     psubb mm0, mm1
740 :    
741 : Isibaar 1795 pavgb mm0, [TMP0]
742 :     movq [TMP0], mm0
743 : edgomez 1530 %endmacro
744 :    
745 :     %macro ADD_HH_RND1 0
746 : Isibaar 1795 lea _EAX,[_EAX+TMP1]
747 : edgomez 1530
748 : Isibaar 1795 movq mm0, [_EAX]
749 :     movq mm1, [_EAX+1]
750 : edgomez 1530
751 :     movq mm6, mm0
752 :     pavgb mm0, mm1 ; mm0=(j+k+1)/2. preserved for next step
753 : Isibaar 1795 lea _EAX,[_EAX+TMP1]
754 : edgomez 1530 pxor mm1, mm6 ; mm1=(j^k). preserved for next step
755 :    
756 :     pand mm3, mm1
757 :     movq mm6, mm2
758 :     pxor mm6, mm0
759 :     por mm3, mm6
760 :     pavgb mm2, mm0
761 :     pand mm3, mm7
762 :     psubb mm2, mm3
763 :    
764 : Isibaar 1795 pavgb mm2, [TMP0]
765 :     movq [TMP0], mm2
766 : edgomez 1530
767 : Isibaar 1795 movq mm2, [_EAX]
768 :     movq mm3, [_EAX+1]
769 : edgomez 1530 movq mm6, mm2
770 :     pavgb mm2, mm3 ; preserved for next iteration
771 : Isibaar 1795 lea TMP0,[TMP0+TMP1]
772 : edgomez 1530 pxor mm3, mm6 ; preserved for next iteration
773 :    
774 :     pand mm1, mm3
775 :     movq mm6, mm0
776 :     pxor mm6, mm2
777 :     por mm1, mm6
778 :     pavgb mm0, mm2
779 :     pand mm1, mm7
780 :     psubb mm0, mm1
781 :    
782 : Isibaar 1795 pavgb mm0, [TMP0]
783 :     movq [TMP0], mm0
784 : edgomez 1530 %endmacro
785 :    
786 : Isibaar 1795 ALIGN SECTION_ALIGN
787 : edgomez 1530 interpolate8x8_halfpel_hv_add_xmm:
788 :     PROLOG1
789 :    
790 :     movq mm7, [mmx_one]
791 :    
792 :     ; loop invariants: mm2=(i+j+1)/2 and mm3= i^j
793 : Isibaar 1795 movq mm2, [_EAX]
794 :     movq mm3, [_EAX+1]
795 : edgomez 1530 movq mm6, mm2
796 :     pavgb mm2, mm3
797 :     pxor mm3, mm6 ; mm2/mm3 ready
798 :    
799 :     jnz near .Loop1
800 :    
801 :     ADD_HH_RND0
802 : Isibaar 1795 add TMP0, TMP1
803 : edgomez 1530 ADD_HH_RND0
804 : Isibaar 1795 add TMP0, TMP1
805 : edgomez 1530 ADD_HH_RND0
806 : Isibaar 1795 add TMP0, TMP1
807 : edgomez 1530 ADD_HH_RND0
808 :     EPILOG
809 :    
810 : Isibaar 1793 .Loop1:
811 : edgomez 1530 ADD_HH_RND1
812 : Isibaar 1795 add TMP0, TMP1
813 : edgomez 1530 ADD_HH_RND1
814 : Isibaar 1795 add TMP0, TMP1
815 : edgomez 1530 ADD_HH_RND1
816 : Isibaar 1795 add TMP0, TMP1
817 : edgomez 1530 ADD_HH_RND1
818 :    
819 :     EPILOG
820 : Isibaar 1793 ENDFUNC
821 : edgomez 1540
822 : Isibaar 1877 NON_EXEC_STACK

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4