[cvs] / xvidcore / src / image / x86_asm / interpolate8x8_3dne.asm Repository:
ViewVC logotype

Annotation of /xvidcore/src/image/x86_asm/interpolate8x8_3dne.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2.2.1 - (view) (download)

1 : edgomez 1.2.2.1 ;/*****************************************************************************
2 : edgomez 1.2 ; *
3 : edgomez 1.2.2.1 ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * - 3dne pipeline optimized 8x8 block-based halfpel interpolation -
5 : edgomez 1.2 ; *
6 : edgomez 1.2.2.1 ; * Copyright(C) 2002 Jaan Kalda
7 : edgomez 1.2 ; *
8 : edgomez 1.2.2.1 ; * This program is free software ; you can redistribute it and/or modify
9 :     ; * it under the terms of the GNU General Public License as published by
10 :     ; * the Free Software Foundation ; either version 2 of the License, or
11 :     ; * (at your option) any later version.
12 : edgomez 1.2 ; *
13 : edgomez 1.2.2.1 ; * This program is distributed in the hope that it will be useful,
14 :     ; * but WITHOUT ANY WARRANTY ; without even the implied warranty of
15 :     ; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 :     ; * GNU General Public License for more details.
17 : edgomez 1.2 ; *
18 : edgomez 1.2.2.1 ; * You should have received a copy of the GNU General Public License
19 :     ; * along with this program ; if not, write to the Free Software
20 :     ; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 : edgomez 1.2 ; *
22 : edgomez 1.2.2.1 ; ****************************************************************************/
23 : edgomez 1.2
24 : edgomez 1.2.2.1 ; these 3dne functions are compatible with iSSE, but are optimized specifically
25 :     ; for K7 pipelines
26 : edgomez 1.2
27 : edgomez 1.2.2.1 BITS 32
28 : edgomez 1.2
29 : edgomez 1.2.2.1 %macro cglobal 1
30 : edgomez 1.2 %ifdef PREFIX
31 : edgomez 1.2.2.1 global _%1
32 : edgomez 1.2 %define %1 _%1
33 :     %else
34 :     global %1
35 :     %endif
36 :     %endmacro
37 :    
38 : edgomez 1.2.2.1 ;=============================================================================
39 :     ; Read only data
40 :     ;=============================================================================
41 :    
42 :     SECTION .rodata
43 : edgomez 1.2
44 : edgomez 1.2.2.1 ALIGN 16
45 :     mmx_one:
46 :     times 8 db 1
47 : edgomez 1.2
48 : edgomez 1.2.2.1 ALIGN 8
49 : edgomez 1.2 mm_minusone:
50 : edgomez 1.2.2.1 dd -1,-1
51 : edgomez 1.2
52 : edgomez 1.2.2.1 ;=============================================================================
53 :     ; Macros
54 :     ;=============================================================================
55 :    
56 :     %macro nop4 0
57 :     DB 08Dh,074h,026h,0
58 :     %endmacro
59 :    
60 :     ;=============================================================================
61 :     ; Macros
62 :     ;=============================================================================
63 :    
64 :     SECTION .text
65 : edgomez 1.2
66 :     cglobal interpolate8x8_halfpel_h_3dne
67 :     cglobal interpolate8x8_halfpel_v_3dne
68 :     cglobal interpolate8x8_halfpel_hv_3dne
69 :    
70 : edgomez 1.2.2.1 ;-----------------------------------------------------------------------------
71 : edgomez 1.2 ;
72 :     ; void interpolate8x8_halfpel_h_3dne(uint8_t * const dst,
73 : edgomez 1.2.2.1 ; const uint8_t * const src,
74 :     ; const uint32_t stride,
75 :     ; const uint32_t rounding);
76 : edgomez 1.2 ;
77 : edgomez 1.2.2.1 ;-----------------------------------------------------------------------------
78 : edgomez 1.2
79 :     %macro COPY_H_SSE_RND0 1
80 :     %if (%1)
81 : edgomez 1.2.2.1 movq mm0, [eax]
82 : edgomez 1.2 %else
83 : edgomez 1.2.2.1 movq mm0, [dword eax]
84 : edgomez 1.2 %endif
85 :     pavgb mm0, [eax+1]
86 : edgomez 1.2.2.1 movq mm1, [eax+edx]
87 : edgomez 1.2 pavgb mm1, [eax+edx+1]
88 : edgomez 1.2.2.1 lea eax, [eax+2*edx]
89 :     movq [ecx], mm0
90 :     movq [ecx+edx], mm1
91 : edgomez 1.2 %endmacro
92 :    
93 :     %macro COPY_H_SSE_RND1 0
94 :     movq mm0, [eax]
95 :     movq mm1, [eax+edx]
96 :     movq mm4, mm0
97 :     movq mm5, mm1
98 : edgomez 1.2.2.1 movq mm2, [eax+1]
99 : edgomez 1.2 movq mm3, [eax+edx+1]
100 :     pavgb mm0, mm2
101 :     pxor mm2, mm4
102 :     pavgb mm1, mm3
103 : edgomez 1.2.2.1 lea eax, [eax+2*edx]
104 : edgomez 1.2 pxor mm3, mm5
105 :     pand mm2, mm7
106 :     pand mm3, mm7
107 :     psubb mm0, mm2
108 :     movq [ecx], mm0
109 :     psubb mm1, mm3
110 : edgomez 1.2.2.1 movq [ecx+edx], mm1
111 : edgomez 1.2 %endmacro
112 :    
113 : edgomez 1.2.2.1 ALIGN 16
114 : edgomez 1.2 interpolate8x8_halfpel_h_3dne:
115 :    
116 :     mov eax, [esp+ 8] ; Src
117 :     mov edx, [esp+12] ; stride
118 :     dec dword [esp+16]; rounding
119 :    
120 :     jz .rounding1
121 :     mov ecx, [esp+ 4] ; Dst
122 :    
123 :     COPY_H_SSE_RND0 0
124 :     lea ecx,[ecx+2*edx]
125 :     COPY_H_SSE_RND0 1
126 :     lea ecx,[ecx+2*edx]
127 :     COPY_H_SSE_RND0 1
128 :     lea ecx,[ecx+2*edx]
129 :     COPY_H_SSE_RND0 1
130 :     ret
131 :    
132 :     .rounding1
133 : edgomez 1.2.2.1 ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
134 : edgomez 1.2 mov ecx, [esp+ 4] ; Dst
135 :     movq mm7, [mmx_one]
136 :     COPY_H_SSE_RND1
137 :     lea ecx, [ecx+2*edx]
138 :     COPY_H_SSE_RND1
139 :     lea ecx,[ecx+2*edx]
140 :     COPY_H_SSE_RND1
141 :     lea ecx,[ecx+2*edx]
142 :     COPY_H_SSE_RND1
143 :     ret
144 :    
145 : edgomez 1.2.2.1 ;-----------------------------------------------------------------------------
146 : edgomez 1.2 ;
147 :     ; void interpolate8x8_halfpel_v_3dne(uint8_t * const dst,
148 : edgomez 1.2.2.1 ; const uint8_t * const src,
149 :     ; const uint32_t stride,
150 :     ; const uint32_t rounding);
151 : edgomez 1.2 ;
152 : edgomez 1.2.2.1 ;-----------------------------------------------------------------------------
153 : edgomez 1.2
154 : edgomez 1.2.2.1 ALIGN 16
155 : edgomez 1.2 interpolate8x8_halfpel_v_3dne:
156 :    
157 :     mov eax, [esp+ 8] ; Src
158 :     mov edx, [esp+12] ; stride
159 :     dec dword [esp+16]; rounding
160 :    
161 :     ; we process 2 line at a time
162 :    
163 :     jz .rounding1
164 :     pxor mm2,mm2
165 : edgomez 1.2.2.1 movq mm0, [eax]
166 :     movq mm1, [eax+edx]
167 :     por mm2, [eax+2*edx]
168 : edgomez 1.2 mov ecx, [esp+ 4] ; Dst
169 : edgomez 1.2.2.1 lea eax, [eax+2*edx]
170 :     pxor mm4, mm4
171 : edgomez 1.2 pavgb mm0, mm1
172 : edgomez 1.2.2.1 pavgb mm1, mm2
173 :     movq [byte ecx], mm0
174 :     movq [ecx+edx], mm1
175 :     pxor mm6, mm6
176 :     add eax, edx
177 :     lea ecx, [ecx+2*edx]
178 :     movq mm3, [byte eax]
179 :     por mm4, [eax+edx]
180 :     lea eax, [eax+2*edx]
181 : edgomez 1.2 pavgb mm2, mm3
182 :     pavgb mm3, mm4
183 : edgomez 1.2.2.1 movq [ecx], mm2
184 :     movq [ecx+edx], mm3
185 :     lea ecx, [byte ecx+2*edx]
186 :     movq mm5, [byte eax]
187 :     por mm6, [eax+edx]
188 :     lea eax, [eax+2*edx]
189 : edgomez 1.2 pavgb mm4, mm5
190 :     pavgb mm5, mm6
191 : edgomez 1.2.2.1 movq [ecx], mm4
192 :     movq [ecx+edx], mm5
193 :     lea ecx, [ecx+2*edx]
194 :     movq mm7, [eax]
195 :     movq mm0, [eax+edx]
196 : edgomez 1.2 pavgb mm6, mm7
197 :     pavgb mm7, mm0
198 : edgomez 1.2.2.1 movq [ecx], mm6
199 :     movq [ecx+edx], mm7
200 : edgomez 1.2 ret
201 :    
202 : edgomez 1.2.2.1 ALIGN 8
203 : edgomez 1.2 .rounding1
204 : edgomez 1.2.2.1 pcmpeqb mm0, mm0
205 :     psubusb mm0, [eax]
206 :     add eax, edx
207 : edgomez 1.2 mov ecx, [esp+ 4] ; Dst
208 :     push esi
209 : edgomez 1.2.2.1 pcmpeqb mm1, mm1
210 :     pcmpeqb mm2, mm2
211 :     mov esi, mm_minusone
212 :     psubusb mm1, [byte eax]
213 :     psubusb mm2, [eax+edx]
214 :     lea eax, [eax+2*edx]
215 : edgomez 1.2 movq mm6, [esi]
216 :     movq mm7, [esi]
217 :     pavgb mm0, mm1
218 :     pavgb mm1, mm2
219 : edgomez 1.2.2.1 psubusb mm6, mm0
220 :     psubusb mm7, mm1
221 : edgomez 1.2 movq [ecx], mm6
222 :     movq [ecx+edx], mm7
223 : edgomez 1.2.2.1 lea ecx, [ecx+2*edx]
224 :     pcmpeqb mm3, mm3
225 :     pcmpeqb mm4, mm4
226 :     psubusb mm3, [eax]
227 :     psubusb mm4, [eax+edx]
228 :     lea eax, [eax+2*edx]
229 : edgomez 1.2 pavgb mm2, mm3
230 :     pavgb mm3, mm4
231 :     movq mm0, [esi]
232 :     movq mm1, [esi]
233 : edgomez 1.2.2.1 psubusb mm0, mm2
234 :     psubusb mm1, mm3
235 : edgomez 1.2 movq [ecx], mm0
236 :     movq [ecx+edx], mm1
237 :     lea ecx,[ecx+2*edx]
238 :    
239 : edgomez 1.2.2.1 pcmpeqb mm5, mm5
240 :     pcmpeqb mm6, mm6
241 :     psubusb mm5, [eax]
242 :     psubusb mm6, [eax+edx]
243 :     lea eax, [eax+2*edx]
244 : edgomez 1.2 pavgb mm4, mm5
245 :     pavgb mm5, mm6
246 :     movq mm2, [esi]
247 :     movq mm3, [esi]
248 : edgomez 1.2.2.1 psubusb mm2, mm4
249 :     psubusb mm3, mm5
250 : edgomez 1.2 movq [ecx], mm2
251 :     movq [ecx+edx], mm3
252 : edgomez 1.2.2.1 lea ecx, [ecx+2*edx]
253 :     pcmpeqb mm7, mm7
254 :     pcmpeqb mm0, mm0
255 :     psubusb mm7, [eax]
256 :     psubusb mm0, [eax+edx]
257 : edgomez 1.2 pavgb mm6, mm7
258 :     pavgb mm7, mm0
259 :     movq mm4, [esi]
260 :     movq mm5, [esi]
261 : edgomez 1.2.2.1 psubusb mm4, mm6
262 : edgomez 1.2 pop esi
263 : edgomez 1.2.2.1 psubusb mm5, mm7
264 : edgomez 1.2 movq [ecx], mm4
265 :     movq [ecx+edx], mm5
266 :     ret
267 : edgomez 1.2.2.1
268 :     ;-----------------------------------------------------------------------------
269 : edgomez 1.2 ;
270 :     ; void interpolate8x8_halfpel_hv_3dne(uint8_t * const dst,
271 : edgomez 1.2.2.1 ; const uint8_t * const src,
272 :     ; const uint32_t stride,
273 :     ; const uint32_t rounding);
274 : edgomez 1.2 ;
275 :     ;
276 : edgomez 1.2.2.1 ;-----------------------------------------------------------------------------
277 : edgomez 1.2
278 :     ; The trick is to correct the result of 'pavgb' with some combination of the
279 :     ; lsb's of the 4 input values i,j,k,l, and their intermediate 'pavgb' (s and t).
280 :     ; The boolean relations are:
281 : edgomez 1.2.2.1 ; (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
282 : edgomez 1.2 ; (i+j+k+l+2)/4 = (s+t+1)/2 - (ij|kl)&st
283 :     ; (i+j+k+l+1)/4 = (s+t+1)/2 - (ij&kl)|st
284 :     ; (i+j+k+l+0)/4 = (s+t+1)/2 - (ij|kl)|st
285 :     ; with s=(i+j+1)/2, t=(k+l+1)/2, ij = i^j, kl = k^l, st = s^t.
286 :    
287 :     ; Moreover, we process 2 lines at a times, for better overlapping (~15% faster).
288 :    
289 :     %macro COPY_HV_SSE_RND0 0
290 :    
291 : edgomez 1.2.2.1 movq mm0, [eax+edx]
292 :     movq mm1, [eax+edx+1]
293 : edgomez 1.2
294 : edgomez 1.2.2.1 movq mm6, mm0
295 :     pavgb mm0, mm1 ; mm0=(j+k+1)/2. preserved for next step
296 :     lea eax, [eax+2*edx]
297 :     pxor mm1, mm6 ; mm1=(j^k). preserved for next step
298 : edgomez 1.2
299 : edgomez 1.2.2.1 por mm3, mm1 ; ij |= jk
300 :     movq mm6, mm2
301 :     pxor mm6, mm0 ; mm6 = s^t
302 :     pand mm3, mm6 ; (ij|jk) &= st
303 :     pavgb mm2, mm0 ; mm2 = (s+t+1)/2
304 :     movq mm6, [eax]
305 :     pand mm3, mm7 ; mask lsb
306 :     psubb mm2, mm3 ; apply.
307 :    
308 :     movq [ecx], mm2
309 : edgomez 1.2
310 : edgomez 1.2.2.1 movq mm2, [eax]
311 :     movq mm3, [eax+1]
312 :     pavgb mm2, mm3 ; preserved for next iteration
313 :     pxor mm3, mm6 ; preserved for next iteration
314 :    
315 :     por mm1, mm3
316 :     movq mm6, mm0
317 :     pxor mm6, mm2
318 :     pand mm1, mm6
319 :     pavgb mm0, mm2
320 :    
321 :     pand mm1, mm7
322 :     psubb mm0, mm1
323 :    
324 :     movq [ecx+edx], mm0
325 : edgomez 1.2 %endmacro
326 :    
327 :     %macro COPY_HV_SSE_RND1 0
328 : edgomez 1.2.2.1 movq mm0, [eax+edx]
329 :     movq mm1, [eax+edx+1]
330 :    
331 :     movq mm6, mm0
332 :     pavgb mm0, mm1 ; mm0=(j+k+1)/2. preserved for next step
333 :     lea eax,[eax+2*edx]
334 :     pxor mm1, mm6 ; mm1=(j^k). preserved for next step
335 : edgomez 1.2
336 : edgomez 1.2.2.1 pand mm3, mm1
337 :     movq mm6, mm2
338 :     pxor mm6, mm0
339 :     por mm3, mm6
340 :     pavgb mm2, mm0
341 :     movq mm6, [eax]
342 :     pand mm3, mm7
343 :     psubb mm2, mm3
344 :    
345 :     movq [ecx], mm2
346 :    
347 :     movq mm2, [eax]
348 :     movq mm3, [eax+1]
349 :     pavgb mm2, mm3 ; preserved for next iteration
350 :     pxor mm3, mm6 ; preserved for next iteration
351 :    
352 :     pand mm1, mm3
353 :     movq mm6, mm0
354 :     pxor mm6, mm2
355 :     por mm1, mm6
356 :     pavgb mm0, mm2
357 :     pand mm1, mm7
358 :     psubb mm0, mm1
359 :     movq [ecx+edx], mm0
360 : edgomez 1.2 %endmacro
361 :    
362 : edgomez 1.2.2.1 ALIGN 16
363 : edgomez 1.2 interpolate8x8_halfpel_hv_3dne:
364 : edgomez 1.2.2.1 mov eax, [esp+ 8] ; Src
365 :     mov edx, [esp+12] ; stride
366 :     dec dword [esp+16] ; rounding
367 : edgomez 1.2
368 :     ; loop invariants: mm2=(i+j+1)/2 and mm3= i^j
369 :     movq mm2, [eax]
370 :     movq mm3, [eax+1]
371 :     movq mm6, mm2
372 :     pavgb mm2, mm3
373 : edgomez 1.2.2.1 pxor mm3, mm6 ; mm2/mm3 ready
374 :     mov ecx, [esp+ 4] ; Dst
375 : edgomez 1.2 movq mm7, [mmx_one]
376 :    
377 :     jz near .rounding1
378 : edgomez 1.2.2.1 lea ebp,[byte ebp]
379 : edgomez 1.2 COPY_HV_SSE_RND0
380 : edgomez 1.2.2.1 lea ecx,[ecx+2*edx]
381 : edgomez 1.2 COPY_HV_SSE_RND0
382 : edgomez 1.2.2.1 lea ecx,[ecx+2*edx]
383 : edgomez 1.2 COPY_HV_SSE_RND0
384 : edgomez 1.2.2.1 lea ecx,[ecx+2*edx]
385 : edgomez 1.2 COPY_HV_SSE_RND0
386 :     ret
387 :    
388 : edgomez 1.2.2.1 ALIGN 16
389 : edgomez 1.2 .rounding1
390 :     COPY_HV_SSE_RND1
391 : edgomez 1.2.2.1 lea ecx,[ecx+2*edx]
392 : edgomez 1.2 COPY_HV_SSE_RND1
393 : edgomez 1.2.2.1 lea ecx,[ecx+2*edx]
394 : edgomez 1.2 COPY_HV_SSE_RND1
395 : edgomez 1.2.2.1 lea ecx,[ecx+2*edx]
396 : edgomez 1.2 COPY_HV_SSE_RND1
397 : edgomez 1.2.2.1 ret

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