Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(100)

Side by Side Diff: media/base/simd/yuv_row_yuv.inc

Issue 7003082: Implements RGB to YV12 conversion in YASM. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 ; Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 ; Use of this source code is governed by a BSD-style license that can be
3 ; found in the LICENSE file.
4
5 ;
6 ; void media::simd::ConvertYUVtoARGBRow(const uint8* y,
7 ; const uint8* u,
8 ; const uint8* v,
9 ; uint8* argb,
10 ; int width);
11 ; void media::simd::ConvertYUVtoRGBRow(const uint8* y,
12 ; const uint8* u,
13 ; const uint8* v,
14 ; uint8* rgb,
15 ; int width);
16 ;
17 ; Converts a row of YUV (4:1:1) pixels to the ARGB (RGB) colorspace. This
18 ; function reads YUV pixels from right to left, convert their colorspace to ARGB
19 ; (RGB), and write the converted pixels to the output buffers. The following
20 ; code snippet represents the rough structure of this fucntion.
21 ;
22 ; if (width & 1) {
23 ; --width;
24 ; convert_one_pixel(y, u, v, argb, width);
25 ; }
26 ; if (width & 2) {
27 ; width -= 2;
28 ; convert_two_pixels(y, u, v, argb, width);
29 ; }
30 ; while (width) {
31 ; width -= 4;
32 ; convert_four_pixels(y, u, v, argb, width);
33 ; }
34 ;
35 ; This function has pseudo-code snippets to describe its behaviors. For
36 ; simplicity, they use the following notations.
37 ;
38 ; #define Y(n) y[n] - 16
39 ; #define U(n) u[n] - 128
40 ; #define V(n) v[n] - 128
41 ; #define FIX(n) (n * (1 << SHIFT_BITS) * 0.5)
42 ; #define ToByte(n) ((n < 0) ? 0 : (n > 255 ? 255 : n))
43 ;
44 ; union {
45 ; int32 d[4];
46 ; int16 w[8];
47 ; int8 b[16];
48 ; } xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
49 ;
50
51 ; Input Parameters
52 %ifdef __x86_64__
53 %ifdef WIN64
54 %define PARAM_Y(r) rcx
55 %define PARAM_U(r) rdx
56 %define PARAM_V(r) r8
57 %define PARAM_ARGB(r) r9
58 %define PARAM_WIDTH(r) INT [(r) + SIZEOF_POINTER * 2]
59 %else
60 %define PARAM_Y(r) rdi
61 %define PARAM_U(r) rsi
62 %define PARAM_V(r) rdx
63 %define PARAM_ARGB(r) rcx
64 %define PARAM_WIDTH(r) r8
65 %endif
66 %else
67 %define PARAM_Y(r) POINTER [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 0]
68 %define PARAM_U(r) POINTER [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 1]
69 %define PARAM_V(r) POINTER [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 2]
70 %define PARAM_ARGB(r) POINTER [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 3]
71 %define PARAM_WIDTH(r) INT [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 4]
72 %endif ; __x86_64__
73
74 ; Local variables used in this function.
75 %define INT_WIDTH32 eax
76 %define INT_WIDTH8 al
77
78 %define INT_PIXEL32 ebx
79 %define INT_PIXEL16 bx
80 %define INT_PIXEL8 bl
81
82 %ifdef __x86_64__
83 %define INT_WIDTH rax
84 %define INT_PIXEL rbx
85 %define PTR_Y PARAM_Y(_EBP_)
86 %define PTR_U PARAM_U(_EBP_)
87 %define PTR_V PARAM_V(_EBP_)
88 %define PTR_ARGB PARAM_ARGB(_EBP_)
89 %else
90 %define INT_WIDTH eax
91 %define INT_PIXEL ebx
92 %define PTR_ARGB ecx
93 %define PTR_Y edx
94 %define PTR_U esi
95 %define PTR_V edi
96 %endif
97
98 %define XMM_TABLE0 xmm7
99 %define XMM_TABLE1 xmm6
100 %define XMM_ARGB xmm5
101 %define XMM_ZERO xmm4
102
103 align 16
104 global EXTN(SYMBOL_NAME) PRIVATE
105
106 EXTN(SYMBOL_NAME):
107 push _EBP_
108 mov _EBP_, _ESP_
109
110 ; Save the resisters used in this function. We do not need to save eax, ecx,
111 ; or edx even though this function uses them. (Callers save them.)
112 push _EBX_
113 push _ESI_
114 push _EDI_
115
116 ; Copy the tables used in this function to xmm6 and xmm7.
117 LOADSYM _EAX_, SIMD_ConvertYUVtoARGB_kTable
118 movdqa XMM_TABLE0, XMMWORD [_EAX_ + 0]
119 movdqa XMM_TABLE1, XMMWORD [_EAX_ + 16]
120
121 ; Copy the input parameters to registers. (We do not need to copy the input
122 ; pointers on x64 because x64 uses registers to provide the first five
123 ; parameters and we can use them.)
124 mov INT_WIDTH, PARAM_WIDTH(_EBP_)
125 %ifndef __x86_64__
126 mov PTR_ARGB, PARAM_ARGB(_EBP_)
127 mov PTR_Y, PARAM_Y(_EBP_)
128 mov PTR_U, PARAM_U(_EBP_)
129 mov PTR_V, PARAM_V(_EBP_)
130 %endif
131
132 .convert_one_pixel:
133 ; Divide the input width by 2 so it represents the offset for u or v. When
134 ; this width is odd, we read the rightmost Y pixel, U pixel, and V pixel to
135 ; convert its colorspace to RGB.
136 sar INT_WIDTH, 1
137 jnc .convert_two_pixels
138
139 movzx INT_PIXEL32, BYTE [PTR_Y + INT_WIDTH * 2]
140 movd xmm0, INT_PIXEL32
141 movzx INT_PIXEL32, BYTE [PTR_U + INT_WIDTH]
142 movd xmm1, INT_PIXEL32
143 movzx INT_PIXEL32, BYTE [PTR_V + INT_WIDTH]
144 movd xmm2, INT_PIXEL32
145
146 ; xmm0.w[0] = Y(0); xmm0.w[1] = U(0); xmm0.w[2] = V(0); xmm0.w[3] = FIX(0.5);
147 ; xmm0.w[4] = Y(1); xmm0.w[5] = U(0); xmm0.w[6] = V(0); xmm0.w[7] = FIX(0.5);
148 pxor XMM_ZERO, XMM_ZERO
149 punpcklbw xmm0, XMM_ZERO
150 punpcklwd xmm0, XMM_ZERO
151
152 punpcklbw xmm1, XMM_ZERO
153 punpcklwd xmm1, XMM_ZERO
154 pshufd xmm1, xmm1, 01010000B
155 pslld xmm1, 8
156 por xmm0, xmm1
157
158 punpcklbw xmm2, XMM_ZERO
159 punpcklwd xmm2, XMM_ZERO
160 pshufd xmm2, xmm2, 01010000B
161 pslld xmm2, 16
162 por xmm0, xmm2
163
164 punpcklbw xmm0, XMM_ZERO
165
166 pshufd xmm2, XMM_TABLE0, 01000100B
167 paddsw xmm0, xmm2
168
169 ; Set up the result pixels.
170 %if ALPHA == 0 || PIXELSIZE == 3
171 ; xmm5.d[0] = xmm5.d[1] = xmm5.d[2] = xmm5.d[3] = 0;
172 pxor XMM_ARGB, XMM_ARGB
173 %else
174 ; xmm5.d[0] = xmm5.d[1] = xmm5.d[2] = xmm5.d[3] = 0xFF000000;
175 pcmpeqd XMM_ARGB, XMM_ARGB
176 psrad XMM_ARGB, 24
177 pslld XMM_ARGB, 24
178 %endif
179
180 ; Calculate r[0].
181 ; xmm2.d[0] = FIX(1.164) * Y(0) + 0 * U(0);
182 ; xmm2.d[1] = FIX(1.596) * V(0) + FIX(0.5);
183 movdqa xmm2, xmm0
184 pshufd xmm3, XMM_TABLE0, 11101110B
185 pmaddwd xmm2, xmm3
186
187 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
188 pshufd xmm3, xmm2, 11011101B
189 pshufd xmm2, xmm2, 10001000B
190 paddd xmm2, xmm3
191 psrad xmm2, SHIFT_BITS
192
193 ; xmm5.b[02] = ToByte(xmm2.d[0]);
194 packssdw xmm2, xmm2
195 packuswb xmm2, xmm2
196 punpckhbw xmm2, XMM_ZERO
197 punpcklbw xmm2, XMM_ZERO
198 pslld xmm2, 16
199 por XMM_ARGB, xmm2
200
201 ; Calculate g[0].
202 ; xmm2.d[0] = FIX(1.164) * Y(0) + -FIX(0.391) * U(0);
203 ; xmm2.d[1] = -FIX(0.813) * V(0) + FIX(0.5);
204 movdqa xmm2, xmm0
205 pshufd xmm3, XMM_TABLE1, 01000100B
206 pmaddwd xmm2, xmm3
207
208 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
209 pshufd xmm3, xmm2, 11011101B
210 shufps xmm2, xmm2, 10001000B
211 paddd xmm2, xmm3
212 psrad xmm2, SHIFT_BITS
213
214 ; xmm5.b[01] = ToByte(xmm2.d[0]);
215 packssdw xmm2, xmm2
216 packuswb xmm2, xmm2
217 punpckhbw xmm2, XMM_ZERO
218 punpcklbw xmm2, XMM_ZERO
219 pslld xmm2, 8
220 por XMM_ARGB, xmm2
221
222 ; Calculate b[0].
223 ; xmm2.d[0] = FIX(1.164) * Y(0) + FIX(2.018) * U(0);
224 ; xmm2.d[1] = 0 * V(0) + FIX(0.5);
225 movdqa xmm2, xmm0
226 pshufd xmm3, XMM_TABLE1, 11101110B
227 pmaddwd xmm2, xmm3
228
229 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
230 pshufd xmm3, xmm2, 11011101B
231 shufps xmm2, xmm2, 10001000B
232 paddd xmm2, xmm3
233 psrad xmm2, SHIFT_BITS
234
235 ; xmm5.b[00] = ToByte(xmm2.d[0]);
236 packssdw xmm2, xmm2
237 packuswb xmm2, xmm2
238 punpckhbw xmm2, XMM_ZERO
239 punpcklbw xmm2, XMM_ZERO
240 por XMM_ARGB, xmm2
241
242 %if PIXELSIZE == 4
243 movd DWORD [PTR_ARGB + INT_WIDTH * 4 * 2], XMM_ARGB
244 %else
245 movd xmm0, INT_WIDTH32
246 lea INT_WIDTH, [INT_WIDTH + INT_WIDTH * 2]
247 movd INT_PIXEL32, XMM_ARGB
248 mov WORD [PTR_ARGB + INT_WIDTH * 2], INT_PIXEL16
249 sar INT_PIXEL32, 16
250 mov BYTE [PTR_ARGB + INT_WIDTH * 2 + 2], INT_PIXEL8
251 movd INT_WIDTH32, xmm0
252 %endif
253
254 .convert_two_pixels:
255 ; When the input width is not a multiple of four, we read the rightmost two Y
256 ; pixels, one U pixel, and one V pixel to convert their colorspace to RGB.
257 ; This code stores two ARGB pixels.
258 test INT_WIDTH8, 1
259 jz .convert_four_pixels
260 sub INT_WIDTH8, 2 / 2
261
262 movzx INT_PIXEL32, WORD [PTR_Y + INT_WIDTH * 2]
263 movd xmm0, INT_PIXEL32
264 movzx INT_PIXEL32, BYTE [PTR_U + INT_WIDTH]
265 movd xmm1, INT_PIXEL32
266 movzx INT_PIXEL32, BYTE [PTR_V + INT_WIDTH]
267 movd xmm2, INT_PIXEL32
268
269 ; xmm0.w[0] = Y(0); xmm0.w[1] = U(0); xmm0.w[2] = V(0); xmm0.w[3] = FIX(0.5);
270 ; xmm0.w[4] = Y(1); xmm0.w[5] = U(0); xmm0.w[6] = V(0); xmm0.w[7] = FIX(0.5);
271 pxor XMM_ZERO, XMM_ZERO
272 punpcklbw xmm0, XMM_ZERO
273 punpcklwd xmm0, XMM_ZERO
274
275 punpcklbw xmm1, XMM_ZERO
276 punpcklwd xmm1, XMM_ZERO
277 pshufd xmm1, xmm1, 01010000B
278 pslld xmm1, 8
279 por xmm0, xmm1
280
281 punpcklbw xmm2, XMM_ZERO
282 punpcklwd xmm2, XMM_ZERO
283 pshufd xmm2, xmm2, 01010000B
284 pslld xmm2, 16
285 por xmm0, xmm2
286
287 punpcklbw xmm0, XMM_ZERO
288
289 pshufd xmm2, XMM_TABLE0, 01000100B
290 paddsw xmm0, xmm2
291
292 ; Set up the result pixels.
293 %if ALPHA == 0 || PIXELSIZE == 3
294 ; xmm5.d[0] = xmm5.d[1] = xmm5.d[2] = xmm5.d[3] = 0;
295 pxor XMM_ARGB, XMM_ARGB
296 %else
297 ; xmm5.d[0] = xmm5.d[1] = xmm5.d[2] = xmm5.d[3] = 0xFF000000;
298 pcmpeqd XMM_ARGB, XMM_ARGB
299 psrad XMM_ARGB, 24
300 pslld XMM_ARGB, 24
301 %endif
302
303 ; Calculate r[0] and r[1].
304 ; xmm2.d[0] = FIX(1.164) * Y(0) + 0 * U(0);
305 ; xmm2.d[1] = FIX(1.596) * V(0) + FIX(0.5);
306 ; xmm2.d[2] = FIX(1.164) * Y(1) + 0 * U(0);
307 ; xmm2.d[3] = FIX(1.596) * V(0) + FIX(0.5);
308 movdqa xmm2, xmm0
309 pshufd xmm3, XMM_TABLE0, 11101110B
310 pmaddwd xmm2, xmm3
311
312 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
313 ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3]) / FIX(1);
314 pshufd xmm3, xmm2, 11011101B
315 pshufd xmm2, xmm2, 10001000B
316 paddd xmm2, xmm3
317 psrad xmm2, SHIFT_BITS
318
319 ; xmm5.b[02] = ToByte(xmm2.d[0]); xmm5.b[06] = ToByte(xmm2.d[1]);
320 packssdw xmm2, xmm2
321 packuswb xmm2, xmm2
322 punpckhbw xmm2, XMM_ZERO
323 punpcklbw xmm2, XMM_ZERO
324 pslld xmm2, 16
325 por XMM_ARGB, xmm2
326
327 ; Calculate g[0] and g[1].
328 ; xmm2.d[0] = FIX(1.164) * Y(0) + -FIX(0.391) * U(0);
329 ; xmm2.d[1] = -FIX(0.813) * V(0) + FIX(0.5);
330 ; xmm2.d[2] = FIX(1.164) * Y(1) + -FIX(0.391) * U(0);
331 ; xmm2.d[3] = -FIX(0.813) * V(0) + FIX(0.5);
332 movdqa xmm2, xmm0
333 pshufd xmm3, XMM_TABLE1, 01000100B
334 pmaddwd xmm2, xmm3
335
336 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
337 ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3]) / FIX(1);
338 pshufd xmm3, xmm2, 11011101B
339 shufps xmm2, xmm2, 10001000B
340 paddd xmm2, xmm3
341 psrad xmm2, SHIFT_BITS
342
343 ; xmm5.b[01] = ToByte(xmm2.d[0]); xmm5.b[05] = ToByte(xmm2.d[1]);
344 packssdw xmm2, xmm2
345 packuswb xmm2, xmm2
346 punpckhbw xmm2, XMM_ZERO
347 punpcklbw xmm2, XMM_ZERO
348 pslld xmm2, 8
349 por XMM_ARGB, xmm2
350
351 ; Calculate b[0] and b[1].
352 ; xmm2.d[0] = FIX(1.164) * Y(0) + FIX(2.018) * U(0);
353 ; xmm2.d[1] = FIX(0.000) * V(0) + FIX(0.5);
354 ; xmm2.d[2] = FIX(1.164) * Y(1) + FIX(2.018) * U(0);
355 ; xmm2.d[3] = FIX(0.000) * V(0) + FIX(0.5);
356 movdqa xmm2, xmm0
357 pshufd xmm3, XMM_TABLE1, 11101110B
358 pmaddwd xmm2, xmm3
359
360 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
361 ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3]) / FIX(1);
362 pshufd xmm3, xmm2, 11011101B
363 shufps xmm2, xmm2, 10001000B
364 paddd xmm2, xmm3
365 psrad xmm2, SHIFT_BITS
366
367 ; xmm5.b[00] = ToByte(xmm2.d[0]); xmm5.b[04] = ToByte(xmm2.d[1]);
368 packssdw xmm2, xmm2
369 packuswb xmm2, xmm2
370 punpckhbw xmm2, XMM_ZERO
371 punpcklbw xmm2, XMM_ZERO
372 por XMM_ARGB, xmm2
373
374 %if PIXELSIZE == 3
375 ; Pack two ARGB pixels to two RGB pixels.
376 movdqa xmm0, XMM_ARGB
377 psrldq xmm0, 4
378 pslldq xmm0, 4
379 pxor XMM_ARGB, xmm0
380
381 psrldq xmm0, 1
382 por XMM_ARGB, xmm0
383 %endif
384
385 %if PIXELSIZE == 4
386 movq MMWORD [PTR_ARGB + INT_WIDTH * 4 * 2], XMM_ARGB
387 %else
388 movd xmm0, INT_WIDTH
389 lea INT_WIDTH, [INT_WIDTH + INT_WIDTH * 2]
390 movd DWORD [PTR_ARGB + INT_WIDTH * 2], XMM_ARGB
391 psrldq XMM_ARGB, 4
392 movd INT_PIXEL32, XMM_ARGB
393 mov WORD [PTR_ARGB + INT_WIDTH * 2 + 4], INT_PIXEL16
394 movd INT_WIDTH, xmm0
395 %endif
396
397 .convert_four_pixels:
398 ; Read four Y pixels, two U pixels, and two V pixels to convert their
399 ; colorspace to RGB. This code stores four ARGB (or RGB) pixels.
400 test INT_WIDTH32, INT_WIDTH32
401 jz .convert_finish
402
403 .convert_four_pixels_main:
404 sub INT_WIDTH32, 4 / 2
405
406 movd xmm0, DWORD [PTR_Y + INT_WIDTH * 2]
407 movzx INT_PIXEL32, WORD [PTR_U + INT_WIDTH]
408 movd xmm1, INT_PIXEL32
409 movzx INT_PIXEL32, WORD [PTR_V + INT_WIDTH]
410 movd xmm2, INT_PIXEL32
411
412 ; xmm0.w[0] = Y(0); xmm0.w[1] = U(0); xmm0.w[2] = V(0); xmm0.w[3] = FIX(0.5);
413 ; xmm0.w[4] = Y(1); xmm0.w[5] = U(0); xmm0.w[6] = V(0); xmm0.w[7] = FIX(0.5);
414 ; xmm1.w[0] = Y(2); xmm1.w[1] = U(1); xmm1.w[2] = V(1); xmm1.w[3] = FIX(0.5);
415 ; xmm1.w[4] = Y(3); xmm1.w[5] = U(1); xmm1.w[6] = V(1); xmm1.w[7] = FIX(0.5);
416 pxor XMM_ZERO, XMM_ZERO
417 punpcklbw xmm0, XMM_ZERO
418 punpcklwd xmm0, XMM_ZERO
419
420 punpcklbw xmm1, XMM_ZERO
421 punpcklwd xmm1, XMM_ZERO
422 pshufd xmm1, xmm1, 01010000B
423 pslld xmm1, 8
424 por xmm0, xmm1
425
426 punpcklbw xmm2, XMM_ZERO
427 punpcklwd xmm2, XMM_ZERO
428 pshufd xmm2, xmm2, 01010000B
429 pslld xmm2, 16
430 por xmm0, xmm2
431
432 movdqa xmm1, xmm0
433 punpckhbw xmm1, XMM_ZERO
434 punpcklbw xmm0, XMM_ZERO
435
436 pshufd xmm2, XMM_TABLE0, 01000100B
437 paddsw xmm0, xmm2
438 paddsw xmm1, xmm2
439
440 ; Set up the result pixels.
441 %if ALPHA == 0 || PIXELSIZE == 3
442 ; xmm5.d[0] = xmm5.d[1] = xmm5.d[2] = xmm5.d[3] = 0;
443 pxor XMM_ARGB, XMM_ARGB
444 %else
445 ; xmm5.d[0] = xmm5.d[1] = xmm5.d[2] = xmm5.d[3] = 0xFF000000;
446 pcmpeqd XMM_ARGB, XMM_ARGB
447 psrad XMM_ARGB, 24
448 pslld XMM_ARGB, 24
449 %endif
450
451 ; Calculate r[0], r[1], r[2], and r[3].
452 ; xmm2.d[0] = FIX(1.164) * Y(0) + 0 * U(0);
453 ; xmm2.d[1] = FIX(1.596) * V(0) + FIX(0.5);
454 ; xmm2.d[2] = FIX(1.164) * Y(1) + 0 * U(0);
455 ; xmm2.d[3] = FIX(1.596) * V(0) + FIX(0.5);
456 ; xmm3.d[0] = FIX(1.164) * Y(2) + 0 * U(0);
457 ; xmm3.d[1] = FIX(1.596) * V(1) + FIX(0.5);
458 ; xmm3.d[2] = FIX(1.164) * Y(2) + 0 * U(0);
459 ; xmm3.d[3] = FIX(1.596) * V(1) + FIX(0.5);
460 movdqa xmm2, xmm0
461 movdqa xmm3, xmm1
462 pshufd xmm4, XMM_TABLE0, 11101110B
463 pmaddwd xmm2, xmm4
464 pmaddwd xmm3, xmm4
465
466 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
467 ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3]) / FIX(1);
468 ; xmm2.d[2] = (xmm3.d[0] + xmm3.d[1]) / FIX(1);
469 ; xmm2.d[3] = (xmm3.d[2] + xmm3.d[3]) / FIX(1);
470 movdqa xmm4, xmm2
471 shufps xmm4, xmm3, 10001000B
472 shufps xmm2, xmm3, 11011101B
473 paddd xmm2, xmm4
474 psrad xmm2, SHIFT_BITS
475
476 ; xmm5.b[02] = ToByte(xmm2.d[0]); xmm5.b[06] = ToByte(xmm2.d[1]);
477 ; xmm5.b[10] = ToByte(xmm2.d[2]); xmm5.b[14] = ToByte(xmm2.d[3]);
478 packssdw xmm2, xmm2
479 packuswb xmm2, xmm2
480 pxor XMM_ZERO, XMM_ZERO
481 punpckhbw xmm2, XMM_ZERO
482 punpcklbw xmm2, XMM_ZERO
483 pslld xmm2, 16
484 por XMM_ARGB, xmm2
485
486 ; Calculate g[0], g[1], g[2], and g[3].
487 ; xmm2.d[0] = FIX(1.164) * Y(0) + -FIX(0.391) * U(0);
488 ; xmm2.d[1] = -FIX(0.813) * V(0) + FIX(0.5);
489 ; xmm2.d[2] = FIX(1.164) * Y(1) + -FIX(0.391) * U(0);
490 ; xmm2.d[3] = -FIX(0.813) * V(0) + FIX(0.5);
491 ; xmm3.d[0] = FIX(1.164) * Y(2) + -FIX(0.391) * U(0);
492 ; xmm3.d[1] = -FIX(0.813) * V(1) + FIX(0.5);
493 ; xmm3.d[2] = FIX(1.164) * Y(2) + -FIX(0.391) * U(0);
494 ; xmm3.d[3] = -FIX(0.813) * V(1) + FIX(0.5);
495 movdqa xmm2, xmm0
496 movdqa xmm3, xmm1
497 pshufd xmm4, XMM_TABLE1, 01000100B
498 pmaddwd xmm2, xmm4
499 pmaddwd xmm3, xmm4
500
501 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
502 ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3]) / FIX(1);
503 ; xmm2.d[2] = (xmm3.d[0] + xmm3.d[1]) / FIX(1);
504 ; xmm2.d[3] = (xmm3.d[2] + xmm3.d[3]) / FIX(1);
505 movdqa xmm4, xmm2
506 shufps xmm4, xmm3, 10001000B
507 shufps xmm2, xmm3, 11011101B
508 paddd xmm2, xmm4
509 psrad xmm2, SHIFT_BITS
510
511 ; xmm5.b[01] = ToByte(xmm2.d[0]); xmm5.b[05] = ToByte(xmm2.d[1]);
512 ; xmm5.b[09] = ToByte(xmm2.d[2]); xmm5.b[13] = ToByte(xmm2.d[3]);
513 packssdw xmm2, xmm2
514 packuswb xmm2, xmm2
515 pxor XMM_ZERO, XMM_ZERO
516 punpckhbw xmm2, XMM_ZERO
517 punpcklbw xmm2, XMM_ZERO
518 pslld xmm2, 8
519 por XMM_ARGB, xmm2
520
521 ; Calculate b[0], b[1], b[2], and b[3].
522 ; xmm2.d[0] = FIX(1.164) * Y(0) + FIX(2.018) * U(0);
523 ; xmm2.d[1] = FIX(0.000) * V(0) + FIX(0.5);
524 ; xmm2.d[2] = FIX(1.164) * Y(1) + FIX(2.018) * U(0);
525 ; xmm2.d[3] = FIX(0.000) * V(0) + FIX(0.5);
526 ; xmm3.d[0] = FIX(1.164) * Y(2) + FIX(2.018) * U(0);
527 ; xmm3.d[1] = FIX(0.000) * V(1) + FIX(0.5);
528 ; xmm3.d[2] = FIX(1.164) * Y(2) + FIX(2.018) * U(0);
529 ; xmm3.d[3] = FIX(0.000) * V(1) + FIX(0.5);
530 movdqa xmm2, xmm0
531 movdqa xmm3, xmm1
532 pshufd xmm4, XMM_TABLE1, 11101110B
533 pmaddwd xmm2, xmm4
534 pmaddwd xmm3, xmm4
535
536 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1]) / FIX(1);
537 ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3]) / FIX(1);
538 ; xmm2.d[2] = (xmm3.d[0] + xmm3.d[1]) / FIX(1);
539 ; xmm2.d[3] = (xmm3.d[2] + xmm3.d[3]) / FIX(1);
540 movdqa xmm4, xmm2
541 shufps xmm4, xmm3, 10001000B
542 shufps xmm2, xmm3, 11011101B
543 paddd xmm2, xmm4
544 psrad xmm2, SHIFT_BITS
545
546 ; xmm5.b[00] = ToByte(xmm2.d[0]); xmm5.b[04] = ToByte(xmm2.d[1]);
547 ; xmm5.b[08] = ToByte(xmm2.d[2]); xmm5.b[12] = ToByte(xmm2.d[3]);
548 packssdw xmm2, xmm2
549 packuswb xmm2, xmm2
550 pxor XMM_ZERO, XMM_ZERO
551 punpckhbw xmm2, XMM_ZERO
552 punpcklbw xmm2, XMM_ZERO
553 por XMM_ARGB, xmm2
554
555 %if PIXELSIZE == 3
556 ; Pack four ARGB pixels to four RGB pixels.
557 movdqa xmm0, XMM_ARGB
558 psrldq xmm0, 4
559 pslldq xmm0, 4
560 movdqa xmm1, XMM_ARGB
561 psrldq xmm1, 8
562 pslldq xmm1, 8
563 movdqa xmm2, XMM_ARGB
564 psrldq xmm2, 12
565 pslldq xmm2, 12
566
567 pxor XMM_ARGB, xmm0
568 pxor xmm0, xmm1
569 pxor xmm1, xmm2
570
571 psrldq xmm0, 1
572 por XMM_ARGB, xmm0
573 psrldq xmm1, 2
574 por XMM_ARGB, xmm1
575 psrldq xmm2, 3
576 por XMM_ARGB, xmm2
577 %endif
578
579 %if PIXELSIZE == 4
580 movdqa XMMWORD [PTR_ARGB + INT_WIDTH * 4 * 2], XMM_ARGB
581 %else
582 mov _EBX_, INT_WIDTH
583 lea _EBX_, [_EBX_ + _EBX_ * 2]
584 movq MMWORD [PTR_ARGB + _EBX_ * 2], XMM_ARGB
585 psrldq XMM_ARGB, 8
586 movd DWORD [PTR_ARGB + _EBX_ * 2 + 8], XMM_ARGB
587 %endif
588
589 test INT_WIDTH32, INT_WIDTH32
590 jnz .convert_four_pixels_main
591
592 .convert_finish:
593 ; Restore the registers used in this function, the stack frame, and the stack
594 ; pointer.
595 pop _EDI_
596 pop _ESI_
597 pop _EBX_
598
599 mov _ESP_, _EBP_
600 pop _EBP_
601
602 ret
603
604 ; For some reason, the OS X linker does not honor the request to align the
605 ; segment unless we do this.
606 align 16
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698