[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 1535 - (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 :     global _%1:function
32 :     %define %1 _%1:function
33 :     %else
34 :     global _%1
35 :     %define %1 _%1
36 :     %endif
37 : Isibaar 262 %else
38 : edgomez 1535 %ifdef MARK_FUNCS
39 :     global %1:function
40 :     %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 :    
141 :    
142 : edgomez 1382 ;-----------------------------------------------------------------------------
143 : Isibaar 262 ;
144 :     ; void interpolate8x8_halfpel_v_3dn(uint8_t * const dst,
145 : edgomez 1382 ; const uint8_t * const src,
146 :     ; const uint32_t stride,
147 :     ; const uint32_t rounding);
148 : Isibaar 262 ;
149 : edgomez 1382 ;-----------------------------------------------------------------------------
150 : Isibaar 262
151 :     %macro COPY_V_3DN_RND0 0
152 : edgomez 1382 movq mm0, [eax]
153 :     movq mm1, [eax+edx]
154 : Isibaar 262 pavgusb mm0, mm1
155 :     pavgusb mm1, [eax+2*edx]
156 : edgomez 1382 lea eax, [eax+2*edx]
157 :     movq [ecx], mm0
158 :     movq [ecx+edx], mm1
159 : Isibaar 262 %endmacro
160 :    
161 :     %macro COPY_V_3DN_RND1 0
162 :     movq mm0, mm2
163 :     movq mm1, [eax]
164 :     movq mm2, [eax+edx]
165 : edgomez 1382 lea eax, [eax+2*edx]
166 : Isibaar 262 movq mm4, mm0
167 :     movq mm5, mm1
168 :     pavgusb mm0, mm1
169 : edgomez 1382 pxor mm4, mm1
170 : Isibaar 262 pavgusb mm1, mm2
171 :     pxor mm5, mm2
172 : edgomez 1382 pand mm4, mm7 ; lsb's of (i^j)...
173 :     pand mm5, mm7 ; lsb's of (i^j)...
174 :     psubb mm0, mm4 ; ...are substracted from result of pavgusb
175 : Isibaar 262 movq [ecx], mm0
176 : edgomez 1382 psubb mm1, mm5 ; ...are substracted from result of pavgusb
177 : Isibaar 262 movq [ecx+edx], mm1
178 :     %endmacro
179 :    
180 : edgomez 1382 ALIGN 16
181 : Isibaar 262 interpolate8x8_halfpel_v_3dn:
182 :    
183 :     mov eax, [esp+16] ; rounding
184 :     mov ecx, [esp+ 4] ; Dst
185 :     test eax,eax
186 :     mov eax, [esp+ 8] ; Src
187 :     mov edx, [esp+12] ; stride
188 :    
189 :     ; we process 2 line at a time
190 :    
191 :     jnz near .rounding1
192 :    
193 :     COPY_V_3DN_RND0
194 :     lea ecx, [ecx+2*edx]
195 :     COPY_V_3DN_RND0
196 :     lea ecx, [ecx+2*edx]
197 :     COPY_V_3DN_RND0
198 :     lea ecx, [ecx+2*edx]
199 :     COPY_V_3DN_RND0
200 :     ret
201 :    
202 :     .rounding1
203 : edgomez 1382 ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
204 : Isibaar 262 movq mm7, [mmx_one]
205 : edgomez 1382 movq mm2, [eax] ; loop invariant
206 : Isibaar 262 add eax, edx
207 :    
208 :     COPY_V_3DN_RND1
209 : edgomez 1382 lea ecx, [ecx+2*edx]
210 : Isibaar 262 COPY_V_3DN_RND1
211 : edgomez 1382 lea ecx, [ecx+2*edx]
212 : Isibaar 262 COPY_V_3DN_RND1
213 : edgomez 1382 lea ecx, [ecx+2*edx]
214 : Isibaar 262 COPY_V_3DN_RND1
215 :     ret
216 :    
217 :    
218 : edgomez 1382 ;-----------------------------------------------------------------------------
219 : Isibaar 262 ;
220 :     ; void interpolate8x8_halfpel_hv_3dn(uint8_t * const dst,
221 : edgomez 1382 ; const uint8_t * const src,
222 :     ; const uint32_t stride,
223 :     ; const uint32_t rounding);
224 : Isibaar 262 ;
225 :     ;
226 : edgomez 1382 ;-----------------------------------------------------------------------------
227 : Isibaar 262
228 :     ; The trick is to correct the result of 'pavgusb' with some combination of the
229 :     ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgusb' (s and t).
230 :     ; The boolean relations are:
231 : edgomez 1382 ; (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
232 : Isibaar 262 ; (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
233 :     ; (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
234 :     ; (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
235 :     ; with s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
236 :    
237 :     ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
238 :    
239 :     %macro COPY_HV_3DN_RND0 0
240 : edgomez 1382 lea eax, [eax+edx]
241 : Isibaar 262
242 : edgomez 1382 movq mm0, [eax]
243 :     movq mm1, [eax+1]
244 : Isibaar 262
245 : edgomez 1382 movq mm6, mm0
246 :     pavgusb mm0, mm1 ; mm0=(j+k+1)/2. preserved for next step
247 :     lea eax, [eax+edx]
248 :     pxor mm1, mm6 ; mm1=(j^k). preserved for next step
249 : Isibaar 262
250 : edgomez 1382 por mm3, mm1 ; ij |= jk
251 :     movq mm6, mm2
252 :     pxor mm6, mm0 ; mm6 = s^t
253 :     pand mm3, mm6 ; (ij|jk) &= st
254 :     pavgusb mm2, mm0 ; mm2 = (s+t+1)/2
255 :     pand mm3, mm7 ; mask lsb
256 :     psubb mm2, mm3 ; apply.
257 : Isibaar 262
258 : edgomez 1382 movq [ecx], mm2
259 : Isibaar 262
260 : edgomez 1382 movq mm2, [eax]
261 :     movq mm3, [eax+1]
262 :     movq mm6, mm2
263 :     pavgusb mm2, mm3 ; preserved for next iteration
264 :     lea ecx, [ecx+edx]
265 :     pxor mm3, mm6 ; preserved for next iteration
266 : Isibaar 262
267 : edgomez 1382 por mm1, mm3
268 :     movq mm6, mm0
269 :     pxor mm6, mm2
270 :     pand mm1, mm6
271 :     pavgusb mm0, mm2
272 : Isibaar 262
273 : edgomez 1382 pand mm1, mm7
274 :     psubb mm0, mm1
275 : Isibaar 262
276 : edgomez 1382 movq [ecx], mm0
277 : Isibaar 262 %endmacro
278 :    
279 :     %macro COPY_HV_3DN_RND1 0
280 : edgomez 1382 lea eax,[eax+edx]
281 : Isibaar 262
282 : edgomez 1382 movq mm0, [eax]
283 :     movq mm1, [eax+1]
284 : Isibaar 262
285 : edgomez 1382 movq mm6, mm0
286 :     pavgusb mm0, mm1 ; mm0=(j+k+1)/2. preserved for next step
287 :     lea eax, [eax+edx]
288 :     pxor mm1, mm6 ; mm1=(j^k). preserved for next step
289 : Isibaar 262
290 : edgomez 1382 pand mm3, mm1
291 :     movq mm6, mm2
292 :     pxor mm6, mm0
293 :     por mm3, mm6
294 :     pavgusb mm2, mm0
295 :     pand mm3, mm7
296 :     psubb mm2, mm3
297 : Isibaar 262
298 : edgomez 1382 movq [ecx], mm2
299 : Isibaar 262
300 : edgomez 1382 movq mm2, [eax]
301 :     movq mm3, [eax+1]
302 :     movq mm6, mm2
303 :     pavgusb mm2, mm3 ; preserved for next iteration
304 :     lea ecx, [ecx+edx]
305 :     pxor mm3, mm6 ; preserved for next iteration
306 : Isibaar 262
307 : edgomez 1382 pand mm1, mm3
308 :     movq mm6, mm0
309 :     pxor mm6, mm2
310 :     por mm1, mm6
311 :     pavgusb mm0, mm2
312 :     pand mm1, mm7
313 :     psubb mm0, mm1
314 : Isibaar 262
315 : edgomez 1382 movq [ecx], mm0
316 : Isibaar 262 %endmacro
317 :    
318 : edgomez 1382 ALIGN 16
319 : Isibaar 262 interpolate8x8_halfpel_hv_3dn
320 :     mov eax, [esp+16] ; rounding
321 :     mov ecx, [esp+ 4] ; Dst
322 : edgomez 1382 test eax, eax
323 : Isibaar 262 mov eax, [esp+ 8] ; Src
324 :     mov edx, [esp+12] ; stride
325 :    
326 :     movq mm7, [mmx_one]
327 :    
328 :     ; loop invariants: mm2=(i+j+1)/2 and mm3= i^j
329 :     movq mm2, [eax]
330 :     movq mm3, [eax+1]
331 :     movq mm6, mm2
332 :     pavgusb mm2, mm3
333 : edgomez 1382 pxor mm3, mm6 ; mm2/mm3 ready
334 : Isibaar 262
335 :     jnz near .rounding1
336 :    
337 :     COPY_HV_3DN_RND0
338 :     add ecx, edx
339 :     COPY_HV_3DN_RND0
340 :     add ecx, edx
341 :     COPY_HV_3DN_RND0
342 :     add ecx, edx
343 :     COPY_HV_3DN_RND0
344 :     ret
345 :    
346 :     .rounding1
347 :     COPY_HV_3DN_RND1
348 :     add ecx, edx
349 :     COPY_HV_3DN_RND1
350 :     add ecx, edx
351 :     COPY_HV_3DN_RND1
352 :     add ecx, edx
353 :     COPY_HV_3DN_RND1
354 : edgomez 1382 ret

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