[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 1793 - (view) (download)

1 : edgomez 1382 ;/****************************************************************************
2 :     ; *
3 :     ; * XVID MPEG-4 VIDEO CODEC
4 :     ; * - MMX and XMM YV12->YV12 conversion -
5 :     ; *
6 :     ; * Copyright(C) 2001 Michael Militzer <isibaar@xvid.org>
7 :     ; *
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 1793 ; * $Id: colorspace_yuv_mmx.asm,v 1.8 2008-11-11 20:46:24 Isibaar Exp $
23 : edgomez 1382 ; *
24 :     ; ***************************************************************************/
25 : edgomez 851
26 :     BITS 32
27 :    
28 : edgomez 1382 %macro cglobal 1
29 : edgomez 1535 %ifdef PREFIX
30 :     %ifdef MARK_FUNCS
31 : edgomez 1540 global _%1:function %1.endfunc-%1
32 :     %define %1 _%1:function %1.endfunc-%1
33 : Isibaar 1793 %define ENDFUNC .endfunc
34 : edgomez 1535 %else
35 :     global _%1
36 :     %define %1 _%1
37 : Isibaar 1793 %define ENDFUNC
38 : edgomez 1535 %endif
39 : edgomez 851 %else
40 : edgomez 1535 %ifdef MARK_FUNCS
41 : edgomez 1540 global %1:function %1.endfunc-%1
42 : Isibaar 1793 %define ENDFUNC .endfunc
43 : edgomez 1535 %else
44 :     global %1
45 : Isibaar 1793 %define ENDFUNC
46 : edgomez 1535 %endif
47 : edgomez 851 %endif
48 :     %endmacro
49 :    
50 : edgomez 1382 ;=============================================================================
51 :     ; Helper macros
52 :     ;=============================================================================
53 : edgomez 851
54 :     ;------------------------------------------------------------------------------
55 : Skal 1742 ; PLANE_COPY ( DST, DST_STRIDE, SRC, SRC_STRIDE, WIDTH, HEIGHT, OPT )
56 : edgomez 851 ; DST dst buffer
57 : Skal 1742 ; DST_STRIDE dst stride
58 : edgomez 851 ; SRC src destination buffer
59 : Skal 1742 ; SRC_STRIDE src stride
60 : edgomez 851 ; WIDTH width
61 :     ; HEIGHT height
62 :     ; OPT 0=plain mmx, 1=xmm
63 :     ;------------------------------------------------------------------------------
64 : edgomez 1382
65 : edgomez 851 %macro PLANE_COPY 7
66 : Skal 1742 %define DST %1
67 :     %define DST_STRIDE %2
68 :     %define SRC %3
69 :     %define SRC_STRIDE %4
70 : edgomez 851 %define WIDTH %5
71 :     %define HEIGHT %6
72 : Skal 1742 %define OPT %7
73 : edgomez 851
74 : edgomez 1382 mov eax, WIDTH
75 :     mov ebp, HEIGHT ; $ebp$ = height
76 :     mov esi, SRC
77 :     mov edi, DST
78 : edgomez 851
79 : edgomez 1382 mov ebx, eax
80 :     shr eax, 6 ; $eax$ = width / 64
81 :     and ebx, 63 ; remainder = width % 64
82 :     mov edx, ebx
83 :     shr ebx, 4 ; $ebx$ = remainder / 16
84 :     and edx, 15 ; $edx$ = remainder % 16
85 : edgomez 851
86 : Skal 1742 %%loop64_start_pc:
87 :     push edi
88 :     push esi
89 :     mov ecx, eax ; width64
90 :     test eax, eax
91 :     jz %%loop16_start_pc
92 :    
93 :     %%loop64_pc:
94 : edgomez 1382 %if OPT == 1 ; xmm
95 :     prefetchnta [esi + 64] ; non temporal prefetch
96 :     prefetchnta [esi + 96]
97 : edgomez 851 %endif
98 : Skal 1742 movq mm1, [esi ] ; read from src
99 :     movq mm2, [esi + 8]
100 : edgomez 1382 movq mm3, [esi + 16]
101 :     movq mm4, [esi + 24]
102 :     movq mm5, [esi + 32]
103 :     movq mm6, [esi + 40]
104 :     movq mm7, [esi + 48]
105 :     movq mm0, [esi + 56]
106 : edgomez 851
107 : edgomez 1382 %if OPT == 0 ; plain mmx
108 : Skal 1742 movq [edi ], mm1 ; write to y_out
109 :     movq [edi + 8], mm2
110 : edgomez 1382 movq [edi + 16], mm3
111 :     movq [edi + 24], mm4
112 :     movq [edi + 32], mm5
113 :     movq [edi + 40], mm6
114 :     movq [edi + 48], mm7
115 :     movq [edi + 56], mm0
116 : edgomez 851 %else
117 : Skal 1742 movntq [edi ], mm1 ; write to y_out
118 :     movntq [edi + 8], mm2
119 : edgomez 1382 movntq [edi + 16], mm3
120 :     movntq [edi + 24], mm4
121 :     movntq [edi + 32], mm5
122 :     movntq [edi + 40], mm6
123 :     movntq [edi + 48], mm7
124 :     movntq [edi + 56], mm0
125 : edgomez 851 %endif
126 :    
127 : edgomez 1382 add esi, 64
128 :     add edi, 64
129 : Skal 1742 loop %%loop64_pc
130 : edgomez 851
131 :    
132 : Skal 1742 %%loop16_start_pc:
133 :     mov ecx, ebx ; width16
134 :     test ebx, ebx
135 :     jz %%loop1_start_pc
136 :    
137 :     %%loop16_pc:
138 : edgomez 1382 movq mm1, [esi]
139 :     movq mm2, [esi + 8]
140 :     %if OPT == 0 ; plain mmx
141 :     movq [edi], mm1
142 :     movq [edi + 8], mm2
143 : edgomez 851 %else
144 : edgomez 1382 movntq [edi], mm1
145 :     movntq [edi + 8], mm2
146 : edgomez 851 %endif
147 :    
148 : edgomez 1382 add esi, 16
149 :     add edi, 16
150 : Skal 1742 loop %%loop16_pc
151 : edgomez 851
152 :    
153 : Skal 1742 %%loop1_start_pc:
154 : edgomez 1382 mov ecx, edx
155 :     rep movsb
156 : edgomez 851
157 : Skal 1742 pop esi
158 :     pop edi
159 :     add esi, SRC_STRIDE
160 :     add edi, DST_STRIDE
161 : edgomez 1382 dec ebp
162 : Skal 1742 jg near %%loop64_start_pc
163 : edgomez 851 %endmacro
164 :    
165 :     ;------------------------------------------------------------------------------
166 : Skal 1742 ; PLANE_FILL ( DST, DST_STRIDE, WIDTH, HEIGHT, OPT )
167 :     ; DST dst buffer
168 :     ; DST_STRIDE dst stride
169 :     ; WIDTH width
170 :     ; HEIGHT height
171 :     ; OPT 0=plain mmx, 1=xmm
172 :     ;------------------------------------------------------------------------------
173 :    
174 :     %macro PLANE_FILL 5
175 :     %define DST %1
176 :     %define DST_STRIDE %2
177 :     %define WIDTH %3
178 :     %define HEIGHT %4
179 :     %define OPT %5
180 :    
181 :     mov esi, WIDTH
182 :     mov ebp, HEIGHT ; $ebp$ = height
183 :     mov edi, DST
184 :    
185 :     mov eax, 0x80808080
186 :     mov ebx, esi
187 :     shr esi, 6 ; $esi$ = width / 64
188 :     and ebx, 63 ; ebx = remainder = width % 64
189 :     movd mm0, eax
190 :     mov edx, ebx
191 :     shr ebx, 4 ; $ebx$ = remainder / 16
192 :     and edx, 15 ; $edx$ = remainder % 16
193 :     punpckldq mm0, mm0
194 :    
195 :     %%loop64_start_pf:
196 :     push edi
197 :     mov ecx, esi ; width64
198 :     test esi, esi
199 :     jz %%loop16_start_pf
200 :    
201 :     %%loop64_pf:
202 :    
203 :     %if OPT == 0 ; plain mmx
204 :     movq [edi ], mm0 ; write to y_out
205 :     movq [edi + 8], mm0
206 :     movq [edi + 16], mm0
207 :     movq [edi + 24], mm0
208 :     movq [edi + 32], mm0
209 :     movq [edi + 40], mm0
210 :     movq [edi + 48], mm0
211 :     movq [edi + 56], mm0
212 :     %else
213 :     movntq [edi ], mm0 ; write to y_out
214 :     movntq [edi + 8], mm0
215 :     movntq [edi + 16], mm0
216 :     movntq [edi + 24], mm0
217 :     movntq [edi + 32], mm0
218 :     movntq [edi + 40], mm0
219 :     movntq [edi + 48], mm0
220 :     movntq [edi + 56], mm0
221 :     %endif
222 :    
223 :     add edi, 64
224 :     loop %%loop64_pf
225 :    
226 :     %%loop16_start_pf:
227 :     mov ecx, ebx ; width16
228 :     test ebx, ebx
229 :     jz %%loop1_start_pf
230 :    
231 :     %%loop16_pf:
232 :     %if OPT == 0 ; plain mmx
233 :     movq [edi ], mm0
234 :     movq [edi + 8], mm0
235 :     %else
236 :     movntq [edi ], mm0
237 :     movntq [edi + 8], mm0
238 :     %endif
239 :    
240 :     add edi, 16
241 :     loop %%loop16_pf
242 :    
243 :     %%loop1_start_pf:
244 :     mov ecx, edx
245 :     rep stosb
246 :    
247 :     pop edi
248 :     add edi, DST_STRIDE
249 :     dec ebp
250 :     jg near %%loop64_start_pf
251 :     %endmacro
252 :    
253 :     ;------------------------------------------------------------------------------
254 : edgomez 851 ; MAKE_YV12_TO_YV12( NAME, OPT )
255 :     ; NAME function name
256 :     ; OPT 0=plain mmx, 1=xmm
257 :     ;
258 : edgomez 1382 ; yv12_to_yv12_mmx(uint8_t * y_dst, uint8_t * u_dst, uint8_t * v_dst,
259 : edgomez 851 ; int y_dst_stride, int uv_dst_stride,
260 : edgomez 1382 ; uint8_t * y_src, uint8_t * u_src, uint8_t * v_src,
261 : edgomez 851 ; int y_src_stride, int uv_src_stride,
262 :     ; int width, int height, int vflip)
263 :     ;------------------------------------------------------------------------------
264 :     %macro MAKE_YV12_TO_YV12 2
265 :     %define NAME %1
266 : Skal 1742 %define OPT %2
267 : edgomez 1382 ALIGN 16
268 : edgomez 851 cglobal NAME
269 : edgomez 1382 NAME:
270 : edgomez 851 %define pushsize 16
271 : Skal 1742 %define localsize 12
272 : edgomez 851
273 : Skal 1742 %define vflip esp + localsize + pushsize + 52
274 :     %define height esp + localsize + pushsize + 48
275 : edgomez 851 %define width esp + localsize + pushsize + 44
276 :     %define uv_src_stride esp + localsize + pushsize + 40
277 :     %define y_src_stride esp + localsize + pushsize + 36
278 : Skal 1742 %define v_src esp + localsize + pushsize + 32
279 :     %define u_src esp + localsize + pushsize + 28
280 :     %define y_src esp + localsize + pushsize + 24
281 : edgomez 851 %define uv_dst_stride esp + localsize + pushsize + 20
282 :     %define y_dst_stride esp + localsize + pushsize + 16
283 : Skal 1742 %define v_dst esp + localsize + pushsize + 12
284 :     %define u_dst esp + localsize + pushsize + 8
285 :     %define y_dst esp + localsize + pushsize + 4
286 :     %define _ip esp + localsize + pushsize + 0
287 : edgomez 851
288 : edgomez 1382 push ebx ; esp + localsize + 16
289 :     push esi ; esp + localsize + 8
290 :     push edi ; esp + localsize + 4
291 :     push ebp ; esp + localsize + 0
292 : edgomez 851
293 :     %define width2 esp + localsize - 4
294 :     %define height2 esp + localsize - 8
295 :    
296 : edgomez 1382 sub esp, localsize
297 : edgomez 851
298 : edgomez 1382 mov eax, [width]
299 :     mov ebx, [height]
300 :     shr eax, 1 ; calculate widht/2, heigh/2
301 :     shr ebx, 1
302 :     mov [width2], eax
303 :     mov [height2], ebx
304 : edgomez 851
305 : Skal 1742 mov eax, [vflip]
306 :     test eax, eax
307 :     jz near .go
308 : edgomez 851
309 : Skal 1742 ; flipping support
310 : edgomez 1382 mov eax, [height]
311 :     mov esi, [y_src]
312 : Skal 1742 mov ecx, [y_src_stride]
313 :     sub eax, 1
314 :     imul eax, ecx
315 : edgomez 1382 add esi, eax ; y_src += (height-1) * y_src_stride
316 : Skal 1742 neg ecx
317 : edgomez 1382 mov [y_src], esi
318 : Skal 1742 mov [y_src_stride], ecx ; y_src_stride = -y_src_stride
319 : edgomez 851
320 : edgomez 1382 mov eax, [height2]
321 :     mov esi, [u_src]
322 :     mov edi, [v_src]
323 : Skal 1742 mov ecx, [uv_src_stride]
324 :     test esi, esi
325 :     jz .go
326 :     test edi, edi
327 :     jz .go
328 :     sub eax, 1 ; eax = height2 - 1
329 :     imul eax, ecx
330 : edgomez 1382 add esi, eax ; u_src += (height2-1) * uv_src_stride
331 :     add edi, eax ; v_src += (height2-1) * uv_src_stride
332 : Skal 1742 neg ecx
333 : edgomez 1382 mov [u_src], esi
334 :     mov [v_src], edi
335 : Skal 1742 mov [uv_src_stride], ecx ; uv_src_stride = -uv_src_stride
336 : edgomez 851
337 : Skal 1742 .go:
338 : edgomez 851
339 : Skal 1742 PLANE_COPY [y_dst], [y_dst_stride], [y_src], [y_src_stride], [width], [height], OPT
340 : edgomez 851
341 : Skal 1742 mov eax, [u_src]
342 :     or eax, [v_src]
343 :     jz near .UVFill_0x80
344 :     PLANE_COPY [u_dst], [uv_dst_stride], [u_src], [uv_src_stride], [width2], [height2], OPT
345 :     PLANE_COPY [v_dst], [uv_dst_stride], [v_src], [uv_src_stride], [width2], [height2], OPT
346 : edgomez 851
347 : Skal 1742 .Done_UVPlane:
348 : edgomez 1382 add esp, localsize
349 :     pop ebp
350 :     pop edi
351 :     pop esi
352 :     pop ebx
353 : Skal 1742 ret
354 : edgomez 851
355 : Skal 1742 .UVFill_0x80:
356 :     PLANE_FILL [u_dst], [uv_dst_stride], [width2], [height2], OPT
357 :     PLANE_FILL [v_dst], [uv_dst_stride], [width2], [height2], OPT
358 :     jmp near .Done_UVPlane
359 : Isibaar 1793 ENDFUNC
360 : edgomez 851 %endmacro
361 :    
362 : edgomez 1382 ;=============================================================================
363 :     ; Code
364 :     ;=============================================================================
365 : edgomez 851
366 : edgomez 1382 SECTION .text
367 :    
368 : edgomez 851 MAKE_YV12_TO_YV12 yv12_to_yv12_mmx, 0
369 : edgomez 1382
370 : edgomez 851 MAKE_YV12_TO_YV12 yv12_to_yv12_xmm, 1
371 : Isibaar 1790
372 :     %ifidn __OUTPUT_FORMAT__,elf
373 :     section ".note.GNU-stack" noalloc noexec nowrite progbits
374 :     %endif
375 :    

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