[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.5 - (view) (download)

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

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