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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1803 - (view) (download)

1 : edgomez 1382 ;/****************************************************************************
2 :     ; *
3 :     ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * - MMX and XMM YV12->YV12 conversion -
5 :     ; *
6 : Isibaar 1795 ; * Copyright(C) 2001-2008 Michael Militzer <michael@xvid.org>
7 : edgomez 1382 ; *
8 :     ; * This program is free software; you can redistribute it and/or modify it
9 :     ; * 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 :     ; *
13 :     ; * 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 :     ; *
18 :     ; * 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 :     ; *
22 : Isibaar 1803 ; * $Id: colorspace_yuv_mmx.asm,v 1.10 2008-11-26 23:35:50 Isibaar Exp $
23 : edgomez 1382 ; *
24 :     ; ***************************************************************************/
25 : edgomez 851
26 : Isibaar 1795 %include "nasm.inc"
27 : edgomez 851
28 : edgomez 1382 ;=============================================================================
29 :     ; Helper macros
30 :     ;=============================================================================
31 : edgomez 851
32 :     ;------------------------------------------------------------------------------
33 : Skal 1742 ; PLANE_COPY ( DST, DST_STRIDE, SRC, SRC_STRIDE, WIDTH, HEIGHT, OPT )
34 : edgomez 851 ; DST dst buffer
35 : Skal 1742 ; DST_STRIDE dst stride
36 : edgomez 851 ; SRC src destination buffer
37 : Skal 1742 ; SRC_STRIDE src stride
38 : edgomez 851 ; WIDTH width
39 :     ; HEIGHT height
40 :     ; OPT 0=plain mmx, 1=xmm
41 : Isibaar 1795 ;
42 :     ;
43 :     ; Trashes: DST, SRC, WIDTH, HEIGHT, _EBX, _ECX, _EDX
44 : edgomez 851 ;------------------------------------------------------------------------------
45 : edgomez 1382
46 : edgomez 851 %macro PLANE_COPY 7
47 : Isibaar 1795 %define DST %1
48 : Isibaar 1803 %define DST_STRIDE %2
49 : Isibaar 1795 %define SRC %3
50 : Isibaar 1803 %define SRC_STRIDE %4
51 :     %define WIDTH %5
52 :     %define HEIGHT %6
53 : Isibaar 1795 %define OPT %7
54 : edgomez 851
55 : Isibaar 1795 mov _EBX, WIDTH
56 :     shr WIDTH, 6 ; $_EAX$ = width / 64
57 :     and _EBX, 63 ; remainder = width % 64
58 :     mov _EDX, _EBX
59 :     shr _EBX, 4 ; $_EBX$ = remainder / 16
60 :     and _EDX, 15 ; $_EDX$ = remainder % 16
61 : edgomez 851
62 : Isibaar 1795 %%loop64_start_pc:
63 :     push DST
64 :     push SRC
65 : edgomez 851
66 : Isibaar 1795 mov _ECX, WIDTH ; width64
67 :     test WIDTH, WIDTH
68 : Skal 1742 jz %%loop16_start_pc
69 :    
70 :     %%loop64_pc:
71 : edgomez 1382 %if OPT == 1 ; xmm
72 : Isibaar 1795 prefetchnta [SRC + 64] ; non temporal prefetch
73 :     prefetchnta [SRC + 96]
74 : edgomez 851 %endif
75 : Isibaar 1795 movq mm1, [SRC ] ; read from src
76 :     movq mm2, [SRC + 8]
77 :     movq mm3, [SRC + 16]
78 :     movq mm4, [SRC + 24]
79 :     movq mm5, [SRC + 32]
80 :     movq mm6, [SRC + 40]
81 :     movq mm7, [SRC + 48]
82 :     movq mm0, [SRC + 56]
83 : edgomez 851
84 : edgomez 1382 %if OPT == 0 ; plain mmx
85 : Isibaar 1795 movq [DST ], mm1 ; write to y_out
86 :     movq [DST + 8], mm2
87 :     movq [DST + 16], mm3
88 :     movq [DST + 24], mm4
89 :     movq [DST + 32], mm5
90 :     movq [DST + 40], mm6
91 :     movq [DST + 48], mm7
92 :     movq [DST + 56], mm0
93 : edgomez 851 %else
94 : Isibaar 1795 movntq [DST ], mm1 ; write to y_out
95 :     movntq [DST + 8], mm2
96 :     movntq [DST + 16], mm3
97 :     movntq [DST + 24], mm4
98 :     movntq [DST + 32], mm5
99 :     movntq [DST + 40], mm6
100 :     movntq [DST + 48], mm7
101 :     movntq [DST + 56], mm0
102 : edgomez 851 %endif
103 :    
104 : Isibaar 1795 add SRC, 64
105 :     add DST, 64
106 : Skal 1742 loop %%loop64_pc
107 : edgomez 851
108 : Skal 1742 %%loop16_start_pc:
109 : Isibaar 1795 mov _ECX, _EBX ; width16
110 :     test _EBX, _EBX
111 : Skal 1742 jz %%loop1_start_pc
112 :    
113 :     %%loop16_pc:
114 : Isibaar 1795 movq mm1, [SRC]
115 :     movq mm2, [SRC + 8]
116 : edgomez 1382 %if OPT == 0 ; plain mmx
117 : Isibaar 1795 movq [DST], mm1
118 :     movq [DST + 8], mm2
119 : edgomez 851 %else
120 : Isibaar 1795 movntq [DST], mm1
121 :     movntq [DST + 8], mm2
122 : edgomez 851 %endif
123 :    
124 : Isibaar 1795 add SRC, 16
125 :     add DST, 16
126 : Skal 1742 loop %%loop16_pc
127 : edgomez 851
128 : Skal 1742 %%loop1_start_pc:
129 : Isibaar 1795 mov _ECX, _EDX
130 : edgomez 1382 rep movsb
131 : edgomez 851
132 : Isibaar 1795 pop SRC
133 :     pop DST
134 :    
135 :     %ifdef ARCH_IS_X86_64
136 :     movsx _ECX, SRC_STRIDE
137 :     add SRC, _ECX
138 :     mov ecx, DST_STRIDE
139 :     add DST, _ECX
140 :     %else
141 :     add SRC, SRC_STRIDE
142 :     add DST, DST_STRIDE
143 :     %endif
144 : Isibaar 1803
145 : Isibaar 1795 dec HEIGHT
146 : Skal 1742 jg near %%loop64_start_pc
147 : Isibaar 1795
148 :     %undef DST
149 :     %undef DST_STRIDE
150 :     %undef SRC
151 :     %undef SRC_STRIDE
152 :     %undef WIDTH
153 :     %undef HEIGHT
154 :     %undef OPT
155 : edgomez 851 %endmacro
156 :    
157 :     ;------------------------------------------------------------------------------
158 : Skal 1742 ; PLANE_FILL ( DST, DST_STRIDE, WIDTH, HEIGHT, OPT )
159 :     ; DST dst buffer
160 :     ; DST_STRIDE dst stride
161 :     ; WIDTH width
162 :     ; HEIGHT height
163 :     ; OPT 0=plain mmx, 1=xmm
164 : Isibaar 1795 ;
165 :     ; Trashes: DST, WIDTH, HEIGHT, _EBX, _ECX, _EDX, _EAX
166 : Skal 1742 ;------------------------------------------------------------------------------
167 :    
168 :     %macro PLANE_FILL 5
169 :     %define DST %1
170 :     %define DST_STRIDE %2
171 :     %define WIDTH %3
172 :     %define HEIGHT %4
173 :     %define OPT %5
174 :    
175 : Isibaar 1795 mov _EAX, 0x80808080
176 :     mov _EBX, WIDTH
177 :     shr WIDTH, 6 ; $_ESI$ = width / 64
178 :     and _EBX, 63 ; _EBX = remainder = width % 64
179 :     movd mm0, eax
180 :     mov _EDX, _EBX
181 :     shr _EBX, 4 ; $_EBX$ = remainder / 16
182 :     and _EDX, 15 ; $_EDX$ = remainder % 16
183 : Skal 1742 punpckldq mm0, mm0
184 :    
185 :     %%loop64_start_pf:
186 : Isibaar 1795 push DST
187 :     mov _ECX, WIDTH ; width64
188 :     test WIDTH, WIDTH
189 : Skal 1742 jz %%loop16_start_pf
190 :    
191 :     %%loop64_pf:
192 :    
193 : Isibaar 1795 %if OPT == 0 ; plain mmx
194 :     movq [DST ], mm0 ; write to y_out
195 :     movq [DST + 8], mm0
196 :     movq [DST + 16], mm0
197 :     movq [DST + 24], mm0
198 :     movq [DST + 32], mm0
199 :     movq [DST + 40], mm0
200 :     movq [DST + 48], mm0
201 :     movq [DST + 56], mm0
202 : Skal 1742 %else
203 : Isibaar 1795 movntq [DST ], mm0 ; write to y_out
204 :     movntq [DST + 8], mm0
205 :     movntq [DST + 16], mm0
206 :     movntq [DST + 24], mm0
207 :     movntq [DST + 32], mm0
208 :     movntq [DST + 40], mm0
209 :     movntq [DST + 48], mm0
210 :     movntq [DST + 56], mm0
211 : Skal 1742 %endif
212 :    
213 : Isibaar 1795 add DST, 64
214 : Skal 1742 loop %%loop64_pf
215 :    
216 :     %%loop16_start_pf:
217 : Isibaar 1795 mov _ECX, _EBX ; width16
218 :     test _EBX, _EBX
219 : Skal 1742 jz %%loop1_start_pf
220 :    
221 :     %%loop16_pf:
222 : Isibaar 1795 %if OPT == 0 ; plain mmx
223 :     movq [DST ], mm0
224 :     movq [DST + 8], mm0
225 : Skal 1742 %else
226 : Isibaar 1795 movntq [DST ], mm0
227 :     movntq [DST + 8], mm0
228 : Skal 1742 %endif
229 :    
230 : Isibaar 1795 add DST, 16
231 : Skal 1742 loop %%loop16_pf
232 :    
233 :     %%loop1_start_pf:
234 : Isibaar 1795 mov _ECX, _EDX
235 : Skal 1742 rep stosb
236 :    
237 : Isibaar 1795 pop DST
238 :    
239 :     %ifdef ARCH_IS_X86_64
240 :     mov ecx, DST_STRIDE
241 :     add DST, _ECX
242 :     %else
243 :     add DST, DST_STRIDE
244 :     %endif
245 :    
246 :     dec HEIGHT
247 : Skal 1742 jg near %%loop64_start_pf
248 : Isibaar 1795
249 :     %undef DST
250 :     %undef DST_STRIDE
251 :     %undef WIDTH
252 :     %undef HEIGHT
253 :     %undef OPT
254 : Skal 1742 %endmacro
255 :    
256 :     ;------------------------------------------------------------------------------
257 : edgomez 851 ; MAKE_YV12_TO_YV12( NAME, OPT )
258 :     ; NAME function name
259 :     ; OPT 0=plain mmx, 1=xmm
260 :     ;
261 : edgomez 1382 ; yv12_to_yv12_mmx(uint8_t * y_dst, uint8_t * u_dst, uint8_t * v_dst,
262 : edgomez 851 ; int y_dst_stride, int uv_dst_stride,
263 : edgomez 1382 ; uint8_t * y_src, uint8_t * u_src, uint8_t * v_src,
264 : edgomez 851 ; int y_src_stride, int uv_src_stride,
265 :     ; int width, int height, int vflip)
266 :     ;------------------------------------------------------------------------------
267 :     %macro MAKE_YV12_TO_YV12 2
268 :     %define NAME %1
269 : Isibaar 1795 %define XMM_OPT %2
270 :     ALIGN SECTION_ALIGN
271 : edgomez 851 cglobal NAME
272 : edgomez 1382 NAME:
273 : edgomez 851
274 : Isibaar 1795 push _EBX ; _ESP + localsize + 3*PTR_SIZE
275 : edgomez 851
276 : Isibaar 1795 %define localsize 2*4
277 : edgomez 851
278 : Isibaar 1795 %ifdef ARCH_IS_X86_64
279 : edgomez 851
280 : Isibaar 1795 %ifndef WINDOWS
281 :     %define pushsize 2*PTR_SIZE
282 :     %define shadow 0
283 :     %else
284 :     %define pushsize 4*PTR_SIZE
285 : Isibaar 1803 %define shadow 32 + 2*PTR_SIZE
286 : Isibaar 1795 %endif
287 : edgomez 851
288 : Isibaar 1795 %define prm_vflip dword [_ESP + localsize + pushsize + shadow + 7*PTR_SIZE]
289 :     %define prm_height dword [_ESP + localsize + pushsize + shadow + 6*PTR_SIZE]
290 :     %define prm_width dword [_ESP + localsize + pushsize + shadow + 5*PTR_SIZE]
291 :     %define prm_uv_src_stride dword [_ESP + localsize + pushsize + shadow + 4*PTR_SIZE]
292 :     %define prm_y_src_stride dword [_ESP + localsize + pushsize + shadow + 3*PTR_SIZE]
293 :     %define prm_v_src [_ESP + localsize + pushsize + shadow + 2*PTR_SIZE]
294 :     %define prm_u_src [_ESP + localsize + pushsize + shadow + 1*PTR_SIZE]
295 :    
296 :     %ifdef WINDOWS
297 :     push _ESI ; _ESP + localsize + 2*PTR_SIZE
298 :     push _EDI ; _ESP + localsize + 1*PTR_SIZE
299 :     push _EBP ; _ESP + localsize + 0*PTR_SIZE
300 :    
301 :     sub _ESP, localsize
302 :    
303 :     %define prm_y_src _ESI
304 :     %define prm_uv_dst_stride TMP0d
305 :     %define prm_y_dst_stride prm4d
306 :     %define prm_v_dst prm3
307 :     %define prm_u_dst TMP1
308 :     %define prm_y_dst _EDI
309 :    
310 :     mov _EDI, prm1
311 :     mov TMP1, prm2
312 :    
313 : Isibaar 1803 mov _ESI, [_ESP + localsize + pushsize + shadow + 0*PTR_SIZE]
314 :     mov TMP0d, dword [_ESP + localsize + pushsize + shadow - 1*PTR_SIZE]
315 : Isibaar 1795
316 :     %else
317 :     push _EBP ; _ESP + localsize + 0*PTR_SIZE
318 :    
319 :     sub _ESP, localsize
320 :    
321 :     %define prm_y_src _ESI
322 :     %define prm_uv_dst_stride prm5d
323 :     %define prm_y_dst_stride TMP1d
324 :     %define prm_v_dst prm6
325 :     %define prm_u_dst TMP0
326 :     %define prm_y_dst _EDI
327 :    
328 :     mov TMP0, prm2
329 :     mov _ESI, prm6
330 :    
331 :     mov prm6, prm3
332 :     mov TMP1d, prm4d
333 :     %endif
334 :    
335 :     %define _ip _ESP + localsize + pushsize + 0
336 :    
337 :     %else
338 :    
339 :     %define pushsize 4*PTR_SIZE
340 :    
341 :     %define prm_vflip [_ESP + localsize + pushsize + 13*PTR_SIZE]
342 :     %define prm_height [_ESP + localsize + pushsize + 12*PTR_SIZE]
343 :     %define prm_width [_ESP + localsize + pushsize + 11*PTR_SIZE]
344 :     %define prm_uv_src_stride [_ESP + localsize + pushsize + 10*PTR_SIZE]
345 :     %define prm_y_src_stride [_ESP + localsize + pushsize + 9*PTR_SIZE]
346 :     %define prm_v_src [_ESP + localsize + pushsize + 8*PTR_SIZE]
347 :     %define prm_u_src [_ESP + localsize + pushsize + 7*PTR_SIZE]
348 :    
349 :     %define prm_y_src _ESI
350 :     %define prm_uv_dst_stride [_ESP + localsize + pushsize + 5*PTR_SIZE]
351 :     %define prm_y_dst_stride [_ESP + localsize + pushsize + 4*PTR_SIZE]
352 :     %define prm_v_dst [_ESP + localsize + pushsize + 3*PTR_SIZE]
353 :     %define prm_u_dst [_ESP + localsize + pushsize + 2*PTR_SIZE]
354 :     %define prm_y_dst _EDI
355 :    
356 :     %define _ip _ESP + localsize + pushsize + 0
357 :    
358 :     push _ESI ; _ESP + localsize + 2*PTR_SIZE
359 :     push _EDI ; _ESP + localsize + 1*PTR_SIZE
360 :     push _EBP ; _ESP + localsize + 0*PTR_SIZE
361 :    
362 :     sub _ESP, localsize
363 :    
364 :     mov _ESI, [_ESP + localsize + pushsize + 6*PTR_SIZE]
365 :     mov _EDI, [_ESP + localsize + pushsize + 1*PTR_SIZE]
366 :    
367 :     %endif
368 :    
369 :     %define width2 dword [_ESP + localsize - 1*4]
370 :     %define height2 dword [_ESP + localsize - 2*4]
371 :    
372 :     mov eax, prm_width
373 :     mov ebx, prm_height
374 : edgomez 1382 shr eax, 1 ; calculate widht/2, heigh/2
375 :     shr ebx, 1
376 : Isibaar 1795 mov width2, eax
377 :     mov height2, ebx
378 : edgomez 851
379 : Isibaar 1795 mov eax, prm_vflip
380 :     test eax, eax
381 : Skal 1742 jz near .go
382 : edgomez 851
383 : Skal 1742 ; flipping support
384 : Isibaar 1795 mov eax, prm_height
385 :     mov ecx, prm_y_src_stride
386 : Skal 1742 sub eax, 1
387 : Isibaar 1795 imul eax, ecx
388 : Isibaar 1803 add _ESI, _EAX ; y_src += (height-1) * y_src_stride
389 : Isibaar 1795 neg ecx
390 :     mov prm_y_src_stride, ecx ; y_src_stride = -y_src_stride
391 : edgomez 851
392 : Isibaar 1795 mov eax, height2
393 :     mov _EDX, prm_u_src
394 :     mov _EBP, prm_v_src
395 :     mov ecx, prm_uv_src_stride
396 :     test _EDX, _EDX
397 : Skal 1742 jz .go
398 : Isibaar 1795 test _EBP, _EBP
399 : Skal 1742 jz .go
400 : Isibaar 1795 sub eax, 1 ; _EAX = height2 - 1
401 :     imul eax, ecx
402 : Isibaar 1803 add _EDX, _EAX ; u_src += (height2-1) * uv_src_stride
403 :     add _EBP, _EAX ; v_src += (height2-1) * uv_src_stride
404 : Isibaar 1795 neg ecx
405 :     mov prm_u_src, _EDX
406 :     mov prm_v_src, _EBP
407 :     mov prm_uv_src_stride, ecx ; uv_src_stride = -uv_src_stride
408 : edgomez 851
409 : Skal 1742 .go:
410 : Isibaar 1795 mov eax, prm_width
411 :     mov ebp, prm_height
412 :     PLANE_COPY _EDI, prm_y_dst_stride, _ESI, prm_y_src_stride, _EAX, _EBP, XMM_OPT
413 : edgomez 851
414 : Isibaar 1795 mov _EAX, prm_u_src
415 :     or _EAX, prm_v_src
416 : Skal 1742 jz near .UVFill_0x80
417 : edgomez 851
418 : Isibaar 1795 mov eax, width2
419 :     mov ebp, height2
420 :     mov _ESI, prm_u_src
421 :     mov _EDI, prm_u_dst
422 :     PLANE_COPY _EDI, prm_uv_dst_stride, _ESI, prm_uv_src_stride, _EAX, _EBP, XMM_OPT
423 :    
424 :     mov eax, width2
425 :     mov ebp, height2
426 :     mov _ESI, prm_v_src
427 :     mov _EDI, prm_v_dst
428 :     PLANE_COPY _EDI, prm_uv_dst_stride, _ESI, prm_uv_src_stride, _EAX, _EBP, XMM_OPT
429 :    
430 : Skal 1742 .Done_UVPlane:
431 : Isibaar 1795 add _ESP, localsize
432 :    
433 :     pop _EBP
434 :     %ifndef ARCH_IS_X86_64
435 :     pop _EDI
436 :     pop _ESI
437 :     %else
438 :     %ifdef WINDOWS
439 :     pop _EDI
440 :     pop _ESI
441 :     %endif
442 :     %endif
443 :     pop _EBX
444 :    
445 : Skal 1742 ret
446 : edgomez 851
447 : Skal 1742 .UVFill_0x80:
448 : Isibaar 1795
449 :     mov esi, width2
450 :     mov ebp, height2
451 :     mov _EDI, prm_u_dst
452 :     PLANE_FILL _EDI, prm_uv_dst_stride, _ESI, _EBP, XMM_OPT
453 :    
454 :     mov esi, width2
455 :     mov ebp, height2
456 :     mov _EDI, prm_v_dst
457 :     PLANE_FILL _EDI, prm_uv_dst_stride, _ESI, _EBP, XMM_OPT
458 :    
459 : Skal 1742 jmp near .Done_UVPlane
460 : Isibaar 1795
461 : Isibaar 1793 ENDFUNC
462 : Isibaar 1795
463 :     %undef NAME
464 :     %undef XMM_OPT
465 : edgomez 851 %endmacro
466 :    
467 : edgomez 1382 ;=============================================================================
468 :     ; Code
469 :     ;=============================================================================
470 : edgomez 851
471 : Isibaar 1795 SECTION .rotext align=SECTION_ALIGN
472 : edgomez 1382
473 : edgomez 851 MAKE_YV12_TO_YV12 yv12_to_yv12_mmx, 0
474 : edgomez 1382
475 : edgomez 851 MAKE_YV12_TO_YV12 yv12_to_yv12_xmm, 1
476 : Isibaar 1790
477 :     %ifidn __OUTPUT_FORMAT__,elf
478 :     section ".note.GNU-stack" noalloc noexec nowrite progbits
479 :     %endif
480 :    

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