memcpyaltivec.c
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:7k
源码类别:

多媒体

开发平台:

MultiPlatform

  1. /*****************************************************************************
  2.  * memcpyaltivec.c : AltiVec memcpy module
  3.  *****************************************************************************
  4.  * Copyright (C) 2001 VideoLAN
  5.  * $Id: memcpyaltivec.c 7406 2004-04-21 13:23:01Z sam $
  6.  *
  7.  * Author: Christophe Massiot <massiot@via.ecp.fr>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. #ifndef __BUILD_ALTIVEC_ASM__
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <vlc/vlc.h>
  30. #ifdef HAVE_ALTIVEC_H
  31. #   include <altivec.h>
  32. #endif
  33. /*****************************************************************************
  34.  * Local prototypes.
  35.  *****************************************************************************/
  36. static void * fast_memcpy ( void * to, const void * from, size_t len );
  37. /*****************************************************************************
  38.  * Module initializer.
  39.  *****************************************************************************/
  40. static int Activate ( vlc_object_t *p_this )
  41. {
  42.     p_this->p_vlc->pf_memcpy = fast_memcpy;
  43.     return VLC_SUCCESS;
  44. }
  45. /*****************************************************************************
  46.  * Module descriptor.
  47.  *****************************************************************************/
  48. vlc_module_begin();
  49.     set_description( _("AltiVec memcpy") );
  50.     add_requirement( ALTIVEC );
  51.     set_capability( "memcpy", 100 );
  52.     set_callbacks( Activate, NULL );
  53.     add_shortcut( "altivec" );
  54. vlc_module_end();
  55. #else
  56. typedef unsigned long size_t;
  57. #endif /* __BUILD_ALTIVEC_ASM__ */
  58. #if defined(CAN_COMPILE_C_ALTIVEC) || defined( __BUILD_ALTIVEC_ASM__ )
  59. #define vector_s16_t vector signed short
  60. #define vector_u16_t vector unsigned short
  61. #define vector_s8_t vector signed char
  62. #define vector_u8_t vector unsigned char
  63. #define vector_s32_t vector signed int
  64. #define vector_u32_t vector unsigned int
  65. #define MMREG_SIZE 16
  66. #define SMALL_MEMCPY(to, from, len)                                         
  67. {                                                                           
  68.     unsigned char * end = to + len;                                         
  69.     while( to < end )                                                       
  70.     {                                                                       
  71.         *to++ = *from++;                                                    
  72.     }                                                                       
  73. }
  74. static void * fast_memcpy( void * _to, const void * _from, size_t len )
  75. {
  76.     void * retval = _to;
  77.     unsigned char * to = (unsigned char *)_to;
  78.     unsigned char * from = (unsigned char *)_from;
  79.     if( len > 16 )
  80.     {
  81.         /* Align destination to MMREG_SIZE -boundary */
  82.         register unsigned long int delta;
  83.         delta = ((unsigned long)to)&(MMREG_SIZE-1);
  84.         if( delta )
  85.         {
  86.             delta = MMREG_SIZE - delta;
  87.             len -= delta;
  88.             SMALL_MEMCPY(to, from, delta);
  89.         }
  90.         if( len & ~(MMREG_SIZE-1) )
  91.         {
  92.             vector_u8_t perm, ref0, ref1, tmp;
  93.             perm = vec_lvsl( 0, from );
  94.             ref0 = vec_ld( 0, from );
  95.             ref1 = vec_ld( 15, from );
  96.             from += 16;
  97.             len -= 16;
  98.             tmp = vec_perm( ref0, ref1, perm );
  99.             while( len & ~(MMREG_SIZE-1) )
  100.             {
  101.                 ref0 = vec_ld( 0, from );
  102.                 ref1 = vec_ld( 15, from );
  103.                 from += 16;
  104.                 len -= 16;
  105.                 vec_st( tmp, 0, to );
  106.                 tmp = vec_perm( ref0, ref1, perm );
  107.                 to += 16;
  108.             }
  109.             vec_st( tmp, 0, to );
  110.             to += 16;
  111.         }
  112.     }
  113.     if( len )
  114.     {
  115.         SMALL_MEMCPY( to, from, len );
  116.     }
  117.     return retval;
  118. }
  119. #endif
  120. #if !defined(CAN_COMPILE_C_ALTIVEC) && !defined(__BUILD_ALTIVEC_ASM__)
  121. /*
  122.  * The asm code is generated with:
  123.  *
  124.  * gcc-2.95 -fvec -D__BUILD_ALTIVEC_ASM__ -O9 -fomit-frame-pointer -mregnames -S *      memcpyaltivec.c
  125.  *
  126.  * sed 's/.L/._L/g' memcpyaltivec.s |
  127.  * awk '{args=""; len=split ($2, arg, ",");
  128.  *      for (i=1; i<=len; i++) { a=arg[i]; if (i<len) a=a",";
  129.  *                               args = args sprintf ("%-6s", a) }
  130.  *      printf ("t"t%-16s%-24s\n"n", $1, args) }' |
  131.  * unexpand -a
  132.  */
  133. static void * fast_memcpy( void * _to, const void * _from, size_t len )
  134. {
  135.     asm ("                                              n"
  136. " cmplwi %cr0, %r5,  16 n"
  137. " mr %r9,  %r3 n"
  138. " bc 4,    1,    ._L3 n"
  139. " andi. %r0,  %r3,  15 n"
  140. " bc 12,   2,    ._L4 n"
  141. " subfic %r0,  %r0,  16 n"
  142. " add %r11, %r3,  %r0 n"
  143. " cmplw %cr0, %r3,  %r11 n"
  144. " subf %r5,  %r0,  %r5 n"
  145. " bc 4,    0,    ._L4 n"
  146. " ._L7: n"
  147. " lbz %r0,  0(%r4) n"
  148. " stb %r0,  0(%r9) n"
  149. " addi %r9,  %r9,  1 n"
  150. " cmplw %cr0, %r9,  %r11 n"
  151. " addi %r4,  %r4,  1 n"
  152. " bc 12,   0,    ._L7 n"
  153. " ._L4: n"
  154. " rlwinm. %r0,  %r5,  0,   0, 27    n"
  155. " bc 12,   2,    ._L3 n"
  156. " addi %r5,  %r5,  -16 n"
  157. " li %r11, 15 n"
  158. " lvsl %v12, 0,    %r4 n"
  159. " lvx %v1,  0,    %r4 n"
  160. " lvx %v0,  %r11, %r4 n"
  161. " rlwinm. %r0,  %r5,  0,   0, 27    n"
  162. " vperm %v13, %v1,  %v0,  %v12 n"
  163. " addi %r4,  %r4,  16 n"
  164. " bc 12,   2,    ._L11 n"
  165. " ._L12: n"
  166. " addi %r5,  %r5,  -16 n"
  167. " li %r11, 15 n"
  168. " lvx %v1,  0,    %r4 n"
  169. " lvx %v0,  %r11, %r4 n"
  170. " rlwinm. %r0,  %r5,  0,   0, 27    n"
  171. " stvx %v13, 0,    %r9 n"
  172. " vperm %v13, %v1,  %v0,  %v12 n"
  173. " addi %r4,  %r4,  16 n"
  174. " addi %r9,  %r9,  16 n"
  175. " bc 4,    2,    ._L12 n"
  176. " ._L11: n"
  177. " stvx %v13, 0,    %r9 n"
  178. " addi %r9,  %r9,  16 n"
  179. " ._L3: n"
  180. " cmpwi %cr0, %r5,  0 n"
  181. " bclr 12,   2 n"
  182. " add %r5,  %r9,  %r5 n"
  183. " cmplw %cr0, %r9,  %r5 n"
  184. " bclr 4,    0 n"
  185. " ._L17: n"
  186. " lbz %r0,  0(%r4) n"
  187. " stb %r0,  0(%r9) n"
  188. " addi %r9,  %r9,  1 n"
  189. " cmplw %cr0, %r9,  %r5 n"
  190. " addi %r4,  %r4,  1 n"
  191. " bc 12,   0,    ._L17 n"
  192.         );
  193. }
  194. #endif