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

Side by Side Diff: media/base/simd/convert_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, 6 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
Property Changes:
Added: svn:eol-style
+ LF
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::ConvertRGBAtoYUVRow(const uint8* rgba,
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 RGBA (RGB) pixels to the YUV (4:1:1) colorspace. This
18 ; function reads RGBA (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(rgba, y, u, v, width);
25 ; }
26 ; if (width & 2) {
27 ; width -= 2;
28 ; convert_two_pixels(rgba, y, u, v, width);
29 ; }
30 ; while (width) {
31 ; width -= 4;
32 ; convert_four_pixels(rgba, 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) rgba[n * PIXELSIZE + 0];
39 ; #define G(n) rgba[n * PIXELSIZE + 1];
40 ; #define R(n) rgba[n * PIXELSIZE + 2];
41 ; #define A(n) PIXELSIZE == 4 ? rgba[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_RGBA(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_RGBA(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_RGBA(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
rbultje 2011/06/10 18:26:33 So what you're doing here is providing compatibili
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
rbultje 2011/06/10 18:26:33 There's an issue here: width is defined as int, wh
86 %define PTR_RGBA PARAM_RGBA(_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_RGBA 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 lea _EAX_, [SIMD_ConvertRGBAToYUVRow_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_RGBA, PARAM_RGBA(_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 RGBA 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_RGBA + 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_RGBA + INT_WIDTH * 2 + 2]
151 shl INT_PIXEL32, 16
152 mov INT_PIXEL16, WORD [PTR_RGBA + 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 ; xmm1.d[0] = FIX(0.439) * B(0) + -FIX(0.291) * G(0);
185 ; xmm1.d[1] = -FIX(0.148) * R(0) + FIX(0.000) * A(0);
186 movdqa xmm1, xmm0
187 pshufd xmm2, XMM_TABLE_UV, 01000100B
188 pmaddwd xmm1, xmm2
189
190 ; xmm1.d[0] = (xmm1.d[0] + xmm1.d[1] + FIX(0.5)) / FIX(1) + 128;
191 pshufd xmm2, xmm1, 11011101B
192 pshufd xmm1, xmm1, 10001000B
193 paddd xmm1, xmm2
194 paddd xmm1, XMM_TABLE_0_5
195 psrad xmm1, SHIFT_BITS
196 %if SHIFT_BITS == 8
197 paddd xmm1, XMM_TABLE_0_5
198 %else
199 movdqa xmm3, XMM_TABLE_0_5
200 psrad xmm3, SHIFT_BITS - 8
201 paddd xmm1, xmm3
202 %endif
203
204 ; u[0] = ToByte(xmm1.d[0]);
205 packssdw xmm1, xmm1
206 packuswb xmm1, xmm1
207 movd INT_PIXEL32, xmm1
208 mov BYTE [PTR_U + INT_WIDTH], INT_PIXEL8
209
210 ; Calculate v[0] from xmm0.
211 ; xmm0.d[0] = -FIX(0.071) * B(0) + -FIX(0.368) * G(0);
212 ; xmm0.d[1] = FIX(0.439) * R(0) + FIX(0.000) * A(0);
213 pshufd xmm2, XMM_TABLE_UV, 11101110B
214 pmaddwd xmm0, xmm2
215
216 ; xmm0.d[0] = (xmm0.d[0] + xmm0.d[1] + FIX(0.5)) / FIX(1) + 128;
217 pshufd xmm2, xmm0, 11011101B
218 pshufd xmm1, xmm0, 10001000B
219 paddd xmm0, xmm2
220 paddd xmm0, XMM_TABLE_0_5
221 psrad xmm0, SHIFT_BITS
222 %if SHIFT_BITS == 8
223 paddd xmm0, XMM_TABLE_0_5
224 %else
225 movdqa xmm3, XMM_TABLE_0_5
226 psrad xmm3, SHIFT_BITS - 8
227 paddd xmm0, xmm3
228 %endif
229
230 ; v[0] = ToByte(xmm0.d[0]);
231 packssdw xmm0, xmm0
232 packuswb xmm0, xmm0
233 movd INT_PIXEL32, xmm0
234 mov BYTE [PTR_V + INT_WIDTH], INT_PIXEL8
235
236 .convert_two_pixels:
237 ; If the input width is not a multiple of four, read the rightmost two RGBA
238 ; pixels and convert their colorspace to YUV. This code stores two Y pixels,
239 ; one U pixel, and one V pixel.
240 test INT_WIDTH8, 2 / 2
241 jz .convert_four_pixels
242 sub INT_WIDTH8, 2 / 2
243
244 ; xmm0.w[0] = B(0); xmm0.w[1] = G(0); xmm0.w[2] = R(0); xmm0.w[3] = A(0);
245 ; xmm0.w[4] = B(1); xmm0.w[5] = G(1); xmm0.w[6] = R(1); xmm0.w[7] = A(1);
246 %if PIXELSIZE == 4
247 movq xmm0, MMWORD [PTR_RGBA + INT_WIDTH * 4 * 2]
248 %elif PIXELSIZE == 3
249 mov _EBX_, INT_WIDTH
250 lea _EBX_, [_EBX_ + _EBX_ * 2]
251 movd xmm0, DWORD [PTR_RGBA + _EBX_ * 2]
252 pinsrw xmm0, WORD [PTR_RGBA + _EBX_ * 2 + 4], 3
253 movdqa xmm1, xmm0
254 psrldq xmm1, 3
255 pslldq xmm1, 3
256 pxor xmm0, xmm1
257 pslldq xmm1, 1
258 por xmm0, xmm1
259 %else
260 %error unsupported pixel size.
261 %endif
262 pxor XMM_ZERO, XMM_ZERO
263 punpcklbw xmm0, XMM_ZERO
264
265 ; xmm2.d[0] = FIX(0.098) * B(0) + FIX(0.504) * G(0);
266 ; xmm2.d[1] = FIX(0.257) * R(0) + FIX(0.000) * A(0) ;
267 ; xmm2.d[2] = FIX(0.098) * B(1) + FIX(0.504) * G(1);
268 ; xmm2.d[3] = FIX(0.257) * R(1) + FIX(0.000) * A(1);
269 movdqa xmm2, xmm0
270 pmaddwd xmm2, XMM_TABLE_Y
271
272 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1] + FIX(0.5)) / FIX(1) + 16;
273 ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3] + FIX(0.5)) / FIX(1) + 16;
274 pshufd xmm4, xmm2, 10001000B
275 pshufd xmm2, xmm2, 11011101B
276 paddd xmm2, xmm4
277
278 paddd xmm2, XMM_TABLE_0_5
279 psrld xmm2, SHIFT_BITS
280 movdqa xmm3, XMM_TABLE_0_5
281 psrld xmm3, SHIFT_BITS - 5
282 paddd xmm2, xmm3
283
284 ; y[0] = ToByte(xmm2.d[0]); y[1] = ToByte(xmm2.d[1]);
285 packssdw xmm2, xmm2
286 packuswb xmm2, xmm2
287 movd INT_PIXEL32, xmm2
288 mov WORD [PTR_Y + INT_WIDTH * 2], INT_PIXEL16
289
290 ; Calculate u[0] from xmm0.
291 ; xmm1.d[0] = FIX(0.439) * B(0) + -FIX(0.291) * G(0);
292 ; xmm1.d[1] = -FIX(0.148) * R(0) + FIX(0.000) * A(0);
293 movdqa xmm1, xmm0
294 pshufd xmm2, XMM_TABLE_UV, 01000100B
295 pmaddwd xmm1, xmm2
296
297 ; xmm1.d[0] = (xmm1.d[0] + xmm1.d[1] + FIX(0.5)) / FIX(1) + 128;
298 pshufd xmm2, xmm1, 11011101B
299 pshufd xmm1, xmm1, 10001000B
300 paddd xmm1, xmm2
301 paddd xmm1, XMM_TABLE_0_5
302 psrad xmm1, SHIFT_BITS
303 %if SHIFT_BITS == 8
304 paddd xmm1, XMM_TABLE_0_5
305 %else
306 movdqa xmm3, XMM_TABLE_0_5
307 psrad xmm3, SHIFT_BITS - 8
308 paddd xmm1, xmm3
309 %endif
310
311 ; u[0] = ToByte(xmm1.d[0]);
312 packssdw xmm1, xmm1
313 packuswb xmm1, xmm1
314 movd INT_PIXEL32, xmm1
315 mov BYTE [PTR_U + INT_WIDTH], INT_PIXEL8
316
317 ; Calculate v[0] from xmm0.
318 ; xmm0.d[0] = -FIX(0.071) * B(0) + -FIX(0.368) * G(0);
319 ; xmm0.d[1] = FIX(0.439) * R(0) + FIX(0.000) * A(0);
320 pshufd xmm2, XMM_TABLE_UV, 11101110B
321 pmaddwd xmm0, xmm2
322
323 ; xmm0.d[0] = (xmm0.d[0] + xmm0.d[1] + FIX(0.5)) / FIX(1) + 128;
324 pshufd xmm2, xmm0, 11011101B
325 pshufd xmm0, xmm0, 10001000B
326 paddd xmm0, xmm2
327 paddd xmm0, XMM_TABLE_0_5
328 psrad xmm0, SHIFT_BITS
329 %if SHIFT_BITS == 8
330 paddd xmm0, XMM_TABLE_0_5
331 %else
332 movdqa xmm3, XMM_TABLE_0_5
333 psrad xmm3, SHIFT_BITS - 8
334 paddd xmm0, xmm3
335 %endif
336
337 ; v[0] = ToByte(xmm0.d[0]);
338 packssdw xmm0, xmm0
339 packuswb xmm0, xmm0
340 movd INT_PIXEL32, xmm0
341 mov BYTE [PTR_V + INT_WIDTH], INT_PIXEL8
342
343 .convert_four_pixels:
344 ; Read four RGBA pixels and convert their colorspace to YUV. This code stores
345 ; four Y pixels, two U pixels, and two V pixels.
346 test INT_WIDTH32, INT_WIDTH32
347 jz .convert_finish
348 sub INT_WIDTH32, 4 / 2
349
350 ; xmm0.w[0] = B(0); xmm0.w[1] = G(0); xmm0.w[2] = R(0); xmm0.w[3] = A(0);
351 ; xmm0.w[4] = B(1); xmm0.w[5] = G(1); xmm0.w[6] = R(1); xmm0.w[7] = A(1);
352 ; xmm1.w[0] = B(2); xmm1.w[1] = G(2); xmm1.w[2] = R(2); xmm1.w[3] = A(2);
353 ; xmm1.w[4] = B(3); xmm1.w[5] = G(3); xmm1.w[6] = R(3); xmm1.w[7] = A(3);
354 %if PIXELSIZE == 4
355 movdqu xmm0, XMMWORD [PTR_RGBA + INT_WIDTH * 4 * 2]
356 %elif PIXELSIZE == 3
357 mov _EBX_, INT_WIDTH
358 lea _EBX_, [_EBX_ + _EBX_ * 2]
359 movq xmm0, MMWORD [PTR_RGBA + _EBX_ * 2]
360 movd xmm1, DWORD [PTR_RGBA + _EBX_ * 2 + 8]
361 shufps xmm0, xmm1, 01000100B
362 movdqa xmm1, xmm0
363 psrldq xmm1, 6
364 pslldq xmm1, 6
365 pxor xmm0, xmm1
366
367 movdqa xmm2, xmm0
368 psrldq xmm2, 3
369 pslldq xmm2, 3
370 pxor xmm0, xmm2
371 pslldq xmm2, 1
372 por xmm0, xmm2
373
374 movdqa xmm3, xmm1
375 psrldq xmm3, 6 + 3
376 pslldq xmm3, 6 + 3
377 pxor xmm1, xmm3
378 pslldq xmm3, 1
379 por xmm1, xmm3
380
381 pslldq xmm1, 2
382 por xmm0, xmm1
383 %else
384 %error unsupported pixel size.
385 %endif
386 movdqa xmm1, xmm0
387 pxor XMM_ZERO, XMM_ZERO
388 punpckhbw xmm1, XMM_ZERO
389 punpcklbw xmm0, XMM_ZERO
390
391 ; xmm2.d[0] = FIX(0.098) * B(0) + FIX(0.504) * G(0);
392 ; xmm2.d[1] = FIX(0.257) * R(0) + FIX(0.000) * A(0);
393 ; xmm2.d[2] = FIX(0.098) * B(1) + FIX(0.504) * G(1);
394 ; xmm2.d[3] = FIX(0.257) * R(1) + FIX(0.000) * A(1);
395 ; xmm3.d[0] = FIX(0.098) * B(2) + FIX(0.504) * G(2);
396 ; xmm3.d[1] = FIX(0.257) * R(2) + FIX(0.000) * A(2);
397 ; xmm3.d[2] = FIX(0.098) * B(3) + FIX(0.504) * G(3);
398 ; xmm3.d[3] = FIX(0.257) * R(3) + FIX(0.000) * A(3);
399 movdqa xmm2, xmm0
400 movdqa xmm3, xmm1
401 pmaddwd xmm2, XMM_TABLE_Y
402 pmaddwd xmm3, XMM_TABLE_Y
403
404 ; xmm2.d[0] = (xmm2.d[0] + xmm2.d[1] + FIX(0.5)) / FIX(1) + 16;
405 ; xmm2.d[1] = (xmm2.d[2] + xmm2.d[3] + FIX(0.5)) / FIX(1) + 16;
406 ; xmm2.d[2] = (xmm3.d[0] + xmm3.d[1] + FIX(0.5)) / FIX(1) + 16;
407 ; xmm2.d[3] = (xmm3.d[2] + xmm3.d[3] + FIX(0.5)) / FIX(1) + 16;
408 movdqa xmm4, xmm2
409 shufps xmm4, xmm3, 10001000B
410 shufps xmm2, xmm3, 11011101B
411 paddd xmm2, xmm4
412
413 paddd xmm2, XMM_TABLE_0_5
414 psrad xmm2, SHIFT_BITS
415 movdqa xmm3, XMM_TABLE_0_5
416 psrad xmm3, SHIFT_BITS - 5
417 paddd xmm2, xmm3
418
419 ; y[0] = ToByte(xmm2.d[0]); y[1] = ToByte(xmm2.d[1]);
420 ; y[2] = ToByte(xmm2.d[2]); y[3] = ToByte(xmm2.d[3]);
421 packssdw xmm2, xmm2
422 packuswb xmm2, xmm2
423 movd DWORD [PTR_Y + INT_WIDTH * 2], xmm2
424
425 ; Retrieve (R(0), G(0), B(0), A(0)) and (R(2), G(2), B(2), A(2)) from xmm1
426 ; and xmm1.
427 ; xmm0.w[0] = B(0); xmm0.w[1] = G(0); xmm0.w[2] = R(0); xmm0.w[3] = A(0);
428 ; xmm0.w[4] = B(2); xmm0.w[5] = G(2); xmm0.w[6] = R(2); xmm0.w[7] = A(2);
429 shufps xmm0, xmm1, 01000100B
430
431 ; Calculate u[0] and u[2] from xmm0.
432 ; xmm1.d[0] = FIX(0.439) * B(0) + -FIX(0.291) * G(0);
433 ; xmm1.d[1] = -FIX(0.148) * R(0) + FIX(0.000) * A(0);
434 ; xmm1.d[2] = FIX(0.439) * B(2) + -FIX(0.291) * G(2);
435 ; xmm1.d[3] = -FIX(0.148) * R(2) + FIX(0.000) * A(2);
436 movdqa xmm1, xmm0
437 pshufd xmm2, XMM_TABLE_UV, 01000100B
438 pmaddwd xmm1, xmm2
439
440 ; xmm1.d[0] = (xmm1.d[0] + xmm1.d[1] + FIX(0.5)) / FIX(1) + 128;
441 ; xmm1.d[1] = (xmm1.d[2] + xmm1.d[3] + FIX(0.5)) / FIX(1) + 128;
442 pshufd xmm2, xmm1, 11011101B
443 pshufd xmm1, xmm1, 10001000B
444 paddd xmm1, xmm2
445 paddd xmm1, XMM_TABLE_0_5
446 psrad xmm1, SHIFT_BITS
447 %if SHIFT_BITS == 8
448 paddd xmm1, XMM_TABLE_0_5
449 %else
450 movdqa xmm3, XMM_TABLE_0_5
451 psrad xmm3, SHIFT_BITS - 8
452 paddd xmm1, xmm3
453 %endif
454
455 ; u[0] = ToByte(xmm1.d[0]); u[1] = ToByte(xmm1.d[1]);
456 packssdw xmm1, xmm1
457 packuswb xmm1, xmm1
458 movd INT_PIXEL32, xmm1
459 mov WORD [PTR_U + INT_WIDTH], INT_PIXEL16
460
461 ; Calculate v[0] and v[2] from xmm0.
462 ; xmm1.d[0] = -FIX(0.071) * B(0) + -FIX(0.368) * G(0);
463 ; xmm1.d[1] = FIX(0.439) * R(0) + FIX(0.000) * A(0);
464 ; xmm1.d[2] = -FIX(0.071) * B(2) + -FIX(0.368) * G(2);
465 ; xmm1.d[3] = FIX(0.439) * R(2) + FIX(0.000) * A(2);
466 movdqa xmm1, xmm0
467 pshufd xmm2, XMM_TABLE_UV, 11101110B
468 pmaddwd xmm1, xmm2
469
470 ; xmm1.d[0] = (xmm1.d[0] + xmm1.d[1] + FIX(0.5)) / FIX(1) + 128;
471 ; xmm1.d[1] = (xmm1.d[2] + xmm1.d[3] + FIX(0.5)) / FIX(1) + 128;
472 pshufd xmm2, xmm1, 11011101B
473 pshufd xmm1, xmm1, 10001000B
474 paddd xmm1, xmm2
475 paddd xmm1, XMM_TABLE_0_5
476 psrad xmm1, SHIFT_BITS
477 %if SHIFT_BITS == 8
478 paddd xmm1, XMM_TABLE_0_5
479 %else
480 movdqa xmm3, XMM_TABLE_0_5
481 psrad xmm3, SHIFT_BITS - 8
482 paddd xmm1, xmm3
483 %endif
484
485 ; v[0] = ToByte(xmm1.d[0]); v[1] = ToByte(xmm1.d[1]);
486 packssdw xmm1, xmm1
487 packuswb xmm1, xmm1
488 movd INT_PIXEL32, xmm1
489 mov WORD [PTR_V + INT_WIDTH], INT_PIXEL16
490
491 jmp .convert_four_pixels
492
493 .convert_finish:
494 ; Restore the registers used in this function, the stack frame, and the stack
495 ; pointer.
496 pop _EDI_
497 pop _ESI_
498 pop _EBX_
499
500 mov _ESP_, _EBP_
501 pop _EBP_
502
503 ret
504
505 ; For some reason, the OS X linker does not honor the request to align the
506 ; segment unless we do this.
507 align 16
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698