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

Annotation of /trunk/xvidcore/src/image/x86_asm/interpolate8x8_3dn.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 :     ; * - 3dnow 8x8 block-based halfpel interpolation -
5 : Isibaar 262 ; *
6 : edgomez 1382 ; * Copyright(C) 2001 Peter Ross <pross@xvid.org>
7 : Isibaar 1795 ; * 2002-2008 Michael Militzer <michael@xvid.org>
8 : edgomez 1382 ; * 2002 Pascal Massimino <skal@planet-d.net>
9 : Isibaar 262 ; *
10 : edgomez 1382 ; * This program is free software ; you can redistribute it and/or modify
11 :     ; * it under the terms of the GNU General Public License as published by
12 :     ; * the Free Software Foundation ; either version 2 of the License, or
13 :     ; * (at your option) any later version.
14 : Isibaar 262 ; *
15 : edgomez 1382 ; * This program is distributed in the hope that it will be useful,
16 :     ; * but WITHOUT ANY WARRANTY ; without even the implied warranty of
17 :     ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 :     ; * GNU General Public License for more details.
19 : Isibaar 262 ; *
20 : edgomez 1382 ; * You should have received a copy of the GNU General Public License
21 :     ; * along with this program ; if not, write to the Free Software
22 :     ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 : Isibaar 262 ; *
24 : edgomez 1382 ; ****************************************************************************/
25 : Isibaar 262
26 : Isibaar 1795 %include "nasm.inc"
27 : edgomez 851
28 : edgomez 1382 ;=============================================================================
29 :     ; Read Only data
30 :     ;=============================================================================
31 : Isibaar 262
32 : Isibaar 1795 DATA
33 : Isibaar 262
34 : Isibaar 1795 ALIGN SECTION_ALIGN
35 : edgomez 1382 mmx_one:
36 :     times 8 db 1
37 : Isibaar 262
38 : edgomez 1382 ;=============================================================================
39 :     ; Code
40 :     ;=============================================================================
41 : Isibaar 262
42 : Isibaar 1844 TEXT
43 : Isibaar 262
44 :     cglobal interpolate8x8_halfpel_h_3dn
45 :     cglobal interpolate8x8_halfpel_v_3dn
46 :     cglobal interpolate8x8_halfpel_hv_3dn
47 :    
48 : suxen_drol 1632 cglobal interpolate8x4_halfpel_h_3dn
49 :     cglobal interpolate8x4_halfpel_v_3dn
50 :     cglobal interpolate8x4_halfpel_hv_3dn
51 :    
52 : edgomez 1382 ;-----------------------------------------------------------------------------
53 : Isibaar 262 ;
54 :     ; void interpolate8x8_halfpel_h_3dn(uint8_t * const dst,
55 : edgomez 1382 ; const uint8_t * const src,
56 :     ; const uint32_t stride,
57 :     ; const uint32_t rounding);
58 : Isibaar 262 ;
59 : edgomez 1382 ;-----------------------------------------------------------------------------
60 : Isibaar 262
61 :     %macro COPY_H_3DN_RND0 0
62 : Isibaar 1795 movq mm0, [_EAX]
63 :     pavgusb mm0, [_EAX+1]
64 :     movq mm1, [_EAX+TMP1]
65 :     pavgusb 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_3DN_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 pavgusb mm0, mm2
79 :     pxor mm2, mm4
80 :     pavgusb 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_3dn:
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_3DN_RND0
103 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
104 : Isibaar 262 COPY_H_3DN_RND0
105 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
106 : Isibaar 262 COPY_H_3DN_RND0
107 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
108 : Isibaar 262 COPY_H_3DN_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_3DN_RND1
115 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
116 : Isibaar 262 COPY_H_3DN_RND1
117 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
118 : Isibaar 262 COPY_H_3DN_RND1
119 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
120 : Isibaar 262 COPY_H_3DN_RND1
121 :     ret
122 : Isibaar 1793 ENDFUNC
123 : Isibaar 262
124 :    
125 : edgomez 1382 ;-----------------------------------------------------------------------------
126 : Isibaar 262 ;
127 :     ; void interpolate8x8_halfpel_v_3dn(uint8_t * const dst,
128 : edgomez 1382 ; const uint8_t * const src,
129 :     ; const uint32_t stride,
130 :     ; const uint32_t rounding);
131 : Isibaar 262 ;
132 : edgomez 1382 ;-----------------------------------------------------------------------------
133 : Isibaar 262
134 :     %macro COPY_V_3DN_RND0 0
135 : Isibaar 1795 movq mm0, [_EAX]
136 :     movq mm1, [_EAX+TMP1]
137 : Isibaar 262 pavgusb mm0, mm1
138 : Isibaar 1795 pavgusb mm1, [_EAX+2*TMP1]
139 :     lea _EAX, [_EAX+2*TMP1]
140 :     movq [TMP0], mm0
141 :     movq [TMP0+TMP1], mm1
142 : Isibaar 262 %endmacro
143 :    
144 :     %macro COPY_V_3DN_RND1 0
145 :     movq mm0, mm2
146 : Isibaar 1795 movq mm1, [_EAX]
147 :     movq mm2, [_EAX+TMP1]
148 :     lea _EAX, [_EAX+2*TMP1]
149 : Isibaar 262 movq mm4, mm0
150 :     movq mm5, mm1
151 :     pavgusb mm0, mm1
152 : edgomez 1382 pxor mm4, mm1
153 : Isibaar 262 pavgusb mm1, mm2
154 :     pxor mm5, mm2
155 : edgomez 1382 pand mm4, mm7 ; lsb's of (i^j)...
156 :     pand mm5, mm7 ; lsb's of (i^j)...
157 :     psubb mm0, mm4 ; ...are substracted from result of pavgusb
158 : Isibaar 1795 movq [TMP0], mm0
159 : edgomez 1382 psubb mm1, mm5 ; ...are substracted from result of pavgusb
160 : Isibaar 1795 movq [TMP0+TMP1], mm1
161 : Isibaar 262 %endmacro
162 :    
163 : Isibaar 1795 ALIGN SECTION_ALIGN
164 : Isibaar 262 interpolate8x8_halfpel_v_3dn:
165 :    
166 : Isibaar 1795 mov _EAX, prm4 ; rounding
167 :     mov TMP0, prm1 ; Dst
168 :     test _EAX,_EAX
169 :     mov _EAX, prm2 ; Src
170 :     mov TMP1, prm3 ; stride
171 : Isibaar 262
172 :     ; we process 2 line at a time
173 :    
174 :     jnz near .rounding1
175 :    
176 :     COPY_V_3DN_RND0
177 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
178 : Isibaar 262 COPY_V_3DN_RND0
179 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
180 : Isibaar 262 COPY_V_3DN_RND0
181 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
182 : Isibaar 262 COPY_V_3DN_RND0
183 :     ret
184 :    
185 : Isibaar 1793 .rounding1:
186 : edgomez 1382 ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
187 : Isibaar 262 movq mm7, [mmx_one]
188 : Isibaar 1795 movq mm2, [_EAX] ; loop invariant
189 :     add _EAX, TMP1
190 : Isibaar 262
191 :     COPY_V_3DN_RND1
192 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
193 : Isibaar 262 COPY_V_3DN_RND1
194 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
195 : Isibaar 262 COPY_V_3DN_RND1
196 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
197 : Isibaar 262 COPY_V_3DN_RND1
198 :     ret
199 : Isibaar 1793 ENDFUNC
200 : Isibaar 262
201 :    
202 : edgomez 1382 ;-----------------------------------------------------------------------------
203 : Isibaar 262 ;
204 :     ; void interpolate8x8_halfpel_hv_3dn(uint8_t * const dst,
205 : edgomez 1382 ; const uint8_t * const src,
206 :     ; const uint32_t stride,
207 :     ; const uint32_t rounding);
208 : Isibaar 262 ;
209 :     ;
210 : edgomez 1382 ;-----------------------------------------------------------------------------
211 : Isibaar 262
212 :     ; The trick is to correct the result of 'pavgusb' with some combination of the
213 :     ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgusb' (s and t).
214 :     ; The boolean relations are:
215 : edgomez 1382 ; (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
216 : Isibaar 262 ; (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
217 :     ; (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
218 :     ; (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
219 :     ; with s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
220 :    
221 :     ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
222 :    
223 :     %macro COPY_HV_3DN_RND0 0
224 : Isibaar 1795 lea _EAX, [_EAX+TMP1]
225 : Isibaar 262
226 : Isibaar 1795 movq mm0, [_EAX]
227 :     movq mm1, [_EAX+1]
228 : Isibaar 262
229 : edgomez 1382 movq mm6, mm0
230 :     pavgusb mm0, mm1 ; mm0=(j+k+1)/2. preserved for next step
231 : Isibaar 1795 lea _EAX, [_EAX+TMP1]
232 : edgomez 1382 pxor mm1, mm6 ; mm1=(j^k). preserved for next step
233 : Isibaar 262
234 : edgomez 1382 por mm3, mm1 ; ij |= jk
235 :     movq mm6, mm2
236 :     pxor mm6, mm0 ; mm6 = s^t
237 :     pand mm3, mm6 ; (ij|jk) &= st
238 :     pavgusb mm2, mm0 ; mm2 = (s+t+1)/2
239 :     pand mm3, mm7 ; mask lsb
240 :     psubb mm2, mm3 ; apply.
241 : Isibaar 262
242 : Isibaar 1795 movq [TMP0], mm2
243 : Isibaar 262
244 : Isibaar 1795 movq mm2, [_EAX]
245 :     movq mm3, [_EAX+1]
246 : edgomez 1382 movq mm6, mm2
247 :     pavgusb mm2, mm3 ; preserved for next iteration
248 : Isibaar 1795 lea TMP0, [TMP0+TMP1]
249 : edgomez 1382 pxor mm3, mm6 ; preserved for next iteration
250 : Isibaar 262
251 : edgomez 1382 por mm1, mm3
252 :     movq mm6, mm0
253 :     pxor mm6, mm2
254 :     pand mm1, mm6
255 :     pavgusb mm0, mm2
256 : Isibaar 262
257 : edgomez 1382 pand mm1, mm7
258 :     psubb mm0, mm1
259 : Isibaar 262
260 : Isibaar 1795 movq [TMP0], mm0
261 : Isibaar 262 %endmacro
262 :    
263 :     %macro COPY_HV_3DN_RND1 0
264 : Isibaar 1795 lea _EAX,[_EAX+TMP1]
265 : Isibaar 262
266 : Isibaar 1795 movq mm0, [_EAX]
267 :     movq mm1, [_EAX+1]
268 : Isibaar 262
269 : edgomez 1382 movq mm6, mm0
270 :     pavgusb mm0, mm1 ; mm0=(j+k+1)/2. preserved for next step
271 : Isibaar 1795 lea _EAX, [_EAX+TMP1]
272 : edgomez 1382 pxor mm1, mm6 ; mm1=(j^k). preserved for next step
273 : Isibaar 262
274 : edgomez 1382 pand mm3, mm1
275 :     movq mm6, mm2
276 :     pxor mm6, mm0
277 :     por mm3, mm6
278 :     pavgusb mm2, mm0
279 :     pand mm3, mm7
280 :     psubb mm2, mm3
281 : Isibaar 262
282 : Isibaar 1795 movq [TMP0], mm2
283 : Isibaar 262
284 : Isibaar 1795 movq mm2, [_EAX]
285 :     movq mm3, [_EAX+1]
286 : edgomez 1382 movq mm6, mm2
287 :     pavgusb mm2, mm3 ; preserved for next iteration
288 : Isibaar 1795 lea TMP0, [TMP0+TMP1]
289 : edgomez 1382 pxor mm3, mm6 ; preserved for next iteration
290 : Isibaar 262
291 : edgomez 1382 pand mm1, mm3
292 :     movq mm6, mm0
293 :     pxor mm6, mm2
294 :     por mm1, mm6
295 :     pavgusb mm0, mm2
296 :     pand mm1, mm7
297 :     psubb mm0, mm1
298 : Isibaar 262
299 : Isibaar 1795 movq [TMP0], mm0
300 : Isibaar 262 %endmacro
301 :    
302 : Isibaar 1795 ALIGN SECTION_ALIGN
303 : Isibaar 1793 interpolate8x8_halfpel_hv_3dn:
304 : Isibaar 1795 mov _EAX, prm4 ; rounding
305 :     mov TMP0, prm1 ; Dst
306 :     test _EAX, _EAX
307 :     mov _EAX, prm2 ; Src
308 :     mov TMP1, prm3 ; stride
309 : Isibaar 262
310 :     movq mm7, [mmx_one]
311 :    
312 :     ; loop invariants: mm2=(i+j+1)/2 and mm3= i^j
313 : Isibaar 1795 movq mm2, [_EAX]
314 :     movq mm3, [_EAX+1]
315 : Isibaar 262 movq mm6, mm2
316 :     pavgusb mm2, mm3
317 : edgomez 1382 pxor mm3, mm6 ; mm2/mm3 ready
318 : Isibaar 262
319 :     jnz near .rounding1
320 :    
321 :     COPY_HV_3DN_RND0
322 : Isibaar 1795 add TMP0, TMP1
323 : Isibaar 262 COPY_HV_3DN_RND0
324 : Isibaar 1795 add TMP0, TMP1
325 : Isibaar 262 COPY_HV_3DN_RND0
326 : Isibaar 1795 add TMP0, TMP1
327 : Isibaar 262 COPY_HV_3DN_RND0
328 :     ret
329 :    
330 : Isibaar 1793 .rounding1:
331 : Isibaar 262 COPY_HV_3DN_RND1
332 : Isibaar 1795 add TMP0, TMP1
333 : Isibaar 262 COPY_HV_3DN_RND1
334 : Isibaar 1795 add TMP0, TMP1
335 : Isibaar 262 COPY_HV_3DN_RND1
336 : Isibaar 1795 add TMP0, TMP1
337 : Isibaar 262 COPY_HV_3DN_RND1
338 : edgomez 1382 ret
339 : Isibaar 1793 ENDFUNC
340 : edgomez 1540
341 : suxen_drol 1632 ;-----------------------------------------------------------------------------
342 :     ;
343 :     ; void interpolate8x4_halfpel_h_3dn(uint8_t * const dst,
344 :     ; const uint8_t * const src,
345 :     ; const uint32_t stride,
346 :     ; const uint32_t rounding);
347 :     ;
348 :     ;-----------------------------------------------------------------------------
349 :    
350 : Isibaar 1795 ALIGN SECTION_ALIGN
351 : suxen_drol 1632 interpolate8x4_halfpel_h_3dn:
352 :    
353 : Isibaar 1795 mov _EAX, prm4 ; rounding
354 :     mov TMP0, prm1 ; Dst
355 :     test _EAX, _EAX
356 :     mov _EAX, prm2 ; Src
357 :     mov TMP1, prm3 ; stride
358 : suxen_drol 1632
359 :     jnz near .rounding1
360 :    
361 :     COPY_H_3DN_RND0
362 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
363 : suxen_drol 1632 COPY_H_3DN_RND0
364 :     ret
365 :    
366 : Isibaar 1793 .rounding1:
367 : suxen_drol 1632 ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
368 :     movq mm7, [mmx_one]
369 :     COPY_H_3DN_RND1
370 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
371 : suxen_drol 1632 COPY_H_3DN_RND1
372 :     ret
373 : Isibaar 1793 ENDFUNC
374 : suxen_drol 1632
375 :    
376 :     ;-----------------------------------------------------------------------------
377 :     ;
378 :     ; void interpolate8x4_halfpel_v_3dn(uint8_t * const dst,
379 :     ; const uint8_t * const src,
380 :     ; const uint32_t stride,
381 :     ; const uint32_t rounding);
382 :     ;
383 :     ;-----------------------------------------------------------------------------
384 :    
385 : Isibaar 1795 ALIGN SECTION_ALIGN
386 : suxen_drol 1632 interpolate8x4_halfpel_v_3dn:
387 :    
388 : Isibaar 1795 mov _EAX, prm4 ; rounding
389 :     mov TMP0, prm1 ; Dst
390 :     test _EAX,_EAX
391 :     mov _EAX, prm2 ; Src
392 :     mov TMP1, prm3 ; stride
393 : suxen_drol 1632
394 :     ; we process 2 line at a time
395 :    
396 :     jnz near .rounding1
397 :    
398 :     COPY_V_3DN_RND0
399 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
400 : suxen_drol 1632 COPY_V_3DN_RND0
401 :     ret
402 :    
403 : Isibaar 1793 .rounding1:
404 : suxen_drol 1632 ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
405 :     movq mm7, [mmx_one]
406 : Isibaar 1795 movq mm2, [_EAX] ; loop invariant
407 :     add _EAX, TMP1
408 : suxen_drol 1632
409 :     COPY_V_3DN_RND1
410 : Isibaar 1795 lea TMP0, [TMP0+2*TMP1]
411 : suxen_drol 1632 COPY_V_3DN_RND1
412 :     ret
413 : Isibaar 1793 ENDFUNC
414 : suxen_drol 1632
415 :    
416 :     ;-----------------------------------------------------------------------------
417 :     ;
418 :     ; void interpolate8x4_halfpel_hv_3dn(uint8_t * const dst,
419 :     ; const uint8_t * const src,
420 :     ; const uint32_t stride,
421 :     ; const uint32_t rounding);
422 :     ;
423 :     ;
424 :     ;-----------------------------------------------------------------------------
425 :    
426 :     ; The trick is to correct the result of 'pavgusb' with some combination of the
427 :     ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgusb' (s and t).
428 :     ; The boolean relations are:
429 :     ; (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
430 :     ; (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
431 :     ; (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
432 :     ; (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
433 :     ; with s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
434 :    
435 : Isibaar 1795 ALIGN SECTION_ALIGN
436 : Isibaar 1793 interpolate8x4_halfpel_hv_3dn:
437 : Isibaar 1795 mov _EAX, prm4 ; rounding
438 :     mov TMP0, prm1 ; Dst
439 :     test _EAX, _EAX
440 :     mov _EAX, prm2 ; Src
441 :     mov TMP1, prm3 ; stride
442 : suxen_drol 1632
443 :     movq mm7, [mmx_one]
444 :    
445 :     ; loop invariants: mm2=(i+j+1)/2 and mm3= i^j
446 : Isibaar 1795 movq mm2, [_EAX]
447 :     movq mm3, [_EAX+1]
448 : suxen_drol 1632 movq mm6, mm2
449 :     pavgusb mm2, mm3
450 :     pxor mm3, mm6 ; mm2/mm3 ready
451 :    
452 :     jnz near .rounding1
453 :    
454 :     COPY_HV_3DN_RND0
455 : Isibaar 1795 add TMP0, TMP1
456 : suxen_drol 1632 COPY_HV_3DN_RND0
457 :     ret
458 :    
459 : Isibaar 1793 .rounding1:
460 : suxen_drol 1632 COPY_HV_3DN_RND1
461 : Isibaar 1795 add TMP0, TMP1
462 : suxen_drol 1632 COPY_HV_3DN_RND1
463 :     ret
464 : Isibaar 1793 ENDFUNC
465 : suxen_drol 1632
466 : Isibaar 1877 NON_EXEC_STACK

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