michael@0: // Copyright (c) 2010 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #include "yuv_row.h" michael@0: #include "mozilla/SSE.h" michael@0: michael@0: #define DCHECK(a) michael@0: michael@0: extern "C" { michael@0: michael@0: #if defined(ARCH_CPU_X86_64) michael@0: michael@0: // We don't need CPUID guards here, since x86-64 implies SSE2. michael@0: michael@0: // AMD64 ABI uses register paremters. michael@0: void FastConvertYUVToRGB32Row(const uint8* y_buf, // rdi michael@0: const uint8* u_buf, // rsi michael@0: const uint8* v_buf, // rdx michael@0: uint8* rgb_buf, // rcx michael@0: int width) { // r8 michael@0: asm( michael@0: "jmp 1f\n" michael@0: "0:" michael@0: "movzb (%1),%%r10\n" michael@0: "add $0x1,%1\n" michael@0: "movzb (%2),%%r11\n" michael@0: "add $0x1,%2\n" michael@0: "movq 2048(%5,%%r10,8),%%xmm0\n" michael@0: "movzb (%0),%%r10\n" michael@0: "movq 4096(%5,%%r11,8),%%xmm1\n" michael@0: "movzb 0x1(%0),%%r11\n" michael@0: "paddsw %%xmm1,%%xmm0\n" michael@0: "movq (%5,%%r10,8),%%xmm2\n" michael@0: "add $0x2,%0\n" michael@0: "movq (%5,%%r11,8),%%xmm3\n" michael@0: "paddsw %%xmm0,%%xmm2\n" michael@0: "paddsw %%xmm0,%%xmm3\n" michael@0: "shufps $0x44,%%xmm3,%%xmm2\n" michael@0: "psraw $0x6,%%xmm2\n" michael@0: "packuswb %%xmm2,%%xmm2\n" michael@0: "movq %%xmm2,0x0(%3)\n" michael@0: "add $0x8,%3\n" michael@0: "1:" michael@0: "sub $0x2,%4\n" michael@0: "jns 0b\n" michael@0: michael@0: "2:" michael@0: "add $0x1,%4\n" michael@0: "js 3f\n" michael@0: michael@0: "movzb (%1),%%r10\n" michael@0: "movq 2048(%5,%%r10,8),%%xmm0\n" michael@0: "movzb (%2),%%r10\n" michael@0: "movq 4096(%5,%%r10,8),%%xmm1\n" michael@0: "paddsw %%xmm1,%%xmm0\n" michael@0: "movzb (%0),%%r10\n" michael@0: "movq (%5,%%r10,8),%%xmm1\n" michael@0: "paddsw %%xmm0,%%xmm1\n" michael@0: "psraw $0x6,%%xmm1\n" michael@0: "packuswb %%xmm1,%%xmm1\n" michael@0: "movd %%xmm1,0x0(%3)\n" michael@0: "3:" michael@0: : michael@0: : "r"(y_buf), // %0 michael@0: "r"(u_buf), // %1 michael@0: "r"(v_buf), // %2 michael@0: "r"(rgb_buf), // %3 michael@0: "r"(width), // %4 michael@0: "r" (kCoefficientsRgbY) // %5 michael@0: : "memory", "r10", "r11", "xmm0", "xmm1", "xmm2", "xmm3" michael@0: ); michael@0: } michael@0: michael@0: void ScaleYUVToRGB32Row(const uint8* y_buf, // rdi michael@0: const uint8* u_buf, // rsi michael@0: const uint8* v_buf, // rdx michael@0: uint8* rgb_buf, // rcx michael@0: int width, // r8 michael@0: int source_dx) { // r9 michael@0: asm( michael@0: "xor %%r11,%%r11\n" michael@0: "sub $0x2,%4\n" michael@0: "js 1f\n" michael@0: michael@0: "0:" michael@0: "mov %%r11,%%r10\n" michael@0: "sar $0x11,%%r10\n" michael@0: "movzb (%1,%%r10,1),%%rax\n" michael@0: "movq 2048(%5,%%rax,8),%%xmm0\n" michael@0: "movzb (%2,%%r10,1),%%rax\n" michael@0: "movq 4096(%5,%%rax,8),%%xmm1\n" michael@0: "lea (%%r11,%6),%%r10\n" michael@0: "sar $0x10,%%r11\n" michael@0: "movzb (%0,%%r11,1),%%rax\n" michael@0: "paddsw %%xmm1,%%xmm0\n" michael@0: "movq (%5,%%rax,8),%%xmm1\n" michael@0: "lea (%%r10,%6),%%r11\n" michael@0: "sar $0x10,%%r10\n" michael@0: "movzb (%0,%%r10,1),%%rax\n" michael@0: "movq (%5,%%rax,8),%%xmm2\n" michael@0: "paddsw %%xmm0,%%xmm1\n" michael@0: "paddsw %%xmm0,%%xmm2\n" michael@0: "shufps $0x44,%%xmm2,%%xmm1\n" michael@0: "psraw $0x6,%%xmm1\n" michael@0: "packuswb %%xmm1,%%xmm1\n" michael@0: "movq %%xmm1,0x0(%3)\n" michael@0: "add $0x8,%3\n" michael@0: "sub $0x2,%4\n" michael@0: "jns 0b\n" michael@0: michael@0: "1:" michael@0: "add $0x1,%4\n" michael@0: "js 2f\n" michael@0: michael@0: "mov %%r11,%%r10\n" michael@0: "sar $0x11,%%r10\n" michael@0: "movzb (%1,%%r10,1),%%rax\n" michael@0: "movq 2048(%5,%%rax,8),%%xmm0\n" michael@0: "movzb (%2,%%r10,1),%%rax\n" michael@0: "movq 4096(%5,%%rax,8),%%xmm1\n" michael@0: "paddsw %%xmm1,%%xmm0\n" michael@0: "sar $0x10,%%r11\n" michael@0: "movzb (%0,%%r11,1),%%rax\n" michael@0: "movq (%5,%%rax,8),%%xmm1\n" michael@0: "paddsw %%xmm0,%%xmm1\n" michael@0: "psraw $0x6,%%xmm1\n" michael@0: "packuswb %%xmm1,%%xmm1\n" michael@0: "movd %%xmm1,0x0(%3)\n" michael@0: michael@0: "2:" michael@0: : michael@0: : "r"(y_buf), // %0 michael@0: "r"(u_buf), // %1 michael@0: "r"(v_buf), // %2 michael@0: "r"(rgb_buf), // %3 michael@0: "r"(width), // %4 michael@0: "r" (kCoefficientsRgbY), // %5 michael@0: "r"(static_cast(source_dx)) // %6 michael@0: : "memory", "r10", "r11", "rax", "xmm0", "xmm1", "xmm2" michael@0: ); michael@0: } michael@0: michael@0: void LinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx) { michael@0: asm( michael@0: "xor %%r11,%%r11\n" // x = 0 michael@0: "sub $0x2,%4\n" michael@0: "js 2f\n" michael@0: "cmp $0x20000,%6\n" // if source_dx >= 2.0 michael@0: "jl 0f\n" michael@0: "mov $0x8000,%%r11\n" // x = 0.5 for 1/2 or less michael@0: "0:" michael@0: michael@0: "1:" michael@0: "mov %%r11,%%r10\n" michael@0: "sar $0x11,%%r10\n" michael@0: michael@0: "movzb (%1, %%r10, 1), %%r13 \n" michael@0: "movzb 1(%1, %%r10, 1), %%r14 \n" michael@0: "mov %%r11, %%rax \n" michael@0: "and $0x1fffe, %%rax \n" michael@0: "imul %%rax, %%r14 \n" michael@0: "xor $0x1fffe, %%rax \n" michael@0: "imul %%rax, %%r13 \n" michael@0: "add %%r14, %%r13 \n" michael@0: "shr $17, %%r13 \n" michael@0: "movq 2048(%5,%%r13,8), %%xmm0\n" michael@0: michael@0: "movzb (%2, %%r10, 1), %%r13 \n" michael@0: "movzb 1(%2, %%r10, 1), %%r14 \n" michael@0: "mov %%r11, %%rax \n" michael@0: "and $0x1fffe, %%rax \n" michael@0: "imul %%rax, %%r14 \n" michael@0: "xor $0x1fffe, %%rax \n" michael@0: "imul %%rax, %%r13 \n" michael@0: "add %%r14, %%r13 \n" michael@0: "shr $17, %%r13 \n" michael@0: "movq 4096(%5,%%r13,8), %%xmm1\n" michael@0: michael@0: "mov %%r11, %%rax \n" michael@0: "lea (%%r11,%6),%%r10\n" michael@0: "sar $0x10,%%r11\n" michael@0: "paddsw %%xmm1,%%xmm0\n" michael@0: michael@0: "movzb (%0, %%r11, 1), %%r13 \n" michael@0: "movzb 1(%0, %%r11, 1), %%r14 \n" michael@0: "and $0xffff, %%rax \n" michael@0: "imul %%rax, %%r14 \n" michael@0: "xor $0xffff, %%rax \n" michael@0: "imul %%rax, %%r13 \n" michael@0: "add %%r14, %%r13 \n" michael@0: "shr $16, %%r13 \n" michael@0: "movq (%5,%%r13,8),%%xmm1\n" michael@0: michael@0: "mov %%r10, %%rax \n" michael@0: "lea (%%r10,%6),%%r11\n" michael@0: "sar $0x10,%%r10\n" michael@0: michael@0: "movzb (%0,%%r10,1), %%r13 \n" michael@0: "movzb 1(%0,%%r10,1), %%r14 \n" michael@0: "and $0xffff, %%rax \n" michael@0: "imul %%rax, %%r14 \n" michael@0: "xor $0xffff, %%rax \n" michael@0: "imul %%rax, %%r13 \n" michael@0: "add %%r14, %%r13 \n" michael@0: "shr $16, %%r13 \n" michael@0: "movq (%5,%%r13,8),%%xmm2\n" michael@0: michael@0: "paddsw %%xmm0,%%xmm1\n" michael@0: "paddsw %%xmm0,%%xmm2\n" michael@0: "shufps $0x44,%%xmm2,%%xmm1\n" michael@0: "psraw $0x6,%%xmm1\n" michael@0: "packuswb %%xmm1,%%xmm1\n" michael@0: "movq %%xmm1,0x0(%3)\n" michael@0: "add $0x8,%3\n" michael@0: "sub $0x2,%4\n" michael@0: "jns 1b\n" michael@0: michael@0: "2:" michael@0: "add $0x1,%4\n" michael@0: "js 3f\n" michael@0: michael@0: "mov %%r11,%%r10\n" michael@0: "sar $0x11,%%r10\n" michael@0: michael@0: "movzb (%1,%%r10,1), %%r13 \n" michael@0: "movq 2048(%5,%%r13,8),%%xmm0\n" michael@0: michael@0: "movzb (%2,%%r10,1), %%r13 \n" michael@0: "movq 4096(%5,%%r13,8),%%xmm1\n" michael@0: michael@0: "paddsw %%xmm1,%%xmm0\n" michael@0: "sar $0x10,%%r11\n" michael@0: michael@0: "movzb (%0,%%r11,1), %%r13 \n" michael@0: "movq (%5,%%r13,8),%%xmm1\n" michael@0: michael@0: "paddsw %%xmm0,%%xmm1\n" michael@0: "psraw $0x6,%%xmm1\n" michael@0: "packuswb %%xmm1,%%xmm1\n" michael@0: "movd %%xmm1,0x0(%3)\n" michael@0: michael@0: "3:" michael@0: : michael@0: : "r"(y_buf), // %0 michael@0: "r"(u_buf), // %1 michael@0: "r"(v_buf), // %2 michael@0: "r"(rgb_buf), // %3 michael@0: "r"(width), // %4 michael@0: "r" (kCoefficientsRgbY), // %5 michael@0: "r"(static_cast(source_dx)) // %6 michael@0: : "memory", "r10", "r11", "r13", "r14", "rax", "xmm0", "xmm1", "xmm2" michael@0: ); michael@0: } michael@0: michael@0: #elif defined(MOZILLA_MAY_SUPPORT_SSE) && defined(ARCH_CPU_X86_32) && !defined(__PIC__) michael@0: michael@0: // PIC version is slower because less registers are available, so michael@0: // non-PIC is used on platforms where it is possible. michael@0: void FastConvertYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width); michael@0: asm( michael@0: ".text\n" michael@0: ".global FastConvertYUVToRGB32Row_SSE\n" michael@0: ".type FastConvertYUVToRGB32Row_SSE, @function\n" michael@0: "FastConvertYUVToRGB32Row_SSE:\n" michael@0: "pusha\n" michael@0: "mov 0x24(%esp),%edx\n" michael@0: "mov 0x28(%esp),%edi\n" michael@0: "mov 0x2c(%esp),%esi\n" michael@0: "mov 0x30(%esp),%ebp\n" michael@0: "mov 0x34(%esp),%ecx\n" michael@0: "jmp 1f\n" michael@0: michael@0: "0:" michael@0: "movzbl (%edi),%eax\n" michael@0: "add $0x1,%edi\n" michael@0: "movzbl (%esi),%ebx\n" michael@0: "add $0x1,%esi\n" michael@0: "movq kCoefficientsRgbY+2048(,%eax,8),%mm0\n" michael@0: "movzbl (%edx),%eax\n" michael@0: "paddsw kCoefficientsRgbY+4096(,%ebx,8),%mm0\n" michael@0: "movzbl 0x1(%edx),%ebx\n" michael@0: "movq kCoefficientsRgbY(,%eax,8),%mm1\n" michael@0: "add $0x2,%edx\n" michael@0: "movq kCoefficientsRgbY(,%ebx,8),%mm2\n" michael@0: "paddsw %mm0,%mm1\n" michael@0: "paddsw %mm0,%mm2\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "psraw $0x6,%mm2\n" michael@0: "packuswb %mm2,%mm1\n" michael@0: "movntq %mm1,0x0(%ebp)\n" michael@0: "add $0x8,%ebp\n" michael@0: "1:" michael@0: "sub $0x2,%ecx\n" michael@0: "jns 0b\n" michael@0: michael@0: "and $0x1,%ecx\n" michael@0: "je 2f\n" michael@0: michael@0: "movzbl (%edi),%eax\n" michael@0: "movq kCoefficientsRgbY+2048(,%eax,8),%mm0\n" michael@0: "movzbl (%esi),%eax\n" michael@0: "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n" michael@0: "movzbl (%edx),%eax\n" michael@0: "movq kCoefficientsRgbY(,%eax,8),%mm1\n" michael@0: "paddsw %mm0,%mm1\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "packuswb %mm1,%mm1\n" michael@0: "movd %mm1,0x0(%ebp)\n" michael@0: "2:" michael@0: "popa\n" michael@0: "ret\n" michael@0: #if !defined(XP_MACOSX) michael@0: ".previous\n" michael@0: #endif michael@0: ); michael@0: michael@0: void FastConvertYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width) michael@0: { michael@0: if (mozilla::supports_sse()) { michael@0: FastConvertYUVToRGB32Row_SSE(y_buf, u_buf, v_buf, rgb_buf, width); michael@0: return; michael@0: } michael@0: michael@0: FastConvertYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, 1); michael@0: } michael@0: michael@0: michael@0: void ScaleYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx); michael@0: asm( michael@0: ".text\n" michael@0: ".global ScaleYUVToRGB32Row_SSE\n" michael@0: ".type ScaleYUVToRGB32Row_SSE, @function\n" michael@0: "ScaleYUVToRGB32Row_SSE:\n" michael@0: "pusha\n" michael@0: "mov 0x24(%esp),%edx\n" michael@0: "mov 0x28(%esp),%edi\n" michael@0: "mov 0x2c(%esp),%esi\n" michael@0: "mov 0x30(%esp),%ebp\n" michael@0: "mov 0x34(%esp),%ecx\n" michael@0: "xor %ebx,%ebx\n" michael@0: "jmp 1f\n" michael@0: michael@0: "0:" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: "movzbl (%edi,%eax,1),%eax\n" michael@0: "movq kCoefficientsRgbY+2048(,%eax,8),%mm0\n" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: "movzbl (%esi,%eax,1),%eax\n" michael@0: "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n" michael@0: "mov %ebx,%eax\n" michael@0: "add 0x38(%esp),%ebx\n" michael@0: "sar $0x10,%eax\n" michael@0: "movzbl (%edx,%eax,1),%eax\n" michael@0: "movq kCoefficientsRgbY(,%eax,8),%mm1\n" michael@0: "mov %ebx,%eax\n" michael@0: "add 0x38(%esp),%ebx\n" michael@0: "sar $0x10,%eax\n" michael@0: "movzbl (%edx,%eax,1),%eax\n" michael@0: "movq kCoefficientsRgbY(,%eax,8),%mm2\n" michael@0: "paddsw %mm0,%mm1\n" michael@0: "paddsw %mm0,%mm2\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "psraw $0x6,%mm2\n" michael@0: "packuswb %mm2,%mm1\n" michael@0: "movntq %mm1,0x0(%ebp)\n" michael@0: "add $0x8,%ebp\n" michael@0: "1:" michael@0: "sub $0x2,%ecx\n" michael@0: "jns 0b\n" michael@0: michael@0: "and $0x1,%ecx\n" michael@0: "je 2f\n" michael@0: michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: "movzbl (%edi,%eax,1),%eax\n" michael@0: "movq kCoefficientsRgbY+2048(,%eax,8),%mm0\n" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: "movzbl (%esi,%eax,1),%eax\n" michael@0: "paddsw kCoefficientsRgbY+4096(,%eax,8),%mm0\n" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x10,%eax\n" michael@0: "movzbl (%edx,%eax,1),%eax\n" michael@0: "movq kCoefficientsRgbY(,%eax,8),%mm1\n" michael@0: "paddsw %mm0,%mm1\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "packuswb %mm1,%mm1\n" michael@0: "movd %mm1,0x0(%ebp)\n" michael@0: michael@0: "2:" michael@0: "popa\n" michael@0: "ret\n" michael@0: #if !defined(XP_MACOSX) michael@0: ".previous\n" michael@0: #endif michael@0: ); michael@0: michael@0: void ScaleYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx) michael@0: { michael@0: if (mozilla::supports_sse()) { michael@0: ScaleYUVToRGB32Row_SSE(y_buf, u_buf, v_buf, rgb_buf, michael@0: width, source_dx); michael@0: } michael@0: michael@0: ScaleYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, michael@0: width, source_dx); michael@0: } michael@0: michael@0: void LinearScaleYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx); michael@0: asm( michael@0: ".text\n" michael@0: ".global LinearScaleYUVToRGB32Row_SSE\n" michael@0: ".type LinearScaleYUVToRGB32Row_SSE, @function\n" michael@0: "LinearScaleYUVToRGB32Row_SSE:\n" michael@0: "pusha\n" michael@0: "mov 0x24(%esp),%edx\n" michael@0: "mov 0x28(%esp),%edi\n" michael@0: "mov 0x30(%esp),%ebp\n" michael@0: michael@0: // source_width = width * source_dx + ebx michael@0: "mov 0x34(%esp), %ecx\n" michael@0: "imull 0x38(%esp), %ecx\n" michael@0: "mov %ecx, 0x34(%esp)\n" michael@0: michael@0: "mov 0x38(%esp), %ecx\n" michael@0: "xor %ebx,%ebx\n" // x = 0 michael@0: "cmp $0x20000,%ecx\n" // if source_dx >= 2.0 michael@0: "jl 1f\n" michael@0: "mov $0x8000,%ebx\n" // x = 0.5 for 1/2 or less michael@0: "jmp 1f\n" michael@0: michael@0: "0:" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: michael@0: "movzbl (%edi,%eax,1),%ecx\n" michael@0: "movzbl 1(%edi,%eax,1),%esi\n" michael@0: "mov %ebx,%eax\n" michael@0: "andl $0x1fffe, %eax \n" michael@0: "imul %eax, %esi \n" michael@0: "xorl $0x1fffe, %eax \n" michael@0: "imul %eax, %ecx \n" michael@0: "addl %esi, %ecx \n" michael@0: "shrl $17, %ecx \n" michael@0: "movq kCoefficientsRgbY+2048(,%ecx,8),%mm0\n" michael@0: michael@0: "mov 0x2c(%esp),%esi\n" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: michael@0: "movzbl (%esi,%eax,1),%ecx\n" michael@0: "movzbl 1(%esi,%eax,1),%esi\n" michael@0: "mov %ebx,%eax\n" michael@0: "andl $0x1fffe, %eax \n" michael@0: "imul %eax, %esi \n" michael@0: "xorl $0x1fffe, %eax \n" michael@0: "imul %eax, %ecx \n" michael@0: "addl %esi, %ecx \n" michael@0: "shrl $17, %ecx \n" michael@0: "paddsw kCoefficientsRgbY+4096(,%ecx,8),%mm0\n" michael@0: michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x10,%eax\n" michael@0: "movzbl (%edx,%eax,1),%ecx\n" michael@0: "movzbl 1(%edx,%eax,1),%esi\n" michael@0: "mov %ebx,%eax\n" michael@0: "add 0x38(%esp),%ebx\n" michael@0: "andl $0xffff, %eax \n" michael@0: "imul %eax, %esi \n" michael@0: "xorl $0xffff, %eax \n" michael@0: "imul %eax, %ecx \n" michael@0: "addl %esi, %ecx \n" michael@0: "shrl $16, %ecx \n" michael@0: "movq kCoefficientsRgbY(,%ecx,8),%mm1\n" michael@0: michael@0: "cmp 0x34(%esp), %ebx\n" michael@0: "jge 2f\n" michael@0: michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x10,%eax\n" michael@0: "movzbl (%edx,%eax,1),%ecx\n" michael@0: "movzbl 1(%edx,%eax,1),%esi\n" michael@0: "mov %ebx,%eax\n" michael@0: "add 0x38(%esp),%ebx\n" michael@0: "andl $0xffff, %eax \n" michael@0: "imul %eax, %esi \n" michael@0: "xorl $0xffff, %eax \n" michael@0: "imul %eax, %ecx \n" michael@0: "addl %esi, %ecx \n" michael@0: "shrl $16, %ecx \n" michael@0: "movq kCoefficientsRgbY(,%ecx,8),%mm2\n" michael@0: michael@0: "paddsw %mm0,%mm1\n" michael@0: "paddsw %mm0,%mm2\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "psraw $0x6,%mm2\n" michael@0: "packuswb %mm2,%mm1\n" michael@0: "movntq %mm1,0x0(%ebp)\n" michael@0: "add $0x8,%ebp\n" michael@0: michael@0: "1:" michael@0: "cmp 0x34(%esp), %ebx\n" michael@0: "jl 0b\n" michael@0: "popa\n" michael@0: "ret\n" michael@0: michael@0: "2:" michael@0: "paddsw %mm0, %mm1\n" michael@0: "psraw $6, %mm1\n" michael@0: "packuswb %mm1, %mm1\n" michael@0: "movd %mm1, (%ebp)\n" michael@0: "popa\n" michael@0: "ret\n" michael@0: #if !defined(XP_MACOSX) michael@0: ".previous\n" michael@0: #endif michael@0: ); michael@0: michael@0: void LinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx) michael@0: { michael@0: if (mozilla::supports_sse()) { michael@0: LinearScaleYUVToRGB32Row_SSE(y_buf, u_buf, v_buf, rgb_buf, michael@0: width, source_dx); michael@0: } michael@0: michael@0: LinearScaleYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, michael@0: width, source_dx); michael@0: } michael@0: michael@0: #elif defined(MOZILLA_MAY_SUPPORT_SSE) && defined(ARCH_CPU_X86_32) && defined(__PIC__) michael@0: michael@0: void PICConvertYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int16 *kCoefficientsRgbY); michael@0: michael@0: asm( michael@0: ".text\n" michael@0: #if defined(XP_MACOSX) michael@0: "_PICConvertYUVToRGB32Row_SSE:\n" michael@0: #else michael@0: "PICConvertYUVToRGB32Row_SSE:\n" michael@0: #endif michael@0: "pusha\n" michael@0: "mov 0x24(%esp),%edx\n" michael@0: "mov 0x28(%esp),%edi\n" michael@0: "mov 0x2c(%esp),%esi\n" michael@0: "mov 0x30(%esp),%ebp\n" michael@0: "mov 0x38(%esp),%ecx\n" michael@0: michael@0: "jmp 1f\n" michael@0: michael@0: "0:" michael@0: "movzbl (%edi),%eax\n" michael@0: "add $0x1,%edi\n" michael@0: "movzbl (%esi),%ebx\n" michael@0: "add $0x1,%esi\n" michael@0: "movq 2048(%ecx,%eax,8),%mm0\n" michael@0: "movzbl (%edx),%eax\n" michael@0: "paddsw 4096(%ecx,%ebx,8),%mm0\n" michael@0: "movzbl 0x1(%edx),%ebx\n" michael@0: "movq 0(%ecx,%eax,8),%mm1\n" michael@0: "add $0x2,%edx\n" michael@0: "movq 0(%ecx,%ebx,8),%mm2\n" michael@0: "paddsw %mm0,%mm1\n" michael@0: "paddsw %mm0,%mm2\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "psraw $0x6,%mm2\n" michael@0: "packuswb %mm2,%mm1\n" michael@0: "movntq %mm1,0x0(%ebp)\n" michael@0: "add $0x8,%ebp\n" michael@0: "1:" michael@0: "subl $0x2,0x34(%esp)\n" michael@0: "jns 0b\n" michael@0: michael@0: "andl $0x1,0x34(%esp)\n" michael@0: "je 2f\n" michael@0: michael@0: "movzbl (%edi),%eax\n" michael@0: "movq 2048(%ecx,%eax,8),%mm0\n" michael@0: "movzbl (%esi),%eax\n" michael@0: "paddsw 4096(%ecx,%eax,8),%mm0\n" michael@0: "movzbl (%edx),%eax\n" michael@0: "movq 0(%ecx,%eax,8),%mm1\n" michael@0: "paddsw %mm0,%mm1\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "packuswb %mm1,%mm1\n" michael@0: "movd %mm1,0x0(%ebp)\n" michael@0: "2:" michael@0: "popa\n" michael@0: "ret\n" michael@0: #if !defined(XP_MACOSX) michael@0: ".previous\n" michael@0: #endif michael@0: ); michael@0: michael@0: void FastConvertYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width) michael@0: { michael@0: if (mozilla::supports_sse()) { michael@0: PICConvertYUVToRGB32Row_SSE(y_buf, u_buf, v_buf, rgb_buf, width, michael@0: &kCoefficientsRgbY[0][0]); michael@0: return; michael@0: } michael@0: michael@0: FastConvertYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, 1); michael@0: } michael@0: michael@0: void PICScaleYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx, michael@0: int16 *kCoefficientsRgbY); michael@0: michael@0: asm( michael@0: ".text\n" michael@0: #if defined(XP_MACOSX) michael@0: "_PICScaleYUVToRGB32Row_SSE:\n" michael@0: #else michael@0: "PICScaleYUVToRGB32Row_SSE:\n" michael@0: #endif michael@0: "pusha\n" michael@0: "mov 0x24(%esp),%edx\n" michael@0: "mov 0x28(%esp),%edi\n" michael@0: "mov 0x2c(%esp),%esi\n" michael@0: "mov 0x30(%esp),%ebp\n" michael@0: "mov 0x3c(%esp),%ecx\n" michael@0: "xor %ebx,%ebx\n" michael@0: "jmp 1f\n" michael@0: michael@0: "0:" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: "movzbl (%edi,%eax,1),%eax\n" michael@0: "movq 2048(%ecx,%eax,8),%mm0\n" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: "movzbl (%esi,%eax,1),%eax\n" michael@0: "paddsw 4096(%ecx,%eax,8),%mm0\n" michael@0: "mov %ebx,%eax\n" michael@0: "add 0x38(%esp),%ebx\n" michael@0: "sar $0x10,%eax\n" michael@0: "movzbl (%edx,%eax,1),%eax\n" michael@0: "movq 0(%ecx,%eax,8),%mm1\n" michael@0: "mov %ebx,%eax\n" michael@0: "add 0x38(%esp),%ebx\n" michael@0: "sar $0x10,%eax\n" michael@0: "movzbl (%edx,%eax,1),%eax\n" michael@0: "movq 0(%ecx,%eax,8),%mm2\n" michael@0: "paddsw %mm0,%mm1\n" michael@0: "paddsw %mm0,%mm2\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "psraw $0x6,%mm2\n" michael@0: "packuswb %mm2,%mm1\n" michael@0: "movntq %mm1,0x0(%ebp)\n" michael@0: "add $0x8,%ebp\n" michael@0: "1:" michael@0: "subl $0x2,0x34(%esp)\n" michael@0: "jns 0b\n" michael@0: michael@0: "andl $0x1,0x34(%esp)\n" michael@0: "je 2f\n" michael@0: michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: "movzbl (%edi,%eax,1),%eax\n" michael@0: "movq 2048(%ecx,%eax,8),%mm0\n" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: "movzbl (%esi,%eax,1),%eax\n" michael@0: "paddsw 4096(%ecx,%eax,8),%mm0\n" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x10,%eax\n" michael@0: "movzbl (%edx,%eax,1),%eax\n" michael@0: "movq 0(%ecx,%eax,8),%mm1\n" michael@0: "paddsw %mm0,%mm1\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "packuswb %mm1,%mm1\n" michael@0: "movd %mm1,0x0(%ebp)\n" michael@0: michael@0: "2:" michael@0: "popa\n" michael@0: "ret\n" michael@0: #if !defined(XP_MACOSX) michael@0: ".previous\n" michael@0: #endif michael@0: ); michael@0: michael@0: void ScaleYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx) michael@0: { michael@0: if (mozilla::supports_sse()) { michael@0: PICScaleYUVToRGB32Row_SSE(y_buf, u_buf, v_buf, rgb_buf, width, source_dx, michael@0: &kCoefficientsRgbY[0][0]); michael@0: return; michael@0: } michael@0: michael@0: ScaleYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, source_dx); michael@0: } michael@0: michael@0: void PICLinearScaleYUVToRGB32Row_SSE(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx, michael@0: int16 *kCoefficientsRgbY); michael@0: michael@0: asm( michael@0: ".text\n" michael@0: #if defined(XP_MACOSX) michael@0: "_PICLinearScaleYUVToRGB32Row_SSE:\n" michael@0: #else michael@0: "PICLinearScaleYUVToRGB32Row_SSE:\n" michael@0: #endif michael@0: "pusha\n" michael@0: "mov 0x24(%esp),%edx\n" michael@0: "mov 0x30(%esp),%ebp\n" michael@0: "mov 0x34(%esp),%ecx\n" michael@0: "mov 0x3c(%esp),%edi\n" michael@0: "xor %ebx,%ebx\n" michael@0: michael@0: // source_width = width * source_dx + ebx michael@0: "mov 0x34(%esp), %ecx\n" michael@0: "imull 0x38(%esp), %ecx\n" michael@0: "mov %ecx, 0x34(%esp)\n" michael@0: michael@0: "mov 0x38(%esp), %ecx\n" michael@0: "xor %ebx,%ebx\n" // x = 0 michael@0: "cmp $0x20000,%ecx\n" // if source_dx >= 2.0 michael@0: "jl 1f\n" michael@0: "mov $0x8000,%ebx\n" // x = 0.5 for 1/2 or less michael@0: "jmp 1f\n" michael@0: michael@0: "0:" michael@0: "mov 0x28(%esp),%esi\n" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: michael@0: "movzbl (%esi,%eax,1),%ecx\n" michael@0: "movzbl 1(%esi,%eax,1),%esi\n" michael@0: "mov %ebx,%eax\n" michael@0: "andl $0x1fffe, %eax \n" michael@0: "imul %eax, %esi \n" michael@0: "xorl $0x1fffe, %eax \n" michael@0: "imul %eax, %ecx \n" michael@0: "addl %esi, %ecx \n" michael@0: "shrl $17, %ecx \n" michael@0: "movq 2048(%edi,%ecx,8),%mm0\n" michael@0: michael@0: "mov 0x2c(%esp),%esi\n" michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x11,%eax\n" michael@0: michael@0: "movzbl (%esi,%eax,1),%ecx\n" michael@0: "movzbl 1(%esi,%eax,1),%esi\n" michael@0: "mov %ebx,%eax\n" michael@0: "andl $0x1fffe, %eax \n" michael@0: "imul %eax, %esi \n" michael@0: "xorl $0x1fffe, %eax \n" michael@0: "imul %eax, %ecx \n" michael@0: "addl %esi, %ecx \n" michael@0: "shrl $17, %ecx \n" michael@0: "paddsw 4096(%edi,%ecx,8),%mm0\n" michael@0: michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x10,%eax\n" michael@0: "movzbl (%edx,%eax,1),%ecx\n" michael@0: "movzbl 1(%edx,%eax,1),%esi\n" michael@0: "mov %ebx,%eax\n" michael@0: "add 0x38(%esp),%ebx\n" michael@0: "andl $0xffff, %eax \n" michael@0: "imul %eax, %esi \n" michael@0: "xorl $0xffff, %eax \n" michael@0: "imul %eax, %ecx \n" michael@0: "addl %esi, %ecx \n" michael@0: "shrl $16, %ecx \n" michael@0: "movq (%edi,%ecx,8),%mm1\n" michael@0: michael@0: "cmp 0x34(%esp), %ebx\n" michael@0: "jge 2f\n" michael@0: michael@0: "mov %ebx,%eax\n" michael@0: "sar $0x10,%eax\n" michael@0: "movzbl (%edx,%eax,1),%ecx\n" michael@0: "movzbl 1(%edx,%eax,1),%esi\n" michael@0: "mov %ebx,%eax\n" michael@0: "add 0x38(%esp),%ebx\n" michael@0: "andl $0xffff, %eax \n" michael@0: "imul %eax, %esi \n" michael@0: "xorl $0xffff, %eax \n" michael@0: "imul %eax, %ecx \n" michael@0: "addl %esi, %ecx \n" michael@0: "shrl $16, %ecx \n" michael@0: "movq (%edi,%ecx,8),%mm2\n" michael@0: michael@0: "paddsw %mm0,%mm1\n" michael@0: "paddsw %mm0,%mm2\n" michael@0: "psraw $0x6,%mm1\n" michael@0: "psraw $0x6,%mm2\n" michael@0: "packuswb %mm2,%mm1\n" michael@0: "movntq %mm1,0x0(%ebp)\n" michael@0: "add $0x8,%ebp\n" michael@0: michael@0: "1:" michael@0: "cmp %ebx, 0x34(%esp)\n" michael@0: "jg 0b\n" michael@0: "popa\n" michael@0: "ret\n" michael@0: michael@0: "2:" michael@0: "paddsw %mm0, %mm1\n" michael@0: "psraw $6, %mm1\n" michael@0: "packuswb %mm1, %mm1\n" michael@0: "movd %mm1, (%ebp)\n" michael@0: "popa\n" michael@0: "ret\n" michael@0: #if !defined(XP_MACOSX) michael@0: ".previous\n" michael@0: #endif michael@0: ); michael@0: michael@0: michael@0: void LinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx) michael@0: { michael@0: if (mozilla::supports_sse()) { michael@0: PICLinearScaleYUVToRGB32Row_SSE(y_buf, u_buf, v_buf, rgb_buf, width, michael@0: source_dx, &kCoefficientsRgbY[0][0]); michael@0: return; michael@0: } michael@0: michael@0: LinearScaleYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, source_dx); michael@0: } michael@0: #else michael@0: void FastConvertYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width) { michael@0: FastConvertYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, 1); michael@0: } michael@0: michael@0: void ScaleYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx) { michael@0: ScaleYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, source_dx); michael@0: } michael@0: michael@0: void LinearScaleYUVToRGB32Row(const uint8* y_buf, michael@0: const uint8* u_buf, michael@0: const uint8* v_buf, michael@0: uint8* rgb_buf, michael@0: int width, michael@0: int source_dx) { michael@0: LinearScaleYUVToRGB32Row_C(y_buf, u_buf, v_buf, rgb_buf, width, source_dx); michael@0: } michael@0: #endif michael@0: michael@0: }