[svn] / branches / dev-api-4 / xvidcore / src / image / x86_asm / interpolate8x8_3dne.asm Repository:
ViewVC logotype

Annotation of /branches/dev-api-4/xvidcore/src/image/x86_asm/interpolate8x8_3dne.asm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1192 - (view) (download)

1 : edgomez 1192 ;/*****************************************************************************
2 : edgomez 851 ; *
3 : edgomez 1192 ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * - 3dne pipeline optimized 8x8 block-based halfpel interpolation -
5 : edgomez 851 ; *
6 : edgomez 1192 ; * Copyright(C) 2002 Jaan Kalda
7 : edgomez 851 ; *
8 : edgomez 1192 ; * 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 1192 ; * 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 1192 ; * 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 1192 ; ****************************************************************************/
23 : edgomez 851
24 : edgomez 1192 ; these 3dne functions are compatible with iSSE, but are optimized specifically
25 :     ; for K7 pipelines
26 : edgomez 851
27 : edgomez 1192 BITS 32
28 : edgomez 851
29 : edgomez 1192 %macro cglobal 1
30 : edgomez 851 %ifdef PREFIX
31 : edgomez 1192 global _%1
32 : edgomez 851 %define %1 _%1
33 :     %else
34 :     global %1
35 :     %endif
36 :     %endmacro
37 :    
38 : edgomez 1192 ;=============================================================================
39 :     ; Read only data
40 :     ;=============================================================================
41 : edgomez 851
42 : edgomez 1192 SECTION .rodata
43 : edgomez 851
44 : edgomez 1192 ALIGN 16
45 :     mmx_one:
46 :     times 8 db 1
47 :    
48 :     ALIGN 8
49 : edgomez 851 mm_minusone:
50 : edgomez 1192 dd -1,-1
51 : edgomez 851
52 : edgomez 1192 ;=============================================================================
53 :     ; Macros
54 :     ;=============================================================================
55 : edgomez 851
56 : edgomez 1192 %macro nop4 0
57 :     DB 08Dh,074h,026h,0
58 :     %endmacro
59 :    
60 :     ;=============================================================================
61 :     ; Macros
62 :     ;=============================================================================
63 :    
64 :     SECTION .text
65 :    
66 : edgomez 851 cglobal interpolate8x8_halfpel_h_3dne
67 :     cglobal interpolate8x8_halfpel_v_3dne
68 :     cglobal interpolate8x8_halfpel_hv_3dne
69 :    
70 : edgomez 1192 ;-----------------------------------------------------------------------------
71 : edgomez 851 ;
72 :     ; void interpolate8x8_halfpel_h_3dne(uint8_t * const dst,
73 : edgomez 1192 ; const uint8_t * const src,
74 :     ; const uint32_t stride,
75 :     ; const uint32_t rounding);
76 : edgomez 851 ;
77 : edgomez 1192 ;-----------------------------------------------------------------------------
78 : edgomez 851
79 :     %macro COPY_H_SSE_RND0 1
80 :     %if (%1)
81 : edgomez 1192 movq mm0, [eax]
82 : edgomez 851 %else
83 : edgomez 1192 movq mm0, [dword eax]
84 : edgomez 851 %endif
85 :     pavgb mm0, [eax+1]
86 : edgomez 1192 movq mm1, [eax+edx]
87 : edgomez 851 pavgb mm1, [eax+edx+1]
88 : edgomez 1192 lea eax, [eax+2*edx]
89 :     movq [ecx], mm0
90 :     movq [ecx+edx], mm1
91 : edgomez 851 %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 1192 movq mm2, [eax+1]
99 : edgomez 851 movq mm3, [eax+edx+1]
100 :     pavgb mm0, mm2
101 :     pxor mm2, mm4
102 :     pavgb mm1, mm3
103 : edgomez 1192 lea eax, [eax+2*edx]
104 : edgomez 851 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 1192 movq [ecx+edx], mm1
111 : edgomez 851 %endmacro
112 :    
113 : edgomez 1192 ALIGN 16
114 : edgomez 851 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 1192 ; we use: (i+j)/2 = ( i+j+1 )/2 - (i^j)&1
134 : edgomez 851 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 1192 ;-----------------------------------------------------------------------------
146 : edgomez 851 ;
147 :     ; void interpolate8x8_halfpel_v_3dne(uint8_t * const dst,
148 : edgomez 1192 ; const uint8_t * const src,
149 :     ; const uint32_t stride,
150 :     ; const uint32_t rounding);
151 : edgomez 851 ;
152 : edgomez 1192 ;-----------------------------------------------------------------------------
153 : edgomez 851
154 : edgomez 1192 ALIGN 16
155 : edgomez 851 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 1192 movq mm0, [eax]
166 :     movq mm1, [eax+edx]
167 :     por mm2, [eax+2*edx]
168 : edgomez 851 mov ecx, [esp+ 4] ; Dst
169 : edgomez 1192 lea eax, [eax+2*edx]
170 :     pxor mm4, mm4
171 : edgomez 851 pavgb mm0, mm1
172 : edgomez 1192 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 851 pavgb mm2, mm3
182 :     pavgb mm3, mm4
183 : edgomez 1192 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 851 pavgb mm4, mm5
190 :     pavgb mm5, mm6
191 : edgomez 1192 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 851 pavgb mm6, mm7
197 :     pavgb mm7, mm0
198 : edgomez 1192 movq [ecx], mm6
199 :     movq [ecx+edx], mm7
200 : edgomez 851 ret
201 :    
202 : edgomez 1192 ALIGN 8
203 : edgomez 851 .rounding1
204 : edgomez 1192 pcmpeqb mm0, mm0
205 :     psubusb mm0, [eax]
206 :     add eax, edx
207 : edgomez 851 mov ecx, [esp+ 4] ; Dst
208 :     push esi
209 : edgomez 1192 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 851 movq mm6, [esi]
216 :     movq mm7, [esi]
217 :     pavgb mm0, mm1
218 :     pavgb mm1, mm2
219 : edgomez 1192 psubusb mm6, mm0
220 :     psubusb mm7, mm1
221 : edgomez 851 movq [ecx], mm6
222 :     movq [ecx+edx], mm7
223 : edgomez 1192 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 851 pavgb mm2, mm3
230 :     pavgb mm3, mm4
231 :     movq mm0, [esi]
232 :     movq mm1, [esi]
233 : edgomez 1192 psubusb mm0, mm2
234 :     psubusb mm1, mm3
235 : edgomez 851 movq [ecx], mm0
236 :     movq [ecx+edx], mm1
237 :     lea ecx,[ecx+2*edx]
238 :    
239 : edgomez 1192 pcmpeqb mm5, mm5
240 :     pcmpeqb mm6, mm6
241 :     psubusb mm5, [eax]
242 :     psubusb mm6, [eax+edx]
243 :     lea eax, [eax+2*edx]
244 : edgomez 851 pavgb mm4, mm5
245 :     pavgb mm5, mm6
246 :     movq mm2, [esi]
247 :     movq mm3, [esi]
248 : edgomez 1192 psubusb mm2, mm4
249 :     psubusb mm3, mm5
250 : edgomez 851 movq [ecx], mm2
251 :     movq [ecx+edx], mm3
252 : edgomez 1192 lea ecx, [ecx+2*edx]
253 :     pcmpeqb mm7, mm7
254 :     pcmpeqb mm0, mm0
255 :     psubusb mm7, [eax]
256 :     psubusb mm0, [eax+edx]
257 : edgomez 851 pavgb mm6, mm7
258 :     pavgb mm7, mm0
259 :     movq mm4, [esi]
260 :     movq mm5, [esi]
261 : edgomez 1192 psubusb mm4, mm6
262 : edgomez 851 pop esi
263 : edgomez 1192 psubusb mm5, mm7
264 : edgomez 851 movq [ecx], mm4
265 :     movq [ecx+edx], mm5
266 :     ret
267 : edgomez 1192
268 :     ;-----------------------------------------------------------------------------
269 : edgomez 851 ;
270 :     ; void interpolate8x8_halfpel_hv_3dne(uint8_t * const dst,
271 : edgomez 1192 ; const uint8_t * const src,
272 :     ; const uint32_t stride,
273 :     ; const uint32_t rounding);
274 : edgomez 851 ;
275 :     ;
276 : edgomez 1192 ;-----------------------------------------------------------------------------
277 : edgomez 851
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 1192 ; (i+j+k+l+3)/4 = (s+t+1)/2 - (ij&kl)&st
282 : edgomez 851 ; (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 1192 movq mm0, [eax+edx]
292 :     movq mm1, [eax+edx+1]
293 : edgomez 851
294 : edgomez 1192 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 851
299 : edgomez 1192 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 : edgomez 851
308 : edgomez 1192 movq [ecx], mm2
309 : edgomez 851
310 : edgomez 1192 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 : edgomez 851
315 : edgomez 1192 por mm1, mm3
316 :     movq mm6, mm0
317 :     pxor mm6, mm2
318 :     pand mm1, mm6
319 :     pavgb mm0, mm2
320 : edgomez 851
321 : edgomez 1192 pand mm1, mm7
322 :     psubb mm0, mm1
323 : edgomez 851
324 : edgomez 1192 movq [ecx+edx], mm0
325 : edgomez 851 %endmacro
326 :    
327 :     %macro COPY_HV_SSE_RND1 0
328 : edgomez 1192 movq mm0, [eax+edx]
329 :     movq mm1, [eax+edx+1]
330 : edgomez 851
331 : edgomez 1192 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 851
336 : edgomez 1192 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 : edgomez 851
345 : edgomez 1192 movq [ecx], mm2
346 : edgomez 851
347 : edgomez 1192 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 : edgomez 851
352 : edgomez 1192 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 851 %endmacro
361 :    
362 : edgomez 1192 ALIGN 16
363 : edgomez 851 interpolate8x8_halfpel_hv_3dne:
364 : edgomez 1192 mov eax, [esp+ 8] ; Src
365 :     mov edx, [esp+12] ; stride
366 :     dec dword [esp+16] ; rounding
367 : edgomez 851
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 1192 pxor mm3, mm6 ; mm2/mm3 ready
374 :     mov ecx, [esp+ 4] ; Dst
375 : edgomez 851 movq mm7, [mmx_one]
376 :    
377 :     jz near .rounding1
378 : edgomez 1192 lea ebp,[byte ebp]
379 : edgomez 851 COPY_HV_SSE_RND0
380 : edgomez 1192 lea ecx,[ecx+2*edx]
381 : edgomez 851 COPY_HV_SSE_RND0
382 : edgomez 1192 lea ecx,[ecx+2*edx]
383 : edgomez 851 COPY_HV_SSE_RND0
384 : edgomez 1192 lea ecx,[ecx+2*edx]
385 : edgomez 851 COPY_HV_SSE_RND0
386 :     ret
387 :    
388 : edgomez 1192 ALIGN 16
389 : edgomez 851 .rounding1
390 :     COPY_HV_SSE_RND1
391 : edgomez 1192 lea ecx,[ecx+2*edx]
392 : edgomez 851 COPY_HV_SSE_RND1
393 : edgomez 1192 lea ecx,[ecx+2*edx]
394 : edgomez 851 COPY_HV_SSE_RND1
395 : edgomez 1192 lea ecx,[ecx+2*edx]
396 : edgomez 851 COPY_HV_SSE_RND1
397 : edgomez 1192 ret

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