[svn] / branches / dev-api-4 / xvidcore / src / image / x86_asm / interpolate8x8_3dn.asm Repository:
ViewVC logotype

Annotation of /branches/dev-api-4/xvidcore/src/image/x86_asm/interpolate8x8_3dn.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1192 - (view) (download)

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

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