memcpyaltivec.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:8k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * memcpyaltivec.c : AltiVec memcpy module
  3.  *****************************************************************************
  4.  * Copyright (C) 2001 the VideoLAN team
  5.  * $Id: 2f75063ea31f4fd157c3e02faa24d04b2e4a387f $
  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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  22.  *****************************************************************************/
  23. #ifndef __BUILD_ALTIVEC_ASM__
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #ifdef HAVE_CONFIG_H
  28. # include "config.h"
  29. #endif
  30. #include <vlc_common.h>
  31. #include <vlc_plugin.h>
  32. #ifdef HAVE_ALTIVEC_H
  33. #   include <altivec.h>
  34. #endif
  35. /*****************************************************************************
  36.  * Local prototypes.
  37.  *****************************************************************************/
  38. static void * fast_memcpy ( void * to, const void * from, size_t len );
  39. /*****************************************************************************
  40.  * Module initializer.
  41.  *****************************************************************************/
  42. static int Activate ( vlc_object_t *p_this )
  43. {
  44.     vlc_fastmem_register( fast_memcpy, NULL );
  45.     return VLC_SUCCESS;
  46. }
  47. /*****************************************************************************
  48.  * Module descriptor.
  49.  *****************************************************************************/
  50. vlc_module_begin ()
  51.     set_description( N_("AltiVec memcpy") )
  52.     set_category( CAT_ADVANCED )
  53.     set_subcategory( SUBCAT_ADVANCED_MISC )
  54.     add_requirement( ALTIVEC )
  55.     set_capability( "memcpy", 100 )
  56.     set_callbacks( Activate, NULL )
  57.     add_shortcut( "altivec" )
  58. vlc_module_end ()
  59. #else
  60. typedef unsigned long size_t;
  61. #endif /* __BUILD_ALTIVEC_ASM__ */
  62. #if defined(CAN_COMPILE_C_ALTIVEC) || defined( __BUILD_ALTIVEC_ASM__ )
  63. #define vector_s16_t vector signed short
  64. #define vector_u16_t vector unsigned short
  65. #define vector_s8_t vector signed char
  66. #define vector_u8_t vector unsigned char
  67. #define vector_s32_t vector signed int
  68. #define vector_u32_t vector unsigned int
  69. #define MMREG_SIZE 16
  70. #define SMALL_MEMCPY(to, from, len)                                         
  71. {                                                                           
  72.     unsigned char * end = to + len;                                         
  73.     while( to < end )                                                       
  74.     {                                                                       
  75.         *to++ = *from++;                                                    
  76.     }                                                                       
  77. }
  78. static void * fast_memcpy( void * _to, const void * _from, size_t len )
  79. {
  80.     void * retval = _to;
  81.     unsigned char * to = (unsigned char *)_to;
  82.     unsigned char * from = (unsigned char *)_from;
  83.     if( len > 16 )
  84.     {
  85.         /* Align destination to MMREG_SIZE -boundary */
  86.         register unsigned long int delta;
  87.         delta = ((unsigned long)to)&(MMREG_SIZE-1);
  88.         if( delta )
  89.         {
  90.             delta = MMREG_SIZE - delta;
  91.             len -= delta;
  92.             SMALL_MEMCPY(to, from, delta);
  93.         }
  94.         if( len & ~(MMREG_SIZE-1) )
  95.         {
  96.             vector_u8_t perm, ref0, ref1, tmp;
  97.             perm = vec_lvsl( 0, from );
  98.             ref0 = vec_ld( 0, from );
  99.             ref1 = vec_ld( 15, from );
  100.             from += 16;
  101.             len -= 16;
  102.             tmp = vec_perm( ref0, ref1, perm );
  103.             while( len & ~(MMREG_SIZE-1) )
  104.             {
  105.                 ref0 = vec_ld( 0, from );
  106.                 ref1 = vec_ld( 15, from );
  107.                 from += 16;
  108.                 len -= 16;
  109.                 vec_st( tmp, 0, to );
  110.                 tmp = vec_perm( ref0, ref1, perm );
  111.                 to += 16;
  112.             }
  113.             vec_st( tmp, 0, to );
  114.             to += 16;
  115.         }
  116.     }
  117.     if( len )
  118.     {
  119.         SMALL_MEMCPY( to, from, len );
  120.     }
  121.     return retval;
  122. }
  123. #endif
  124. #if !defined(CAN_COMPILE_C_ALTIVEC) && !defined(__BUILD_ALTIVEC_ASM__)
  125. /*
  126.  * The asm code is generated with:
  127.  *
  128.  * gcc-2.95 -fvec -D__BUILD_ALTIVEC_ASM__ -O9 -fomit-frame-pointer -mregnames -S *      memcpyaltivec.c
  129.  *
  130.  * sed 's/.L/._L/g' memcpyaltivec.s |
  131.  * awk '{args=""; len=split ($2, arg, ",");
  132.  *      for (i=1; i<=len; i++) { a=arg[i]; if (i<len) a=a",";
  133.  *                               args = args sprintf ("%-6s", a) }
  134.  *      printf ("t"t%-16s%-24s\n"n", $1, args) }' |
  135.  * unexpand -a
  136.  */
  137. static void * fast_memcpy( void * _to, const void * _from, size_t len )
  138. {
  139.     asm ("                                              n"
  140.     "    cmplwi        %cr0, %r5,  16        n"
  141.     "    mr        %r9,  %r3        n"
  142.     "    bc        4,    1,    ._L3    n"
  143.     "    andi.        %r0,  %r3,  15        n"
  144.     "    bc        12,   2,    ._L4    n"
  145.     "    subfic        %r0,  %r0,  16        n"
  146.     "    add        %r11, %r3,  %r0        n"
  147.     "    cmplw        %cr0, %r3,  %r11    n"
  148.     "    subf        %r5,  %r0,  %r5        n"
  149.     "    bc        4,    0,    ._L4    n"
  150.     "    ._L7:                    n"
  151.     "    lbz        %r0,  0(%r4)        n"
  152.     "    stb        %r0,  0(%r9)        n"
  153.     "    addi        %r9,  %r9,  1        n"
  154.     "    cmplw        %cr0, %r9,  %r11    n"
  155.     "    addi        %r4,  %r4,  1        n"
  156.     "    bc        12,   0,    ._L7    n"
  157.     "    ._L4:                    n"
  158.     "    rlwinm.        %r0,  %r5,  0,      0,    27    n"
  159.     "    bc        12,   2,    ._L3    n"
  160.     "    addi        %r5,  %r5,  -16        n"
  161.     "    li        %r11, 15        n"
  162.     "    lvsl        %v12, 0,    %r4        n"
  163.     "    lvx        %v1,  0,    %r4        n"
  164.     "    lvx        %v0,  %r11, %r4        n"
  165.     "    rlwinm.        %r0,  %r5,  0,      0,    27    n"
  166.     "    vperm        %v13, %v1,  %v0,  %v12    n"
  167.     "    addi        %r4,  %r4,  16        n"
  168.     "    bc        12,   2,    ._L11    n"
  169.     "    ._L12:                    n"
  170.     "    addi        %r5,  %r5,  -16        n"
  171.     "    li        %r11, 15        n"
  172.     "    lvx        %v1,  0,    %r4        n"
  173.     "    lvx        %v0,  %r11, %r4        n"
  174.     "    rlwinm.        %r0,  %r5,  0,      0,    27    n"
  175.     "    stvx        %v13, 0,    %r9        n"
  176.     "    vperm        %v13, %v1,  %v0,  %v12    n"
  177.     "    addi        %r4,  %r4,  16        n"
  178.     "    addi        %r9,  %r9,  16        n"
  179.     "    bc        4,    2,    ._L12    n"
  180.     "    ._L11:                    n"
  181.     "    stvx        %v13, 0,    %r9        n"
  182.     "    addi        %r9,  %r9,  16        n"
  183.     "    ._L3:                    n"
  184.     "    cmpwi        %cr0, %r5,  0        n"
  185.     "    bclr        12,   2            n"
  186.     "    add        %r5,  %r9,  %r5        n"
  187.     "    cmplw        %cr0, %r9,  %r5        n"
  188.     "    bclr        4,    0            n"
  189.     "    ._L17:                    n"
  190.     "    lbz        %r0,  0(%r4)        n"
  191.     "    stb        %r0,  0(%r9)        n"
  192.     "    addi        %r9,  %r9,  1        n"
  193.     "    cmplw        %cr0, %r9,  %r5        n"
  194.     "    addi        %r4,  %r4,  1        n"
  195.     "    bc        12,   0,    ._L17    n"
  196.         );
  197. }
  198. #endif