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

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