asm_arm.h
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:6k
源码类别:

Windows CE

开发平台:

C/C++

  1. /********************************************************************
  2.  *                                                                  *
  3.  * THIS FILE IS PART OF THE OggVorbis 'TREMOR' CODEC SOURCE CODE.   *
  4.  *                                                                  *
  5.  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  6.  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  7.  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  8.  *                                                                  *
  9.  * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002    *
  10.  * BY THE Xiph.Org FOUNDATION http://www.xiph.org/                  *
  11.  *                                                                  *
  12.  ********************************************************************
  13.  function: arm7 and later wide math functions
  14.  ********************************************************************/
  15. #ifdef _ARM_ASSEM_
  16. #if !defined(_V_WIDE_MATH) && !defined(_LOW_ACCURACY_)
  17. #define _V_WIDE_MATH
  18. static inline ogg_int32_t MULT32(ogg_int32_t x, ogg_int32_t y) {
  19.   int lo,hi;
  20.   asm volatile("smullt%0, %1, %2, %3"
  21.                : "=&r"(lo),"=&r"(hi)
  22.                : "%r"(x),"r"(y)
  23.        : "cc");
  24.   return(hi);
  25. }
  26. static inline ogg_int32_t MULT31(ogg_int32_t x, ogg_int32_t y) {
  27.   return MULT32(x,y)<<1;
  28. }
  29. static inline ogg_int32_t MULT31_SHIFT15(ogg_int32_t x, ogg_int32_t y) {
  30.   int lo,hi;
  31.   asm volatile("smull %0, %1, %2, %3nt"
  32.        "movs %0, %0, lsr #15nt"
  33.        "adc %1, %0, %1, lsl #17nt"
  34.                : "=&r"(lo),"=&r"(hi)
  35.                : "%r"(x),"r"(y)
  36.        : "cc");
  37.   return(hi);
  38. }
  39. #define MB() asm volatile ("" : : : "memory")
  40. static inline void XPROD32(ogg_int32_t  a, ogg_int32_t  b,
  41.    ogg_int32_t  t, ogg_int32_t  v,
  42.    ogg_int32_t *x, ogg_int32_t *y)
  43. {
  44.   int x1, y1, l;
  45.   asm( "smull %0, %1, %4, %6nt"
  46. "smlal %0, %1, %5, %7nt"
  47. "rsb %3, %4, #0nt"
  48. "smull %0, %2, %5, %6nt"
  49. "smlal %0, %2, %3, %7"
  50. : "=&r" (l), "=&r" (x1), "=&r" (y1), "=r" (a)
  51. : "3" (a), "r" (b), "r" (t), "r" (v)
  52. : "cc" );
  53.   *x = x1;
  54.   MB();
  55.   *y = y1;
  56. }
  57. static inline void XPROD31(ogg_int32_t  a, ogg_int32_t  b,
  58.    ogg_int32_t  t, ogg_int32_t  v,
  59.    ogg_int32_t *x, ogg_int32_t *y)
  60. {
  61.   int x1, y1, l;
  62.   asm( "smull %0, %1, %4, %6nt"
  63. "smlal %0, %1, %5, %7nt"
  64. "rsb %3, %4, #0nt"
  65. "smull %0, %2, %5, %6nt"
  66. "smlal %0, %2, %3, %7"
  67. : "=&r" (l), "=&r" (x1), "=&r" (y1), "=r" (a)
  68. : "3" (a), "r" (b), "r" (t), "r" (v)
  69. : "cc" );
  70.   *x = x1 << 1;
  71.   MB();
  72.   *y = y1 << 1;
  73. }
  74. static inline void XNPROD31(ogg_int32_t  a, ogg_int32_t  b,
  75.     ogg_int32_t  t, ogg_int32_t  v,
  76.     ogg_int32_t *x, ogg_int32_t *y)
  77. {
  78.   int x1, y1, l;
  79.   asm( "rsb %2, %4, #0nt"
  80. "smull %0, %1, %3, %5nt"
  81. "smlal %0, %1, %2, %6nt"
  82. "smull %0, %2, %4, %5nt"
  83. "smlal %0, %2, %3, %6"
  84. : "=&r" (l), "=&r" (x1), "=&r" (y1)
  85. : "r" (a), "r" (b), "r" (t), "r" (v)
  86. : "cc" );
  87.   *x = x1 << 1;
  88.   MB();
  89.   *y = y1 << 1;
  90. }
  91. #endif
  92. #ifndef _V_CLIP_MATH
  93. #define _V_CLIP_MATH
  94. static inline ogg_int32_t CLIP_TO_15(ogg_int32_t x) {
  95.   int tmp;
  96.   asm volatile("subs %1, %0, #32768nt"
  97.        "movpl %0, #0x7f00nt"
  98.        "orrpl %0, %0, #0xffn"
  99.        "adds %1, %0, #32768nt"
  100.        "movmi %0, #0x8000"
  101.        : "+r"(x),"=r"(tmp)
  102.        :
  103.        : "cc");
  104.   return(x);
  105. }
  106. #endif
  107. #ifndef _V_LSP_MATH_ASM
  108. #define _V_LSP_MATH_ASM
  109. static inline void lsp_loop_asm(ogg_uint32_t *qip,ogg_uint32_t *pip,
  110. ogg_int32_t *qexpp,
  111. ogg_int32_t *ilsp,ogg_int32_t wi,
  112. ogg_int32_t m){
  113.   
  114.   ogg_uint32_t qi=*qip,pi=*pip;
  115.   ogg_int32_t qexp=*qexpp;
  116.   asm("mov     r0,%3;"
  117.       "mov     r1,%5,asr#1;"
  118.       "add     r0,r0,r1,lsl#3;"
  119.       "1:"
  120.       
  121.       "ldmdb   r0!,{r1,r3};"
  122.       "subs    r1,r1,%4;"          //ilsp[j]-wi
  123.       "rsbmi   r1,r1,#0;"          //labs(ilsp[j]-wi)
  124.       "umull   %0,r2,r1,%0;"       //qi*=labs(ilsp[j]-wi)
  125.       
  126.       "subs    r1,r3,%4;"          //ilsp[j+1]-wi
  127.       "rsbmi   r1,r1,#0;"          //labs(ilsp[j+1]-wi)
  128.       "umull   %1,r3,r1,%1;"       //pi*=labs(ilsp[j+1]-wi)
  129.       
  130.       "cmn     r2,r3;"             // shift down 16?
  131.       "beq     0f;"
  132.       "add     %2,%2,#16;"
  133.       "mov     %0,%0,lsr #16;"
  134.       "orr     %0,%0,r2,lsl #16;"
  135.       "mov     %1,%1,lsr #16;"
  136.       "orr     %1,%1,r3,lsl #16;"
  137.       "0:"
  138.       "cmp     r0,%3;n"
  139.       "bhi     1b;n"
  140.       
  141.       // odd filter assymetry
  142.       "ands    r0,%5,#1;n"
  143.       "beq     2f;n"
  144.       "add     r0,%3,%5,lsl#2;n"
  145.       
  146.       "ldr     r1,[r0,#-4];n"
  147.       "mov     r0,#0x4000;n"
  148.       
  149.       "subs    r1,r1,%4;n"          //ilsp[j]-wi
  150.       "rsbmi   r1,r1,#0;n"          //labs(ilsp[j]-wi)
  151.       "umull   %0,r2,r1,%0;n"       //qi*=labs(ilsp[j]-wi)
  152.       "umull   %1,r3,r0,%1;n"       //pi*=labs(ilsp[j+1]-wi)
  153.       
  154.       "cmn     r2,r3;n"             // shift down 16?
  155.       "beq     2f;n"
  156.       "add     %2,%2,#16;n"
  157.       "mov     %0,%0,lsr #16;n"
  158.       "orr     %0,%0,r2,lsl #16;n"
  159.       "mov     %1,%1,lsr #16;n"
  160.       "orr     %1,%1,r3,lsl #16;n"
  161.       
  162.       //qi=(pi>>shift)*labs(ilsp[j]-wi);
  163.       //pi=(qi>>shift)*labs(ilsp[j+1]-wi);
  164.       //qexp+=shift;
  165.       
  166.       //}
  167.  
  168.       /* normalize to max 16 sig figs */
  169.       "2:"
  170.       "mov     r2,#0;"
  171.       "orr     r1,%0,%1;"
  172.       "tst     r1,#0xff000000;"
  173.       "addne   r2,r2,#8;"
  174.       "movne   r1,r1,lsr #8;"
  175.       "tst     r1,#0x00f00000;"
  176.       "addne   r2,r2,#4;"
  177.       "movne   r1,r1,lsr #4;"
  178.       "tst     r1,#0x000c0000;"
  179.       "addne   r2,r2,#2;"
  180.       "movne   r1,r1,lsr #2;"
  181.       "tst     r1,#0x00020000;"
  182.       "addne   r2,r2,#1;"
  183.       "movne   r1,r1,lsr #1;"
  184.       "tst     r1,#0x00010000;"
  185.       "addne   r2,r2,#1;"
  186.       "mov     %0,%0,lsr r2;"
  187.       "mov     %1,%1,lsr r2;"
  188.       "add     %2,%2,r2;"
  189.       
  190.       : "+r"(qi),"+r"(pi),"+r"(qexp)
  191.       : "r"(ilsp),"r"(wi),"r"(m)
  192.       : "r0","r1","r2","r3","cc");
  193.   
  194.   *qip=qi;
  195.   *pip=pi;
  196.   *qexpp=qexp;
  197. }
  198. static inline void lsp_norm_asm(ogg_uint32_t *qip,ogg_int32_t *qexpp){
  199.   ogg_uint32_t qi=*qip;
  200.   ogg_int32_t qexp=*qexpp;
  201.   asm("tst     %0,#0x0000ff00;"
  202.       "moveq   %0,%0,lsl #8;"
  203.       "subeq   %1,%1,#8;"
  204.       "tst     %0,#0x0000f000;"
  205.       "moveq   %0,%0,lsl #4;"
  206.       "subeq   %1,%1,#4;"
  207.       "tst     %0,#0x0000c000;"
  208.       "moveq   %0,%0,lsl #2;"
  209.       "subeq   %1,%1,#2;"
  210.       "tst     %0,#0x00008000;"
  211.       "moveq   %0,%0,lsl #1;"
  212.       "subeq   %1,%1,#1;"
  213.       : "+r"(qi),"+r"(qexp)
  214.       :
  215.       : "cc");
  216.   *qip=qi;
  217.   *qexpp=qexp;
  218. }
  219. #endif
  220. #endif