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

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