[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 1795 - (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 1795 ; * $Id: colorspace_yuv_mmx.asm,v 1.9 2008-11-26 01:04:34 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 : Skal 1742 %define DST_STRIDE %2
49 : Isibaar 1795 %define SRC %3
50 : Skal 1742 %define SRC_STRIDE %4
51 : Isibaar 1795 %define WIDTH %5
52 :     %define HEIGHT %6
53 :     %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 :     dec HEIGHT
145 : Skal 1742 jg near %%loop64_start_pc
146 : Isibaar 1795
147 :     %undef DST
148 :     %undef DST_STRIDE
149 :     %undef SRC
150 :     %undef SRC_STRIDE
151 :     %undef WIDTH
152 :     %undef HEIGHT
153 :     %undef OPT
154 : edgomez 851 %endmacro
155 :    
156 :     ;------------------------------------------------------------------------------
157 : Skal 1742 ; PLANE_FILL ( DST, DST_STRIDE, WIDTH, HEIGHT, OPT )
158 :     ; DST dst buffer
159 :     ; DST_STRIDE dst stride
160 :     ; WIDTH width
161 :     ; HEIGHT height
162 :     ; OPT 0=plain mmx, 1=xmm
163 : Isibaar 1795 ;
164 :     ; Trashes: DST, WIDTH, HEIGHT, _EBX, _ECX, _EDX, _EAX
165 : Skal 1742 ;------------------------------------------------------------------------------
166 :    
167 :     %macro PLANE_FILL 5
168 :     %define DST %1
169 :     %define DST_STRIDE %2
170 :     %define WIDTH %3
171 :     %define HEIGHT %4
172 :     %define OPT %5
173 :    
174 : Isibaar 1795 mov _EAX, 0x80808080
175 :     mov _EBX, WIDTH
176 :     shr WIDTH, 6 ; $_ESI$ = width / 64
177 :     and _EBX, 63 ; _EBX = remainder = width % 64
178 :     movd mm0, eax
179 :     mov _EDX, _EBX
180 :     shr _EBX, 4 ; $_EBX$ = remainder / 16
181 :     and _EDX, 15 ; $_EDX$ = remainder % 16
182 : Skal 1742 punpckldq mm0, mm0
183 :    
184 :     %%loop64_start_pf:
185 : Isibaar 1795 push DST
186 :     mov _ECX, WIDTH ; width64
187 :     test WIDTH, WIDTH
188 : Skal 1742 jz %%loop16_start_pf
189 :    
190 :     %%loop64_pf:
191 :    
192 : Isibaar 1795 %if OPT == 0 ; plain mmx
193 :     movq [DST ], mm0 ; write to y_out
194 :     movq [DST + 8], mm0
195 :     movq [DST + 16], mm0
196 :     movq [DST + 24], mm0
197 :     movq [DST + 32], mm0
198 :     movq [DST + 40], mm0
199 :     movq [DST + 48], mm0
200 :     movq [DST + 56], mm0
201 : Skal 1742 %else
202 : Isibaar 1795 movntq [DST ], mm0 ; write to y_out
203 :     movntq [DST + 8], mm0
204 :     movntq [DST + 16], mm0
205 :     movntq [DST + 24], mm0
206 :     movntq [DST + 32], mm0
207 :     movntq [DST + 40], mm0
208 :     movntq [DST + 48], mm0
209 :     movntq [DST + 56], mm0
210 : Skal 1742 %endif
211 :    
212 : Isibaar 1795 add DST, 64
213 : Skal 1742 loop %%loop64_pf
214 :    
215 :     %%loop16_start_pf:
216 : Isibaar 1795 mov _ECX, _EBX ; width16
217 :     test _EBX, _EBX
218 : Skal 1742 jz %%loop1_start_pf
219 :    
220 :     %%loop16_pf:
221 : Isibaar 1795 %if OPT == 0 ; plain mmx
222 :     movq [DST ], mm0
223 :     movq [DST + 8], mm0
224 : Skal 1742 %else
225 : Isibaar 1795 movntq [DST ], mm0
226 :     movntq [DST + 8], mm0
227 : Skal 1742 %endif
228 :    
229 : Isibaar 1795 add DST, 16
230 : Skal 1742 loop %%loop16_pf
231 :    
232 :     %%loop1_start_pf:
233 : Isibaar 1795 mov _ECX, _EDX
234 : Skal 1742 rep stosb
235 :    
236 : Isibaar 1795 pop DST
237 :    
238 :     %ifdef ARCH_IS_X86_64
239 :     mov ecx, DST_STRIDE
240 :     add DST, _ECX
241 :     %else
242 :     add DST, DST_STRIDE
243 :     %endif
244 :    
245 :     dec HEIGHT
246 : Skal 1742 jg near %%loop64_start_pf
247 : Isibaar 1795
248 :     %undef DST
249 :     %undef DST_STRIDE
250 :     %undef WIDTH
251 :     %undef HEIGHT
252 :     %undef OPT
253 : Skal 1742 %endmacro
254 :    
255 :     ;------------------------------------------------------------------------------
256 : edgomez 851 ; MAKE_YV12_TO_YV12( NAME, OPT )
257 :     ; NAME function name
258 :     ; OPT 0=plain mmx, 1=xmm
259 :     ;
260 : edgomez 1382 ; yv12_to_yv12_mmx(uint8_t * y_dst, uint8_t * u_dst, uint8_t * v_dst,
261 : edgomez 851 ; int y_dst_stride, int uv_dst_stride,
262 : edgomez 1382 ; uint8_t * y_src, uint8_t * u_src, uint8_t * v_src,
263 : edgomez 851 ; int y_src_stride, int uv_src_stride,
264 :     ; int width, int height, int vflip)
265 :     ;------------------------------------------------------------------------------
266 :     %macro MAKE_YV12_TO_YV12 2
267 :     %define NAME %1
268 : Isibaar 1795 %define XMM_OPT %2
269 :     ALIGN SECTION_ALIGN
270 : edgomez 851 cglobal NAME
271 : edgomez 1382 NAME:
272 : edgomez 851
273 : Isibaar 1795 push _EBX ; _ESP + localsize + 3*PTR_SIZE
274 : edgomez 851
275 : Isibaar 1795 %define localsize 2*4
276 : edgomez 851
277 : Isibaar 1795 %ifdef ARCH_IS_X86_64
278 : edgomez 851
279 : Isibaar 1795 %ifndef WINDOWS
280 :     %define pushsize 2*PTR_SIZE
281 :     %define shadow 0
282 :     %else
283 :     %define pushsize 4*PTR_SIZE
284 :     %define shadow 32 + 16
285 :     %endif
286 : edgomez 851
287 : Isibaar 1795 %define prm_vflip dword [_ESP + localsize + pushsize + shadow + 7*PTR_SIZE]
288 :     %define prm_height dword [_ESP + localsize + pushsize + shadow + 6*PTR_SIZE]
289 :     %define prm_width dword [_ESP + localsize + pushsize + shadow + 5*PTR_SIZE]
290 :     %define prm_uv_src_stride dword [_ESP + localsize + pushsize + shadow + 4*PTR_SIZE]
291 :     %define prm_y_src_stride dword [_ESP + localsize + pushsize + shadow + 3*PTR_SIZE]
292 :     %define prm_v_src [_ESP + localsize + pushsize + shadow + 2*PTR_SIZE]
293 :     %define prm_u_src [_ESP + localsize + pushsize + shadow + 1*PTR_SIZE]
294 :    
295 :     %ifdef WINDOWS
296 :     push _ESI ; _ESP + localsize + 2*PTR_SIZE
297 :     push _EDI ; _ESP + localsize + 1*PTR_SIZE
298 :     push _EBP ; _ESP + localsize + 0*PTR_SIZE
299 :    
300 :     sub _ESP, localsize
301 :    
302 :     %define prm_y_src _ESI
303 :     %define prm_uv_dst_stride TMP0d
304 :     %define prm_y_dst_stride prm4d
305 :     %define prm_v_dst prm3
306 :     %define prm_u_dst TMP1
307 :     %define prm_y_dst _EDI
308 :    
309 :     mov _EDI, prm1
310 :     mov TMP1, prm2
311 :    
312 :     mov _ESI, [_ESP + localsize + pushsize + shadow - 1*PTR_SIZE]
313 :     mov TMP0d, dword [_ESP + localsize + pushsize + shadow - 2*PTR_SIZE]
314 :    
315 :     %else
316 :     push _EBP ; _ESP + localsize + 0*PTR_SIZE
317 :    
318 :     sub _ESP, localsize
319 :    
320 :     %define prm_y_src _ESI
321 :     %define prm_uv_dst_stride prm5d
322 :     %define prm_y_dst_stride TMP1d
323 :     %define prm_v_dst prm6
324 :     %define prm_u_dst TMP0
325 :     %define prm_y_dst _EDI
326 :    
327 :     mov TMP0, prm2
328 :     mov _ESI, prm6
329 :    
330 :     mov prm6, prm3
331 :     mov TMP1d, prm4d
332 :     %endif
333 :    
334 :     %define _ip _ESP + localsize + pushsize + 0
335 :    
336 :     %else
337 :    
338 :     %define pushsize 4*PTR_SIZE
339 :    
340 :     %define prm_vflip [_ESP + localsize + pushsize + 13*PTR_SIZE]
341 :     %define prm_height [_ESP + localsize + pushsize + 12*PTR_SIZE]
342 :     %define prm_width [_ESP + localsize + pushsize + 11*PTR_SIZE]
343 :     %define prm_uv_src_stride [_ESP + localsize + pushsize + 10*PTR_SIZE]
344 :     %define prm_y_src_stride [_ESP + localsize + pushsize + 9*PTR_SIZE]
345 :     %define prm_v_src [_ESP + localsize + pushsize + 8*PTR_SIZE]
346 :     %define prm_u_src [_ESP + localsize + pushsize + 7*PTR_SIZE]
347 :    
348 :     %define prm_y_src _ESI
349 :     %define prm_uv_dst_stride [_ESP + localsize + pushsize + 5*PTR_SIZE]
350 :     %define prm_y_dst_stride [_ESP + localsize + pushsize + 4*PTR_SIZE]
351 :     %define prm_v_dst [_ESP + localsize + pushsize + 3*PTR_SIZE]
352 :     %define prm_u_dst [_ESP + localsize + pushsize + 2*PTR_SIZE]
353 :     %define prm_y_dst _EDI
354 :    
355 :     %define _ip _ESP + localsize + pushsize + 0
356 :    
357 :     push _ESI ; _ESP + localsize + 2*PTR_SIZE
358 :     push _EDI ; _ESP + localsize + 1*PTR_SIZE
359 :     push _EBP ; _ESP + localsize + 0*PTR_SIZE
360 :    
361 :     sub _ESP, localsize
362 :    
363 :     mov _ESI, [_ESP + localsize + pushsize + 6*PTR_SIZE]
364 :     mov _EDI, [_ESP + localsize + pushsize + 1*PTR_SIZE]
365 :    
366 :     %endif
367 :    
368 :     %define width2 dword [_ESP + localsize - 1*4]
369 :     %define height2 dword [_ESP + localsize - 2*4]
370 :    
371 :     mov eax, prm_width
372 :     mov ebx, prm_height
373 : edgomez 1382 shr eax, 1 ; calculate widht/2, heigh/2
374 :     shr ebx, 1
375 : Isibaar 1795 mov width2, eax
376 :     mov height2, ebx
377 : edgomez 851
378 : Isibaar 1795 mov eax, prm_vflip
379 :     test eax, eax
380 : Skal 1742 jz near .go
381 : edgomez 851
382 : Skal 1742 ; flipping support
383 : Isibaar 1795 mov eax, prm_height
384 :     mov ecx, prm_y_src_stride
385 : Skal 1742 sub eax, 1
386 : Isibaar 1795 imul eax, ecx
387 :     add _ESI, _EAX ; y_src += (height-1) * y_src_stride
388 :     neg ecx
389 :     mov prm_y_src_stride, ecx ; y_src_stride = -y_src_stride
390 : edgomez 851
391 : Isibaar 1795 mov eax, height2
392 :     mov _EDX, prm_u_src
393 :     mov _EBP, prm_v_src
394 :     mov ecx, prm_uv_src_stride
395 :     test _EDX, _EDX
396 : Skal 1742 jz .go
397 : Isibaar 1795 test _EBP, _EBP
398 : Skal 1742 jz .go
399 : Isibaar 1795 sub eax, 1 ; _EAX = height2 - 1
400 :     imul eax, ecx
401 :     add _EDX, _EAX ; u_src += (height2-1) * uv_src_stride
402 :     add _EBP, _EAX ; v_src += (height2-1) * uv_src_stride
403 :     neg ecx
404 :     mov prm_u_src, _EDX
405 :     mov prm_v_src, _EBP
406 :     mov prm_uv_src_stride, ecx ; uv_src_stride = -uv_src_stride
407 : edgomez 851
408 : Skal 1742 .go:
409 : Isibaar 1795 mov eax, prm_width
410 :     mov ebp, prm_height
411 :     PLANE_COPY _EDI, prm_y_dst_stride, _ESI, prm_y_src_stride, _EAX, _EBP, XMM_OPT
412 : edgomez 851
413 : Isibaar 1795 mov _EAX, prm_u_src
414 :     or _EAX, prm_v_src
415 : Skal 1742 jz near .UVFill_0x80
416 : edgomez 851
417 : Isibaar 1795 mov eax, width2
418 :     mov ebp, height2
419 :     mov _ESI, prm_u_src
420 :     mov _EDI, prm_u_dst
421 :     PLANE_COPY _EDI, prm_uv_dst_stride, _ESI, prm_uv_src_stride, _EAX, _EBP, XMM_OPT
422 :    
423 :     mov eax, width2
424 :     mov ebp, height2
425 :     mov _ESI, prm_v_src
426 :     mov _EDI, prm_v_dst
427 :     PLANE_COPY _EDI, prm_uv_dst_stride, _ESI, prm_uv_src_stride, _EAX, _EBP, XMM_OPT
428 :    
429 : Skal 1742 .Done_UVPlane:
430 : Isibaar 1795 add _ESP, localsize
431 :    
432 :     pop _EBP
433 :     %ifndef ARCH_IS_X86_64
434 :     pop _EDI
435 :     pop _ESI
436 :     %else
437 :     %ifdef WINDOWS
438 :     pop _EDI
439 :     pop _ESI
440 :     %endif
441 :     %endif
442 :     pop _EBX
443 :    
444 : Skal 1742 ret
445 : edgomez 851
446 : Skal 1742 .UVFill_0x80:
447 : Isibaar 1795
448 :     mov esi, width2
449 :     mov ebp, height2
450 :     mov _EDI, prm_u_dst
451 :     PLANE_FILL _EDI, prm_uv_dst_stride, _ESI, _EBP, XMM_OPT
452 :    
453 :     mov esi, width2
454 :     mov ebp, height2
455 :     mov _EDI, prm_v_dst
456 :     PLANE_FILL _EDI, prm_uv_dst_stride, _ESI, _EBP, XMM_OPT
457 :    
458 : Skal 1742 jmp near .Done_UVPlane
459 : Isibaar 1795
460 : Isibaar 1793 ENDFUNC
461 : Isibaar 1795
462 :     %undef NAME
463 :     %undef XMM_OPT
464 : edgomez 851 %endmacro
465 :    
466 : edgomez 1382 ;=============================================================================
467 :     ; Code
468 :     ;=============================================================================
469 : edgomez 851
470 : Isibaar 1795 SECTION .rotext align=SECTION_ALIGN
471 : edgomez 1382
472 : edgomez 851 MAKE_YV12_TO_YV12 yv12_to_yv12_mmx, 0
473 : edgomez 1382
474 : edgomez 851 MAKE_YV12_TO_YV12 yv12_to_yv12_xmm, 1
475 : Isibaar 1790
476 :     %ifidn __OUTPUT_FORMAT__,elf
477 :     section ".note.GNU-stack" noalloc noexec nowrite progbits
478 :     %endif
479 :    

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