Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * software RGB to RGB converter
  3.  * pluralize by software PAL8 to RGB converter
  4.  *              software YUV to YUV converter
  5.  *              software YUV to RGB converter
  6.  * Written by Nick Kurshev.
  7.  * palette & YUV & runtime CPU stuff by Michael (michaelni@gmx.at)
  8.  * lot of big-endian byte order fixes by Alex Beregszaszi
  9.  *
  10.  * This file is part of FFmpeg.
  11.  *
  12.  * FFmpeg is free software; you can redistribute it and/or
  13.  * modify it under the terms of the GNU Lesser General Public
  14.  * License as published by the Free Software Foundation; either
  15.  * version 2.1 of the License, or (at your option) any later version.
  16.  *
  17.  * FFmpeg is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  20.  * Lesser General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU Lesser General Public
  23.  * License along with FFmpeg; if not, write to the Free Software
  24.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  25.  */
  26.  
  27. #include <stddef.h>
  28. #include <stdint.h>
  29.  
  30. #include "libavutil/attributes.h"
  31. #include "libavutil/x86/asm.h"
  32.  
  33. #undef PREFETCH
  34. #undef MOVNTQ
  35. #undef EMMS
  36. #undef SFENCE
  37. #undef PAVGB
  38.  
  39. #if COMPILE_TEMPLATE_AMD3DNOW
  40. #define PREFETCH  "prefetch"
  41. #define PAVGB     "pavgusb"
  42. #elif COMPILE_TEMPLATE_MMXEXT
  43. #define PREFETCH "prefetchnta"
  44. #define PAVGB     "pavgb"
  45. #else
  46. #define PREFETCH  " # nop"
  47. #endif
  48.  
  49. #if COMPILE_TEMPLATE_AMD3DNOW
  50. /* On K6 femms is faster than emms. On K7 femms is directly mapped to emms. */
  51. #define EMMS     "femms"
  52. #else
  53. #define EMMS     "emms"
  54. #endif
  55.  
  56. #if COMPILE_TEMPLATE_MMXEXT
  57. #define MOVNTQ "movntq"
  58. #define SFENCE "sfence"
  59. #else
  60. #define MOVNTQ "movq"
  61. #define SFENCE " # nop"
  62. #endif
  63.  
  64. #if !COMPILE_TEMPLATE_SSE2
  65.  
  66. #if !COMPILE_TEMPLATE_AMD3DNOW
  67.  
  68. static inline void RENAME(rgb24tobgr32)(const uint8_t *src, uint8_t *dst, int src_size)
  69. {
  70.     uint8_t *dest = dst;
  71.     const uint8_t *s = src;
  72.     const uint8_t *end;
  73.     const uint8_t *mm_end;
  74.     end = s + src_size;
  75.     __asm__ volatile(PREFETCH"    %0"::"m"(*s):"memory");
  76.     mm_end = end - 23;
  77.     __asm__ volatile("movq        %0, %%mm7"::"m"(mask32a):"memory");
  78.     while (s < mm_end) {
  79.         __asm__ volatile(
  80.             PREFETCH"  32(%1)           \n\t"
  81.             "movd        (%1), %%mm0    \n\t"
  82.             "punpckldq  3(%1), %%mm0    \n\t"
  83.             "movd       6(%1), %%mm1    \n\t"
  84.             "punpckldq  9(%1), %%mm1    \n\t"
  85.             "movd      12(%1), %%mm2    \n\t"
  86.             "punpckldq 15(%1), %%mm2    \n\t"
  87.             "movd      18(%1), %%mm3    \n\t"
  88.             "punpckldq 21(%1), %%mm3    \n\t"
  89.             "por        %%mm7, %%mm0    \n\t"
  90.             "por        %%mm7, %%mm1    \n\t"
  91.             "por        %%mm7, %%mm2    \n\t"
  92.             "por        %%mm7, %%mm3    \n\t"
  93.             MOVNTQ"     %%mm0,   (%0)   \n\t"
  94.             MOVNTQ"     %%mm1,  8(%0)   \n\t"
  95.             MOVNTQ"     %%mm2, 16(%0)   \n\t"
  96.             MOVNTQ"     %%mm3, 24(%0)"
  97.             :: "r"(dest), "r"(s)
  98.             :"memory");
  99.         dest += 32;
  100.         s += 24;
  101.     }
  102.     __asm__ volatile(SFENCE:::"memory");
  103.     __asm__ volatile(EMMS:::"memory");
  104.     while (s < end) {
  105.         *dest++ = *s++;
  106.         *dest++ = *s++;
  107.         *dest++ = *s++;
  108.         *dest++ = 255;
  109.     }
  110. }
  111.  
  112. #define STORE_BGR24_MMX \
  113.             "psrlq         $8, %%mm2    \n\t" \
  114.             "psrlq         $8, %%mm3    \n\t" \
  115.             "psrlq         $8, %%mm6    \n\t" \
  116.             "psrlq         $8, %%mm7    \n\t" \
  117.             "pand "MANGLE(mask24l)", %%mm0\n\t" \
  118.             "pand "MANGLE(mask24l)", %%mm1\n\t" \
  119.             "pand "MANGLE(mask24l)", %%mm4\n\t" \
  120.             "pand "MANGLE(mask24l)", %%mm5\n\t" \
  121.             "pand "MANGLE(mask24h)", %%mm2\n\t" \
  122.             "pand "MANGLE(mask24h)", %%mm3\n\t" \
  123.             "pand "MANGLE(mask24h)", %%mm6\n\t" \
  124.             "pand "MANGLE(mask24h)", %%mm7\n\t" \
  125.             "por        %%mm2, %%mm0    \n\t" \
  126.             "por        %%mm3, %%mm1    \n\t" \
  127.             "por        %%mm6, %%mm4    \n\t" \
  128.             "por        %%mm7, %%mm5    \n\t" \
  129.  \
  130.             "movq       %%mm1, %%mm2    \n\t" \
  131.             "movq       %%mm4, %%mm3    \n\t" \
  132.             "psllq        $48, %%mm2    \n\t" \
  133.             "psllq        $32, %%mm3    \n\t" \
  134.             "por        %%mm2, %%mm0    \n\t" \
  135.             "psrlq        $16, %%mm1    \n\t" \
  136.             "psrlq        $32, %%mm4    \n\t" \
  137.             "psllq        $16, %%mm5    \n\t" \
  138.             "por        %%mm3, %%mm1    \n\t" \
  139.             "por        %%mm5, %%mm4    \n\t" \
  140.  \
  141.             MOVNTQ"     %%mm0,   (%0)    \n\t" \
  142.             MOVNTQ"     %%mm1,  8(%0)    \n\t" \
  143.             MOVNTQ"     %%mm4, 16(%0)"
  144.  
  145.  
  146. static inline void RENAME(rgb32tobgr24)(const uint8_t *src, uint8_t *dst, int src_size)
  147. {
  148.     uint8_t *dest = dst;
  149.     const uint8_t *s = src;
  150.     const uint8_t *end;
  151.     const uint8_t *mm_end;
  152.     end = s + src_size;
  153.     __asm__ volatile(PREFETCH"    %0"::"m"(*s):"memory");
  154.     mm_end = end - 31;
  155.     while (s < mm_end) {
  156.         __asm__ volatile(
  157.             PREFETCH"  32(%1)           \n\t"
  158.             "movq        (%1), %%mm0    \n\t"
  159.             "movq       8(%1), %%mm1    \n\t"
  160.             "movq      16(%1), %%mm4    \n\t"
  161.             "movq      24(%1), %%mm5    \n\t"
  162.             "movq       %%mm0, %%mm2    \n\t"
  163.             "movq       %%mm1, %%mm3    \n\t"
  164.             "movq       %%mm4, %%mm6    \n\t"
  165.             "movq       %%mm5, %%mm7    \n\t"
  166.             STORE_BGR24_MMX
  167.             :: "r"(dest), "r"(s)
  168.               NAMED_CONSTRAINTS_ADD(mask24l,mask24h)
  169.             :"memory");
  170.         dest += 24;
  171.         s += 32;
  172.     }
  173.     __asm__ volatile(SFENCE:::"memory");
  174.     __asm__ volatile(EMMS:::"memory");
  175.     while (s < end) {
  176.         *dest++ = *s++;
  177.         *dest++ = *s++;
  178.         *dest++ = *s++;
  179.         s++;
  180.     }
  181. }
  182.  
  183. /*
  184.  original by Strepto/Astral
  185.  ported to gcc & bugfixed: A'rpi
  186.  MMXEXT, 3DNOW optimization by Nick Kurshev
  187.  32-bit C version, and and&add trick by Michael Niedermayer
  188. */
  189. static inline void RENAME(rgb15to16)(const uint8_t *src, uint8_t *dst, int src_size)
  190. {
  191.     register const uint8_t* s=src;
  192.     register uint8_t* d=dst;
  193.     register const uint8_t *end;
  194.     const uint8_t *mm_end;
  195.     end = s + src_size;
  196.     __asm__ volatile(PREFETCH"    %0"::"m"(*s));
  197.     __asm__ volatile("movq        %0, %%mm4"::"m"(mask15s));
  198.     mm_end = end - 15;
  199.     while (s<mm_end) {
  200.         __asm__ volatile(
  201.             PREFETCH" 32(%1)        \n\t"
  202.             "movq      (%1), %%mm0  \n\t"
  203.             "movq     8(%1), %%mm2  \n\t"
  204.             "movq     %%mm0, %%mm1  \n\t"
  205.             "movq     %%mm2, %%mm3  \n\t"
  206.             "pand     %%mm4, %%mm0  \n\t"
  207.             "pand     %%mm4, %%mm2  \n\t"
  208.             "paddw    %%mm1, %%mm0  \n\t"
  209.             "paddw    %%mm3, %%mm2  \n\t"
  210.             MOVNTQ"   %%mm0,  (%0)  \n\t"
  211.             MOVNTQ"   %%mm2, 8(%0)"
  212.             :: "r"(d), "r"(s)
  213.         );
  214.         d+=16;
  215.         s+=16;
  216.     }
  217.     __asm__ volatile(SFENCE:::"memory");
  218.     __asm__ volatile(EMMS:::"memory");
  219.     mm_end = end - 3;
  220.     while (s < mm_end) {
  221.         register unsigned x= *((const uint32_t *)s);
  222.         *((uint32_t *)d) = (x&0x7FFF7FFF) + (x&0x7FE07FE0);
  223.         d+=4;
  224.         s+=4;
  225.     }
  226.     if (s < end) {
  227.         register unsigned short x= *((const uint16_t *)s);
  228.         *((uint16_t *)d) = (x&0x7FFF) + (x&0x7FE0);
  229.     }
  230. }
  231.  
  232. static inline void RENAME(rgb16to15)(const uint8_t *src, uint8_t *dst, int src_size)
  233. {
  234.     register const uint8_t* s=src;
  235.     register uint8_t* d=dst;
  236.     register const uint8_t *end;
  237.     const uint8_t *mm_end;
  238.     end = s + src_size;
  239.     __asm__ volatile(PREFETCH"    %0"::"m"(*s));
  240.     __asm__ volatile("movq        %0, %%mm7"::"m"(mask15rg));
  241.     __asm__ volatile("movq        %0, %%mm6"::"m"(mask15b));
  242.     mm_end = end - 15;
  243.     while (s<mm_end) {
  244.         __asm__ volatile(
  245.             PREFETCH" 32(%1)        \n\t"
  246.             "movq      (%1), %%mm0  \n\t"
  247.             "movq     8(%1), %%mm2  \n\t"
  248.             "movq     %%mm0, %%mm1  \n\t"
  249.             "movq     %%mm2, %%mm3  \n\t"
  250.             "psrlq       $1, %%mm0  \n\t"
  251.             "psrlq       $1, %%mm2  \n\t"
  252.             "pand     %%mm7, %%mm0  \n\t"
  253.             "pand     %%mm7, %%mm2  \n\t"
  254.             "pand     %%mm6, %%mm1  \n\t"
  255.             "pand     %%mm6, %%mm3  \n\t"
  256.             "por      %%mm1, %%mm0  \n\t"
  257.             "por      %%mm3, %%mm2  \n\t"
  258.             MOVNTQ"   %%mm0,  (%0)  \n\t"
  259.             MOVNTQ"   %%mm2, 8(%0)"
  260.             :: "r"(d), "r"(s)
  261.         );
  262.         d+=16;
  263.         s+=16;
  264.     }
  265.     __asm__ volatile(SFENCE:::"memory");
  266.     __asm__ volatile(EMMS:::"memory");
  267.     mm_end = end - 3;
  268.     while (s < mm_end) {
  269.         register uint32_t x= *((const uint32_t*)s);
  270.         *((uint32_t *)d) = ((x>>1)&0x7FE07FE0) | (x&0x001F001F);
  271.         s+=4;
  272.         d+=4;
  273.     }
  274.     if (s < end) {
  275.         register uint16_t x= *((const uint16_t*)s);
  276.         *((uint16_t *)d) = ((x>>1)&0x7FE0) | (x&0x001F);
  277.     }
  278. }
  279.  
  280. static inline void RENAME(rgb32to16)(const uint8_t *src, uint8_t *dst, int src_size)
  281. {
  282.     const uint8_t *s = src;
  283.     const uint8_t *end;
  284.     const uint8_t *mm_end;
  285.     uint16_t *d = (uint16_t *)dst;
  286.     end = s + src_size;
  287.     mm_end = end - 15;
  288.     __asm__ volatile(
  289.         "movq           %3, %%mm5   \n\t"
  290.         "movq           %4, %%mm6   \n\t"
  291.         "movq           %5, %%mm7   \n\t"
  292.         "jmp 2f                     \n\t"
  293.         ".p2align        4          \n\t"
  294.         "1:                         \n\t"
  295.         PREFETCH"   32(%1)          \n\t"
  296.         "movd         (%1), %%mm0   \n\t"
  297.         "movd        4(%1), %%mm3   \n\t"
  298.         "punpckldq   8(%1), %%mm0   \n\t"
  299.         "punpckldq  12(%1), %%mm3   \n\t"
  300.         "movq        %%mm0, %%mm1   \n\t"
  301.         "movq        %%mm3, %%mm4   \n\t"
  302.         "pand        %%mm6, %%mm0   \n\t"
  303.         "pand        %%mm6, %%mm3   \n\t"
  304.         "pmaddwd     %%mm7, %%mm0   \n\t"
  305.         "pmaddwd     %%mm7, %%mm3   \n\t"
  306.         "pand        %%mm5, %%mm1   \n\t"
  307.         "pand        %%mm5, %%mm4   \n\t"
  308.         "por         %%mm1, %%mm0   \n\t"
  309.         "por         %%mm4, %%mm3   \n\t"
  310.         "psrld          $5, %%mm0   \n\t"
  311.         "pslld         $11, %%mm3   \n\t"
  312.         "por         %%mm3, %%mm0   \n\t"
  313.         MOVNTQ"      %%mm0, (%0)    \n\t"
  314.         "add           $16,  %1     \n\t"
  315.         "add            $8,  %0     \n\t"
  316.         "2:                         \n\t"
  317.         "cmp            %2,  %1     \n\t"
  318.         " jb            1b          \n\t"
  319.         : "+r" (d), "+r"(s)
  320.         : "r" (mm_end), "m" (mask3216g), "m" (mask3216br), "m" (mul3216)
  321.     );
  322.     __asm__ volatile(SFENCE:::"memory");
  323.     __asm__ volatile(EMMS:::"memory");
  324.     while (s < end) {
  325.         register int rgb = *(const uint32_t*)s; s += 4;
  326.         *d++ = ((rgb&0xFF)>>3) + ((rgb&0xFC00)>>5) + ((rgb&0xF80000)>>8);
  327.     }
  328. }
  329.  
  330. static inline void RENAME(rgb32tobgr16)(const uint8_t *src, uint8_t *dst, int src_size)
  331. {
  332.     const uint8_t *s = src;
  333.     const uint8_t *end;
  334.     const uint8_t *mm_end;
  335.     uint16_t *d = (uint16_t *)dst;
  336.     end = s + src_size;
  337.     __asm__ volatile(PREFETCH"    %0"::"m"(*src):"memory");
  338.     __asm__ volatile(
  339.         "movq          %0, %%mm7    \n\t"
  340.         "movq          %1, %%mm6    \n\t"
  341.         ::"m"(red_16mask),"m"(green_16mask));
  342.     mm_end = end - 15;
  343.     while (s < mm_end) {
  344.         __asm__ volatile(
  345.             PREFETCH"  32(%1)           \n\t"
  346.             "movd        (%1), %%mm0    \n\t"
  347.             "movd       4(%1), %%mm3    \n\t"
  348.             "punpckldq  8(%1), %%mm0    \n\t"
  349.             "punpckldq 12(%1), %%mm3    \n\t"
  350.             "movq       %%mm0, %%mm1    \n\t"
  351.             "movq       %%mm0, %%mm2    \n\t"
  352.             "movq       %%mm3, %%mm4    \n\t"
  353.             "movq       %%mm3, %%mm5    \n\t"
  354.             "psllq         $8, %%mm0    \n\t"
  355.             "psllq         $8, %%mm3    \n\t"
  356.             "pand       %%mm7, %%mm0    \n\t"
  357.             "pand       %%mm7, %%mm3    \n\t"
  358.             "psrlq         $5, %%mm1    \n\t"
  359.             "psrlq         $5, %%mm4    \n\t"
  360.             "pand       %%mm6, %%mm1    \n\t"
  361.             "pand       %%mm6, %%mm4    \n\t"
  362.             "psrlq        $19, %%mm2    \n\t"
  363.             "psrlq        $19, %%mm5    \n\t"
  364.             "pand          %2, %%mm2    \n\t"
  365.             "pand          %2, %%mm5    \n\t"
  366.             "por        %%mm1, %%mm0    \n\t"
  367.             "por        %%mm4, %%mm3    \n\t"
  368.             "por        %%mm2, %%mm0    \n\t"
  369.             "por        %%mm5, %%mm3    \n\t"
  370.             "psllq        $16, %%mm3    \n\t"
  371.             "por        %%mm3, %%mm0    \n\t"
  372.             MOVNTQ"     %%mm0, (%0)     \n\t"
  373.             :: "r"(d),"r"(s),"m"(blue_16mask):"memory");
  374.         d += 4;
  375.         s += 16;
  376.     }
  377.     __asm__ volatile(SFENCE:::"memory");
  378.     __asm__ volatile(EMMS:::"memory");
  379.     while (s < end) {
  380.         register int rgb = *(const uint32_t*)s; s += 4;
  381.         *d++ = ((rgb&0xF8)<<8) + ((rgb&0xFC00)>>5) + ((rgb&0xF80000)>>19);
  382.     }
  383. }
  384.  
  385. static inline void RENAME(rgb32to15)(const uint8_t *src, uint8_t *dst, int src_size)
  386. {
  387.     const uint8_t *s = src;
  388.     const uint8_t *end;
  389.     const uint8_t *mm_end;
  390.     uint16_t *d = (uint16_t *)dst;
  391.     end = s + src_size;
  392.     mm_end = end - 15;
  393.     __asm__ volatile(
  394.         "movq           %3, %%mm5   \n\t"
  395.         "movq           %4, %%mm6   \n\t"
  396.         "movq           %5, %%mm7   \n\t"
  397.         "jmp            2f          \n\t"
  398.         ".p2align        4          \n\t"
  399.         "1:                         \n\t"
  400.         PREFETCH"   32(%1)          \n\t"
  401.         "movd         (%1), %%mm0   \n\t"
  402.         "movd        4(%1), %%mm3   \n\t"
  403.         "punpckldq   8(%1), %%mm0   \n\t"
  404.         "punpckldq  12(%1), %%mm3   \n\t"
  405.         "movq        %%mm0, %%mm1   \n\t"
  406.         "movq        %%mm3, %%mm4   \n\t"
  407.         "pand        %%mm6, %%mm0   \n\t"
  408.         "pand        %%mm6, %%mm3   \n\t"
  409.         "pmaddwd     %%mm7, %%mm0   \n\t"
  410.         "pmaddwd     %%mm7, %%mm3   \n\t"
  411.         "pand        %%mm5, %%mm1   \n\t"
  412.         "pand        %%mm5, %%mm4   \n\t"
  413.         "por         %%mm1, %%mm0   \n\t"
  414.         "por         %%mm4, %%mm3   \n\t"
  415.         "psrld          $6, %%mm0   \n\t"
  416.         "pslld         $10, %%mm3   \n\t"
  417.         "por         %%mm3, %%mm0   \n\t"
  418.         MOVNTQ"      %%mm0, (%0)    \n\t"
  419.         "add           $16,  %1     \n\t"
  420.         "add            $8,  %0     \n\t"
  421.         "2:                         \n\t"
  422.         "cmp            %2,  %1     \n\t"
  423.         " jb            1b          \n\t"
  424.         : "+r" (d), "+r"(s)
  425.         : "r" (mm_end), "m" (mask3215g), "m" (mask3216br), "m" (mul3215)
  426.     );
  427.     __asm__ volatile(SFENCE:::"memory");
  428.     __asm__ volatile(EMMS:::"memory");
  429.     while (s < end) {
  430.         register int rgb = *(const uint32_t*)s; s += 4;
  431.         *d++ = ((rgb&0xFF)>>3) + ((rgb&0xF800)>>6) + ((rgb&0xF80000)>>9);
  432.     }
  433. }
  434.  
  435. static inline void RENAME(rgb32tobgr15)(const uint8_t *src, uint8_t *dst, int src_size)
  436. {
  437.     const uint8_t *s = src;
  438.     const uint8_t *end;
  439.     const uint8_t *mm_end;
  440.     uint16_t *d = (uint16_t *)dst;
  441.     end = s + src_size;
  442.     __asm__ volatile(PREFETCH"    %0"::"m"(*src):"memory");
  443.     __asm__ volatile(
  444.         "movq          %0, %%mm7    \n\t"
  445.         "movq          %1, %%mm6    \n\t"
  446.         ::"m"(red_15mask),"m"(green_15mask));
  447.     mm_end = end - 15;
  448.     while (s < mm_end) {
  449.         __asm__ volatile(
  450.             PREFETCH"  32(%1)           \n\t"
  451.             "movd        (%1), %%mm0    \n\t"
  452.             "movd       4(%1), %%mm3    \n\t"
  453.             "punpckldq  8(%1), %%mm0    \n\t"
  454.             "punpckldq 12(%1), %%mm3    \n\t"
  455.             "movq       %%mm0, %%mm1    \n\t"
  456.             "movq       %%mm0, %%mm2    \n\t"
  457.             "movq       %%mm3, %%mm4    \n\t"
  458.             "movq       %%mm3, %%mm5    \n\t"
  459.             "psllq         $7, %%mm0    \n\t"
  460.             "psllq         $7, %%mm3    \n\t"
  461.             "pand       %%mm7, %%mm0    \n\t"
  462.             "pand       %%mm7, %%mm3    \n\t"
  463.             "psrlq         $6, %%mm1    \n\t"
  464.             "psrlq         $6, %%mm4    \n\t"
  465.             "pand       %%mm6, %%mm1    \n\t"
  466.             "pand       %%mm6, %%mm4    \n\t"
  467.             "psrlq        $19, %%mm2    \n\t"
  468.             "psrlq        $19, %%mm5    \n\t"
  469.             "pand          %2, %%mm2    \n\t"
  470.             "pand          %2, %%mm5    \n\t"
  471.             "por        %%mm1, %%mm0    \n\t"
  472.             "por        %%mm4, %%mm3    \n\t"
  473.             "por        %%mm2, %%mm0    \n\t"
  474.             "por        %%mm5, %%mm3    \n\t"
  475.             "psllq        $16, %%mm3    \n\t"
  476.             "por        %%mm3, %%mm0    \n\t"
  477.             MOVNTQ"     %%mm0, (%0)     \n\t"
  478.             ::"r"(d),"r"(s),"m"(blue_15mask):"memory");
  479.         d += 4;
  480.         s += 16;
  481.     }
  482.     __asm__ volatile(SFENCE:::"memory");
  483.     __asm__ volatile(EMMS:::"memory");
  484.     while (s < end) {
  485.         register int rgb = *(const uint32_t*)s; s += 4;
  486.         *d++ = ((rgb&0xF8)<<7) + ((rgb&0xF800)>>6) + ((rgb&0xF80000)>>19);
  487.     }
  488. }
  489.  
  490. static inline void RENAME(rgb24tobgr16)(const uint8_t *src, uint8_t *dst, int src_size)
  491. {
  492.     const uint8_t *s = src;
  493.     const uint8_t *end;
  494.     const uint8_t *mm_end;
  495.     uint16_t *d = (uint16_t *)dst;
  496.     end = s + src_size;
  497.     __asm__ volatile(PREFETCH"    %0"::"m"(*src):"memory");
  498.     __asm__ volatile(
  499.         "movq         %0, %%mm7     \n\t"
  500.         "movq         %1, %%mm6     \n\t"
  501.         ::"m"(red_16mask),"m"(green_16mask));
  502.     mm_end = end - 11;
  503.     while (s < mm_end) {
  504.         __asm__ volatile(
  505.             PREFETCH"  32(%1)           \n\t"
  506.             "movd        (%1), %%mm0    \n\t"
  507.             "movd       3(%1), %%mm3    \n\t"
  508.             "punpckldq  6(%1), %%mm0    \n\t"
  509.             "punpckldq  9(%1), %%mm3    \n\t"
  510.             "movq       %%mm0, %%mm1    \n\t"
  511.             "movq       %%mm0, %%mm2    \n\t"
  512.             "movq       %%mm3, %%mm4    \n\t"
  513.             "movq       %%mm3, %%mm5    \n\t"
  514.             "psrlq         $3, %%mm0    \n\t"
  515.             "psrlq         $3, %%mm3    \n\t"
  516.             "pand          %2, %%mm0    \n\t"
  517.             "pand          %2, %%mm3    \n\t"
  518.             "psrlq         $5, %%mm1    \n\t"
  519.             "psrlq         $5, %%mm4    \n\t"
  520.             "pand       %%mm6, %%mm1    \n\t"
  521.             "pand       %%mm6, %%mm4    \n\t"
  522.             "psrlq         $8, %%mm2    \n\t"
  523.             "psrlq         $8, %%mm5    \n\t"
  524.             "pand       %%mm7, %%mm2    \n\t"
  525.             "pand       %%mm7, %%mm5    \n\t"
  526.             "por        %%mm1, %%mm0    \n\t"
  527.             "por        %%mm4, %%mm3    \n\t"
  528.             "por        %%mm2, %%mm0    \n\t"
  529.             "por        %%mm5, %%mm3    \n\t"
  530.             "psllq        $16, %%mm3    \n\t"
  531.             "por        %%mm3, %%mm0    \n\t"
  532.             MOVNTQ"     %%mm0, (%0)     \n\t"
  533.             ::"r"(d),"r"(s),"m"(blue_16mask):"memory");
  534.         d += 4;
  535.         s += 12;
  536.     }
  537.     __asm__ volatile(SFENCE:::"memory");
  538.     __asm__ volatile(EMMS:::"memory");
  539.     while (s < end) {
  540.         const int b = *s++;
  541.         const int g = *s++;
  542.         const int r = *s++;
  543.         *d++ = (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8);
  544.     }
  545. }
  546.  
  547. static inline void RENAME(rgb24to16)(const uint8_t *src, uint8_t *dst, int src_size)
  548. {
  549.     const uint8_t *s = src;
  550.     const uint8_t *end;
  551.     const uint8_t *mm_end;
  552.     uint16_t *d = (uint16_t *)dst;
  553.     end = s + src_size;
  554.     __asm__ volatile(PREFETCH"    %0"::"m"(*src):"memory");
  555.     __asm__ volatile(
  556.         "movq         %0, %%mm7     \n\t"
  557.         "movq         %1, %%mm6     \n\t"
  558.         ::"m"(red_16mask),"m"(green_16mask));
  559.     mm_end = end - 15;
  560.     while (s < mm_end) {
  561.         __asm__ volatile(
  562.             PREFETCH"  32(%1)           \n\t"
  563.             "movd        (%1), %%mm0    \n\t"
  564.             "movd       3(%1), %%mm3    \n\t"
  565.             "punpckldq  6(%1), %%mm0    \n\t"
  566.             "punpckldq  9(%1), %%mm3    \n\t"
  567.             "movq       %%mm0, %%mm1    \n\t"
  568.             "movq       %%mm0, %%mm2    \n\t"
  569.             "movq       %%mm3, %%mm4    \n\t"
  570.             "movq       %%mm3, %%mm5    \n\t"
  571.             "psllq         $8, %%mm0    \n\t"
  572.             "psllq         $8, %%mm3    \n\t"
  573.             "pand       %%mm7, %%mm0    \n\t"
  574.             "pand       %%mm7, %%mm3    \n\t"
  575.             "psrlq         $5, %%mm1    \n\t"
  576.             "psrlq         $5, %%mm4    \n\t"
  577.             "pand       %%mm6, %%mm1    \n\t"
  578.             "pand       %%mm6, %%mm4    \n\t"
  579.             "psrlq        $19, %%mm2    \n\t"
  580.             "psrlq        $19, %%mm5    \n\t"
  581.             "pand          %2, %%mm2    \n\t"
  582.             "pand          %2, %%mm5    \n\t"
  583.             "por        %%mm1, %%mm0    \n\t"
  584.             "por        %%mm4, %%mm3    \n\t"
  585.             "por        %%mm2, %%mm0    \n\t"
  586.             "por        %%mm5, %%mm3    \n\t"
  587.             "psllq        $16, %%mm3    \n\t"
  588.             "por        %%mm3, %%mm0    \n\t"
  589.             MOVNTQ"     %%mm0, (%0)     \n\t"
  590.             ::"r"(d),"r"(s),"m"(blue_16mask):"memory");
  591.         d += 4;
  592.         s += 12;
  593.     }
  594.     __asm__ volatile(SFENCE:::"memory");
  595.     __asm__ volatile(EMMS:::"memory");
  596.     while (s < end) {
  597.         const int r = *s++;
  598.         const int g = *s++;
  599.         const int b = *s++;
  600.         *d++ = (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8);
  601.     }
  602. }
  603.  
  604. static inline void RENAME(rgb24tobgr15)(const uint8_t *src, uint8_t *dst, int src_size)
  605. {
  606.     const uint8_t *s = src;
  607.     const uint8_t *end;
  608.     const uint8_t *mm_end;
  609.     uint16_t *d = (uint16_t *)dst;
  610.     end = s + src_size;
  611.     __asm__ volatile(PREFETCH"    %0"::"m"(*src):"memory");
  612.     __asm__ volatile(
  613.         "movq          %0, %%mm7    \n\t"
  614.         "movq          %1, %%mm6    \n\t"
  615.         ::"m"(red_15mask),"m"(green_15mask));
  616.     mm_end = end - 11;
  617.     while (s < mm_end) {
  618.         __asm__ volatile(
  619.             PREFETCH"  32(%1)           \n\t"
  620.             "movd        (%1), %%mm0    \n\t"
  621.             "movd       3(%1), %%mm3    \n\t"
  622.             "punpckldq  6(%1), %%mm0    \n\t"
  623.             "punpckldq  9(%1), %%mm3    \n\t"
  624.             "movq       %%mm0, %%mm1    \n\t"
  625.             "movq       %%mm0, %%mm2    \n\t"
  626.             "movq       %%mm3, %%mm4    \n\t"
  627.             "movq       %%mm3, %%mm5    \n\t"
  628.             "psrlq         $3, %%mm0    \n\t"
  629.             "psrlq         $3, %%mm3    \n\t"
  630.             "pand          %2, %%mm0    \n\t"
  631.             "pand          %2, %%mm3    \n\t"
  632.             "psrlq         $6, %%mm1    \n\t"
  633.             "psrlq         $6, %%mm4    \n\t"
  634.             "pand       %%mm6, %%mm1    \n\t"
  635.             "pand       %%mm6, %%mm4    \n\t"
  636.             "psrlq         $9, %%mm2    \n\t"
  637.             "psrlq         $9, %%mm5    \n\t"
  638.             "pand       %%mm7, %%mm2    \n\t"
  639.             "pand       %%mm7, %%mm5    \n\t"
  640.             "por        %%mm1, %%mm0    \n\t"
  641.             "por        %%mm4, %%mm3    \n\t"
  642.             "por        %%mm2, %%mm0    \n\t"
  643.             "por        %%mm5, %%mm3    \n\t"
  644.             "psllq        $16, %%mm3    \n\t"
  645.             "por        %%mm3, %%mm0    \n\t"
  646.             MOVNTQ"     %%mm0, (%0)     \n\t"
  647.             ::"r"(d),"r"(s),"m"(blue_15mask):"memory");
  648.         d += 4;
  649.         s += 12;
  650.     }
  651.     __asm__ volatile(SFENCE:::"memory");
  652.     __asm__ volatile(EMMS:::"memory");
  653.     while (s < end) {
  654.         const int b = *s++;
  655.         const int g = *s++;
  656.         const int r = *s++;
  657.         *d++ = (b>>3) | ((g&0xF8)<<2) | ((r&0xF8)<<7);
  658.     }
  659. }
  660.  
  661. static inline void RENAME(rgb24to15)(const uint8_t *src, uint8_t *dst, int src_size)
  662. {
  663.     const uint8_t *s = src;
  664.     const uint8_t *end;
  665.     const uint8_t *mm_end;
  666.     uint16_t *d = (uint16_t *)dst;
  667.     end = s + src_size;
  668.     __asm__ volatile(PREFETCH"    %0"::"m"(*src):"memory");
  669.     __asm__ volatile(
  670.         "movq         %0, %%mm7     \n\t"
  671.         "movq         %1, %%mm6     \n\t"
  672.         ::"m"(red_15mask),"m"(green_15mask));
  673.     mm_end = end - 15;
  674.     while (s < mm_end) {
  675.         __asm__ volatile(
  676.             PREFETCH" 32(%1)            \n\t"
  677.             "movd       (%1), %%mm0     \n\t"
  678.             "movd      3(%1), %%mm3     \n\t"
  679.             "punpckldq 6(%1), %%mm0     \n\t"
  680.             "punpckldq 9(%1), %%mm3     \n\t"
  681.             "movq      %%mm0, %%mm1     \n\t"
  682.             "movq      %%mm0, %%mm2     \n\t"
  683.             "movq      %%mm3, %%mm4     \n\t"
  684.             "movq      %%mm3, %%mm5     \n\t"
  685.             "psllq        $7, %%mm0     \n\t"
  686.             "psllq        $7, %%mm3     \n\t"
  687.             "pand      %%mm7, %%mm0     \n\t"
  688.             "pand      %%mm7, %%mm3     \n\t"
  689.             "psrlq        $6, %%mm1     \n\t"
  690.             "psrlq        $6, %%mm4     \n\t"
  691.             "pand      %%mm6, %%mm1     \n\t"
  692.             "pand      %%mm6, %%mm4     \n\t"
  693.             "psrlq       $19, %%mm2     \n\t"
  694.             "psrlq       $19, %%mm5     \n\t"
  695.             "pand         %2, %%mm2     \n\t"
  696.             "pand         %2, %%mm5     \n\t"
  697.             "por       %%mm1, %%mm0     \n\t"
  698.             "por       %%mm4, %%mm3     \n\t"
  699.             "por       %%mm2, %%mm0     \n\t"
  700.             "por       %%mm5, %%mm3     \n\t"
  701.             "psllq       $16, %%mm3     \n\t"
  702.             "por       %%mm3, %%mm0     \n\t"
  703.             MOVNTQ"    %%mm0, (%0)      \n\t"
  704.             ::"r"(d),"r"(s),"m"(blue_15mask):"memory");
  705.         d += 4;
  706.         s += 12;
  707.     }
  708.     __asm__ volatile(SFENCE:::"memory");
  709.     __asm__ volatile(EMMS:::"memory");
  710.     while (s < end) {
  711.         const int r = *s++;
  712.         const int g = *s++;
  713.         const int b = *s++;
  714.         *d++ = (b>>3) | ((g&0xF8)<<2) | ((r&0xF8)<<7);
  715.     }
  716. }
  717.  
  718. static inline void RENAME(rgb15tobgr24)(const uint8_t *src, uint8_t *dst, int src_size)
  719. {
  720.     const uint16_t *end;
  721.     const uint16_t *mm_end;
  722.     uint8_t *d = dst;
  723.     const uint16_t *s = (const uint16_t*)src;
  724.     end = s + src_size/2;
  725.     __asm__ volatile(PREFETCH"    %0"::"m"(*s):"memory");
  726.     mm_end = end - 7;
  727.     while (s < mm_end) {
  728.         __asm__ volatile(
  729.             PREFETCH"  32(%1)           \n\t"
  730.             "movq        (%1), %%mm0    \n\t"
  731.             "movq        (%1), %%mm1    \n\t"
  732.             "movq        (%1), %%mm2    \n\t"
  733.             "pand          %2, %%mm0    \n\t"
  734.             "pand          %3, %%mm1    \n\t"
  735.             "pand          %4, %%mm2    \n\t"
  736.             "psllq         $5, %%mm0    \n\t"
  737.             "pmulhw        "MANGLE(mul15_mid)", %%mm0    \n\t"
  738.             "pmulhw        "MANGLE(mul15_mid)", %%mm1    \n\t"
  739.             "pmulhw        "MANGLE(mul15_hi)", %%mm2    \n\t"
  740.             "movq       %%mm0, %%mm3    \n\t"
  741.             "movq       %%mm1, %%mm4    \n\t"
  742.             "movq       %%mm2, %%mm5    \n\t"
  743.             "punpcklwd     %5, %%mm0    \n\t"
  744.             "punpcklwd     %5, %%mm1    \n\t"
  745.             "punpcklwd     %5, %%mm2    \n\t"
  746.             "punpckhwd     %5, %%mm3    \n\t"
  747.             "punpckhwd     %5, %%mm4    \n\t"
  748.             "punpckhwd     %5, %%mm5    \n\t"
  749.             "psllq         $8, %%mm1    \n\t"
  750.             "psllq        $16, %%mm2    \n\t"
  751.             "por        %%mm1, %%mm0    \n\t"
  752.             "por        %%mm2, %%mm0    \n\t"
  753.             "psllq         $8, %%mm4    \n\t"
  754.             "psllq        $16, %%mm5    \n\t"
  755.             "por        %%mm4, %%mm3    \n\t"
  756.             "por        %%mm5, %%mm3    \n\t"
  757.  
  758.             "movq       %%mm0, %%mm6    \n\t"
  759.             "movq       %%mm3, %%mm7    \n\t"
  760.  
  761.             "movq       8(%1), %%mm0    \n\t"
  762.             "movq       8(%1), %%mm1    \n\t"
  763.             "movq       8(%1), %%mm2    \n\t"
  764.             "pand          %2, %%mm0    \n\t"
  765.             "pand          %3, %%mm1    \n\t"
  766.             "pand          %4, %%mm2    \n\t"
  767.             "psllq         $5, %%mm0    \n\t"
  768.             "pmulhw        "MANGLE(mul15_mid)", %%mm0    \n\t"
  769.             "pmulhw        "MANGLE(mul15_mid)", %%mm1    \n\t"
  770.             "pmulhw        "MANGLE(mul15_hi)", %%mm2    \n\t"
  771.             "movq       %%mm0, %%mm3    \n\t"
  772.             "movq       %%mm1, %%mm4    \n\t"
  773.             "movq       %%mm2, %%mm5    \n\t"
  774.             "punpcklwd     %5, %%mm0    \n\t"
  775.             "punpcklwd     %5, %%mm1    \n\t"
  776.             "punpcklwd     %5, %%mm2    \n\t"
  777.             "punpckhwd     %5, %%mm3    \n\t"
  778.             "punpckhwd     %5, %%mm4    \n\t"
  779.             "punpckhwd     %5, %%mm5    \n\t"
  780.             "psllq         $8, %%mm1    \n\t"
  781.             "psllq        $16, %%mm2    \n\t"
  782.             "por        %%mm1, %%mm0    \n\t"
  783.             "por        %%mm2, %%mm0    \n\t"
  784.             "psllq         $8, %%mm4    \n\t"
  785.             "psllq        $16, %%mm5    \n\t"
  786.             "por        %%mm4, %%mm3    \n\t"
  787.             "por        %%mm5, %%mm3    \n\t"
  788.  
  789.             :"=m"(*d)
  790.             :"r"(s),"m"(mask15b),"m"(mask15g),"m"(mask15r), "m"(mmx_null)
  791.              NAMED_CONSTRAINTS_ADD(mul15_mid,mul15_hi)
  792.             :"memory");
  793.         /* borrowed 32 to 24 */
  794.         __asm__ volatile(
  795.             "movq       %%mm0, %%mm4    \n\t"
  796.             "movq       %%mm3, %%mm5    \n\t"
  797.             "movq       %%mm6, %%mm0    \n\t"
  798.             "movq       %%mm7, %%mm1    \n\t"
  799.  
  800.             "movq       %%mm4, %%mm6    \n\t"
  801.             "movq       %%mm5, %%mm7    \n\t"
  802.             "movq       %%mm0, %%mm2    \n\t"
  803.             "movq       %%mm1, %%mm3    \n\t"
  804.  
  805.             STORE_BGR24_MMX
  806.  
  807.             :: "r"(d), "m"(*s)
  808.               NAMED_CONSTRAINTS_ADD(mask24l,mask24h)
  809.             :"memory");
  810.         d += 24;
  811.         s += 8;
  812.     }
  813.     __asm__ volatile(SFENCE:::"memory");
  814.     __asm__ volatile(EMMS:::"memory");
  815.     while (s < end) {
  816.         register uint16_t bgr;
  817.         bgr = *s++;
  818.         *d++ = ((bgr&0x1F)<<3) | ((bgr&0x1F)>>2);
  819.         *d++ = ((bgr&0x3E0)>>2) | ((bgr&0x3E0)>>7);
  820.         *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
  821.     }
  822. }
  823.  
  824. static inline void RENAME(rgb16tobgr24)(const uint8_t *src, uint8_t *dst, int src_size)
  825. {
  826.     const uint16_t *end;
  827.     const uint16_t *mm_end;
  828.     uint8_t *d = (uint8_t *)dst;
  829.     const uint16_t *s = (const uint16_t *)src;
  830.     end = s + src_size/2;
  831.     __asm__ volatile(PREFETCH"    %0"::"m"(*s):"memory");
  832.     mm_end = end - 7;
  833.     while (s < mm_end) {
  834.         __asm__ volatile(
  835.             PREFETCH"  32(%1)           \n\t"
  836.             "movq        (%1), %%mm0    \n\t"
  837.             "movq        (%1), %%mm1    \n\t"
  838.             "movq        (%1), %%mm2    \n\t"
  839.             "pand          %2, %%mm0    \n\t"
  840.             "pand          %3, %%mm1    \n\t"
  841.             "pand          %4, %%mm2    \n\t"
  842.             "psllq         $5, %%mm0    \n\t"
  843.             "psrlq         $1, %%mm2    \n\t"
  844.             "pmulhw        "MANGLE(mul15_mid)", %%mm0    \n\t"
  845.             "pmulhw        "MANGLE(mul16_mid)", %%mm1    \n\t"
  846.             "pmulhw        "MANGLE(mul15_hi)", %%mm2    \n\t"
  847.             "movq       %%mm0, %%mm3    \n\t"
  848.             "movq       %%mm1, %%mm4    \n\t"
  849.             "movq       %%mm2, %%mm5    \n\t"
  850.             "punpcklwd     %5, %%mm0    \n\t"
  851.             "punpcklwd     %5, %%mm1    \n\t"
  852.             "punpcklwd     %5, %%mm2    \n\t"
  853.             "punpckhwd     %5, %%mm3    \n\t"
  854.             "punpckhwd     %5, %%mm4    \n\t"
  855.             "punpckhwd     %5, %%mm5    \n\t"
  856.             "psllq         $8, %%mm1    \n\t"
  857.             "psllq        $16, %%mm2    \n\t"
  858.             "por        %%mm1, %%mm0    \n\t"
  859.             "por        %%mm2, %%mm0    \n\t"
  860.             "psllq         $8, %%mm4    \n\t"
  861.             "psllq        $16, %%mm5    \n\t"
  862.             "por        %%mm4, %%mm3    \n\t"
  863.             "por        %%mm5, %%mm3    \n\t"
  864.  
  865.             "movq       %%mm0, %%mm6    \n\t"
  866.             "movq       %%mm3, %%mm7    \n\t"
  867.  
  868.             "movq       8(%1), %%mm0    \n\t"
  869.             "movq       8(%1), %%mm1    \n\t"
  870.             "movq       8(%1), %%mm2    \n\t"
  871.             "pand          %2, %%mm0    \n\t"
  872.             "pand          %3, %%mm1    \n\t"
  873.             "pand          %4, %%mm2    \n\t"
  874.             "psllq         $5, %%mm0    \n\t"
  875.             "psrlq         $1, %%mm2    \n\t"
  876.             "pmulhw        "MANGLE(mul15_mid)", %%mm0    \n\t"
  877.             "pmulhw        "MANGLE(mul16_mid)", %%mm1    \n\t"
  878.             "pmulhw        "MANGLE(mul15_hi)", %%mm2    \n\t"
  879.             "movq       %%mm0, %%mm3    \n\t"
  880.             "movq       %%mm1, %%mm4    \n\t"
  881.             "movq       %%mm2, %%mm5    \n\t"
  882.             "punpcklwd     %5, %%mm0    \n\t"
  883.             "punpcklwd     %5, %%mm1    \n\t"
  884.             "punpcklwd     %5, %%mm2    \n\t"
  885.             "punpckhwd     %5, %%mm3    \n\t"
  886.             "punpckhwd     %5, %%mm4    \n\t"
  887.             "punpckhwd     %5, %%mm5    \n\t"
  888.             "psllq         $8, %%mm1    \n\t"
  889.             "psllq        $16, %%mm2    \n\t"
  890.             "por        %%mm1, %%mm0    \n\t"
  891.             "por        %%mm2, %%mm0    \n\t"
  892.             "psllq         $8, %%mm4    \n\t"
  893.             "psllq        $16, %%mm5    \n\t"
  894.             "por        %%mm4, %%mm3    \n\t"
  895.             "por        %%mm5, %%mm3    \n\t"
  896.             :"=m"(*d)
  897.             :"r"(s),"m"(mask16b),"m"(mask16g),"m"(mask16r),"m"(mmx_null)
  898.              NAMED_CONSTRAINTS_ADD(mul15_mid,mul16_mid,mul15_hi)
  899.             :"memory");
  900.         /* borrowed 32 to 24 */
  901.         __asm__ volatile(
  902.             "movq       %%mm0, %%mm4    \n\t"
  903.             "movq       %%mm3, %%mm5    \n\t"
  904.             "movq       %%mm6, %%mm0    \n\t"
  905.             "movq       %%mm7, %%mm1    \n\t"
  906.  
  907.             "movq       %%mm4, %%mm6    \n\t"
  908.             "movq       %%mm5, %%mm7    \n\t"
  909.             "movq       %%mm0, %%mm2    \n\t"
  910.             "movq       %%mm1, %%mm3    \n\t"
  911.  
  912.             STORE_BGR24_MMX
  913.  
  914.             :: "r"(d), "m"(*s)
  915.               NAMED_CONSTRAINTS_ADD(mask24l,mask24h)
  916.             :"memory");
  917.         d += 24;
  918.         s += 8;
  919.     }
  920.     __asm__ volatile(SFENCE:::"memory");
  921.     __asm__ volatile(EMMS:::"memory");
  922.     while (s < end) {
  923.         register uint16_t bgr;
  924.         bgr = *s++;
  925.         *d++ = ((bgr&0x1F)<<3) | ((bgr&0x1F)>>2);
  926.         *d++ = ((bgr&0x7E0)>>3) | ((bgr&0x7E0)>>9);
  927.         *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
  928.     }
  929. }
  930.  
  931. /*
  932.  * mm0 = 00 B3 00 B2 00 B1 00 B0
  933.  * mm1 = 00 G3 00 G2 00 G1 00 G0
  934.  * mm2 = 00 R3 00 R2 00 R1 00 R0
  935.  * mm6 = FF FF FF FF FF FF FF FF
  936.  * mm7 = 00 00 00 00 00 00 00 00
  937.  */
  938. #define PACK_RGB32 \
  939.     "packuswb   %%mm7, %%mm0    \n\t" /* 00 00 00 00 B3 B2 B1 B0 */ \
  940.     "packuswb   %%mm7, %%mm1    \n\t" /* 00 00 00 00 G3 G2 G1 G0 */ \
  941.     "packuswb   %%mm7, %%mm2    \n\t" /* 00 00 00 00 R3 R2 R1 R0 */ \
  942.     "punpcklbw  %%mm1, %%mm0    \n\t" /* G3 B3 G2 B2 G1 B1 G0 B0 */ \
  943.     "punpcklbw  %%mm6, %%mm2    \n\t" /* FF R3 FF R2 FF R1 FF R0 */ \
  944.     "movq       %%mm0, %%mm3    \n\t"                               \
  945.     "punpcklwd  %%mm2, %%mm0    \n\t" /* FF R1 G1 B1 FF R0 G0 B0 */ \
  946.     "punpckhwd  %%mm2, %%mm3    \n\t" /* FF R3 G3 B3 FF R2 G2 B2 */ \
  947.     MOVNTQ"     %%mm0,  (%0)    \n\t"                               \
  948.     MOVNTQ"     %%mm3, 8(%0)    \n\t"                               \
  949.  
  950. static inline void RENAME(rgb15to32)(const uint8_t *src, uint8_t *dst, int src_size)
  951. {
  952.     const uint16_t *end;
  953.     const uint16_t *mm_end;
  954.     uint8_t *d = dst;
  955.     const uint16_t *s = (const uint16_t *)src;
  956.     end = s + src_size/2;
  957.     __asm__ volatile(PREFETCH"    %0"::"m"(*s):"memory");
  958.     __asm__ volatile("pxor    %%mm7,%%mm7    \n\t":::"memory");
  959.     __asm__ volatile("pcmpeqd %%mm6,%%mm6    \n\t":::"memory");
  960.     mm_end = end - 3;
  961.     while (s < mm_end) {
  962.         __asm__ volatile(
  963.             PREFETCH"  32(%1)           \n\t"
  964.             "movq        (%1), %%mm0    \n\t"
  965.             "movq        (%1), %%mm1    \n\t"
  966.             "movq        (%1), %%mm2    \n\t"
  967.             "pand          %2, %%mm0    \n\t"
  968.             "pand          %3, %%mm1    \n\t"
  969.             "pand          %4, %%mm2    \n\t"
  970.             "psllq         $5, %%mm0    \n\t"
  971.             "pmulhw        %5, %%mm0    \n\t"
  972.             "pmulhw        %5, %%mm1    \n\t"
  973.             "pmulhw        "MANGLE(mul15_hi)", %%mm2    \n\t"
  974.             PACK_RGB32
  975.             ::"r"(d),"r"(s),"m"(mask15b),"m"(mask15g),"m"(mask15r) ,"m"(mul15_mid)
  976.               NAMED_CONSTRAINTS_ADD(mul15_hi)
  977.             :"memory");
  978.         d += 16;
  979.         s += 4;
  980.     }
  981.     __asm__ volatile(SFENCE:::"memory");
  982.     __asm__ volatile(EMMS:::"memory");
  983.     while (s < end) {
  984.         register uint16_t bgr;
  985.         bgr = *s++;
  986.         *d++ = ((bgr&0x1F)<<3) | ((bgr&0x1F)>>2);
  987.         *d++ = ((bgr&0x3E0)>>2) | ((bgr&0x3E0)>>7);
  988.         *d++ = ((bgr&0x7C00)>>7) | ((bgr&0x7C00)>>12);
  989.         *d++ = 255;
  990.     }
  991. }
  992.  
  993. static inline void RENAME(rgb16to32)(const uint8_t *src, uint8_t *dst, int src_size)
  994. {
  995.     const uint16_t *end;
  996.     const uint16_t *mm_end;
  997.     uint8_t *d = dst;
  998.     const uint16_t *s = (const uint16_t*)src;
  999.     end = s + src_size/2;
  1000.     __asm__ volatile(PREFETCH"    %0"::"m"(*s):"memory");
  1001.     __asm__ volatile("pxor    %%mm7,%%mm7    \n\t":::"memory");
  1002.     __asm__ volatile("pcmpeqd %%mm6,%%mm6    \n\t":::"memory");
  1003.     mm_end = end - 3;
  1004.     while (s < mm_end) {
  1005.         __asm__ volatile(
  1006.             PREFETCH"  32(%1)           \n\t"
  1007.             "movq        (%1), %%mm0    \n\t"
  1008.             "movq        (%1), %%mm1    \n\t"
  1009.             "movq        (%1), %%mm2    \n\t"
  1010.             "pand          %2, %%mm0    \n\t"
  1011.             "pand          %3, %%mm1    \n\t"
  1012.             "pand          %4, %%mm2    \n\t"
  1013.             "psllq         $5, %%mm0    \n\t"
  1014.             "psrlq         $1, %%mm2    \n\t"
  1015.             "pmulhw        %5, %%mm0    \n\t"
  1016.             "pmulhw        "MANGLE(mul16_mid)", %%mm1    \n\t"
  1017.             "pmulhw        "MANGLE(mul15_hi)", %%mm2    \n\t"
  1018.             PACK_RGB32
  1019.             ::"r"(d),"r"(s),"m"(mask16b),"m"(mask16g),"m"(mask16r),"m"(mul15_mid)
  1020.               NAMED_CONSTRAINTS_ADD(mul16_mid,mul15_hi)
  1021.             :"memory");
  1022.         d += 16;
  1023.         s += 4;
  1024.     }
  1025.     __asm__ volatile(SFENCE:::"memory");
  1026.     __asm__ volatile(EMMS:::"memory");
  1027.     while (s < end) {
  1028.         register uint16_t bgr;
  1029.         bgr = *s++;
  1030.         *d++ = ((bgr&0x1F)<<3) | ((bgr&0x1F)>>2);
  1031.         *d++ = ((bgr&0x7E0)>>3) | ((bgr&0x7E0)>>9);
  1032.         *d++ = ((bgr&0xF800)>>8) | ((bgr&0xF800)>>13);
  1033.         *d++ = 255;
  1034.     }
  1035. }
  1036.  
  1037. static inline void RENAME(shuffle_bytes_2103)(const uint8_t *src, uint8_t *dst, int src_size)
  1038. {
  1039.     x86_reg idx = 15 - src_size;
  1040.     const uint8_t *s = src-idx;
  1041.     uint8_t *d = dst-idx;
  1042.     __asm__ volatile(
  1043.         "test          %0, %0           \n\t"
  1044.         "jns           2f               \n\t"
  1045.         PREFETCH"       (%1, %0)        \n\t"
  1046.         "movq          %3, %%mm7        \n\t"
  1047.         "pxor          %4, %%mm7        \n\t"
  1048.         "movq       %%mm7, %%mm6        \n\t"
  1049.         "pxor          %5, %%mm7        \n\t"
  1050.         ".p2align       4               \n\t"
  1051.         "1:                             \n\t"
  1052.         PREFETCH"     32(%1, %0)        \n\t"
  1053.         "movq           (%1, %0), %%mm0 \n\t"
  1054.         "movq          8(%1, %0), %%mm1 \n\t"
  1055. # if COMPILE_TEMPLATE_MMXEXT
  1056.         "pshufw      $177, %%mm0, %%mm3 \n\t"
  1057.         "pshufw      $177, %%mm1, %%mm5 \n\t"
  1058.         "pand       %%mm7, %%mm0        \n\t"
  1059.         "pand       %%mm6, %%mm3        \n\t"
  1060.         "pand       %%mm7, %%mm1        \n\t"
  1061.         "pand       %%mm6, %%mm5        \n\t"
  1062.         "por        %%mm3, %%mm0        \n\t"
  1063.         "por        %%mm5, %%mm1        \n\t"
  1064. # else
  1065.         "movq       %%mm0, %%mm2        \n\t"
  1066.         "movq       %%mm1, %%mm4        \n\t"
  1067.         "pand       %%mm7, %%mm0        \n\t"
  1068.         "pand       %%mm6, %%mm2        \n\t"
  1069.         "pand       %%mm7, %%mm1        \n\t"
  1070.         "pand       %%mm6, %%mm4        \n\t"
  1071.         "movq       %%mm2, %%mm3        \n\t"
  1072.         "movq       %%mm4, %%mm5        \n\t"
  1073.         "pslld        $16, %%mm2        \n\t"
  1074.         "psrld        $16, %%mm3        \n\t"
  1075.         "pslld        $16, %%mm4        \n\t"
  1076.         "psrld        $16, %%mm5        \n\t"
  1077.         "por        %%mm2, %%mm0        \n\t"
  1078.         "por        %%mm4, %%mm1        \n\t"
  1079.         "por        %%mm3, %%mm0        \n\t"
  1080.         "por        %%mm5, %%mm1        \n\t"
  1081. # endif
  1082.         MOVNTQ"     %%mm0,  (%2, %0)    \n\t"
  1083.         MOVNTQ"     %%mm1, 8(%2, %0)    \n\t"
  1084.         "add          $16, %0           \n\t"
  1085.         "js            1b               \n\t"
  1086.         SFENCE"                         \n\t"
  1087.         EMMS"                           \n\t"
  1088.         "2:                             \n\t"
  1089.         : "+&r"(idx)
  1090.         : "r" (s), "r" (d), "m" (mask32b), "m" (mask32r), "m" (mmx_one)
  1091.         : "memory");
  1092.     for (; idx<15; idx+=4) {
  1093.         register unsigned v  = *(const uint32_t *)&s[idx], g = v & 0xff00ff00;
  1094.         v &= 0xff00ff;
  1095.         *(uint32_t *)&d[idx] = (v>>16) + g + (v<<16);
  1096.     }
  1097. }
  1098.  
  1099. static inline void RENAME(rgb24tobgr24)(const uint8_t *src, uint8_t *dst, int src_size)
  1100. {
  1101.     unsigned i;
  1102.     x86_reg mmx_size= 23 - src_size;
  1103.     __asm__ volatile (
  1104.         "test             %%"REG_a", %%"REG_a"          \n\t"
  1105.         "jns                     2f                     \n\t"
  1106.         "movq     "MANGLE(mask24r)", %%mm5              \n\t"
  1107.         "movq     "MANGLE(mask24g)", %%mm6              \n\t"
  1108.         "movq     "MANGLE(mask24b)", %%mm7              \n\t"
  1109.         ".p2align                 4                     \n\t"
  1110.         "1:                                             \n\t"
  1111.         PREFETCH" 32(%1, %%"REG_a")                     \n\t"
  1112.         "movq       (%1, %%"REG_a"), %%mm0              \n\t" // BGR BGR BG
  1113.         "movq       (%1, %%"REG_a"), %%mm1              \n\t" // BGR BGR BG
  1114.         "movq      2(%1, %%"REG_a"), %%mm2              \n\t" // R BGR BGR B
  1115.         "psllq                  $16, %%mm0              \n\t" // 00 BGR BGR
  1116.         "pand                 %%mm5, %%mm0              \n\t"
  1117.         "pand                 %%mm6, %%mm1              \n\t"
  1118.         "pand                 %%mm7, %%mm2              \n\t"
  1119.         "por                  %%mm0, %%mm1              \n\t"
  1120.         "por                  %%mm2, %%mm1              \n\t"
  1121.         "movq      6(%1, %%"REG_a"), %%mm0              \n\t" // BGR BGR BG
  1122.         MOVNTQ"               %%mm1,   (%2, %%"REG_a")  \n\t" // RGB RGB RG
  1123.         "movq      8(%1, %%"REG_a"), %%mm1              \n\t" // R BGR BGR B
  1124.         "movq     10(%1, %%"REG_a"), %%mm2              \n\t" // GR BGR BGR
  1125.         "pand                 %%mm7, %%mm0              \n\t"
  1126.         "pand                 %%mm5, %%mm1              \n\t"
  1127.         "pand                 %%mm6, %%mm2              \n\t"
  1128.         "por                  %%mm0, %%mm1              \n\t"
  1129.         "por                  %%mm2, %%mm1              \n\t"
  1130.         "movq     14(%1, %%"REG_a"), %%mm0              \n\t" // R BGR BGR B
  1131.         MOVNTQ"               %%mm1,  8(%2, %%"REG_a")  \n\t" // B RGB RGB R
  1132.         "movq     16(%1, %%"REG_a"), %%mm1              \n\t" // GR BGR BGR
  1133.         "movq     18(%1, %%"REG_a"), %%mm2              \n\t" // BGR BGR BG
  1134.         "pand                 %%mm6, %%mm0              \n\t"
  1135.         "pand                 %%mm7, %%mm1              \n\t"
  1136.         "pand                 %%mm5, %%mm2              \n\t"
  1137.         "por                  %%mm0, %%mm1              \n\t"
  1138.         "por                  %%mm2, %%mm1              \n\t"
  1139.         MOVNTQ"               %%mm1, 16(%2, %%"REG_a")  \n\t"
  1140.         "add                    $24, %%"REG_a"          \n\t"
  1141.         " js                     1b                     \n\t"
  1142.         "2:                                             \n\t"
  1143.         : "+a" (mmx_size)
  1144.         : "r" (src-mmx_size), "r"(dst-mmx_size)
  1145.           NAMED_CONSTRAINTS_ADD(mask24r,mask24g,mask24b)
  1146.     );
  1147.  
  1148.     __asm__ volatile(SFENCE:::"memory");
  1149.     __asm__ volatile(EMMS:::"memory");
  1150.  
  1151.     if (mmx_size==23) return; //finished, was multiple of 8
  1152.  
  1153.     src+= src_size;
  1154.     dst+= src_size;
  1155.     src_size= 23-mmx_size;
  1156.     src-= src_size;
  1157.     dst-= src_size;
  1158.     for (i=0; i<src_size; i+=3) {
  1159.         register uint8_t x;
  1160.         x          = src[i + 2];
  1161.         dst[i + 1] = src[i + 1];
  1162.         dst[i + 2] = src[i + 0];
  1163.         dst[i + 0] = x;
  1164.     }
  1165. }
  1166.  
  1167. static inline void RENAME(yuvPlanartoyuy2)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst,
  1168.                                            int width, int height,
  1169.                                            int lumStride, int chromStride, int dstStride, int vertLumPerChroma)
  1170. {
  1171.     int y;
  1172.     const x86_reg chromWidth= width>>1;
  1173.     for (y=0; y<height; y++) {
  1174.         //FIXME handle 2 lines at once (fewer prefetches, reuse some chroma, but very likely memory-limited anyway)
  1175.         __asm__ volatile(
  1176.             "xor                 %%"REG_a", %%"REG_a"   \n\t"
  1177.             ".p2align                    4              \n\t"
  1178.             "1:                                         \n\t"
  1179.             PREFETCH"    32(%1, %%"REG_a", 2)           \n\t"
  1180.             PREFETCH"    32(%2, %%"REG_a")              \n\t"
  1181.             PREFETCH"    32(%3, %%"REG_a")              \n\t"
  1182.             "movq          (%2, %%"REG_a"), %%mm0       \n\t" // U(0)
  1183.             "movq                    %%mm0, %%mm2       \n\t" // U(0)
  1184.             "movq          (%3, %%"REG_a"), %%mm1       \n\t" // V(0)
  1185.             "punpcklbw               %%mm1, %%mm0       \n\t" // UVUV UVUV(0)
  1186.             "punpckhbw               %%mm1, %%mm2       \n\t" // UVUV UVUV(8)
  1187.  
  1188.             "movq        (%1, %%"REG_a",2), %%mm3       \n\t" // Y(0)
  1189.             "movq       8(%1, %%"REG_a",2), %%mm5       \n\t" // Y(8)
  1190.             "movq                    %%mm3, %%mm4       \n\t" // Y(0)
  1191.             "movq                    %%mm5, %%mm6       \n\t" // Y(8)
  1192.             "punpcklbw               %%mm0, %%mm3       \n\t" // YUYV YUYV(0)
  1193.             "punpckhbw               %%mm0, %%mm4       \n\t" // YUYV YUYV(4)
  1194.             "punpcklbw               %%mm2, %%mm5       \n\t" // YUYV YUYV(8)
  1195.             "punpckhbw               %%mm2, %%mm6       \n\t" // YUYV YUYV(12)
  1196.  
  1197.             MOVNTQ"                  %%mm3,   (%0, %%"REG_a", 4)    \n\t"
  1198.             MOVNTQ"                  %%mm4,  8(%0, %%"REG_a", 4)    \n\t"
  1199.             MOVNTQ"                  %%mm5, 16(%0, %%"REG_a", 4)    \n\t"
  1200.             MOVNTQ"                  %%mm6, 24(%0, %%"REG_a", 4)    \n\t"
  1201.  
  1202.             "add                        $8, %%"REG_a"   \n\t"
  1203.             "cmp                        %4, %%"REG_a"   \n\t"
  1204.             " jb                        1b              \n\t"
  1205.             ::"r"(dst), "r"(ysrc), "r"(usrc), "r"(vsrc), "g" (chromWidth)
  1206.             : "%"REG_a
  1207.         );
  1208.         if ((y&(vertLumPerChroma-1)) == vertLumPerChroma-1) {
  1209.             usrc += chromStride;
  1210.             vsrc += chromStride;
  1211.         }
  1212.         ysrc += lumStride;
  1213.         dst  += dstStride;
  1214.     }
  1215.     __asm__(EMMS"       \n\t"
  1216.             SFENCE"     \n\t"
  1217.             :::"memory");
  1218. }
  1219.  
  1220. /**
  1221.  * Height should be a multiple of 2 and width should be a multiple of 16.
  1222.  * (If this is a problem for anyone then tell me, and I will fix it.)
  1223.  */
  1224. static inline void RENAME(yv12toyuy2)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst,
  1225.                                       int width, int height,
  1226.                                       int lumStride, int chromStride, int dstStride)
  1227. {
  1228.     //FIXME interpolate chroma
  1229.     RENAME(yuvPlanartoyuy2)(ysrc, usrc, vsrc, dst, width, height, lumStride, chromStride, dstStride, 2);
  1230. }
  1231.  
  1232. static inline void RENAME(yuvPlanartouyvy)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst,
  1233.                                            int width, int height,
  1234.                                            int lumStride, int chromStride, int dstStride, int vertLumPerChroma)
  1235. {
  1236.     int y;
  1237.     const x86_reg chromWidth= width>>1;
  1238.     for (y=0; y<height; y++) {
  1239.         //FIXME handle 2 lines at once (fewer prefetches, reuse some chroma, but very likely memory-limited anyway)
  1240.         __asm__ volatile(
  1241.             "xor                %%"REG_a", %%"REG_a"    \n\t"
  1242.             ".p2align                   4               \n\t"
  1243.             "1:                                         \n\t"
  1244.             PREFETCH"   32(%1, %%"REG_a", 2)            \n\t"
  1245.             PREFETCH"   32(%2, %%"REG_a")               \n\t"
  1246.             PREFETCH"   32(%3, %%"REG_a")               \n\t"
  1247.             "movq         (%2, %%"REG_a"), %%mm0        \n\t" // U(0)
  1248.             "movq                   %%mm0, %%mm2        \n\t" // U(0)
  1249.             "movq         (%3, %%"REG_a"), %%mm1        \n\t" // V(0)
  1250.             "punpcklbw              %%mm1, %%mm0        \n\t" // UVUV UVUV(0)
  1251.             "punpckhbw              %%mm1, %%mm2        \n\t" // UVUV UVUV(8)
  1252.  
  1253.             "movq       (%1, %%"REG_a",2), %%mm3        \n\t" // Y(0)
  1254.             "movq      8(%1, %%"REG_a",2), %%mm5        \n\t" // Y(8)
  1255.             "movq                   %%mm0, %%mm4        \n\t" // Y(0)
  1256.             "movq                   %%mm2, %%mm6        \n\t" // Y(8)
  1257.             "punpcklbw              %%mm3, %%mm0        \n\t" // YUYV YUYV(0)
  1258.             "punpckhbw              %%mm3, %%mm4        \n\t" // YUYV YUYV(4)
  1259.             "punpcklbw              %%mm5, %%mm2        \n\t" // YUYV YUYV(8)
  1260.             "punpckhbw              %%mm5, %%mm6        \n\t" // YUYV YUYV(12)
  1261.  
  1262.             MOVNTQ"                 %%mm0,   (%0, %%"REG_a", 4)     \n\t"
  1263.             MOVNTQ"                 %%mm4,  8(%0, %%"REG_a", 4)     \n\t"
  1264.             MOVNTQ"                 %%mm2, 16(%0, %%"REG_a", 4)     \n\t"
  1265.             MOVNTQ"                 %%mm6, 24(%0, %%"REG_a", 4)     \n\t"
  1266.  
  1267.             "add                       $8, %%"REG_a"    \n\t"
  1268.             "cmp                       %4, %%"REG_a"    \n\t"
  1269.             " jb                       1b               \n\t"
  1270.             ::"r"(dst), "r"(ysrc), "r"(usrc), "r"(vsrc), "g" (chromWidth)
  1271.             : "%"REG_a
  1272.         );
  1273.         if ((y&(vertLumPerChroma-1)) == vertLumPerChroma-1) {
  1274.             usrc += chromStride;
  1275.             vsrc += chromStride;
  1276.         }
  1277.         ysrc += lumStride;
  1278.         dst += dstStride;
  1279.     }
  1280.     __asm__(EMMS"       \n\t"
  1281.             SFENCE"     \n\t"
  1282.             :::"memory");
  1283. }
  1284.  
  1285. /**
  1286.  * Height should be a multiple of 2 and width should be a multiple of 16
  1287.  * (If this is a problem for anyone then tell me, and I will fix it.)
  1288.  */
  1289. static inline void RENAME(yv12touyvy)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst,
  1290.                                       int width, int height,
  1291.                                       int lumStride, int chromStride, int dstStride)
  1292. {
  1293.     //FIXME interpolate chroma
  1294.     RENAME(yuvPlanartouyvy)(ysrc, usrc, vsrc, dst, width, height, lumStride, chromStride, dstStride, 2);
  1295. }
  1296.  
  1297. /**
  1298.  * Width should be a multiple of 16.
  1299.  */
  1300. static inline void RENAME(yuv422ptouyvy)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst,
  1301.                                          int width, int height,
  1302.                                          int lumStride, int chromStride, int dstStride)
  1303. {
  1304.     RENAME(yuvPlanartouyvy)(ysrc, usrc, vsrc, dst, width, height, lumStride, chromStride, dstStride, 1);
  1305. }
  1306.  
  1307. /**
  1308.  * Width should be a multiple of 16.
  1309.  */
  1310. static inline void RENAME(yuv422ptoyuy2)(const uint8_t *ysrc, const uint8_t *usrc, const uint8_t *vsrc, uint8_t *dst,
  1311.                                          int width, int height,
  1312.                                          int lumStride, int chromStride, int dstStride)
  1313. {
  1314.     RENAME(yuvPlanartoyuy2)(ysrc, usrc, vsrc, dst, width, height, lumStride, chromStride, dstStride, 1);
  1315. }
  1316.  
  1317. /**
  1318.  * Height should be a multiple of 2 and width should be a multiple of 16.
  1319.  * (If this is a problem for anyone then tell me, and I will fix it.)
  1320.  */
  1321. static inline void RENAME(yuy2toyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
  1322.                                       int width, int height,
  1323.                                       int lumStride, int chromStride, int srcStride)
  1324. {
  1325.     int y;
  1326.     const x86_reg chromWidth= width>>1;
  1327.     for (y=0; y<height; y+=2) {
  1328.         __asm__ volatile(
  1329.             "xor                 %%"REG_a", %%"REG_a"   \n\t"
  1330.             "pcmpeqw                 %%mm7, %%mm7       \n\t"
  1331.             "psrlw                      $8, %%mm7       \n\t" // FF,00,FF,00...
  1332.             ".p2align                    4              \n\t"
  1333.             "1:                \n\t"
  1334.             PREFETCH" 64(%0, %%"REG_a", 4)              \n\t"
  1335.             "movq       (%0, %%"REG_a", 4), %%mm0       \n\t" // YUYV YUYV(0)
  1336.             "movq      8(%0, %%"REG_a", 4), %%mm1       \n\t" // YUYV YUYV(4)
  1337.             "movq                    %%mm0, %%mm2       \n\t" // YUYV YUYV(0)
  1338.             "movq                    %%mm1, %%mm3       \n\t" // YUYV YUYV(4)
  1339.             "psrlw                      $8, %%mm0       \n\t" // U0V0 U0V0(0)
  1340.             "psrlw                      $8, %%mm1       \n\t" // U0V0 U0V0(4)
  1341.             "pand                    %%mm7, %%mm2       \n\t" // Y0Y0 Y0Y0(0)
  1342.             "pand                    %%mm7, %%mm3       \n\t" // Y0Y0 Y0Y0(4)
  1343.             "packuswb                %%mm1, %%mm0       \n\t" // UVUV UVUV(0)
  1344.             "packuswb                %%mm3, %%mm2       \n\t" // YYYY YYYY(0)
  1345.  
  1346.             MOVNTQ"                  %%mm2, (%1, %%"REG_a", 2)  \n\t"
  1347.  
  1348.             "movq     16(%0, %%"REG_a", 4), %%mm1       \n\t" // YUYV YUYV(8)
  1349.             "movq     24(%0, %%"REG_a", 4), %%mm2       \n\t" // YUYV YUYV(12)
  1350.             "movq                    %%mm1, %%mm3       \n\t" // YUYV YUYV(8)
  1351.             "movq                    %%mm2, %%mm4       \n\t" // YUYV YUYV(12)
  1352.             "psrlw                      $8, %%mm1       \n\t" // U0V0 U0V0(8)
  1353.             "psrlw                      $8, %%mm2       \n\t" // U0V0 U0V0(12)
  1354.             "pand                    %%mm7, %%mm3       \n\t" // Y0Y0 Y0Y0(8)
  1355.             "pand                    %%mm7, %%mm4       \n\t" // Y0Y0 Y0Y0(12)
  1356.             "packuswb                %%mm2, %%mm1       \n\t" // UVUV UVUV(8)
  1357.             "packuswb                %%mm4, %%mm3       \n\t" // YYYY YYYY(8)
  1358.  
  1359.             MOVNTQ"                  %%mm3, 8(%1, %%"REG_a", 2) \n\t"
  1360.  
  1361.             "movq                    %%mm0, %%mm2       \n\t" // UVUV UVUV(0)
  1362.             "movq                    %%mm1, %%mm3       \n\t" // UVUV UVUV(8)
  1363.             "psrlw                      $8, %%mm0       \n\t" // V0V0 V0V0(0)
  1364.             "psrlw                      $8, %%mm1       \n\t" // V0V0 V0V0(8)
  1365.             "pand                    %%mm7, %%mm2       \n\t" // U0U0 U0U0(0)
  1366.             "pand                    %%mm7, %%mm3       \n\t" // U0U0 U0U0(8)
  1367.             "packuswb                %%mm1, %%mm0       \n\t" // VVVV VVVV(0)
  1368.             "packuswb                %%mm3, %%mm2       \n\t" // UUUU UUUU(0)
  1369.  
  1370.             MOVNTQ"                  %%mm0, (%3, %%"REG_a")     \n\t"
  1371.             MOVNTQ"                  %%mm2, (%2, %%"REG_a")     \n\t"
  1372.  
  1373.             "add                        $8, %%"REG_a"   \n\t"
  1374.             "cmp                        %4, %%"REG_a"   \n\t"
  1375.             " jb                        1b              \n\t"
  1376.             ::"r"(src), "r"(ydst), "r"(udst), "r"(vdst), "g" (chromWidth)
  1377.             : "memory", "%"REG_a
  1378.         );
  1379.  
  1380.         ydst += lumStride;
  1381.         src  += srcStride;
  1382.  
  1383.         __asm__ volatile(
  1384.             "xor                 %%"REG_a", %%"REG_a"   \n\t"
  1385.             ".p2align                    4              \n\t"
  1386.             "1:                                         \n\t"
  1387.             PREFETCH" 64(%0, %%"REG_a", 4)              \n\t"
  1388.             "movq       (%0, %%"REG_a", 4), %%mm0       \n\t" // YUYV YUYV(0)
  1389.             "movq      8(%0, %%"REG_a", 4), %%mm1       \n\t" // YUYV YUYV(4)
  1390.             "movq     16(%0, %%"REG_a", 4), %%mm2       \n\t" // YUYV YUYV(8)
  1391.             "movq     24(%0, %%"REG_a", 4), %%mm3       \n\t" // YUYV YUYV(12)
  1392.             "pand                    %%mm7, %%mm0       \n\t" // Y0Y0 Y0Y0(0)
  1393.             "pand                    %%mm7, %%mm1       \n\t" // Y0Y0 Y0Y0(4)
  1394.             "pand                    %%mm7, %%mm2       \n\t" // Y0Y0 Y0Y0(8)
  1395.             "pand                    %%mm7, %%mm3       \n\t" // Y0Y0 Y0Y0(12)
  1396.             "packuswb                %%mm1, %%mm0       \n\t" // YYYY YYYY(0)
  1397.             "packuswb                %%mm3, %%mm2       \n\t" // YYYY YYYY(8)
  1398.  
  1399.             MOVNTQ"                  %%mm0,  (%1, %%"REG_a", 2) \n\t"
  1400.             MOVNTQ"                  %%mm2, 8(%1, %%"REG_a", 2) \n\t"
  1401.  
  1402.             "add                        $8, %%"REG_a"   \n\t"
  1403.             "cmp                        %4, %%"REG_a"   \n\t"
  1404.             " jb                        1b              \n\t"
  1405.  
  1406.             ::"r"(src), "r"(ydst), "r"(udst), "r"(vdst), "g" (chromWidth)
  1407.             : "memory", "%"REG_a
  1408.         );
  1409.         udst += chromStride;
  1410.         vdst += chromStride;
  1411.         ydst += lumStride;
  1412.         src  += srcStride;
  1413.     }
  1414.     __asm__ volatile(EMMS"       \n\t"
  1415.                      SFENCE"     \n\t"
  1416.                      :::"memory");
  1417. }
  1418. #endif /* !COMPILE_TEMPLATE_AMD3DNOW */
  1419.  
  1420. #if COMPILE_TEMPLATE_MMXEXT || COMPILE_TEMPLATE_AMD3DNOW
  1421. static inline void RENAME(planar2x)(const uint8_t *src, uint8_t *dst, int srcWidth, int srcHeight, int srcStride, int dstStride)
  1422. {
  1423.     int x,y;
  1424.  
  1425.     dst[0]= src[0];
  1426.  
  1427.     // first line
  1428.     for (x=0; x<srcWidth-1; x++) {
  1429.         dst[2*x+1]= (3*src[x] +   src[x+1])>>2;
  1430.         dst[2*x+2]= (  src[x] + 3*src[x+1])>>2;
  1431.     }
  1432.     dst[2*srcWidth-1]= src[srcWidth-1];
  1433.  
  1434.     dst+= dstStride;
  1435.  
  1436.     for (y=1; y<srcHeight; y++) {
  1437.         const x86_reg mmxSize= srcWidth&~15;
  1438.         __asm__ volatile(
  1439.             "mov           %4, %%"REG_a"            \n\t"
  1440.             "movq        "MANGLE(mmx_ff)", %%mm0    \n\t"
  1441.             "movq         (%0, %%"REG_a"), %%mm4    \n\t"
  1442.             "movq                   %%mm4, %%mm2    \n\t"
  1443.             "psllq                     $8, %%mm4    \n\t"
  1444.             "pand                   %%mm0, %%mm2    \n\t"
  1445.             "por                    %%mm2, %%mm4    \n\t"
  1446.             "movq         (%1, %%"REG_a"), %%mm5    \n\t"
  1447.             "movq                   %%mm5, %%mm3    \n\t"
  1448.             "psllq                     $8, %%mm5    \n\t"
  1449.             "pand                   %%mm0, %%mm3    \n\t"
  1450.             "por                    %%mm3, %%mm5    \n\t"
  1451.             "1:                                     \n\t"
  1452.             "movq         (%0, %%"REG_a"), %%mm0    \n\t"
  1453.             "movq         (%1, %%"REG_a"), %%mm1    \n\t"
  1454.             "movq        1(%0, %%"REG_a"), %%mm2    \n\t"
  1455.             "movq        1(%1, %%"REG_a"), %%mm3    \n\t"
  1456.             PAVGB"                  %%mm0, %%mm5    \n\t"
  1457.             PAVGB"                  %%mm0, %%mm3    \n\t"
  1458.             PAVGB"                  %%mm0, %%mm5    \n\t"
  1459.             PAVGB"                  %%mm0, %%mm3    \n\t"
  1460.             PAVGB"                  %%mm1, %%mm4    \n\t"
  1461.             PAVGB"                  %%mm1, %%mm2    \n\t"
  1462.             PAVGB"                  %%mm1, %%mm4    \n\t"
  1463.             PAVGB"                  %%mm1, %%mm2    \n\t"
  1464.             "movq                   %%mm5, %%mm7    \n\t"
  1465.             "movq                   %%mm4, %%mm6    \n\t"
  1466.             "punpcklbw              %%mm3, %%mm5    \n\t"
  1467.             "punpckhbw              %%mm3, %%mm7    \n\t"
  1468.             "punpcklbw              %%mm2, %%mm4    \n\t"
  1469.             "punpckhbw              %%mm2, %%mm6    \n\t"
  1470.             MOVNTQ"                 %%mm5,  (%2, %%"REG_a", 2)  \n\t"
  1471.             MOVNTQ"                 %%mm7, 8(%2, %%"REG_a", 2)  \n\t"
  1472.             MOVNTQ"                 %%mm4,  (%3, %%"REG_a", 2)  \n\t"
  1473.             MOVNTQ"                 %%mm6, 8(%3, %%"REG_a", 2)  \n\t"
  1474.             "add                       $8, %%"REG_a"            \n\t"
  1475.             "movq       -1(%0, %%"REG_a"), %%mm4    \n\t"
  1476.             "movq       -1(%1, %%"REG_a"), %%mm5    \n\t"
  1477.             " js                       1b                       \n\t"
  1478.             :: "r" (src + mmxSize  ), "r" (src + srcStride + mmxSize  ),
  1479.                "r" (dst + mmxSize*2), "r" (dst + dstStride + mmxSize*2),
  1480.                "g" (-mmxSize)
  1481.                NAMED_CONSTRAINTS_ADD(mmx_ff)
  1482.             : "%"REG_a
  1483.         );
  1484.  
  1485.         for (x=mmxSize-1; x<srcWidth-1; x++) {
  1486.             dst[2*x          +1]= (3*src[x+0] +   src[x+srcStride+1])>>2;
  1487.             dst[2*x+dstStride+2]= (  src[x+0] + 3*src[x+srcStride+1])>>2;
  1488.             dst[2*x+dstStride+1]= (  src[x+1] + 3*src[x+srcStride  ])>>2;
  1489.             dst[2*x          +2]= (3*src[x+1] +   src[x+srcStride  ])>>2;
  1490.         }
  1491.         dst[srcWidth*2 -1            ]= (3*src[srcWidth-1] +   src[srcWidth-1 + srcStride])>>2;
  1492.         dst[srcWidth*2 -1 + dstStride]= (  src[srcWidth-1] + 3*src[srcWidth-1 + srcStride])>>2;
  1493.  
  1494.         dst+=dstStride*2;
  1495.         src+=srcStride;
  1496.     }
  1497.  
  1498.     // last line
  1499.     dst[0]= src[0];
  1500.  
  1501.     for (x=0; x<srcWidth-1; x++) {
  1502.         dst[2*x+1]= (3*src[x] +   src[x+1])>>2;
  1503.         dst[2*x+2]= (  src[x] + 3*src[x+1])>>2;
  1504.     }
  1505.     dst[2*srcWidth-1]= src[srcWidth-1];
  1506.  
  1507.     __asm__ volatile(EMMS"       \n\t"
  1508.                      SFENCE"     \n\t"
  1509.                      :::"memory");
  1510. }
  1511. #endif /* COMPILE_TEMPLATE_MMXEXT || COMPILE_TEMPLATE_AMD3DNOW */
  1512.  
  1513. #if !COMPILE_TEMPLATE_AMD3DNOW
  1514. /**
  1515.  * Height should be a multiple of 2 and width should be a multiple of 16.
  1516.  * (If this is a problem for anyone then tell me, and I will fix it.)
  1517.  * Chrominance data is only taken from every second line, others are ignored.
  1518.  * FIXME: Write HQ version.
  1519.  */
  1520. static inline void RENAME(uyvytoyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
  1521.                                       int width, int height,
  1522.                                       int lumStride, int chromStride, int srcStride)
  1523. {
  1524.     int y;
  1525.     const x86_reg chromWidth= width>>1;
  1526.     for (y=0; y<height; y+=2) {
  1527.         __asm__ volatile(
  1528.             "xor                 %%"REG_a", %%"REG_a"   \n\t"
  1529.             "pcmpeqw             %%mm7, %%mm7   \n\t"
  1530.             "psrlw                  $8, %%mm7   \n\t" // FF,00,FF,00...
  1531.             ".p2align                4          \n\t"
  1532.             "1:                                 \n\t"
  1533.             PREFETCH" 64(%0, %%"REG_a", 4)          \n\t"
  1534.             "movq       (%0, %%"REG_a", 4), %%mm0   \n\t" // UYVY UYVY(0)
  1535.             "movq      8(%0, %%"REG_a", 4), %%mm1   \n\t" // UYVY UYVY(4)
  1536.             "movq                %%mm0, %%mm2   \n\t" // UYVY UYVY(0)
  1537.             "movq                %%mm1, %%mm3   \n\t" // UYVY UYVY(4)
  1538.             "pand                %%mm7, %%mm0   \n\t" // U0V0 U0V0(0)
  1539.             "pand                %%mm7, %%mm1   \n\t" // U0V0 U0V0(4)
  1540.             "psrlw                  $8, %%mm2   \n\t" // Y0Y0 Y0Y0(0)
  1541.             "psrlw                  $8, %%mm3   \n\t" // Y0Y0 Y0Y0(4)
  1542.             "packuswb            %%mm1, %%mm0   \n\t" // UVUV UVUV(0)
  1543.             "packuswb            %%mm3, %%mm2   \n\t" // YYYY YYYY(0)
  1544.  
  1545.             MOVNTQ"              %%mm2,  (%1, %%"REG_a", 2) \n\t"
  1546.  
  1547.             "movq     16(%0, %%"REG_a", 4), %%mm1   \n\t" // UYVY UYVY(8)
  1548.             "movq     24(%0, %%"REG_a", 4), %%mm2   \n\t" // UYVY UYVY(12)
  1549.             "movq                %%mm1, %%mm3   \n\t" // UYVY UYVY(8)
  1550.             "movq                %%mm2, %%mm4   \n\t" // UYVY UYVY(12)
  1551.             "pand                %%mm7, %%mm1   \n\t" // U0V0 U0V0(8)
  1552.             "pand                %%mm7, %%mm2   \n\t" // U0V0 U0V0(12)
  1553.             "psrlw                  $8, %%mm3   \n\t" // Y0Y0 Y0Y0(8)
  1554.             "psrlw                  $8, %%mm4   \n\t" // Y0Y0 Y0Y0(12)
  1555.             "packuswb            %%mm2, %%mm1   \n\t" // UVUV UVUV(8)
  1556.             "packuswb            %%mm4, %%mm3   \n\t" // YYYY YYYY(8)
  1557.  
  1558.             MOVNTQ"              %%mm3, 8(%1, %%"REG_a", 2) \n\t"
  1559.  
  1560.             "movq                %%mm0, %%mm2   \n\t" // UVUV UVUV(0)
  1561.             "movq                %%mm1, %%mm3   \n\t" // UVUV UVUV(8)
  1562.             "psrlw                  $8, %%mm0   \n\t" // V0V0 V0V0(0)
  1563.             "psrlw                  $8, %%mm1   \n\t" // V0V0 V0V0(8)
  1564.             "pand                %%mm7, %%mm2   \n\t" // U0U0 U0U0(0)
  1565.             "pand                %%mm7, %%mm3   \n\t" // U0U0 U0U0(8)
  1566.             "packuswb            %%mm1, %%mm0   \n\t" // VVVV VVVV(0)
  1567.             "packuswb            %%mm3, %%mm2   \n\t" // UUUU UUUU(0)
  1568.  
  1569.             MOVNTQ"              %%mm0, (%3, %%"REG_a") \n\t"
  1570.             MOVNTQ"              %%mm2, (%2, %%"REG_a") \n\t"
  1571.  
  1572.             "add                    $8, %%"REG_a"   \n\t"
  1573.             "cmp                    %4, %%"REG_a"   \n\t"
  1574.             " jb                    1b          \n\t"
  1575.             ::"r"(src), "r"(ydst), "r"(udst), "r"(vdst), "g" (chromWidth)
  1576.             : "memory", "%"REG_a
  1577.         );
  1578.  
  1579.         ydst += lumStride;
  1580.         src  += srcStride;
  1581.  
  1582.         __asm__ volatile(
  1583.             "xor                 %%"REG_a", %%"REG_a"   \n\t"
  1584.             ".p2align                    4              \n\t"
  1585.             "1:                                 \n\t"
  1586.             PREFETCH" 64(%0, %%"REG_a", 4)          \n\t"
  1587.             "movq       (%0, %%"REG_a", 4), %%mm0   \n\t" // YUYV YUYV(0)
  1588.             "movq      8(%0, %%"REG_a", 4), %%mm1   \n\t" // YUYV YUYV(4)
  1589.             "movq     16(%0, %%"REG_a", 4), %%mm2   \n\t" // YUYV YUYV(8)
  1590.             "movq     24(%0, %%"REG_a", 4), %%mm3   \n\t" // YUYV YUYV(12)
  1591.             "psrlw                  $8, %%mm0   \n\t" // Y0Y0 Y0Y0(0)
  1592.             "psrlw                  $8, %%mm1   \n\t" // Y0Y0 Y0Y0(4)
  1593.             "psrlw                  $8, %%mm2   \n\t" // Y0Y0 Y0Y0(8)
  1594.             "psrlw                  $8, %%mm3   \n\t" // Y0Y0 Y0Y0(12)
  1595.             "packuswb            %%mm1, %%mm0   \n\t" // YYYY YYYY(0)
  1596.             "packuswb            %%mm3, %%mm2   \n\t" // YYYY YYYY(8)
  1597.  
  1598.             MOVNTQ"              %%mm0,  (%1, %%"REG_a", 2) \n\t"
  1599.             MOVNTQ"              %%mm2, 8(%1, %%"REG_a", 2) \n\t"
  1600.  
  1601.             "add                    $8, %%"REG_a"   \n\t"
  1602.             "cmp                    %4, %%"REG_a"   \n\t"
  1603.             " jb                    1b          \n\t"
  1604.  
  1605.             ::"r"(src), "r"(ydst), "r"(udst), "r"(vdst), "g" (chromWidth)
  1606.             : "memory", "%"REG_a
  1607.         );
  1608.         udst += chromStride;
  1609.         vdst += chromStride;
  1610.         ydst += lumStride;
  1611.         src  += srcStride;
  1612.     }
  1613.     __asm__ volatile(EMMS"       \n\t"
  1614.                      SFENCE"     \n\t"
  1615.                      :::"memory");
  1616. }
  1617. #endif /* !COMPILE_TEMPLATE_AMD3DNOW */
  1618.  
  1619. /**
  1620.  * Height should be a multiple of 2 and width should be a multiple of 2.
  1621.  * (If this is a problem for anyone then tell me, and I will fix it.)
  1622.  * Chrominance data is only taken from every second line,
  1623.  * others are ignored in the C version.
  1624.  * FIXME: Write HQ version.
  1625.  */
  1626. #if HAVE_7REGS
  1627. static inline void RENAME(rgb24toyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst,
  1628.                                        int width, int height,
  1629.                                        int lumStride, int chromStride, int srcStride,
  1630.                                        int32_t *rgb2yuv)
  1631. {
  1632. #define BGR2Y_IDX "16*4+16*32"
  1633. #define BGR2U_IDX "16*4+16*33"
  1634. #define BGR2V_IDX "16*4+16*34"
  1635.     int y;
  1636.     const x86_reg chromWidth= width>>1;
  1637.  
  1638.     if (height > 2) {
  1639.         ff_rgb24toyv12_c(src, ydst, udst, vdst, width, 2, lumStride, chromStride, srcStride, rgb2yuv);
  1640.         src  += 2*srcStride;
  1641.         ydst += 2*lumStride;
  1642.         udst += chromStride;
  1643.         vdst += chromStride;
  1644.         height -= 2;
  1645.     }
  1646.  
  1647.     for (y=0; y<height-2; y+=2) {
  1648.         int i;
  1649.         for (i=0; i<2; i++) {
  1650.             __asm__ volatile(
  1651.                 "mov                        %2, %%"REG_a"   \n\t"
  1652.                 "movq          "BGR2Y_IDX"(%3), %%mm6       \n\t"
  1653.                 "movq       "MANGLE(ff_w1111)", %%mm5       \n\t"
  1654.                 "pxor                    %%mm7, %%mm7       \n\t"
  1655.                 "lea (%%"REG_a", %%"REG_a", 2), %%"REG_d"   \n\t"
  1656.                 ".p2align                    4              \n\t"
  1657.                 "1:                                         \n\t"
  1658.                 PREFETCH"    64(%0, %%"REG_d")              \n\t"
  1659.                 "movd          (%0, %%"REG_d"), %%mm0       \n\t"
  1660.                 "movd         3(%0, %%"REG_d"), %%mm1       \n\t"
  1661.                 "punpcklbw               %%mm7, %%mm0       \n\t"
  1662.                 "punpcklbw               %%mm7, %%mm1       \n\t"
  1663.                 "movd         6(%0, %%"REG_d"), %%mm2       \n\t"
  1664.                 "movd         9(%0, %%"REG_d"), %%mm3       \n\t"
  1665.                 "punpcklbw               %%mm7, %%mm2       \n\t"
  1666.                 "punpcklbw               %%mm7, %%mm3       \n\t"
  1667.                 "pmaddwd                 %%mm6, %%mm0       \n\t"
  1668.                 "pmaddwd                 %%mm6, %%mm1       \n\t"
  1669.                 "pmaddwd                 %%mm6, %%mm2       \n\t"
  1670.                 "pmaddwd                 %%mm6, %%mm3       \n\t"
  1671.                 "psrad                      $8, %%mm0       \n\t"
  1672.                 "psrad                      $8, %%mm1       \n\t"
  1673.                 "psrad                      $8, %%mm2       \n\t"
  1674.                 "psrad                      $8, %%mm3       \n\t"
  1675.                 "packssdw                %%mm1, %%mm0       \n\t"
  1676.                 "packssdw                %%mm3, %%mm2       \n\t"
  1677.                 "pmaddwd                 %%mm5, %%mm0       \n\t"
  1678.                 "pmaddwd                 %%mm5, %%mm2       \n\t"
  1679.                 "packssdw                %%mm2, %%mm0       \n\t"
  1680.                 "psraw                      $7, %%mm0       \n\t"
  1681.  
  1682.                 "movd        12(%0, %%"REG_d"), %%mm4       \n\t"
  1683.                 "movd        15(%0, %%"REG_d"), %%mm1       \n\t"
  1684.                 "punpcklbw               %%mm7, %%mm4       \n\t"
  1685.                 "punpcklbw               %%mm7, %%mm1       \n\t"
  1686.                 "movd        18(%0, %%"REG_d"), %%mm2       \n\t"
  1687.                 "movd        21(%0, %%"REG_d"), %%mm3       \n\t"
  1688.                 "punpcklbw               %%mm7, %%mm2       \n\t"
  1689.                 "punpcklbw               %%mm7, %%mm3       \n\t"
  1690.                 "pmaddwd                 %%mm6, %%mm4       \n\t"
  1691.                 "pmaddwd                 %%mm6, %%mm1       \n\t"
  1692.                 "pmaddwd                 %%mm6, %%mm2       \n\t"
  1693.                 "pmaddwd                 %%mm6, %%mm3       \n\t"
  1694.                 "psrad                      $8, %%mm4       \n\t"
  1695.                 "psrad                      $8, %%mm1       \n\t"
  1696.                 "psrad                      $8, %%mm2       \n\t"
  1697.                 "psrad                      $8, %%mm3       \n\t"
  1698.                 "packssdw                %%mm1, %%mm4       \n\t"
  1699.                 "packssdw                %%mm3, %%mm2       \n\t"
  1700.                 "pmaddwd                 %%mm5, %%mm4       \n\t"
  1701.                 "pmaddwd                 %%mm5, %%mm2       \n\t"
  1702.                 "add                       $24, %%"REG_d"   \n\t"
  1703.                 "packssdw                %%mm2, %%mm4       \n\t"
  1704.                 "psraw                      $7, %%mm4       \n\t"
  1705.  
  1706.                 "packuswb                %%mm4, %%mm0       \n\t"
  1707.                 "paddusb "MANGLE(ff_bgr2YOffset)", %%mm0    \n\t"
  1708.  
  1709.                 MOVNTQ"                  %%mm0, (%1, %%"REG_a") \n\t"
  1710.                 "add                        $8,      %%"REG_a"  \n\t"
  1711.                 " js                        1b                  \n\t"
  1712.                 : : "r" (src+width*3), "r" (ydst+width), "g" ((x86_reg)-width), "r"(rgb2yuv)
  1713.                   NAMED_CONSTRAINTS_ADD(ff_w1111,ff_bgr2YOffset)
  1714.                 : "%"REG_a, "%"REG_d
  1715.             );
  1716.             ydst += lumStride;
  1717.             src  += srcStride;
  1718.         }
  1719.         src -= srcStride*2;
  1720.         __asm__ volatile(
  1721.             "mov                        %4, %%"REG_a"   \n\t"
  1722.             "movq       "MANGLE(ff_w1111)", %%mm5       \n\t"
  1723.             "movq          "BGR2U_IDX"(%5), %%mm6       \n\t"
  1724.             "pxor                    %%mm7, %%mm7       \n\t"
  1725.             "lea (%%"REG_a", %%"REG_a", 2), %%"REG_d"   \n\t"
  1726.             "add                 %%"REG_d", %%"REG_d"   \n\t"
  1727.             ".p2align                    4              \n\t"
  1728.             "1:                                         \n\t"
  1729.             PREFETCH"    64(%0, %%"REG_d")              \n\t"
  1730.             PREFETCH"    64(%1, %%"REG_d")              \n\t"
  1731. #if COMPILE_TEMPLATE_MMXEXT || COMPILE_TEMPLATE_AMD3DNOW
  1732.             "movq          (%0, %%"REG_d"), %%mm0       \n\t"
  1733.             "movq          (%1, %%"REG_d"), %%mm1       \n\t"
  1734.             "movq         6(%0, %%"REG_d"), %%mm2       \n\t"
  1735.             "movq         6(%1, %%"REG_d"), %%mm3       \n\t"
  1736.             PAVGB"                   %%mm1, %%mm0       \n\t"
  1737.             PAVGB"                   %%mm3, %%mm2       \n\t"
  1738.             "movq                    %%mm0, %%mm1       \n\t"
  1739.             "movq                    %%mm2, %%mm3       \n\t"
  1740.             "psrlq                     $24, %%mm0       \n\t"
  1741.             "psrlq                     $24, %%mm2       \n\t"
  1742.             PAVGB"                   %%mm1, %%mm0       \n\t"
  1743.             PAVGB"                   %%mm3, %%mm2       \n\t"
  1744.             "punpcklbw               %%mm7, %%mm0       \n\t"
  1745.             "punpcklbw               %%mm7, %%mm2       \n\t"
  1746. #else
  1747.             "movd          (%0, %%"REG_d"), %%mm0       \n\t"
  1748.             "movd          (%1, %%"REG_d"), %%mm1       \n\t"
  1749.             "movd         3(%0, %%"REG_d"), %%mm2       \n\t"
  1750.             "movd         3(%1, %%"REG_d"), %%mm3       \n\t"
  1751.             "punpcklbw               %%mm7, %%mm0       \n\t"
  1752.             "punpcklbw               %%mm7, %%mm1       \n\t"
  1753.             "punpcklbw               %%mm7, %%mm2       \n\t"
  1754.             "punpcklbw               %%mm7, %%mm3       \n\t"
  1755.             "paddw                   %%mm1, %%mm0       \n\t"
  1756.             "paddw                   %%mm3, %%mm2       \n\t"
  1757.             "paddw                   %%mm2, %%mm0       \n\t"
  1758.             "movd         6(%0, %%"REG_d"), %%mm4       \n\t"
  1759.             "movd         6(%1, %%"REG_d"), %%mm1       \n\t"
  1760.             "movd         9(%0, %%"REG_d"), %%mm2       \n\t"
  1761.             "movd         9(%1, %%"REG_d"), %%mm3       \n\t"
  1762.             "punpcklbw               %%mm7, %%mm4       \n\t"
  1763.             "punpcklbw               %%mm7, %%mm1       \n\t"
  1764.             "punpcklbw               %%mm7, %%mm2       \n\t"
  1765.             "punpcklbw               %%mm7, %%mm3       \n\t"
  1766.             "paddw                   %%mm1, %%mm4       \n\t"
  1767.             "paddw                   %%mm3, %%mm2       \n\t"
  1768.             "paddw                   %%mm4, %%mm2       \n\t"
  1769.             "psrlw                      $2, %%mm0       \n\t"
  1770.             "psrlw                      $2, %%mm2       \n\t"
  1771. #endif
  1772.             "movq          "BGR2V_IDX"(%5), %%mm1       \n\t"
  1773.             "movq          "BGR2V_IDX"(%5), %%mm3       \n\t"
  1774.  
  1775.             "pmaddwd                 %%mm0, %%mm1       \n\t"
  1776.             "pmaddwd                 %%mm2, %%mm3       \n\t"
  1777.             "pmaddwd                 %%mm6, %%mm0       \n\t"
  1778.             "pmaddwd                 %%mm6, %%mm2       \n\t"
  1779.             "psrad                      $8, %%mm0       \n\t"
  1780.             "psrad                      $8, %%mm1       \n\t"
  1781.             "psrad                      $8, %%mm2       \n\t"
  1782.             "psrad                      $8, %%mm3       \n\t"
  1783.             "packssdw                %%mm2, %%mm0       \n\t"
  1784.             "packssdw                %%mm3, %%mm1       \n\t"
  1785.             "pmaddwd                 %%mm5, %%mm0       \n\t"
  1786.             "pmaddwd                 %%mm5, %%mm1       \n\t"
  1787.             "packssdw                %%mm1, %%mm0       \n\t" // V1 V0 U1 U0
  1788.             "psraw                      $7, %%mm0       \n\t"
  1789.  
  1790. #if COMPILE_TEMPLATE_MMXEXT || COMPILE_TEMPLATE_AMD3DNOW
  1791.             "movq        12(%0, %%"REG_d"), %%mm4       \n\t"
  1792.             "movq        12(%1, %%"REG_d"), %%mm1       \n\t"
  1793.             "movq        18(%0, %%"REG_d"), %%mm2       \n\t"
  1794.             "movq        18(%1, %%"REG_d"), %%mm3       \n\t"
  1795.             PAVGB"                   %%mm1, %%mm4       \n\t"
  1796.             PAVGB"                   %%mm3, %%mm2       \n\t"
  1797.             "movq                    %%mm4, %%mm1       \n\t"
  1798.             "movq                    %%mm2, %%mm3       \n\t"
  1799.             "psrlq                     $24, %%mm4       \n\t"
  1800.             "psrlq                     $24, %%mm2       \n\t"
  1801.             PAVGB"                   %%mm1, %%mm4       \n\t"
  1802.             PAVGB"                   %%mm3, %%mm2       \n\t"
  1803.             "punpcklbw               %%mm7, %%mm4       \n\t"
  1804.             "punpcklbw               %%mm7, %%mm2       \n\t"
  1805. #else
  1806.             "movd        12(%0, %%"REG_d"), %%mm4       \n\t"
  1807.             "movd        12(%1, %%"REG_d"), %%mm1       \n\t"
  1808.             "movd        15(%0, %%"REG_d"), %%mm2       \n\t"
  1809.             "movd        15(%1, %%"REG_d"), %%mm3       \n\t"
  1810.             "punpcklbw               %%mm7, %%mm4       \n\t"
  1811.             "punpcklbw               %%mm7, %%mm1       \n\t"
  1812.             "punpcklbw               %%mm7, %%mm2       \n\t"
  1813.             "punpcklbw               %%mm7, %%mm3       \n\t"
  1814.             "paddw                   %%mm1, %%mm4       \n\t"
  1815.             "paddw                   %%mm3, %%mm2       \n\t"
  1816.             "paddw                   %%mm2, %%mm4       \n\t"
  1817.             "movd        18(%0, %%"REG_d"), %%mm5       \n\t"
  1818.             "movd        18(%1, %%"REG_d"), %%mm1       \n\t"
  1819.             "movd        21(%0, %%"REG_d"), %%mm2       \n\t"
  1820.             "movd        21(%1, %%"REG_d"), %%mm3       \n\t"
  1821.             "punpcklbw               %%mm7, %%mm5       \n\t"
  1822.             "punpcklbw               %%mm7, %%mm1       \n\t"
  1823.             "punpcklbw               %%mm7, %%mm2       \n\t"
  1824.             "punpcklbw               %%mm7, %%mm3       \n\t"
  1825.             "paddw                   %%mm1, %%mm5       \n\t"
  1826.             "paddw                   %%mm3, %%mm2       \n\t"
  1827.             "paddw                   %%mm5, %%mm2       \n\t"
  1828.             "movq       "MANGLE(ff_w1111)", %%mm5       \n\t"
  1829.             "psrlw                      $2, %%mm4       \n\t"
  1830.             "psrlw                      $2, %%mm2       \n\t"
  1831. #endif
  1832.             "movq          "BGR2V_IDX"(%5), %%mm1       \n\t"
  1833.             "movq          "BGR2V_IDX"(%5), %%mm3       \n\t"
  1834.  
  1835.             "pmaddwd                 %%mm4, %%mm1       \n\t"
  1836.             "pmaddwd                 %%mm2, %%mm3       \n\t"
  1837.             "pmaddwd                 %%mm6, %%mm4       \n\t"
  1838.             "pmaddwd                 %%mm6, %%mm2       \n\t"
  1839.             "psrad                      $8, %%mm4       \n\t"
  1840.             "psrad                      $8, %%mm1       \n\t"
  1841.             "psrad                      $8, %%mm2       \n\t"
  1842.             "psrad                      $8, %%mm3       \n\t"
  1843.             "packssdw                %%mm2, %%mm4       \n\t"
  1844.             "packssdw                %%mm3, %%mm1       \n\t"
  1845.             "pmaddwd                 %%mm5, %%mm4       \n\t"
  1846.             "pmaddwd                 %%mm5, %%mm1       \n\t"
  1847.             "add                       $24, %%"REG_d"   \n\t"
  1848.             "packssdw                %%mm1, %%mm4       \n\t" // V3 V2 U3 U2
  1849.             "psraw                      $7, %%mm4       \n\t"
  1850.  
  1851.             "movq                    %%mm0, %%mm1           \n\t"
  1852.             "punpckldq               %%mm4, %%mm0           \n\t"
  1853.             "punpckhdq               %%mm4, %%mm1           \n\t"
  1854.             "packsswb                %%mm1, %%mm0           \n\t"
  1855.             "paddb "MANGLE(ff_bgr2UVOffset)", %%mm0         \n\t"
  1856.             "movd                    %%mm0, (%2, %%"REG_a") \n\t"
  1857.             "punpckhdq               %%mm0, %%mm0           \n\t"
  1858.             "movd                    %%mm0, (%3, %%"REG_a") \n\t"
  1859.             "add                        $4, %%"REG_a"       \n\t"
  1860.             " js                        1b                  \n\t"
  1861.             : : "r" (src+chromWidth*6), "r" (src+srcStride+chromWidth*6), "r" (udst+chromWidth), "r" (vdst+chromWidth), "g" (-chromWidth), "r"(rgb2yuv)
  1862.               NAMED_CONSTRAINTS_ADD(ff_w1111,ff_bgr2UVOffset)
  1863.             : "%"REG_a, "%"REG_d
  1864.         );
  1865.  
  1866.         udst += chromStride;
  1867.         vdst += chromStride;
  1868.         src  += srcStride*2;
  1869.     }
  1870.  
  1871.     __asm__ volatile(EMMS"       \n\t"
  1872.                      SFENCE"     \n\t"
  1873.                      :::"memory");
  1874.  
  1875.      ff_rgb24toyv12_c(src, ydst, udst, vdst, width, height-y, lumStride, chromStride, srcStride, rgb2yuv);
  1876. }
  1877. #endif /* HAVE_7REGS */
  1878. #endif /* !COMPILE_TEMPLATE_SSE2 */
  1879.  
  1880. #if !COMPILE_TEMPLATE_AMD3DNOW && !COMPILE_TEMPLATE_AVX
  1881. static void RENAME(interleaveBytes)(const uint8_t *src1, const uint8_t *src2, uint8_t *dest,
  1882.                                     int width, int height, int src1Stride,
  1883.                                     int src2Stride, int dstStride)
  1884. {
  1885.     int h;
  1886.  
  1887.     for (h=0; h < height; h++) {
  1888.         int w;
  1889.  
  1890.         if (width >= 16) {
  1891. #if COMPILE_TEMPLATE_SSE2
  1892.             if (!((((intptr_t)src1) | ((intptr_t)src2) | ((intptr_t)dest))&15)) {
  1893.         __asm__(
  1894.             "xor              %%"REG_a", %%"REG_a"  \n\t"
  1895.             "1:                                     \n\t"
  1896.             PREFETCH" 64(%1, %%"REG_a")             \n\t"
  1897.             PREFETCH" 64(%2, %%"REG_a")             \n\t"
  1898.             "movdqa     (%1, %%"REG_a"), %%xmm0     \n\t"
  1899.             "movdqa     (%1, %%"REG_a"), %%xmm1     \n\t"
  1900.             "movdqa     (%2, %%"REG_a"), %%xmm2     \n\t"
  1901.             "punpcklbw           %%xmm2, %%xmm0     \n\t"
  1902.             "punpckhbw           %%xmm2, %%xmm1     \n\t"
  1903.             "movntdq             %%xmm0,   (%0, %%"REG_a", 2)   \n\t"
  1904.             "movntdq             %%xmm1, 16(%0, %%"REG_a", 2)   \n\t"
  1905.             "add                    $16, %%"REG_a"  \n\t"
  1906.             "cmp                     %3, %%"REG_a"  \n\t"
  1907.             " jb                     1b             \n\t"
  1908.             ::"r"(dest), "r"(src1), "r"(src2), "r" ((x86_reg)width-15)
  1909.             : "memory", XMM_CLOBBERS("xmm0", "xmm1", "xmm2",) "%"REG_a
  1910.         );
  1911.             } else
  1912. #endif
  1913.         __asm__(
  1914.             "xor %%"REG_a", %%"REG_a"               \n\t"
  1915.             "1:                                     \n\t"
  1916.             PREFETCH" 64(%1, %%"REG_a")             \n\t"
  1917.             PREFETCH" 64(%2, %%"REG_a")             \n\t"
  1918.             "movq       (%1, %%"REG_a"), %%mm0      \n\t"
  1919.             "movq      8(%1, %%"REG_a"), %%mm2      \n\t"
  1920.             "movq                 %%mm0, %%mm1      \n\t"
  1921.             "movq                 %%mm2, %%mm3      \n\t"
  1922.             "movq       (%2, %%"REG_a"), %%mm4      \n\t"
  1923.             "movq      8(%2, %%"REG_a"), %%mm5      \n\t"
  1924.             "punpcklbw            %%mm4, %%mm0      \n\t"
  1925.             "punpckhbw            %%mm4, %%mm1      \n\t"
  1926.             "punpcklbw            %%mm5, %%mm2      \n\t"
  1927.             "punpckhbw            %%mm5, %%mm3      \n\t"
  1928.             MOVNTQ"               %%mm0,   (%0, %%"REG_a", 2)   \n\t"
  1929.             MOVNTQ"               %%mm1,  8(%0, %%"REG_a", 2)   \n\t"
  1930.             MOVNTQ"               %%mm2, 16(%0, %%"REG_a", 2)   \n\t"
  1931.             MOVNTQ"               %%mm3, 24(%0, %%"REG_a", 2)   \n\t"
  1932.             "add                    $16, %%"REG_a"  \n\t"
  1933.             "cmp                     %3, %%"REG_a"  \n\t"
  1934.             " jb                     1b             \n\t"
  1935.             ::"r"(dest), "r"(src1), "r"(src2), "r" ((x86_reg)width-15)
  1936.             : "memory", "%"REG_a
  1937.         );
  1938.  
  1939.         }
  1940.         for (w= (width&(~15)); w < width; w++) {
  1941.             dest[2*w+0] = src1[w];
  1942.             dest[2*w+1] = src2[w];
  1943.         }
  1944.         dest += dstStride;
  1945.         src1 += src1Stride;
  1946.         src2 += src2Stride;
  1947.     }
  1948.     __asm__(
  1949.             EMMS"       \n\t"
  1950.             SFENCE"     \n\t"
  1951.             ::: "memory"
  1952.             );
  1953. }
  1954. #endif /* !COMPILE_TEMPLATE_AMD3DNOW && !COMPILE_TEMPLATE_AVX */
  1955.  
  1956. #if !COMPILE_TEMPLATE_AVX || HAVE_AVX_EXTERNAL
  1957. #if !COMPILE_TEMPLATE_AMD3DNOW && (ARCH_X86_32 || COMPILE_TEMPLATE_SSE2) && COMPILE_TEMPLATE_MMXEXT == COMPILE_TEMPLATE_SSE2 && HAVE_YASM
  1958. void RENAME(ff_nv12ToUV)(uint8_t *dstU, uint8_t *dstV,
  1959.                          const uint8_t *unused,
  1960.                          const uint8_t *src1,
  1961.                          const uint8_t *src2,
  1962.                          int w,
  1963.                          uint32_t *unused2);
  1964. static void RENAME(deinterleaveBytes)(const uint8_t *src, uint8_t *dst1, uint8_t *dst2,
  1965.                                       int width, int height, int srcStride,
  1966.                                       int dst1Stride, int dst2Stride)
  1967. {
  1968.     int h;
  1969.  
  1970.     for (h = 0; h < height; h++) {
  1971.         RENAME(ff_nv12ToUV)(dst1, dst2, NULL, src, NULL, width, NULL);
  1972.         src  += srcStride;
  1973.         dst1 += dst1Stride;
  1974.         dst2 += dst2Stride;
  1975.     }
  1976.     __asm__(
  1977. #if !COMPILE_TEMPLATE_SSE2
  1978.             EMMS"       \n\t"
  1979. #endif
  1980.             SFENCE"     \n\t"
  1981.             ::: "memory"
  1982.             );
  1983. }
  1984. #endif /* !COMPILE_TEMPLATE_AMD3DNOW */
  1985. #endif /* !COMPILE_TEMPLATE_AVX || HAVE_AVX_EXTERNAL */
  1986.  
  1987. #if !COMPILE_TEMPLATE_SSE2
  1988. #if !COMPILE_TEMPLATE_AMD3DNOW
  1989. static inline void RENAME(vu9_to_vu12)(const uint8_t *src1, const uint8_t *src2,
  1990.                                        uint8_t *dst1, uint8_t *dst2,
  1991.                                        int width, int height,
  1992.                                        int srcStride1, int srcStride2,
  1993.                                        int dstStride1, int dstStride2)
  1994. {
  1995.     x86_reg x, y;
  1996.     int w,h;
  1997.     w=width/2; h=height/2;
  1998.     __asm__ volatile(
  1999.         PREFETCH" %0    \n\t"
  2000.         PREFETCH" %1    \n\t"
  2001.         ::"m"(*(src1+srcStride1)),"m"(*(src2+srcStride2)):"memory");
  2002.     for (y=0;y<h;y++) {
  2003.         const uint8_t* s1=src1+srcStride1*(y>>1);
  2004.         uint8_t* d=dst1+dstStride1*y;
  2005.         x=0;
  2006.         for (;x<w-31;x+=32) {
  2007.             __asm__ volatile(
  2008.                 PREFETCH"   32(%1,%2)        \n\t"
  2009.                 "movq         (%1,%2), %%mm0 \n\t"
  2010.                 "movq        8(%1,%2), %%mm2 \n\t"
  2011.                 "movq       16(%1,%2), %%mm4 \n\t"
  2012.                 "movq       24(%1,%2), %%mm6 \n\t"
  2013.                 "movq      %%mm0, %%mm1 \n\t"
  2014.                 "movq      %%mm2, %%mm3 \n\t"
  2015.                 "movq      %%mm4, %%mm5 \n\t"
  2016.                 "movq      %%mm6, %%mm7 \n\t"
  2017.                 "punpcklbw %%mm0, %%mm0 \n\t"
  2018.                 "punpckhbw %%mm1, %%mm1 \n\t"
  2019.                 "punpcklbw %%mm2, %%mm2 \n\t"
  2020.                 "punpckhbw %%mm3, %%mm3 \n\t"
  2021.                 "punpcklbw %%mm4, %%mm4 \n\t"
  2022.                 "punpckhbw %%mm5, %%mm5 \n\t"
  2023.                 "punpcklbw %%mm6, %%mm6 \n\t"
  2024.                 "punpckhbw %%mm7, %%mm7 \n\t"
  2025.                 MOVNTQ"    %%mm0,   (%0,%2,2)  \n\t"
  2026.                 MOVNTQ"    %%mm1,  8(%0,%2,2)  \n\t"
  2027.                 MOVNTQ"    %%mm2, 16(%0,%2,2)  \n\t"
  2028.                 MOVNTQ"    %%mm3, 24(%0,%2,2)  \n\t"
  2029.                 MOVNTQ"    %%mm4, 32(%0,%2,2)  \n\t"
  2030.                 MOVNTQ"    %%mm5, 40(%0,%2,2)  \n\t"
  2031.                 MOVNTQ"    %%mm6, 48(%0,%2,2)  \n\t"
  2032.                 MOVNTQ"    %%mm7, 56(%0,%2,2)"
  2033.                 :: "r"(d), "r"(s1), "r"(x)
  2034.                 :"memory");
  2035.         }
  2036.         for (;x<w;x++) d[2*x]=d[2*x+1]=s1[x];
  2037.     }
  2038.     for (y=0;y<h;y++) {
  2039.         const uint8_t* s2=src2+srcStride2*(y>>1);
  2040.         uint8_t* d=dst2+dstStride2*y;
  2041.         x=0;
  2042.         for (;x<w-31;x+=32) {
  2043.             __asm__ volatile(
  2044.                 PREFETCH"   32(%1,%2)        \n\t"
  2045.                 "movq         (%1,%2), %%mm0 \n\t"
  2046.                 "movq        8(%1,%2), %%mm2 \n\t"
  2047.                 "movq       16(%1,%2), %%mm4 \n\t"
  2048.                 "movq       24(%1,%2), %%mm6 \n\t"
  2049.                 "movq      %%mm0, %%mm1 \n\t"
  2050.                 "movq      %%mm2, %%mm3 \n\t"
  2051.                 "movq      %%mm4, %%mm5 \n\t"
  2052.                 "movq      %%mm6, %%mm7 \n\t"
  2053.                 "punpcklbw %%mm0, %%mm0 \n\t"
  2054.                 "punpckhbw %%mm1, %%mm1 \n\t"
  2055.                 "punpcklbw %%mm2, %%mm2 \n\t"
  2056.                 "punpckhbw %%mm3, %%mm3 \n\t"
  2057.                 "punpcklbw %%mm4, %%mm4 \n\t"
  2058.                 "punpckhbw %%mm5, %%mm5 \n\t"
  2059.                 "punpcklbw %%mm6, %%mm6 \n\t"
  2060.                 "punpckhbw %%mm7, %%mm7 \n\t"
  2061.                 MOVNTQ"    %%mm0,   (%0,%2,2)  \n\t"
  2062.                 MOVNTQ"    %%mm1,  8(%0,%2,2)  \n\t"
  2063.                 MOVNTQ"    %%mm2, 16(%0,%2,2)  \n\t"
  2064.                 MOVNTQ"    %%mm3, 24(%0,%2,2)  \n\t"
  2065.                 MOVNTQ"    %%mm4, 32(%0,%2,2)  \n\t"
  2066.                 MOVNTQ"    %%mm5, 40(%0,%2,2)  \n\t"
  2067.                 MOVNTQ"    %%mm6, 48(%0,%2,2)  \n\t"
  2068.                 MOVNTQ"    %%mm7, 56(%0,%2,2)"
  2069.                 :: "r"(d), "r"(s2), "r"(x)
  2070.                 :"memory");
  2071.         }
  2072.         for (;x<w;x++) d[2*x]=d[2*x+1]=s2[x];
  2073.     }
  2074.     __asm__(
  2075.             EMMS"       \n\t"
  2076.             SFENCE"     \n\t"
  2077.             ::: "memory"
  2078.         );
  2079. }
  2080.  
  2081. static inline void RENAME(yvu9_to_yuy2)(const uint8_t *src1, const uint8_t *src2, const uint8_t *src3,
  2082.                                         uint8_t *dst,
  2083.                                         int width, int height,
  2084.                                         int srcStride1, int srcStride2,
  2085.                                         int srcStride3, int dstStride)
  2086. {
  2087.     x86_reg x;
  2088.     int y,w,h;
  2089.     w=width/2; h=height;
  2090.     for (y=0;y<h;y++) {
  2091.         const uint8_t* yp=src1+srcStride1*y;
  2092.         const uint8_t* up=src2+srcStride2*(y>>2);
  2093.         const uint8_t* vp=src3+srcStride3*(y>>2);
  2094.         uint8_t* d=dst+dstStride*y;
  2095.         x=0;
  2096.         for (;x<w-7;x+=8) {
  2097.             __asm__ volatile(
  2098.                 PREFETCH"   32(%1, %0)          \n\t"
  2099.                 PREFETCH"   32(%2, %0)          \n\t"
  2100.                 PREFETCH"   32(%3, %0)          \n\t"
  2101.                 "movq      (%1, %0, 4), %%mm0   \n\t" /* Y0Y1Y2Y3Y4Y5Y6Y7 */
  2102.                 "movq         (%2, %0), %%mm1   \n\t" /* U0U1U2U3U4U5U6U7 */
  2103.                 "movq         (%3, %0), %%mm2   \n\t" /* V0V1V2V3V4V5V6V7 */
  2104.                 "movq            %%mm0, %%mm3   \n\t" /* Y0Y1Y2Y3Y4Y5Y6Y7 */
  2105.                 "movq            %%mm1, %%mm4   \n\t" /* U0U1U2U3U4U5U6U7 */
  2106.                 "movq            %%mm2, %%mm5   \n\t" /* V0V1V2V3V4V5V6V7 */
  2107.                 "punpcklbw       %%mm1, %%mm1   \n\t" /* U0U0 U1U1 U2U2 U3U3 */
  2108.                 "punpcklbw       %%mm2, %%mm2   \n\t" /* V0V0 V1V1 V2V2 V3V3 */
  2109.                 "punpckhbw       %%mm4, %%mm4   \n\t" /* U4U4 U5U5 U6U6 U7U7 */
  2110.                 "punpckhbw       %%mm5, %%mm5   \n\t" /* V4V4 V5V5 V6V6 V7V7 */
  2111.  
  2112.                 "movq            %%mm1, %%mm6   \n\t"
  2113.                 "punpcklbw       %%mm2, %%mm1   \n\t" /* U0V0 U0V0 U1V1 U1V1*/
  2114.                 "punpcklbw       %%mm1, %%mm0   \n\t" /* Y0U0 Y1V0 Y2U0 Y3V0*/
  2115.                 "punpckhbw       %%mm1, %%mm3   \n\t" /* Y4U1 Y5V1 Y6U1 Y7V1*/
  2116.                 MOVNTQ"          %%mm0,  (%4, %0, 8)    \n\t"
  2117.                 MOVNTQ"          %%mm3, 8(%4, %0, 8)    \n\t"
  2118.  
  2119.                 "punpckhbw       %%mm2, %%mm6   \n\t" /* U2V2 U2V2 U3V3 U3V3*/
  2120.                 "movq     8(%1, %0, 4), %%mm0   \n\t"
  2121.                 "movq            %%mm0, %%mm3   \n\t"
  2122.                 "punpcklbw       %%mm6, %%mm0   \n\t" /* Y U2 Y V2 Y U2 Y V2*/
  2123.                 "punpckhbw       %%mm6, %%mm3   \n\t" /* Y U3 Y V3 Y U3 Y V3*/
  2124.                 MOVNTQ"          %%mm0, 16(%4, %0, 8)   \n\t"
  2125.                 MOVNTQ"          %%mm3, 24(%4, %0, 8)   \n\t"
  2126.  
  2127.                 "movq            %%mm4, %%mm6   \n\t"
  2128.                 "movq    16(%1, %0, 4), %%mm0   \n\t"
  2129.                 "movq            %%mm0, %%mm3   \n\t"
  2130.                 "punpcklbw       %%mm5, %%mm4   \n\t"
  2131.                 "punpcklbw       %%mm4, %%mm0   \n\t" /* Y U4 Y V4 Y U4 Y V4*/
  2132.                 "punpckhbw       %%mm4, %%mm3   \n\t" /* Y U5 Y V5 Y U5 Y V5*/
  2133.                 MOVNTQ"          %%mm0, 32(%4, %0, 8)   \n\t"
  2134.                 MOVNTQ"          %%mm3, 40(%4, %0, 8)   \n\t"
  2135.  
  2136.                 "punpckhbw       %%mm5, %%mm6   \n\t"
  2137.                 "movq    24(%1, %0, 4), %%mm0   \n\t"
  2138.                 "movq            %%mm0, %%mm3   \n\t"
  2139.                 "punpcklbw       %%mm6, %%mm0   \n\t" /* Y U6 Y V6 Y U6 Y V6*/
  2140.                 "punpckhbw       %%mm6, %%mm3   \n\t" /* Y U7 Y V7 Y U7 Y V7*/
  2141.                 MOVNTQ"          %%mm0, 48(%4, %0, 8)   \n\t"
  2142.                 MOVNTQ"          %%mm3, 56(%4, %0, 8)   \n\t"
  2143.  
  2144.                 : "+r" (x)
  2145.                 : "r"(yp), "r" (up), "r"(vp), "r"(d)
  2146.                 :"memory");
  2147.         }
  2148.         for (; x<w; x++) {
  2149.             const int x2 = x<<2;
  2150.             d[8*x+0] = yp[x2];
  2151.             d[8*x+1] = up[x];
  2152.             d[8*x+2] = yp[x2+1];
  2153.             d[8*x+3] = vp[x];
  2154.             d[8*x+4] = yp[x2+2];
  2155.             d[8*x+5] = up[x];
  2156.             d[8*x+6] = yp[x2+3];
  2157.             d[8*x+7] = vp[x];
  2158.         }
  2159.     }
  2160.     __asm__(
  2161.             EMMS"       \n\t"
  2162.             SFENCE"     \n\t"
  2163.             ::: "memory"
  2164.         );
  2165. }
  2166. #endif /* !COMPILE_TEMPLATE_AMD3DNOW */
  2167.  
  2168. static void RENAME(extract_even)(const uint8_t *src, uint8_t *dst, x86_reg count)
  2169. {
  2170.     dst +=   count;
  2171.     src += 2*count;
  2172.     count= - count;
  2173.  
  2174.     if(count <= -16) {
  2175.         count += 15;
  2176.         __asm__ volatile(
  2177.             "pcmpeqw       %%mm7, %%mm7        \n\t"
  2178.             "psrlw            $8, %%mm7        \n\t"
  2179.             "1:                                \n\t"
  2180.             "movq -30(%1, %0, 2), %%mm0        \n\t"
  2181.             "movq -22(%1, %0, 2), %%mm1        \n\t"
  2182.             "movq -14(%1, %0, 2), %%mm2        \n\t"
  2183.             "movq  -6(%1, %0, 2), %%mm3        \n\t"
  2184.             "pand          %%mm7, %%mm0        \n\t"
  2185.             "pand          %%mm7, %%mm1        \n\t"
  2186.             "pand          %%mm7, %%mm2        \n\t"
  2187.             "pand          %%mm7, %%mm3        \n\t"
  2188.             "packuswb      %%mm1, %%mm0        \n\t"
  2189.             "packuswb      %%mm3, %%mm2        \n\t"
  2190.             MOVNTQ"        %%mm0,-15(%2, %0)   \n\t"
  2191.             MOVNTQ"        %%mm2,- 7(%2, %0)   \n\t"
  2192.             "add             $16, %0           \n\t"
  2193.             " js 1b                            \n\t"
  2194.             : "+r"(count)
  2195.             : "r"(src), "r"(dst)
  2196.         );
  2197.         count -= 15;
  2198.     }
  2199.     while(count<0) {
  2200.         dst[count]= src[2*count];
  2201.         count++;
  2202.     }
  2203. }
  2204.  
  2205. static void RENAME(extract_odd)(const uint8_t *src, uint8_t *dst, x86_reg count)
  2206. {
  2207.     src ++;
  2208.     dst +=   count;
  2209.     src += 2*count;
  2210.     count= - count;
  2211.  
  2212.     if(count < -16) {
  2213.         count += 16;
  2214.         __asm__ volatile(
  2215.             "pcmpeqw       %%mm7, %%mm7        \n\t"
  2216.             "psrlw            $8, %%mm7        \n\t"
  2217.             "1:                                \n\t"
  2218.             "movq -32(%1, %0, 2), %%mm0        \n\t"
  2219.             "movq -24(%1, %0, 2), %%mm1        \n\t"
  2220.             "movq -16(%1, %0, 2), %%mm2        \n\t"
  2221.             "movq  -8(%1, %0, 2), %%mm3        \n\t"
  2222.             "pand          %%mm7, %%mm0        \n\t"
  2223.             "pand          %%mm7, %%mm1        \n\t"
  2224.             "pand          %%mm7, %%mm2        \n\t"
  2225.             "pand          %%mm7, %%mm3        \n\t"
  2226.             "packuswb      %%mm1, %%mm0        \n\t"
  2227.             "packuswb      %%mm3, %%mm2        \n\t"
  2228.             MOVNTQ"        %%mm0,-16(%2, %0)   \n\t"
  2229.             MOVNTQ"        %%mm2,- 8(%2, %0)   \n\t"
  2230.             "add             $16, %0           \n\t"
  2231.             " js 1b                            \n\t"
  2232.             : "+r"(count)
  2233.             : "r"(src), "r"(dst)
  2234.         );
  2235.         count -= 16;
  2236.     }
  2237.     while(count<0) {
  2238.         dst[count]= src[2*count];
  2239.         count++;
  2240.     }
  2241. }
  2242.  
  2243. #if !COMPILE_TEMPLATE_AMD3DNOW
  2244. static void RENAME(extract_even2)(const uint8_t *src, uint8_t *dst0, uint8_t *dst1, x86_reg count)
  2245. {
  2246.     dst0+=   count;
  2247.     dst1+=   count;
  2248.     src += 4*count;
  2249.     count= - count;
  2250.     if(count <= -8) {
  2251.         count += 7;
  2252.         __asm__ volatile(
  2253.             "pcmpeqw       %%mm7, %%mm7        \n\t"
  2254.             "psrlw            $8, %%mm7        \n\t"
  2255.             "1:                                \n\t"
  2256.             "movq -28(%1, %0, 4), %%mm0        \n\t"
  2257.             "movq -20(%1, %0, 4), %%mm1        \n\t"
  2258.             "movq -12(%1, %0, 4), %%mm2        \n\t"
  2259.             "movq  -4(%1, %0, 4), %%mm3        \n\t"
  2260.             "pand          %%mm7, %%mm0        \n\t"
  2261.             "pand          %%mm7, %%mm1        \n\t"
  2262.             "pand          %%mm7, %%mm2        \n\t"
  2263.             "pand          %%mm7, %%mm3        \n\t"
  2264.             "packuswb      %%mm1, %%mm0        \n\t"
  2265.             "packuswb      %%mm3, %%mm2        \n\t"
  2266.             "movq          %%mm0, %%mm1        \n\t"
  2267.             "movq          %%mm2, %%mm3        \n\t"
  2268.             "psrlw            $8, %%mm0        \n\t"
  2269.             "psrlw            $8, %%mm2        \n\t"
  2270.             "pand          %%mm7, %%mm1        \n\t"
  2271.             "pand          %%mm7, %%mm3        \n\t"
  2272.             "packuswb      %%mm2, %%mm0        \n\t"
  2273.             "packuswb      %%mm3, %%mm1        \n\t"
  2274.             MOVNTQ"        %%mm0,- 7(%3, %0)   \n\t"
  2275.             MOVNTQ"        %%mm1,- 7(%2, %0)   \n\t"
  2276.             "add              $8, %0           \n\t"
  2277.             " js 1b                            \n\t"
  2278.             : "+r"(count)
  2279.             : "r"(src), "r"(dst0), "r"(dst1)
  2280.         );
  2281.         count -= 7;
  2282.     }
  2283.     while(count<0) {
  2284.         dst0[count]= src[4*count+0];
  2285.         dst1[count]= src[4*count+2];
  2286.         count++;
  2287.     }
  2288. }
  2289. #endif /* !COMPILE_TEMPLATE_AMD3DNOW */
  2290.  
  2291. static void RENAME(extract_even2avg)(const uint8_t *src0, const uint8_t *src1, uint8_t *dst0, uint8_t *dst1, x86_reg count)
  2292. {
  2293.     dst0 +=   count;
  2294.     dst1 +=   count;
  2295.     src0 += 4*count;
  2296.     src1 += 4*count;
  2297.     count= - count;
  2298. #ifdef PAVGB
  2299.     if(count <= -8) {
  2300.         count += 7;
  2301.         __asm__ volatile(
  2302.             "pcmpeqw        %%mm7, %%mm7        \n\t"
  2303.             "psrlw             $8, %%mm7        \n\t"
  2304.             "1:                                \n\t"
  2305.             "movq  -28(%1, %0, 4), %%mm0        \n\t"
  2306.             "movq  -20(%1, %0, 4), %%mm1        \n\t"
  2307.             "movq  -12(%1, %0, 4), %%mm2        \n\t"
  2308.             "movq   -4(%1, %0, 4), %%mm3        \n\t"
  2309.             PAVGB" -28(%2, %0, 4), %%mm0        \n\t"
  2310.             PAVGB" -20(%2, %0, 4), %%mm1        \n\t"
  2311.             PAVGB" -12(%2, %0, 4), %%mm2        \n\t"
  2312.             PAVGB" - 4(%2, %0, 4), %%mm3        \n\t"
  2313.             "pand           %%mm7, %%mm0        \n\t"
  2314.             "pand           %%mm7, %%mm1        \n\t"
  2315.             "pand           %%mm7, %%mm2        \n\t"
  2316.             "pand           %%mm7, %%mm3        \n\t"
  2317.             "packuswb       %%mm1, %%mm0        \n\t"
  2318.             "packuswb       %%mm3, %%mm2        \n\t"
  2319.             "movq           %%mm0, %%mm1        \n\t"
  2320.             "movq           %%mm2, %%mm3        \n\t"
  2321.             "psrlw             $8, %%mm0        \n\t"
  2322.             "psrlw             $8, %%mm2        \n\t"
  2323.             "pand           %%mm7, %%mm1        \n\t"
  2324.             "pand           %%mm7, %%mm3        \n\t"
  2325.             "packuswb       %%mm2, %%mm0        \n\t"
  2326.             "packuswb       %%mm3, %%mm1        \n\t"
  2327.             MOVNTQ"         %%mm0,- 7(%4, %0)   \n\t"
  2328.             MOVNTQ"         %%mm1,- 7(%3, %0)   \n\t"
  2329.             "add               $8, %0           \n\t"
  2330.             " js 1b                            \n\t"
  2331.             : "+r"(count)
  2332.             : "r"(src0), "r"(src1), "r"(dst0), "r"(dst1)
  2333.         );
  2334.         count -= 7;
  2335.     }
  2336. #endif
  2337.     while(count<0) {
  2338.         dst0[count]= (src0[4*count+0]+src1[4*count+0])>>1;
  2339.         dst1[count]= (src0[4*count+2]+src1[4*count+2])>>1;
  2340.         count++;
  2341.     }
  2342. }
  2343.  
  2344. #if !COMPILE_TEMPLATE_AMD3DNOW
  2345. static void RENAME(extract_odd2)(const uint8_t *src, uint8_t *dst0, uint8_t *dst1, x86_reg count)
  2346. {
  2347.     dst0+=   count;
  2348.     dst1+=   count;
  2349.     src += 4*count;
  2350.     count= - count;
  2351.     if(count <= -8) {
  2352.         count += 7;
  2353.         __asm__ volatile(
  2354.             "pcmpeqw       %%mm7, %%mm7        \n\t"
  2355.             "psrlw            $8, %%mm7        \n\t"
  2356.             "1:                                \n\t"
  2357.             "movq -28(%1, %0, 4), %%mm0        \n\t"
  2358.             "movq -20(%1, %0, 4), %%mm1        \n\t"
  2359.             "movq -12(%1, %0, 4), %%mm2        \n\t"
  2360.             "movq  -4(%1, %0, 4), %%mm3        \n\t"
  2361.             "psrlw            $8, %%mm0        \n\t"
  2362.             "psrlw            $8, %%mm1        \n\t"
  2363.             "psrlw            $8, %%mm2        \n\t"
  2364.             "psrlw            $8, %%mm3        \n\t"
  2365.             "packuswb      %%mm1, %%mm0        \n\t"
  2366.             "packuswb      %%mm3, %%mm2        \n\t"
  2367.             "movq          %%mm0, %%mm1        \n\t"
  2368.             "movq          %%mm2, %%mm3        \n\t"
  2369.             "psrlw            $8, %%mm0        \n\t"
  2370.             "psrlw            $8, %%mm2        \n\t"
  2371.             "pand          %%mm7, %%mm1        \n\t"
  2372.             "pand          %%mm7, %%mm3        \n\t"
  2373.             "packuswb      %%mm2, %%mm0        \n\t"
  2374.             "packuswb      %%mm3, %%mm1        \n\t"
  2375.             MOVNTQ"        %%mm0,- 7(%3, %0)   \n\t"
  2376.             MOVNTQ"        %%mm1,- 7(%2, %0)   \n\t"
  2377.             "add              $8, %0           \n\t"
  2378.             " js 1b                            \n\t"
  2379.             : "+r"(count)
  2380.             : "r"(src), "r"(dst0), "r"(dst1)
  2381.         );
  2382.         count -= 7;
  2383.     }
  2384.     src++;
  2385.     while(count<0) {
  2386.         dst0[count]= src[4*count+0];
  2387.         dst1[count]= src[4*count+2];
  2388.         count++;
  2389.     }
  2390. }
  2391. #endif /* !COMPILE_TEMPLATE_AMD3DNOW */
  2392.  
  2393. static void RENAME(extract_odd2avg)(const uint8_t *src0, const uint8_t *src1, uint8_t *dst0, uint8_t *dst1, x86_reg count)
  2394. {
  2395.     dst0 +=   count;
  2396.     dst1 +=   count;
  2397.     src0 += 4*count;
  2398.     src1 += 4*count;
  2399.     count= - count;
  2400. #ifdef PAVGB
  2401.     if(count <= -8) {
  2402.         count += 7;
  2403.         __asm__ volatile(
  2404.             "pcmpeqw        %%mm7, %%mm7        \n\t"
  2405.             "psrlw             $8, %%mm7        \n\t"
  2406.             "1:                                \n\t"
  2407.             "movq  -28(%1, %0, 4), %%mm0        \n\t"
  2408.             "movq  -20(%1, %0, 4), %%mm1        \n\t"
  2409.             "movq  -12(%1, %0, 4), %%mm2        \n\t"
  2410.             "movq   -4(%1, %0, 4), %%mm3        \n\t"
  2411.             PAVGB" -28(%2, %0, 4), %%mm0        \n\t"
  2412.             PAVGB" -20(%2, %0, 4), %%mm1        \n\t"
  2413.             PAVGB" -12(%2, %0, 4), %%mm2        \n\t"
  2414.             PAVGB" - 4(%2, %0, 4), %%mm3        \n\t"
  2415.             "psrlw             $8, %%mm0        \n\t"
  2416.             "psrlw             $8, %%mm1        \n\t"
  2417.             "psrlw             $8, %%mm2        \n\t"
  2418.             "psrlw             $8, %%mm3        \n\t"
  2419.             "packuswb       %%mm1, %%mm0        \n\t"
  2420.             "packuswb       %%mm3, %%mm2        \n\t"
  2421.             "movq           %%mm0, %%mm1        \n\t"
  2422.             "movq           %%mm2, %%mm3        \n\t"
  2423.             "psrlw             $8, %%mm0        \n\t"
  2424.             "psrlw             $8, %%mm2        \n\t"
  2425.             "pand           %%mm7, %%mm1        \n\t"
  2426.             "pand           %%mm7, %%mm3        \n\t"
  2427.             "packuswb       %%mm2, %%mm0        \n\t"
  2428.             "packuswb       %%mm3, %%mm1        \n\t"
  2429.             MOVNTQ"         %%mm0,- 7(%4, %0)   \n\t"
  2430.             MOVNTQ"         %%mm1,- 7(%3, %0)   \n\t"
  2431.             "add               $8, %0           \n\t"
  2432.             " js 1b                            \n\t"
  2433.             : "+r"(count)
  2434.             : "r"(src0), "r"(src1), "r"(dst0), "r"(dst1)
  2435.         );
  2436.         count -= 7;
  2437.     }
  2438. #endif
  2439.     src0++;
  2440.     src1++;
  2441.     while(count<0) {
  2442.         dst0[count]= (src0[4*count+0]+src1[4*count+0])>>1;
  2443.         dst1[count]= (src0[4*count+2]+src1[4*count+2])>>1;
  2444.         count++;
  2445.     }
  2446. }
  2447.  
  2448. static void RENAME(yuyvtoyuv420)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src,
  2449.                                  int width, int height,
  2450.                                  int lumStride, int chromStride, int srcStride)
  2451. {
  2452.     int y;
  2453.     const int chromWidth = FF_CEIL_RSHIFT(width, 1);
  2454.  
  2455.     for (y=0; y<height; y++) {
  2456.         RENAME(extract_even)(src, ydst, width);
  2457.         if(y&1) {
  2458.             RENAME(extract_odd2avg)(src-srcStride, src, udst, vdst, chromWidth);
  2459.             udst+= chromStride;
  2460.             vdst+= chromStride;
  2461.         }
  2462.  
  2463.         src += srcStride;
  2464.         ydst+= lumStride;
  2465.     }
  2466.     __asm__(
  2467.             EMMS"       \n\t"
  2468.             SFENCE"     \n\t"
  2469.             ::: "memory"
  2470.         );
  2471. }
  2472.  
  2473. #if !COMPILE_TEMPLATE_AMD3DNOW
  2474. static void RENAME(yuyvtoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src,
  2475.                                  int width, int height,
  2476.                                  int lumStride, int chromStride, int srcStride)
  2477. {
  2478.     int y;
  2479.     const int chromWidth = FF_CEIL_RSHIFT(width, 1);
  2480.  
  2481.     for (y=0; y<height; y++) {
  2482.         RENAME(extract_even)(src, ydst, width);
  2483.         RENAME(extract_odd2)(src, udst, vdst, chromWidth);
  2484.  
  2485.         src += srcStride;
  2486.         ydst+= lumStride;
  2487.         udst+= chromStride;
  2488.         vdst+= chromStride;
  2489.     }
  2490.     __asm__(
  2491.             EMMS"       \n\t"
  2492.             SFENCE"     \n\t"
  2493.             ::: "memory"
  2494.         );
  2495. }
  2496. #endif /* !COMPILE_TEMPLATE_AMD3DNOW */
  2497.  
  2498. static void RENAME(uyvytoyuv420)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src,
  2499.                                  int width, int height,
  2500.                                  int lumStride, int chromStride, int srcStride)
  2501. {
  2502.     int y;
  2503.     const int chromWidth = FF_CEIL_RSHIFT(width, 1);
  2504.  
  2505.     for (y=0; y<height; y++) {
  2506.         RENAME(extract_odd)(src, ydst, width);
  2507.         if(y&1) {
  2508.             RENAME(extract_even2avg)(src-srcStride, src, udst, vdst, chromWidth);
  2509.             udst+= chromStride;
  2510.             vdst+= chromStride;
  2511.         }
  2512.  
  2513.         src += srcStride;
  2514.         ydst+= lumStride;
  2515.     }
  2516.     __asm__(
  2517.             EMMS"       \n\t"
  2518.             SFENCE"     \n\t"
  2519.             ::: "memory"
  2520.         );
  2521. }
  2522.  
  2523. #if !COMPILE_TEMPLATE_AMD3DNOW
  2524. static void RENAME(uyvytoyuv422)(uint8_t *ydst, uint8_t *udst, uint8_t *vdst, const uint8_t *src,
  2525.                                  int width, int height,
  2526.                                  int lumStride, int chromStride, int srcStride)
  2527. {
  2528.     int y;
  2529.     const int chromWidth = FF_CEIL_RSHIFT(width, 1);
  2530.  
  2531.     for (y=0; y<height; y++) {
  2532.         RENAME(extract_odd)(src, ydst, width);
  2533.         RENAME(extract_even2)(src, udst, vdst, chromWidth);
  2534.  
  2535.         src += srcStride;
  2536.         ydst+= lumStride;
  2537.         udst+= chromStride;
  2538.         vdst+= chromStride;
  2539.     }
  2540.     __asm__(
  2541.             EMMS"       \n\t"
  2542.             SFENCE"     \n\t"
  2543.             ::: "memory"
  2544.         );
  2545. }
  2546. #endif /* !COMPILE_TEMPLATE_AMD3DNOW */
  2547. #endif /* !COMPILE_TEMPLATE_SSE2 */
  2548.  
  2549. static av_cold void RENAME(rgb2rgb_init)(void)
  2550. {
  2551. #if !COMPILE_TEMPLATE_SSE2
  2552. #if !COMPILE_TEMPLATE_AMD3DNOW
  2553.     rgb15to16          = RENAME(rgb15to16);
  2554.     rgb15tobgr24       = RENAME(rgb15tobgr24);
  2555.     rgb15to32          = RENAME(rgb15to32);
  2556.     rgb16tobgr24       = RENAME(rgb16tobgr24);
  2557.     rgb16to32          = RENAME(rgb16to32);
  2558.     rgb16to15          = RENAME(rgb16to15);
  2559.     rgb24tobgr16       = RENAME(rgb24tobgr16);
  2560.     rgb24tobgr15       = RENAME(rgb24tobgr15);
  2561.     rgb24tobgr32       = RENAME(rgb24tobgr32);
  2562.     rgb32to16          = RENAME(rgb32to16);
  2563.     rgb32to15          = RENAME(rgb32to15);
  2564.     rgb32tobgr24       = RENAME(rgb32tobgr24);
  2565.     rgb24to15          = RENAME(rgb24to15);
  2566.     rgb24to16          = RENAME(rgb24to16);
  2567.     rgb24tobgr24       = RENAME(rgb24tobgr24);
  2568.     shuffle_bytes_2103 = RENAME(shuffle_bytes_2103);
  2569.     rgb32tobgr16       = RENAME(rgb32tobgr16);
  2570.     rgb32tobgr15       = RENAME(rgb32tobgr15);
  2571.     yv12toyuy2         = RENAME(yv12toyuy2);
  2572.     yv12touyvy         = RENAME(yv12touyvy);
  2573.     yuv422ptoyuy2      = RENAME(yuv422ptoyuy2);
  2574.     yuv422ptouyvy      = RENAME(yuv422ptouyvy);
  2575.     yuy2toyv12         = RENAME(yuy2toyv12);
  2576.     vu9_to_vu12        = RENAME(vu9_to_vu12);
  2577.     yvu9_to_yuy2       = RENAME(yvu9_to_yuy2);
  2578.     uyvytoyuv422       = RENAME(uyvytoyuv422);
  2579.     yuyvtoyuv422       = RENAME(yuyvtoyuv422);
  2580. #endif /* !COMPILE_TEMPLATE_AMD3DNOW */
  2581.  
  2582. #if COMPILE_TEMPLATE_MMXEXT || COMPILE_TEMPLATE_AMD3DNOW
  2583.     planar2x           = RENAME(planar2x);
  2584. #endif /* COMPILE_TEMPLATE_MMXEXT || COMPILE_TEMPLATE_AMD3DNOW */
  2585. #if HAVE_7REGS
  2586.     ff_rgb24toyv12     = RENAME(rgb24toyv12);
  2587. #endif /* HAVE_7REGS */
  2588.  
  2589.     yuyvtoyuv420       = RENAME(yuyvtoyuv420);
  2590.     uyvytoyuv420       = RENAME(uyvytoyuv420);
  2591. #endif /* !COMPILE_TEMPLATE_SSE2 */
  2592.  
  2593. #if !COMPILE_TEMPLATE_AMD3DNOW && !COMPILE_TEMPLATE_AVX
  2594.     interleaveBytes    = RENAME(interleaveBytes);
  2595. #endif /* !COMPILE_TEMPLATE_AMD3DNOW && !COMPILE_TEMPLATE_AVX */
  2596. #if !COMPILE_TEMPLATE_AVX || HAVE_AVX_EXTERNAL
  2597. #if !COMPILE_TEMPLATE_AMD3DNOW && (ARCH_X86_32 || COMPILE_TEMPLATE_SSE2) && COMPILE_TEMPLATE_MMXEXT == COMPILE_TEMPLATE_SSE2 && HAVE_YASM
  2598.     deinterleaveBytes  = RENAME(deinterleaveBytes);
  2599. #endif
  2600. #endif
  2601. }
  2602.