[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 1535 - (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 :     global _%1:function
33 :     %define %1 _%1:function
34 :     %else
35 :     global _%1
36 :     %define %1 _%1
37 :     %endif
38 : edgomez 851 %else
39 : edgomez 1535 %ifdef MARK_FUNCS
40 :     global %1:function
41 :     %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 :    
158 : edgomez 1382 ;-----------------------------------------------------------------------------
159 : edgomez 851 ;
160 :     ; void interpolate8x8_halfpel_v_3dne(uint8_t * const dst,
161 : edgomez 1382 ; const uint8_t * const src,
162 :     ; const uint32_t stride,
163 :     ; const uint32_t rounding);
164 : edgomez 851 ;
165 : edgomez 1382 ;-----------------------------------------------------------------------------
166 : edgomez 851
167 : edgomez 1382 ALIGN 16
168 : edgomez 851 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 1382 movq mm0, [eax]
179 :     movq mm1, [eax+edx]
180 :     por mm2, [eax+2*edx]
181 : edgomez 851 mov ecx, [esp+ 4] ; Dst
182 : edgomez 1382 lea eax, [eax+2*edx]
183 :     pxor mm4, mm4
184 : edgomez 851 pavgb mm0, mm1
185 : edgomez 1382 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 851 pavgb mm2, mm3
195 :     pavgb mm3, mm4
196 : edgomez 1382 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 851 pavgb mm4, mm5
203 :     pavgb mm5, mm6
204 : edgomez 1382 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 851 pavgb mm6, mm7
210 :     pavgb mm7, mm0
211 : edgomez 1382 movq [ecx], mm6
212 :     movq [ecx+edx], mm7
213 : edgomez 851 ret
214 :    
215 : edgomez 1382 ALIGN 8
216 : edgomez 851 .rounding1
217 : edgomez 1382 pcmpeqb mm0, mm0
218 :     psubusb mm0, [eax]
219 :     add eax, edx
220 : edgomez 851 mov ecx, [esp+ 4] ; Dst
221 :     push esi
222 : edgomez 1382 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 851 movq mm6, [esi]
229 :     movq mm7, [esi]
230 :     pavgb mm0, mm1
231 :     pavgb mm1, mm2
232 : edgomez 1382 psubusb mm6, mm0
233 :     psubusb mm7, mm1
234 : edgomez 851 movq [ecx], mm6
235 :     movq [ecx+edx], mm7
236 : edgomez 1382 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 851 pavgb mm2, mm3
243 :     pavgb mm3, mm4
244 :     movq mm0, [esi]
245 :     movq mm1, [esi]
246 : edgomez 1382 psubusb mm0, mm2
247 :     psubusb mm1, mm3
248 : edgomez 851 movq [ecx], mm0
249 :     movq [ecx+edx], mm1
250 :     lea ecx,[ecx+2*edx]
251 :    
252 : edgomez 1382 pcmpeqb mm5, mm5
253 :     pcmpeqb mm6, mm6
254 :     psubusb mm5, [eax]
255 :     psubusb mm6, [eax+edx]
256 :     lea eax, [eax+2*edx]
257 : edgomez 851 pavgb mm4, mm5
258 :     pavgb mm5, mm6
259 :     movq mm2, [esi]
260 :     movq mm3, [esi]
261 : edgomez 1382 psubusb mm2, mm4
262 :     psubusb mm3, mm5
263 : edgomez 851 movq [ecx], mm2
264 :     movq [ecx+edx], mm3
265 : edgomez 1382 lea ecx, [ecx+2*edx]
266 :     pcmpeqb mm7, mm7
267 :     pcmpeqb mm0, mm0
268 :     psubusb mm7, [eax]
269 :     psubusb mm0, [eax+edx]
270 : edgomez 851 pavgb mm6, mm7
271 :     pavgb mm7, mm0
272 :     movq mm4, [esi]
273 :     movq mm5, [esi]
274 : edgomez 1382 psubusb mm4, mm6
275 : edgomez 851 pop esi
276 : edgomez 1382 psubusb mm5, mm7
277 : edgomez 851 movq [ecx], mm4
278 :     movq [ecx+edx], mm5
279 :     ret
280 : edgomez 1382
281 :     ;-----------------------------------------------------------------------------
282 : edgomez 851 ;
283 :     ; void interpolate8x8_halfpel_hv_3dne(uint8_t * const dst,
284 : edgomez 1382 ; const uint8_t * const src,
285 :     ; const uint32_t stride,
286 :     ; const uint32_t rounding);
287 : edgomez 851 ;
288 :     ;
289 : edgomez 1382 ;-----------------------------------------------------------------------------
290 : edgomez 851
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 1382 ; (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
295 : edgomez 851 ; (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 1382 movq mm0, [eax+edx]
305 :     movq mm1, [eax+edx+1]
306 : edgomez 851
307 : edgomez 1382 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 851
312 : edgomez 1382 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 : edgomez 851
321 : edgomez 1382 movq [ecx], mm2
322 : edgomez 851
323 : edgomez 1382 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 : edgomez 851
328 : edgomez 1382 por mm1, mm3
329 :     movq mm6, mm0
330 :     pxor mm6, mm2
331 :     pand mm1, mm6
332 :     pavgb mm0, mm2
333 : edgomez 851
334 : edgomez 1382 pand mm1, mm7
335 :     psubb mm0, mm1
336 : edgomez 851
337 : edgomez 1382 movq [ecx+edx], mm0
338 : edgomez 851 %endmacro
339 :    
340 :     %macro COPY_HV_SSE_RND1 0
341 : edgomez 1382 movq mm0, [eax+edx]
342 :     movq mm1, [eax+edx+1]
343 : edgomez 851
344 : edgomez 1382 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 851
349 : edgomez 1382 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 : edgomez 851
358 : edgomez 1382 movq [ecx], mm2
359 : edgomez 851
360 : edgomez 1382 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 : edgomez 851
365 : edgomez 1382 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 851 %endmacro
374 :    
375 : edgomez 1382 ALIGN 16
376 : edgomez 851 interpolate8x8_halfpel_hv_3dne:
377 : edgomez 1382 mov eax, [esp+ 8] ; Src
378 :     mov edx, [esp+12] ; stride
379 :     dec dword [esp+16] ; rounding
380 : edgomez 851
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 1382 pxor mm3, mm6 ; mm2/mm3 ready
387 :     mov ecx, [esp+ 4] ; Dst
388 : edgomez 851 movq mm7, [mmx_one]
389 :    
390 :     jz near .rounding1
391 : edgomez 1382 lea ebp,[byte ebp]
392 : edgomez 851 COPY_HV_SSE_RND0
393 : edgomez 1382 lea ecx,[ecx+2*edx]
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 :     ret
400 :    
401 : edgomez 1382 ALIGN 16
402 : edgomez 851 .rounding1
403 :     COPY_HV_SSE_RND1
404 : edgomez 1382 lea ecx,[ecx+2*edx]
405 : edgomez 851 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 ret

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