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

Side by Side Diff: media/base/simd/yuv_row_rgb.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.
Alpha Left Google 2011/08/22 14:16:59 Rename this to media/base/yuv_row_rgb2yuv_sse2.inc
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::ConvertARGBtoYUVRow(const uint8* argb,
7 ; uint8* y,
8 ; uint8* u,
9 ; uint8* v,
10 ; int width);
11 ; void media::simd::ConvertRGBtoYUVRow(const uint8* rgb,
12 ; uint8* y,
13 ; uint8* u,
14 ; uint8* v,
15 ; int width);
16 ;
17 ; Converts a row of ARGB (RGB) pixels to the YUV (4:1:1) colorspace. This
18 ; function reads ARGB (RGB) pixels from right to left, convert their colorspace
19 ; to YUV, and write the converted pixels to the output buffers. The following
20 ; code snippetre presents the rough structure of this fucntion.
21 ;
22 ; if (width & 1) {
23 ; --width;
24 ; convert_one_pixel(argb, y, u, v, width);
25 ; }
26 ; if (width & 2) {
27 ; width -= 2;
28 ; convert_two_pixels(argb, y, u, v, width);
29 ; }
30 ; while (width) {
31 ; width -= 4;
32 ; convert_four_pixels(argb, y, u, v, 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 B(n) argb[n * PIXELSIZE + 0];
39 ; #define G(n) argb[n * PIXELSIZE + 1];
40 ; #define R(n) argb[n * PIXELSIZE + 2];
41 ; #define A(n) PIXELSIZE == 4 ? ARGB[n * PIXELSIZE + 3] : 0;
42 ; #define FIX(n) (n * (1 << SHIFT_BITS) + 0.5)
43 ; #define ToByte(n) ((n < 0) ? 0 : (n > 255 ? 255 : n))
44 ;
45 ; union {
46 ; int32 d[4];
47 ; int16 w[8];
48 ; int8 b[16];
49 ; } xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7
50 ;
51
52 ; Input Parameters
53 %ifdef __x86_64__
54 %ifdef WIN64
55 %define PARAM_ARGB(r) rcx
56 %define PARAM_Y(r) rdx
57 %define PARAM_U(r) r8
58 %define PARAM_V(r) r9
59 %define PARAM_WIDTH(r) INT [(r) + SIZEOF_POINTER * 2]
60 %else
61 %define PARAM_ARGB(r) rdi
62 %define PARAM_Y(r) rsi
63 %define PARAM_U(r) rdx
64 %define PARAM_V(r) rcx
65 %define PARAM_WIDTH(r) r8
66 %endif
67 %else
68 %define PARAM_ARGB(r) POINTER [(r) + SIZEOF_POINTER * 2]
69 %define PARAM_Y(r) POINTER [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 1]
70 %define PARAM_U(r) POINTER [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 2]
71 %define PARAM_V(r) POINTER [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 3]
72 %define PARAM_WIDTH(r) INT [(r) + SIZEOF_POINTER * 2 + SIZEOF_POINTER * 4]
73 %endif ; __x86_64__
74
75 ; Local variables used in this function.
76 %define INT_WIDTH32 eax
77 %define INT_WIDTH8 al
78
79 %define INT_PIXEL32 ebx
80 %define INT_PIXEL16 bx
81 %define INT_PIXEL8 bl
82
83 %ifdef __x86_64__
84 %define INT_WIDTH rax
85 %define INT_PIXEL rbx
86 %define PTR_ARGB PARAM_ARGB(_EBP_)
87 %define PTR_Y PARAM_Y(_EBP_)
88 %define PTR_U PARAM_U(_EBP_)
89 %define PTR_V PARAM_V(_EBP_)
90 %else
91 %define INT_WIDTH eax
92 %define INT_PIXEL ebx
93 %define PTR_ARGB ecx
94 %define PTR_Y edx
95 %define PTR_U esi
96 %define PTR_V edi
97 %endif
98
99 %define XMM_TABLE_Y xmm7
100 %define XMM_TABLE_0_5 xmm6
101 %define XMM_TABLE_UV xmm5
102 %define XMM_ZERO xmm4
103
104 ; SECTION SEG_TEXT
105 ; CPU PENTIUM4
106
107 align 16
108 global EXTN(SYMBOL_NAME) PRIVATE
109
110 EXTN(SYMBOL_NAME):
111 push _EBP_
112 mov _EBP_, _ESP_
113
114 ; Save the resisters used in this function. We do not need to save eax, ecx,
115 ; or edx even though this function uses them. (Callers save them.)
116 push _EBX_
117 push _ESI_
118 push _EDI_
119
120 ; Copy the tables used in this function to xmm5, xmm6, and xmm7.
121 LOADSYM _EAX_, SIMD_ConvertARGBToYUVRow_kTable
122 movdqa XMM_TABLE_Y, XMMWORD [_EAX_ + 16 * 0]
123 movdqa XMM_TABLE_0_5, XMMWORD [_EAX_ + 16 * 1]
124 movdqa XMM_TABLE_UV, XMMWORD [_EAX_ + 16 * 2]
125
126 ; Copy the input parameters to registers. (We can use the input pointers on
127 ; x86-64 since we do not change them.)
128 mov INT_WIDTH, PARAM_WIDTH(_EBP_)
129 %ifndef __x86_64__
130 mov PTR_ARGB, PARAM_ARGB(_EBP_)
131 mov PTR_Y, PARAM_Y(_EBP_)
132 mov PTR_U, PARAM_U(_EBP_)
133 mov PTR_V, PARAM_V(_EBP_)
134 %endif
135
136 .convert_one_pixel:
137 ; Divide the input width by two so it represents the offsets for u[] and v[].
138 ; When the width is odd. Wee read the rightmost ARGB pixel and convert its
139 ; colorspace to YUV. This code stores one Y pixel, one U pixel, and one V
140 ; pixel.
141 sar INT_WIDTH, 1
142 jnc .convert_two_pixels
143
144 ; xmm0.w[0] = B(0); xmm0.w[1] = G(0); xmm0.w[2] = R(0); xmm0.w[3] = A(0);
145 %if PIXELSIZE == 4
146 movd xmm0, DWORD [PTR_ARGB + INT_WIDTH * 4 * 2]
147 %elif PIXELSIZE == 3
148 movd xmm1, INT_WIDTH
149 lea INT_WIDTH, [INT_WIDTH + INT_WIDTH * 2]
150 movzx INT_PIXEL32, BYTE [PTR_ARGB + INT_WIDTH * 2 + 2]
151 shl INT_PIXEL32, 16
152 mov INT_PIXEL16, WORD [PTR_ARGB + INT_WIDTH * 2]
153 movd xmm0, INT_PIXEL32
154 movd INT_WIDTH, xmm1
155 %else
156 %error unsupported pixel size.
157 %endif
158 pxor XMM_ZERO, XMM_ZERO
159 punpcklbw xmm0, XMM_ZERO
160
161 ; xmm2.d[0] = FIX(0.098) * B(0) + FIX(0.504) * G(0);
162 ; xmm2.d[1] = FIX(0.257) * R(0) + FIX(0.000) * A(0);
163 movdqa xmm2, xmm0
164 pmaddwd xmm2, XMM_TABLE_Y
165
166 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1] + FIX(0.5)) / FIX(1) + 16;
167 pshufd xmm4, xmm2, 10001000B
168 pshufd xmm2, xmm2, 11011101B
169 paddd xmm2, xmm4
170
171 paddd xmm2, XMM_TABLE_0_5
172 psrad xmm2, SHIFT_BITS
173 movdqa xmm3, XMM_TABLE_0_5
174 psrad xmm3, SHIFT_BITS - 5
175 paddd xmm2, xmm3
176
177 ; y[0] = ToByte(xmm2.d[0]);
178 packssdw xmm2, xmm2
179 packuswb xmm2, xmm2
180 movd INT_PIXEL32, xmm2
181 mov BYTE [PTR_Y + INT_WIDTH * 2], INT_PIXEL8
182
183 ; Calculate u[0] from xmm0.
184 test PTR_U, PTR_U
185 jz .convert_two_pixels
186
187 ; xmm1.d[0] = FIX(0.439) * B(0) + -FIX(0.291) * G(0);
188 ; xmm1.d[1] = -FIX(0.148) * R(0) + FIX(0.000) * A(0);
189 movdqa xmm1, xmm0
190 pshufd xmm2, XMM_TABLE_UV, 01000100B
191 pmaddwd xmm1, xmm2
192
193 ; xmm1.d[0] = (xmm1.d[0] + xmm1.d[1] + FIX(0.5)) / FIX(1) + 128;
194 pshufd xmm2, xmm1, 11011101B
195 pshufd xmm1, xmm1, 10001000B
196 paddd xmm1, xmm2
197 paddd xmm1, XMM_TABLE_0_5
198 psrad xmm1, SHIFT_BITS
199 %if SHIFT_BITS == 8
200 paddd xmm1, XMM_TABLE_0_5
201 %else
202 movdqa xmm3, XMM_TABLE_0_5
203 psrad xmm3, SHIFT_BITS - 8
204 paddd xmm1, xmm3
205 %endif
206
207 ; u[0] = ToByte(xmm1.d[0]);
208 packssdw xmm1, xmm1
209 packuswb xmm1, xmm1
210 movd INT_PIXEL32, xmm1
211 mov BYTE [PTR_U + INT_WIDTH], INT_PIXEL8
212
213 ; Calculate v[0] from xmm0.
214 ; xmm0.d[0] = -FIX(0.071) * B(0) + -FIX(0.368) * G(0);
215 ; xmm0.d[1] = FIX(0.439) * R(0) + FIX(0.000) * A(0);
216 pshufd xmm2, XMM_TABLE_UV, 11101110B
217 pmaddwd xmm0, xmm2
218
219 ; xmm0.d[0] = (xmm0.d[0] + xmm0.d[1] + FIX(0.5)) / FIX(1) + 128;
220 pshufd xmm2, xmm0, 11011101B
221 pshufd xmm1, xmm0, 10001000B
222 paddd xmm0, xmm2
223 paddd xmm0, XMM_TABLE_0_5
224 psrad xmm0, SHIFT_BITS
225 %if SHIFT_BITS == 8
226 paddd xmm0, XMM_TABLE_0_5
227 %else
228 movdqa xmm3, XMM_TABLE_0_5
229 psrad xmm3, SHIFT_BITS - 8
230 paddd xmm0, xmm3
231 %endif
232
233 ; v[0] = ToByte(xmm0.d[0]);
234 packssdw xmm0, xmm0
235 packuswb xmm0, xmm0
236 movd INT_PIXEL32, xmm0
237 mov BYTE [PTR_V + INT_WIDTH], INT_PIXEL8
238
239 .convert_two_pixels:
240 ; If the input width is not a multiple of four, read the rightmost two ARGB
241 ; pixels and convert their colorspace to YUV. This code stores two Y pixels,
242 ; one U pixel, and one V pixel.
243 test INT_WIDTH8, 2 / 2
244 jz .convert_four_pixels
245 sub INT_WIDTH8, 2 / 2
246
247 ; xmm0.w[0] = B(0); xmm0.w[1] = G(0); xmm0.w[2] = R(0); xmm0.w[3] = A(0);
248 ; xmm0.w[4] = B(1); xmm0.w[5] = G(1); xmm0.w[6] = R(1); xmm0.w[7] = A(1);
249 %if PIXELSIZE == 4
250 movq xmm0, MMWORD [PTR_ARGB + INT_WIDTH * 4 * 2]
251 %elif PIXELSIZE == 3
252 mov _EBX_, INT_WIDTH
253 lea _EBX_, [_EBX_ + _EBX_ * 2]
254 movd xmm0, DWORD [PTR_ARGB + _EBX_ * 2]
255 pinsrw xmm0, WORD [PTR_ARGB + _EBX_ * 2 + 4], 3
256 movdqa xmm1, xmm0
257 psrldq xmm1, 3
258 pslldq xmm1, 3
259 pxor xmm0, xmm1
260 pslldq xmm1, 1
261 por xmm0, xmm1
262 %else
263 %error unsupported pixel size.
264 %endif
265 pxor XMM_ZERO, XMM_ZERO
266 punpcklbw xmm0, XMM_ZERO
267
268 ; xmm2.d[0] = FIX(0.098) * B(0) + FIX(0.504) * G(0);
269 ; xmm2.d[1] = FIX(0.257) * R(0) + FIX(0.000) * A(0) ;
270 ; xmm2.d[2] = FIX(0.098) * B(1) + FIX(0.504) * G(1);
271 ; xmm2.d[3] = FIX(0.257) * R(1) + FIX(0.000) * A(1);
272 movdqa xmm2, xmm0
273 pmaddwd xmm2, XMM_TABLE_Y
274
275 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1] + FIX(0.5)) / FIX(1) + 16;
276 ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3] + FIX(0.5)) / FIX(1) + 16;
277 pshufd xmm4, xmm2, 10001000B
278 pshufd xmm2, xmm2, 11011101B
279 paddd xmm2, xmm4
280
281 paddd xmm2, XMM_TABLE_0_5
282 psrld xmm2, SHIFT_BITS
283 movdqa xmm3, XMM_TABLE_0_5
284 psrld xmm3, SHIFT_BITS - 5
285 paddd xmm2, xmm3
286
287 ; y[0] = ToByte(xmm2.d[0]); y[1] = ToByte(xmm2.d[1]);
288 packssdw xmm2, xmm2
289 packuswb xmm2, xmm2
290 movd INT_PIXEL32, xmm2
291 mov WORD [PTR_Y + INT_WIDTH * 2], INT_PIXEL16
292
293 ; Calculate u[0] from xmm0.
294 test PTR_U, PTR_U
295 jz .convert_four_pixels
296
297 ; xmm1.d[0] = FIX(0.439) * B(0) + -FIX(0.291) * G(0);
298 ; xmm1.d[1] = -FIX(0.148) * R(0) + FIX(0.000) * A(0);
299 movdqa xmm1, xmm0
300 pshufd xmm2, XMM_TABLE_UV, 01000100B
301 pmaddwd xmm1, xmm2
302
303 ; xmm1.d[0] = (xmm1.d[0] + xmm1.d[1] + FIX(0.5)) / FIX(1) + 128;
304 pshufd xmm2, xmm1, 11011101B
305 pshufd xmm1, xmm1, 10001000B
306 paddd xmm1, xmm2
307 paddd xmm1, XMM_TABLE_0_5
308 psrad xmm1, SHIFT_BITS
309 %if SHIFT_BITS == 8
310 paddd xmm1, XMM_TABLE_0_5
311 %else
312 movdqa xmm3, XMM_TABLE_0_5
313 psrad xmm3, SHIFT_BITS - 8
314 paddd xmm1, xmm3
315 %endif
316
317 ; u[0] = ToByte(xmm1.d[0]);
318 packssdw xmm1, xmm1
319 packuswb xmm1, xmm1
320 movd INT_PIXEL32, xmm1
321 mov BYTE [PTR_U + INT_WIDTH], INT_PIXEL8
322
323 ; Calculate v[0] from xmm0.
324 ; xmm0.d[0] = -FIX(0.071) * B(0) + -FIX(0.368) * G(0);
325 ; xmm0.d[1] = FIX(0.439) * R(0) + FIX(0.000) * A(0);
326 pshufd xmm2, XMM_TABLE_UV, 11101110B
327 pmaddwd xmm0, xmm2
328
329 ; xmm0.d[0] = (xmm0.d[0] + xmm0.d[1] + FIX(0.5)) / FIX(1) + 128;
330 pshufd xmm2, xmm0, 11011101B
331 pshufd xmm0, xmm0, 10001000B
332 paddd xmm0, xmm2
333 paddd xmm0, XMM_TABLE_0_5
334 psrad xmm0, SHIFT_BITS
335 %if SHIFT_BITS == 8
336 paddd xmm0, XMM_TABLE_0_5
337 %else
338 movdqa xmm3, XMM_TABLE_0_5
339 psrad xmm3, SHIFT_BITS - 8
340 paddd xmm0, xmm3
341 %endif
342
343 ; v[0] = ToByte(xmm0.d[0]);
344 packssdw xmm0, xmm0
345 packuswb xmm0, xmm0
346 movd INT_PIXEL32, xmm0
347 mov BYTE [PTR_V + INT_WIDTH], INT_PIXEL8
348
349 .convert_four_pixels:
350 ; Read four ARGB pixels and convert their colorspace to YUV. This code stores
351 ; four Y pixels, two U pixels, and two V pixels.
352 test INT_WIDTH32, INT_WIDTH32
353 jz .convert_finish
354
355 .convert_four_pixels_main:
356 sub INT_WIDTH32, 4 / 2
357
358 ; xmm0.w[0] = B(0); xmm0.w[1] = G(0); xmm0.w[2] = R(0); xmm0.w[3] = A(0);
359 ; xmm0.w[4] = B(1); xmm0.w[5] = G(1); xmm0.w[6] = R(1); xmm0.w[7] = A(1);
360 ; xmm1.w[0] = B(2); xmm1.w[1] = G(2); xmm1.w[2] = R(2); xmm1.w[3] = A(2);
361 ; xmm1.w[4] = B(3); xmm1.w[5] = G(3); xmm1.w[6] = R(3); xmm1.w[7] = A(3);
362 %if PIXELSIZE == 4
363 movdqa xmm0, XMMWORD [PTR_ARGB + INT_WIDTH * 4 * 2]
364 %elif PIXELSIZE == 3
365 mov _EBX_, INT_WIDTH
366 lea _EBX_, [_EBX_ + _EBX_ * 2]
367 movq xmm0, MMWORD [PTR_ARGB + _EBX_ * 2]
368 movd xmm1, DWORD [PTR_ARGB + _EBX_ * 2 + 8]
369 shufps xmm0, xmm1, 01000100B
370 movdqa xmm1, xmm0
371 psrldq xmm1, 6
372 pslldq xmm1, 6
373 pxor xmm0, xmm1
374
375 movdqa xmm2, xmm0
376 psrldq xmm2, 3
377 pslldq xmm2, 3
378 pxor xmm0, xmm2
379 pslldq xmm2, 1
380 por xmm0, xmm2
381
382 movdqa xmm3, xmm1
383 psrldq xmm3, 6 + 3
384 pslldq xmm3, 6 + 3
385 pxor xmm1, xmm3
386 pslldq xmm3, 1
387 por xmm1, xmm3
388
389 pslldq xmm1, 2
390 por xmm0, xmm1
391 %else
392 %error unsupported pixel size.
393 %endif
394 movdqa xmm1, xmm0
395 pxor XMM_ZERO, XMM_ZERO
396 punpckhbw xmm1, XMM_ZERO
397 punpcklbw xmm0, XMM_ZERO
398
399 ; xmm2.d[0] = FIX(0.098) * B(0) + FIX(0.504) * G(0);
400 ; xmm2.d[1] = FIX(0.257) * R(0) + FIX(0.000) * A(0);
401 ; xmm2.d[2] = FIX(0.098) * B(1) + FIX(0.504) * G(1);
402 ; xmm2.d[3] = FIX(0.257) * R(1) + FIX(0.000) * A(1);
403 ; xmm3.d[0] = FIX(0.098) * B(2) + FIX(0.504) * G(2);
404 ; xmm3.d[1] = FIX(0.257) * R(2) + FIX(0.000) * A(2);
405 ; xmm3.d[2] = FIX(0.098) * B(3) + FIX(0.504) * G(3);
406 ; xmm3.d[3] = FIX(0.257) * R(3) + FIX(0.000) * A(3);
407 movdqa xmm2, xmm0
408 movdqa xmm3, xmm1
409 pmaddwd xmm2, XMM_TABLE_Y
410 pmaddwd xmm3, XMM_TABLE_Y
411
412 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1] + FIX(0.5)) / FIX(1) + 16;
413 ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3] + FIX(0.5)) / FIX(1) + 16;
414 ; xmm2.d[2] = (xmm3.d[0] + xmm3.d[1] + FIX(0.5)) / FIX(1) + 16;
415 ; xmm2.d[3] = (xmm3.d[2] + xmm3.d[3] + FIX(0.5)) / FIX(1) + 16;
416 movdqa xmm4, xmm2
417 shufps xmm4, xmm3, 10001000B
418 shufps xmm2, xmm3, 11011101B
419 paddd xmm2, xmm4
420
421 paddd xmm2, XMM_TABLE_0_5
422 psrad xmm2, SHIFT_BITS
423 movdqa xmm3, XMM_TABLE_0_5
424 psrad xmm3, SHIFT_BITS - 5
425 paddd xmm2, xmm3
426
427 ; y[0] = ToByte(xmm2.d[0]); y[1] = ToByte(xmm2.d[1]);
428 ; y[2] = ToByte(xmm2.d[2]); y[3] = ToByte(xmm2.d[3]);
429 packssdw xmm2, xmm2
430 packuswb xmm2, xmm2
431 movd DWORD [PTR_Y + INT_WIDTH * 2], xmm2
432
433 ; Retrieve (R(0), G(0), B(0), A(0)) and (R(2), G(2), B(2), A(2)) from xmm1
434 ; and xmm1.
435 ; xmm0.w[0] = B(0); xmm0.w[1] = G(0); xmm0.w[2] = R(0); xmm0.w[3] = A(0);
436 ; xmm0.w[4] = B(2); xmm0.w[5] = G(2); xmm0.w[6] = R(2); xmm0.w[7] = A(2);
437 shufps xmm0, xmm1, 01000100B
438
439 ; Calculate u[0] and u[2] from xmm0.
440 test PTR_U, PTR_U
441 jz .convert_four_pixels_next
442
443 ; xmm1.d[0] = FIX(0.439) * B(0) + -FIX(0.291) * G(0);
444 ; xmm1.d[1] = -FIX(0.148) * R(0) + FIX(0.000) * A(0);
445 ; xmm1.d[2] = FIX(0.439) * B(2) + -FIX(0.291) * G(2);
446 ; xmm1.d[3] = -FIX(0.148) * R(2) + FIX(0.000) * A(2);
447 movdqa xmm1, xmm0
448 pshufd xmm2, XMM_TABLE_UV, 01000100B
449 pmaddwd xmm1, xmm2
450
451 ; xmm1.d[0] = (xmm1.d[0] + xmm1.d[1] + FIX(0.5)) / FIX(1) + 128;
452 ; xmm1.d[1] = (xmm1.d[2] + xmm1.d[3] + FIX(0.5)) / FIX(1) + 128;
453 pshufd xmm2, xmm1, 11011101B
454 pshufd xmm1, xmm1, 10001000B
455 paddd xmm1, xmm2
456 paddd xmm1, XMM_TABLE_0_5
457 psrad xmm1, SHIFT_BITS
458 %if SHIFT_BITS == 8
459 paddd xmm1, XMM_TABLE_0_5
460 %else
461 movdqa xmm3, XMM_TABLE_0_5
462 psrad xmm3, SHIFT_BITS - 8
463 paddd xmm1, xmm3
464 %endif
465
466 ; u[0] = ToByte(xmm1.d[0]); u[1] = ToByte(xmm1.d[1]);
467 packssdw xmm1, xmm1
468 packuswb xmm1, xmm1
469 movd INT_PIXEL32, xmm1
470 mov WORD [PTR_U + INT_WIDTH], INT_PIXEL16
471
472 ; Calculate v[0] and v[2] from xmm0.
473 ; xmm1.d[0] = -FIX(0.071) * B(0) + -FIX(0.368) * G(0);
474 ; xmm1.d[1] = FIX(0.439) * R(0) + FIX(0.000) * A(0);
475 ; xmm1.d[2] = -FIX(0.071) * B(2) + -FIX(0.368) * G(2);
476 ; xmm1.d[3] = FIX(0.439) * R(2) + FIX(0.000) * A(2);
477 movdqa xmm1, xmm0
478 pshufd xmm2, XMM_TABLE_UV, 11101110B
479 pmaddwd xmm1, xmm2
480
481 ; xmm1.d[0] = (xmm1.d[0] + xmm1.d[1] + FIX(0.5)) / FIX(1) + 128;
482 ; xmm1.d[1] = (xmm1.d[2] + xmm1.d[3] + FIX(0.5)) / FIX(1) + 128;
483 pshufd xmm2, xmm1, 11011101B
484 pshufd xmm1, xmm1, 10001000B
485 paddd xmm1, xmm2
486 paddd xmm1, XMM_TABLE_0_5
487 psrad xmm1, SHIFT_BITS
488 %if SHIFT_BITS == 8
489 paddd xmm1, XMM_TABLE_0_5
490 %else
491 movdqa xmm3, XMM_TABLE_0_5
492 psrad xmm3, SHIFT_BITS - 8
493 paddd xmm1, xmm3
494 %endif
495
496 ; v[0] = ToByte(xmm1.d[0]); v[1] = ToByte(xmm1.d[1]);
497 packssdw xmm1, xmm1
498 packuswb xmm1, xmm1
499 movd INT_PIXEL32, xmm1
500 mov WORD [PTR_V + INT_WIDTH], INT_PIXEL16
501
502 .convert_four_pixels_next:
503 test INT_WIDTH32, INT_WIDTH32
504 jnz .convert_four_pixels_main
505
506 .convert_finish:
507 ; Restore the registers used in this function, the stack frame, and the stack
508 ; pointer.
509 pop _EDI_
510 pop _ESI_
511 pop _EBX_
512
513 mov _ESP_, _EBP_
514 pop _EBP_
515
516 ret
517
518 ; For some reason, the OS X linker does not honor the request to align the
519 ; segment unless we do this.
520 align 16
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698