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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1540 - (view) (download)

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

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