/*
- * yuv2rgb_mmx.c, Software YUV to RGB converter with Intel MMX "technology"
+ * yuv2rgb_mmx.c, software YUV to RGB converter with Intel MMX "technology"
*
- * Copyright (C) 2000, Silicon Integrated System Corp.
+ * Copyright (C) 2000, Silicon Integrated System Corp
*
* Author: Olie Lho <ollie@sis.com.tw>
*
#undef EMMS
#undef SFENCE
-#ifdef HAVE_3DNOW
-/* On K6 femms is faster of emms. On K7 femms is directly mapped on emms. */
+#if HAVE_AMD3DNOW
+/* On K6 femms is faster than emms. On K7 femms is directly mapped to emms. */
#define EMMS "femms"
#else
#define EMMS "emms"
#endif
-#ifdef HAVE_MMX2
+#if HAVE_MMX2
#define MOVNTQ "movntq"
#define SFENCE "sfence"
#else
"punpcklbw %%mm5, %%mm2;" /* G7 G6 G5 G4 G3 G2 G1 G0 */\
+#define YUV422_UNSHIFT \
+ if(c->srcFormat == PIX_FMT_YUV422P){ \
+ srcStride[1] *= 2; \
+ srcStride[2] *= 2; \
+ } \
+
+#define YUV2RGB_LOOP(depth) \
+ h_size= (c->dstW+7)&~7; \
+ if(h_size*depth > FFABS(dstStride[0])) h_size-=8; \
+\
+ __asm__ volatile ("pxor %mm4, %mm4;" /* zero mm4 */ ); \
+ for (y= 0; y<srcSliceH; y++ ) { \
+ uint8_t *image = dst[0] + (y+srcSliceY)*dstStride[0]; \
+ uint8_t *py = src[0] + y*srcStride[0]; \
+ uint8_t *pu = src[1] + (y>>1)*srcStride[1]; \
+ uint8_t *pv = src[2] + (y>>1)*srcStride[2]; \
+ x86_reg index= -h_size/2; \
+
+#define YUV2RGB_INIT \
+ /* This MMX assembly code deals with a SINGLE scan line at a time, \
+ * it converts 8 pixels in each iteration. */ \
+ __asm__ volatile ( \
+ /* load data for start of next scan line */ \
+ "movd (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ \
+ "movd (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */ \
+ "movq (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \
+ /* \
+ ".balign 16 \n\t" \
+ */ \
+ "1: \n\t" \
+ /* No speed difference on my p3@500 with prefetch, \
+ * if it is faster for anyone with -benchmark then tell me. \
+ PREFETCH" 64(%0) \n\t" \
+ PREFETCH" 64(%1) \n\t" \
+ PREFETCH" 64(%2) \n\t" \
+ */ \
+
+#define YUV2RGB_ENDLOOP(depth) \
+ "add $"AV_STRINGIFY(depth*8)", %1 \n\t" \
+ "add $4, %0 \n\t" \
+ " js 1b \n\t" \
+
+#define YUV2RGB_OPERANDS \
+ : "+r" (index), "+r" (image) \
+ : "r" (pu - index), "r" (pv - index), "r"(&c->redDither), "r" (py - 2*index) \
+ ); \
+ } \
+ __asm__ volatile (EMMS); \
+ return srcSliceH; \
+
static inline int RENAME(yuv420_rgb16)(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
int srcSliceH, uint8_t* dst[], int dstStride[]){
int y, h_size;
- if(c->srcFormat == PIX_FMT_YUV422P){
- srcStride[1] *= 2;
- srcStride[2] *= 2;
- }
-
- h_size= (c->dstW+7)&~7;
- if(h_size*2 > FFABS(dstStride[0])) h_size-=8;
-
- __asm__ __volatile__ ("pxor %mm4, %mm4;" /* zero mm4 */ );
- //printf("%X %X %X %X %X %X %X %X %X %X\n", (int)&c->redDither, (int)&b5Dither, (int)src[0], (int)src[1], (int)src[2], (int)dst[0],
- //srcStride[0],srcStride[1],srcStride[2],dstStride[0]);
- for (y= 0; y<srcSliceH; y++ ) {
- uint8_t *_image = dst[0] + (y+srcSliceY)*dstStride[0];
- uint8_t *_py = src[0] + y*srcStride[0];
- uint8_t *_pu = src[1] + (y>>1)*srcStride[1];
- uint8_t *_pv = src[2] + (y>>1)*srcStride[2];
- long index= -h_size/2;
-
- b5Dither= dither8[y&1];
- g6Dither= dither4[y&1];
- g5Dither= dither8[y&1];
- r5Dither= dither8[(y+1)&1];
- /* this mmx assembly code deals with SINGLE scan line at a time, it convert 8
- pixels in each iteration */
- __asm__ __volatile__ (
- /* load data for start of next scan line */
- "movd (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */
- "movd (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */
- "movq (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */
- //".balign 16 \n\t"
- "1: \n\t"
- /* no speed diference on my p3@500 with prefetch,
- * if it is faster for anyone with -benchmark then tell me
- PREFETCH" 64(%0) \n\t"
- PREFETCH" 64(%1) \n\t"
- PREFETCH" 64(%2) \n\t"
- */
-YUV2RGB
+ YUV422_UNSHIFT
+ YUV2RGB_LOOP(2)
+
+ c->blueDither= ff_dither8[y&1];
+ c->greenDither= ff_dither4[y&1];
+ c->redDither= ff_dither8[(y+1)&1];
+
+ YUV2RGB_INIT
+ YUV2RGB
#ifdef DITHER1XBPP
- "paddusb "MANGLE(b5Dither)", %%mm0;"
- "paddusb "MANGLE(g6Dither)", %%mm2;"
- "paddusb "MANGLE(r5Dither)", %%mm1;"
+ "paddusb "BLUE_DITHER"(%4), %%mm0;"
+ "paddusb "GREEN_DITHER"(%4), %%mm2;"
+ "paddusb "RED_DITHER"(%4), %%mm1;"
#endif
/* mask unneeded bits off */
"pand "MANGLE(mmx_redmask)", %%mm0;" /* b7b6b5b4 b3_0_0_0 b7b6b5b4 b3_0_0_0 */
"movq %%mm0, %%mm5;" /* Copy B7-B0 */
"movq %%mm2, %%mm7;" /* Copy G7-G0 */
- /* convert rgb24 plane to rgb16 pack for pixel 0-3 */
+ /* convert RGB24 plane to RGB16 pack for pixel 0-3 */
"punpcklbw %%mm4, %%mm2;" /* 0_0_0_0 0_0_0_0 g7g6g5g4 g3g2_0_0 */
"punpcklbw %%mm1, %%mm0;" /* r7r6r5r4 r3_0_0_0 0_0_0_b7 b6b5b4b3 */
"movq 8 (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */
MOVNTQ " %%mm0, (%1);" /* store pixel 0-3 */
- /* convert rgb24 plane to rgb16 pack for pixel 0-3 */
+ /* convert RGB24 plane to RGB16 pack for pixel 0-3 */
"punpckhbw %%mm4, %%mm7;" /* 0_0_0_0 0_0_0_0 g7g6g5g4 g3g2_0_0 */
"punpckhbw %%mm1, %%mm5;" /* r7r6r5r4 r3_0_0_0 0_0_0_b7 b6b5b4b3 */
MOVNTQ " %%mm5, 8 (%1);" /* store pixel 4-7 */
- "add $16, %1 \n\t"
- "add $4, %0 \n\t"
- " js 1b \n\t"
-
- : "+r" (index), "+r" (_image)
- : "r" (_pu - index), "r" (_pv - index), "r"(&c->redDither), "r" (_py - 2*index)
- );
- }
-
- __asm__ __volatile__ (EMMS);
-
- return srcSliceH;
+ YUV2RGB_ENDLOOP(2)
+ YUV2RGB_OPERANDS
}
static inline int RENAME(yuv420_rgb15)(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
int srcSliceH, uint8_t* dst[], int dstStride[]){
int y, h_size;
- if(c->srcFormat == PIX_FMT_YUV422P){
- srcStride[1] *= 2;
- srcStride[2] *= 2;
- }
-
- h_size= (c->dstW+7)&~7;
- if(h_size*2 > FFABS(dstStride[0])) h_size-=8;
-
- __asm__ __volatile__ ("pxor %mm4, %mm4;" /* zero mm4 */ );
- //printf("%X %X %X %X %X %X %X %X %X %X\n", (int)&c->redDither, (int)&b5Dither, (int)src[0], (int)src[1], (int)src[2], (int)dst[0],
- //srcStride[0],srcStride[1],srcStride[2],dstStride[0]);
- for (y= 0; y<srcSliceH; y++ ) {
- uint8_t *_image = dst[0] + (y+srcSliceY)*dstStride[0];
- uint8_t *_py = src[0] + y*srcStride[0];
- uint8_t *_pu = src[1] + (y>>1)*srcStride[1];
- uint8_t *_pv = src[2] + (y>>1)*srcStride[2];
- long index= -h_size/2;
-
- b5Dither= dither8[y&1];
- g6Dither= dither4[y&1];
- g5Dither= dither8[y&1];
- r5Dither= dither8[(y+1)&1];
- /* this mmx assembly code deals with SINGLE scan line at a time, it convert 8
- pixels in each iteration */
- __asm__ __volatile__ (
- /* load data for start of next scan line */
- "movd (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */
- "movd (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */
- "movq (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */
- //".balign 16 \n\t"
- "1: \n\t"
-YUV2RGB
+ YUV422_UNSHIFT
+ YUV2RGB_LOOP(2)
+
+ c->blueDither= ff_dither8[y&1];
+ c->greenDither= ff_dither8[y&1];
+ c->redDither= ff_dither8[(y+1)&1];
+
+ YUV2RGB_INIT
+ YUV2RGB
#ifdef DITHER1XBPP
- "paddusb "MANGLE(b5Dither)", %%mm0 \n\t"
- "paddusb "MANGLE(g5Dither)", %%mm2 \n\t"
- "paddusb "MANGLE(r5Dither)", %%mm1 \n\t"
+ "paddusb "BLUE_DITHER"(%4), %%mm0 \n\t"
+ "paddusb "GREEN_DITHER"(%4), %%mm2 \n\t"
+ "paddusb "RED_DITHER"(%4), %%mm1 \n\t"
#endif
/* mask unneeded bits off */
"movq %%mm0, %%mm5;" /* Copy B7-B0 */
"movq %%mm2, %%mm7;" /* Copy G7-G0 */
- /* convert rgb24 plane to rgb16 pack for pixel 0-3 */
+ /* convert RGB24 plane to RGB16 pack for pixel 0-3 */
"punpcklbw %%mm4, %%mm2;" /* 0_0_0_0 0_0_0_0 g7g6g5g4 g3_0_0_0 */
"punpcklbw %%mm1, %%mm0;" /* r7r6r5r4 r3_0_0_0 0_0_0_b7 b6b5b4b3 */
"movq 8 (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */
MOVNTQ " %%mm0, (%1);" /* store pixel 0-3 */
- /* convert rgb24 plane to rgb16 pack for pixel 0-3 */
+ /* convert RGB24 plane to RGB16 pack for pixel 0-3 */
"punpckhbw %%mm4, %%mm7;" /* 0_0_0_0 0_0_0_0 0_g7g6g5 g4g3_0_0 */
"punpckhbw %%mm1, %%mm5;" /* r7r6r5r4 r3_0_0_0 0_0_0_b7 b6b5b4b3 */
MOVNTQ " %%mm5, 8 (%1);" /* store pixel 4-7 */
- "add $16, %1 \n\t"
- "add $4, %0 \n\t"
- " js 1b \n\t"
- : "+r" (index), "+r" (_image)
- : "r" (_pu - index), "r" (_pv - index), "r"(&c->redDither), "r" (_py - 2*index)
- );
- }
-
- __asm__ __volatile__ (EMMS);
- return srcSliceH;
+ YUV2RGB_ENDLOOP(2)
+ YUV2RGB_OPERANDS
}
static inline int RENAME(yuv420_rgb24)(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
int srcSliceH, uint8_t* dst[], int dstStride[]){
int y, h_size;
- if(c->srcFormat == PIX_FMT_YUV422P){
- srcStride[1] *= 2;
- srcStride[2] *= 2;
- }
-
- h_size= (c->dstW+7)&~7;
- if(h_size*3 > FFABS(dstStride[0])) h_size-=8;
-
- __asm__ __volatile__ ("pxor %mm4, %mm4;" /* zero mm4 */ );
-
- for (y= 0; y<srcSliceH; y++ ) {
- uint8_t *_image = dst[0] + (y+srcSliceY)*dstStride[0];
- uint8_t *_py = src[0] + y*srcStride[0];
- uint8_t *_pu = src[1] + (y>>1)*srcStride[1];
- uint8_t *_pv = src[2] + (y>>1)*srcStride[2];
- long index= -h_size/2;
-
- /* this mmx assembly code deals with SINGLE scan line at a time, it convert 8
- pixels in each iteration */
- __asm__ __volatile__ (
- /* load data for start of next scan line */
- "movd (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */
- "movd (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */
- "movq (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */
- //".balign 16 \n\t"
- "1: \n\t"
-YUV2RGB
+ YUV422_UNSHIFT
+ YUV2RGB_LOOP(3)
+
+ YUV2RGB_INIT
+ YUV2RGB
/* mm0=B, %%mm2=G, %%mm1=R */
-#ifdef HAVE_MMX2
- "movq "MANGLE(M24A)", %%mm4 \n\t"
- "movq "MANGLE(M24C)", %%mm7 \n\t"
+#if HAVE_MMX2
+ "movq "MANGLE(ff_M24A)", %%mm4 \n\t"
+ "movq "MANGLE(ff_M24C)", %%mm7 \n\t"
"pshufw $0x50, %%mm0, %%mm5 \n\t" /* B3 B2 B3 B2 B1 B0 B1 B0 */
"pshufw $0x50, %%mm2, %%mm3 \n\t" /* G3 G2 G3 G2 G1 G0 G1 G0 */
"pshufw $0x00, %%mm1, %%mm6 \n\t" /* R1 R0 R1 R0 R1 R0 R1 R0 */
"pshufw $0x55, %%mm2, %%mm3 \n\t" /* G4 G3 G4 G3 G4 G3 G4 G3 */
"pshufw $0xA5, %%mm1, %%mm6 \n\t" /* R5 R4 R5 R4 R3 R2 R3 R2 */
- "pand "MANGLE(M24B)", %%mm5 \n\t" /* B5 B4 B3 */
+ "pand "MANGLE(ff_M24B)", %%mm5 \n\t" /* B5 B4 B3 */
"pand %%mm7, %%mm3 \n\t" /* G4 G3 */
"pand %%mm4, %%mm6 \n\t" /* R4 R3 R2 */
"pand %%mm7, %%mm5 \n\t" /* B7 B6 */
"pand %%mm4, %%mm3 \n\t" /* G7 G6 G5 */
- "pand "MANGLE(M24B)", %%mm6 \n\t" /* R7 R6 R5 */
+ "pand "MANGLE(ff_M24B)", %%mm6 \n\t" /* R7 R6 R5 */
"movd 4 (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */
\
"por %%mm5, %%mm3 \n\t"
"pxor %%mm4, %%mm4 \n\t"
#endif
- "add $24, %1 \n\t"
- "add $4, %0 \n\t"
- " js 1b \n\t"
-
- : "+r" (index), "+r" (_image)
- : "r" (_pu - index), "r" (_pv - index), "r"(&c->redDither), "r" (_py - 2*index)
- );
- }
-
- __asm__ __volatile__ (EMMS);
- return srcSliceH;
+ YUV2RGB_ENDLOOP(3)
+ YUV2RGB_OPERANDS
}
+#define RGB_PLANAR2PACKED32 \
+ /* convert RGB plane to RGB packed format, \
+ mm0 -> B, mm1 -> R, mm2 -> G, mm3 -> A, \
+ mm4 -> GB, mm5 -> AR pixel 4-7, \
+ mm6 -> GB, mm7 -> AR pixel 0-3 */ \
+ "movq %%mm0, %%mm6;" /* B7 B6 B5 B4 B3 B2 B1 B0 */ \
+ "movq %%mm1, %%mm7;" /* R7 R6 R5 R4 R3 R2 R1 R0 */ \
+\
+ "movq %%mm0, %%mm4;" /* B7 B6 B5 B4 B3 B2 B1 B0 */ \
+ "movq %%mm1, %%mm5;" /* R7 R6 R5 R4 R3 R2 R1 R0 */ \
+\
+ "punpcklbw %%mm2, %%mm6;" /* G3 B3 G2 B2 G1 B1 G0 B0 */ \
+ "punpcklbw %%mm3, %%mm7;" /* A3 R3 A2 R2 A1 R1 A0 R0 */ \
+\
+ "punpcklwd %%mm7, %%mm6;" /* A1 R1 B1 G1 A0 R0 B0 G0 */ \
+ MOVNTQ " %%mm6, (%1);" /* Store ARGB1 ARGB0 */ \
+\
+ "movq %%mm0, %%mm6;" /* B7 B6 B5 B4 B3 B2 B1 B0 */ \
+ "punpcklbw %%mm2, %%mm6;" /* G3 B3 G2 B2 G1 B1 G0 B0 */ \
+\
+ "punpckhwd %%mm7, %%mm6;" /* A3 R3 G3 B3 A2 R2 B3 G2 */ \
+ MOVNTQ " %%mm6, 8 (%1);" /* Store ARGB3 ARGB2 */ \
+\
+ "punpckhbw %%mm2, %%mm4;" /* G7 B7 G6 B6 G5 B5 G4 B4 */ \
+ "punpckhbw %%mm3, %%mm5;" /* A7 R7 A6 R6 A5 R5 A4 R4 */ \
+\
+ "punpcklwd %%mm5, %%mm4;" /* A5 R5 B5 G5 A4 R4 B4 G4 */ \
+ MOVNTQ " %%mm4, 16 (%1);" /* Store ARGB5 ARGB4 */ \
+\
+ "movq %%mm0, %%mm4;" /* B7 B6 B5 B4 B3 B2 B1 B0 */ \
+ "punpckhbw %%mm2, %%mm4;" /* G7 B7 G6 B6 G5 B5 G4 B4 */ \
+\
+ "punpckhwd %%mm5, %%mm4;" /* A7 R7 G7 B7 A6 R6 B6 G6 */ \
+ MOVNTQ " %%mm4, 24 (%1);" /* Store ARGB7 ARGB6 */ \
+\
+ "movd 4 (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ \
+ "movd 4 (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */ \
+\
+ "pxor %%mm4, %%mm4;" /* zero mm4 */ \
+ "movq 8 (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \
+
static inline int RENAME(yuv420_rgb32)(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY,
int srcSliceH, uint8_t* dst[], int dstStride[]){
int y, h_size;
- if(c->srcFormat == PIX_FMT_YUV422P){
- srcStride[1] *= 2;
- srcStride[2] *= 2;
- }
-
- h_size= (c->dstW+7)&~7;
- if(h_size*4 > FFABS(dstStride[0])) h_size-=8;
-
- __asm__ __volatile__ ("pxor %mm4, %mm4;" /* zero mm4 */ );
-
- for (y= 0; y<srcSliceH; y++ ) {
- uint8_t *_image = dst[0] + (y+srcSliceY)*dstStride[0];
- uint8_t *_py = src[0] + y*srcStride[0];
- uint8_t *_pu = src[1] + (y>>1)*srcStride[1];
- uint8_t *_pv = src[2] + (y>>1)*srcStride[2];
- long index= -h_size/2;
-
- /* this mmx assembly code deals with SINGLE scan line at a time, it convert 8
- pixels in each iteration */
- __asm__ __volatile__ (
- /* load data for start of next scan line */
- "movd (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */
- "movd (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */
- "movq (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */
- //".balign 16 \n\t"
- "1: \n\t"
-YUV2RGB
- /* convert RGB plane to RGB packed format,
- mm0 -> B, mm1 -> R, mm2 -> G, mm3 -> 0,
- mm4 -> GB, mm5 -> AR pixel 4-7,
- mm6 -> GB, mm7 -> AR pixel 0-3 */
- "pxor %%mm3, %%mm3;" /* zero mm3 */
-
- "movq %%mm0, %%mm6;" /* B7 B6 B5 B4 B3 B2 B1 B0 */
- "movq %%mm1, %%mm7;" /* R7 R6 R5 R4 R3 R2 R1 R0 */
-
- "movq %%mm0, %%mm4;" /* B7 B6 B5 B4 B3 B2 B1 B0 */
- "movq %%mm1, %%mm5;" /* R7 R6 R5 R4 R3 R2 R1 R0 */
-
- "punpcklbw %%mm2, %%mm6;" /* G3 B3 G2 B2 G1 B1 G0 B0 */
- "punpcklbw %%mm3, %%mm7;" /* 00 R3 00 R2 00 R1 00 R0 */
-
- "punpcklwd %%mm7, %%mm6;" /* 00 R1 B1 G1 00 R0 B0 G0 */
- MOVNTQ " %%mm6, (%1);" /* Store ARGB1 ARGB0 */
-
- "movq %%mm0, %%mm6;" /* B7 B6 B5 B4 B3 B2 B1 B0 */
- "punpcklbw %%mm2, %%mm6;" /* G3 B3 G2 B2 G1 B1 G0 B0 */
-
- "punpckhwd %%mm7, %%mm6;" /* 00 R3 G3 B3 00 R2 B3 G2 */
- MOVNTQ " %%mm6, 8 (%1);" /* Store ARGB3 ARGB2 */
-
- "punpckhbw %%mm2, %%mm4;" /* G7 B7 G6 B6 G5 B5 G4 B4 */
- "punpckhbw %%mm3, %%mm5;" /* 00 R7 00 R6 00 R5 00 R4 */
-
- "punpcklwd %%mm5, %%mm4;" /* 00 R5 B5 G5 00 R4 B4 G4 */
- MOVNTQ " %%mm4, 16 (%1);" /* Store ARGB5 ARGB4 */
-
- "movq %%mm0, %%mm4;" /* B7 B6 B5 B4 B3 B2 B1 B0 */
- "punpckhbw %%mm2, %%mm4;" /* G7 B7 G6 B6 G5 B5 G4 B4 */
-
- "punpckhwd %%mm5, %%mm4;" /* 00 R7 G7 B7 00 R6 B6 G6 */
- MOVNTQ " %%mm4, 24 (%1);" /* Store ARGB7 ARGB6 */
-
- "movd 4 (%2, %0), %%mm0;" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */
- "movd 4 (%3, %0), %%mm1;" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */
-
- "pxor %%mm4, %%mm4;" /* zero mm4 */
- "movq 8 (%5, %0, 2), %%mm6;" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */
-
- "add $32, %1 \n\t"
- "add $4, %0 \n\t"
- " js 1b \n\t"
+ YUV422_UNSHIFT
+ YUV2RGB_LOOP(4)
- : "+r" (index), "+r" (_image)
- : "r" (_pu - index), "r" (_pv - index), "r"(&c->redDither), "r" (_py - 2*index)
- );
- }
+ YUV2RGB_INIT
+ YUV2RGB
+ "pcmpeqd %%mm3, %%mm3;" /* fill mm3 */
+ RGB_PLANAR2PACKED32
- __asm__ __volatile__ (EMMS);
- return srcSliceH;
+ YUV2RGB_ENDLOOP(4)
+ YUV2RGB_OPERANDS
}