[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 1540 - (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 :     ; * 2002 Michael Militzer <isibaar@xvid.org>
8 :     ; * 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 : edgomez 1382 BITS 32
27 : edgomez 851
28 : edgomez 1382 %macro cglobal 1
29 : Isibaar 262 %ifdef PREFIX
30 : edgomez 1535 %ifdef MARK_FUNCS
31 : edgomez 1540 global _%1:function %1.endfunc-%1
32 :     %define %1 _%1:function %1.endfunc-%1
33 : edgomez 1535 %else
34 :     global _%1
35 :     %define %1 _%1
36 :     %endif
37 : Isibaar 262 %else
38 : edgomez 1535 %ifdef MARK_FUNCS
39 : edgomez 1540 global %1:function %1.endfunc-%1
40 : edgomez 1535 %else
41 :     global %1
42 :     %endif
43 : Isibaar 262 %endif
44 :     %endmacro
45 :    
46 : edgomez 1382 ;=============================================================================
47 :     ; Read Only data
48 :     ;=============================================================================
49 : Isibaar 262
50 : edgomez 1382 %ifdef FORMAT_COFF
51 : edgomez 1519 SECTION .rodata
52 : edgomez 1382 %else
53 : edgomez 1519 SECTION .rodata align=16
54 : edgomez 1382 %endif
55 : Isibaar 262
56 : edgomez 1382 ALIGN 16
57 :     mmx_one:
58 :     times 8 db 1
59 : Isibaar 262
60 : edgomez 1382 ;=============================================================================
61 :     ; Code
62 :     ;=============================================================================
63 : Isibaar 262
64 : edgomez 1382 SECTION .text
65 : Isibaar 262
66 :     cglobal interpolate8x8_halfpel_h_3dn
67 :     cglobal interpolate8x8_halfpel_v_3dn
68 :     cglobal interpolate8x8_halfpel_hv_3dn
69 :    
70 : edgomez 1382 ;-----------------------------------------------------------------------------
71 : Isibaar 262 ;
72 :     ; void interpolate8x8_halfpel_h_3dn(uint8_t * const dst,
73 : edgomez 1382 ; const uint8_t * const src,
74 :     ; const uint32_t stride,
75 :     ; const uint32_t rounding);
76 : Isibaar 262 ;
77 : edgomez 1382 ;-----------------------------------------------------------------------------
78 : Isibaar 262
79 :     %macro COPY_H_3DN_RND0 0
80 : edgomez 1382 movq mm0, [eax]
81 : Isibaar 262 pavgusb mm0, [eax+1]
82 : edgomez 1382 movq mm1, [eax+edx]
83 : Isibaar 262 pavgusb mm1, [eax+edx+1]
84 : edgomez 1382 lea eax, [eax+2*edx]
85 :     movq [ecx], mm0
86 :     movq [ecx+edx], mm1
87 : Isibaar 262 %endmacro
88 :    
89 :     %macro COPY_H_3DN_RND1 0
90 :     movq mm0, [eax]
91 :     movq mm1, [eax+edx]
92 :     movq mm4, mm0
93 :     movq mm5, mm1
94 : edgomez 1382 movq mm2, [eax+1]
95 : Isibaar 262 movq mm3, [eax+edx+1]
96 :     pavgusb mm0, mm2
97 :     pxor mm2, mm4
98 :     pavgusb mm1, mm3
99 : edgomez 1382 lea eax, [eax+2*edx]
100 : Isibaar 262 pxor mm3, mm5
101 :     pand mm2, mm7
102 :     pand mm3, mm7
103 :     psubb mm0, mm2
104 :     movq [ecx], mm0
105 :     psubb mm1, mm3
106 :     movq [ecx+edx], mm1
107 :     %endmacro
108 :    
109 : edgomez 1382 ALIGN 16
110 : Isibaar 262 interpolate8x8_halfpel_h_3dn:
111 :    
112 :     mov eax, [esp+16] ; rounding
113 :     mov ecx, [esp+ 4] ; Dst
114 : edgomez 1382 test eax, eax
115 : Isibaar 262 mov eax, [esp+ 8] ; Src
116 :     mov edx, [esp+12] ; stride
117 :    
118 :     jnz near .rounding1
119 :    
120 :     COPY_H_3DN_RND0
121 : edgomez 1382 lea ecx, [ecx+2*edx]
122 : Isibaar 262 COPY_H_3DN_RND0
123 : edgomez 1382 lea ecx, [ecx+2*edx]
124 : Isibaar 262 COPY_H_3DN_RND0
125 : edgomez 1382 lea ecx, [ecx+2*edx]
126 : Isibaar 262 COPY_H_3DN_RND0
127 :     ret
128 :    
129 :     .rounding1
130 : edgomez 1382 ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
131 : Isibaar 262 movq mm7, [mmx_one]
132 :     COPY_H_3DN_RND1
133 :     lea ecx, [ecx+2*edx]
134 :     COPY_H_3DN_RND1
135 : edgomez 1382 lea ecx, [ecx+2*edx]
136 : Isibaar 262 COPY_H_3DN_RND1
137 : edgomez 1382 lea ecx, [ecx+2*edx]
138 : Isibaar 262 COPY_H_3DN_RND1
139 :     ret
140 : edgomez 1540 .endfunc
141 : Isibaar 262
142 :    
143 : edgomez 1382 ;-----------------------------------------------------------------------------
144 : Isibaar 262 ;
145 :     ; void interpolate8x8_halfpel_v_3dn(uint8_t * const dst,
146 : edgomez 1382 ; const uint8_t * const src,
147 :     ; const uint32_t stride,
148 :     ; const uint32_t rounding);
149 : Isibaar 262 ;
150 : edgomez 1382 ;-----------------------------------------------------------------------------
151 : Isibaar 262
152 :     %macro COPY_V_3DN_RND0 0
153 : edgomez 1382 movq mm0, [eax]
154 :     movq mm1, [eax+edx]
155 : Isibaar 262 pavgusb mm0, mm1
156 :     pavgusb mm1, [eax+2*edx]
157 : edgomez 1382 lea eax, [eax+2*edx]
158 :     movq [ecx], mm0
159 :     movq [ecx+edx], mm1
160 : Isibaar 262 %endmacro
161 :    
162 :     %macro COPY_V_3DN_RND1 0
163 :     movq mm0, mm2
164 :     movq mm1, [eax]
165 :     movq mm2, [eax+edx]
166 : edgomez 1382 lea eax, [eax+2*edx]
167 : Isibaar 262 movq mm4, mm0
168 :     movq mm5, mm1
169 :     pavgusb mm0, mm1
170 : edgomez 1382 pxor mm4, mm1
171 : Isibaar 262 pavgusb mm1, mm2
172 :     pxor mm5, mm2
173 : edgomez 1382 pand mm4, mm7 ; lsb's of (i^j)...
174 :     pand mm5, mm7 ; lsb's of (i^j)...
175 :     psubb mm0, mm4 ; ...are substracted from result of pavgusb
176 : Isibaar 262 movq [ecx], mm0
177 : edgomez 1382 psubb mm1, mm5 ; ...are substracted from result of pavgusb
178 : Isibaar 262 movq [ecx+edx], mm1
179 :     %endmacro
180 :    
181 : edgomez 1382 ALIGN 16
182 : Isibaar 262 interpolate8x8_halfpel_v_3dn:
183 :    
184 :     mov eax, [esp+16] ; rounding
185 :     mov ecx, [esp+ 4] ; Dst
186 :     test eax,eax
187 :     mov eax, [esp+ 8] ; Src
188 :     mov edx, [esp+12] ; stride
189 :    
190 :     ; we process 2 line at a time
191 :    
192 :     jnz near .rounding1
193 :    
194 :     COPY_V_3DN_RND0
195 :     lea ecx, [ecx+2*edx]
196 :     COPY_V_3DN_RND0
197 :     lea ecx, [ecx+2*edx]
198 :     COPY_V_3DN_RND0
199 :     lea ecx, [ecx+2*edx]
200 :     COPY_V_3DN_RND0
201 :     ret
202 :    
203 :     .rounding1
204 : edgomez 1382 ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
205 : Isibaar 262 movq mm7, [mmx_one]
206 : edgomez 1382 movq mm2, [eax] ; loop invariant
207 : Isibaar 262 add eax, edx
208 :    
209 :     COPY_V_3DN_RND1
210 : edgomez 1382 lea ecx, [ecx+2*edx]
211 : Isibaar 262 COPY_V_3DN_RND1
212 : edgomez 1382 lea ecx, [ecx+2*edx]
213 : Isibaar 262 COPY_V_3DN_RND1
214 : edgomez 1382 lea ecx, [ecx+2*edx]
215 : Isibaar 262 COPY_V_3DN_RND1
216 :     ret
217 : edgomez 1540 .endfunc
218 : Isibaar 262
219 :    
220 : edgomez 1382 ;-----------------------------------------------------------------------------
221 : Isibaar 262 ;
222 :     ; void interpolate8x8_halfpel_hv_3dn(uint8_t * const dst,
223 : edgomez 1382 ; const uint8_t * const src,
224 :     ; const uint32_t stride,
225 :     ; const uint32_t rounding);
226 : Isibaar 262 ;
227 :     ;
228 : edgomez 1382 ;-----------------------------------------------------------------------------
229 : Isibaar 262
230 :     ; The trick is to correct the result of 'pavgusb' with some combination of the
231 :     ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgusb' (s and t).
232 :     ; The boolean relations are:
233 : edgomez 1382 ; (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
234 : Isibaar 262 ; (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
235 :     ; (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
236 :     ; (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
237 :     ; with s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
238 :    
239 :     ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
240 :    
241 :     %macro COPY_HV_3DN_RND0 0
242 : edgomez 1382 lea eax, [eax+edx]
243 : Isibaar 262
244 : edgomez 1382 movq mm0, [eax]
245 :     movq mm1, [eax+1]
246 : Isibaar 262
247 : edgomez 1382 movq mm6, mm0
248 :     pavgusb mm0, mm1 ; mm0=(j+k+1)/2. preserved for next step
249 :     lea eax, [eax+edx]
250 :     pxor mm1, mm6 ; mm1=(j^k). preserved for next step
251 : Isibaar 262
252 : edgomez 1382 por mm3, mm1 ; ij |= jk
253 :     movq mm6, mm2
254 :     pxor mm6, mm0 ; mm6 = s^t
255 :     pand mm3, mm6 ; (ij|jk) &= st
256 :     pavgusb mm2, mm0 ; mm2 = (s+t+1)/2
257 :     pand mm3, mm7 ; mask lsb
258 :     psubb mm2, mm3 ; apply.
259 : Isibaar 262
260 : edgomez 1382 movq [ecx], mm2
261 : Isibaar 262
262 : edgomez 1382 movq mm2, [eax]
263 :     movq mm3, [eax+1]
264 :     movq mm6, mm2
265 :     pavgusb mm2, mm3 ; preserved for next iteration
266 :     lea ecx, [ecx+edx]
267 :     pxor mm3, mm6 ; preserved for next iteration
268 : Isibaar 262
269 : edgomez 1382 por mm1, mm3
270 :     movq mm6, mm0
271 :     pxor mm6, mm2
272 :     pand mm1, mm6
273 :     pavgusb mm0, mm2
274 : Isibaar 262
275 : edgomez 1382 pand mm1, mm7
276 :     psubb mm0, mm1
277 : Isibaar 262
278 : edgomez 1382 movq [ecx], mm0
279 : Isibaar 262 %endmacro
280 :    
281 :     %macro COPY_HV_3DN_RND1 0
282 : edgomez 1382 lea eax,[eax+edx]
283 : Isibaar 262
284 : edgomez 1382 movq mm0, [eax]
285 :     movq mm1, [eax+1]
286 : Isibaar 262
287 : edgomez 1382 movq mm6, mm0
288 :     pavgusb mm0, mm1 ; mm0=(j+k+1)/2. preserved for next step
289 :     lea eax, [eax+edx]
290 :     pxor mm1, mm6 ; mm1=(j^k). preserved for next step
291 : Isibaar 262
292 : edgomez 1382 pand mm3, mm1
293 :     movq mm6, mm2
294 :     pxor mm6, mm0
295 :     por mm3, mm6
296 :     pavgusb mm2, mm0
297 :     pand mm3, mm7
298 :     psubb mm2, mm3
299 : Isibaar 262
300 : edgomez 1382 movq [ecx], mm2
301 : Isibaar 262
302 : edgomez 1382 movq mm2, [eax]
303 :     movq mm3, [eax+1]
304 :     movq mm6, mm2
305 :     pavgusb mm2, mm3 ; preserved for next iteration
306 :     lea ecx, [ecx+edx]
307 :     pxor mm3, mm6 ; preserved for next iteration
308 : Isibaar 262
309 : edgomez 1382 pand mm1, mm3
310 :     movq mm6, mm0
311 :     pxor mm6, mm2
312 :     por mm1, mm6
313 :     pavgusb mm0, mm2
314 :     pand mm1, mm7
315 :     psubb mm0, mm1
316 : Isibaar 262
317 : edgomez 1382 movq [ecx], mm0
318 : Isibaar 262 %endmacro
319 :    
320 : edgomez 1382 ALIGN 16
321 : Isibaar 262 interpolate8x8_halfpel_hv_3dn
322 :     mov eax, [esp+16] ; rounding
323 :     mov ecx, [esp+ 4] ; Dst
324 : edgomez 1382 test eax, eax
325 : Isibaar 262 mov eax, [esp+ 8] ; Src
326 :     mov edx, [esp+12] ; stride
327 :    
328 :     movq mm7, [mmx_one]
329 :    
330 :     ; loop invariants: mm2=(i+j+1)/2 and mm3= i^j
331 :     movq mm2, [eax]
332 :     movq mm3, [eax+1]
333 :     movq mm6, mm2
334 :     pavgusb mm2, mm3
335 : edgomez 1382 pxor mm3, mm6 ; mm2/mm3 ready
336 : Isibaar 262
337 :     jnz near .rounding1
338 :    
339 :     COPY_HV_3DN_RND0
340 :     add ecx, edx
341 :     COPY_HV_3DN_RND0
342 :     add ecx, edx
343 :     COPY_HV_3DN_RND0
344 :     add ecx, edx
345 :     COPY_HV_3DN_RND0
346 :     ret
347 :    
348 :     .rounding1
349 :     COPY_HV_3DN_RND1
350 :     add ecx, edx
351 :     COPY_HV_3DN_RND1
352 :     add ecx, edx
353 :     COPY_HV_3DN_RND1
354 :     add ecx, edx
355 :     COPY_HV_3DN_RND1
356 : edgomez 1382 ret
357 : edgomez 1540 .endfunc
358 :    

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