Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2012
  3.  *      MIPS Technologies, Inc., California.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
  14.  *    contributors may be used to endorse or promote products derived from
  15.  *    this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
  18.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
  21.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27.  * SUCH DAMAGE.
  28.  *
  29.  * Authors:  Darko Laus      (darko@mips.com)
  30.  *           Djordje Pesut   (djordje@mips.com)
  31.  *           Mirjana Vulin   (mvulin@mips.com)
  32.  *
  33.  * AAC Spectral Band Replication decoding functions optimized for MIPS
  34.  *
  35.  * This file is part of FFmpeg.
  36.  *
  37.  * FFmpeg is free software; you can redistribute it and/or
  38.  * modify it under the terms of the GNU Lesser General Public
  39.  * License as published by the Free Software Foundation; either
  40.  * version 2.1 of the License, or (at your option) any later version.
  41.  *
  42.  * FFmpeg is distributed in the hope that it will be useful,
  43.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  44.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  45.  * Lesser General Public License for more details.
  46.  *
  47.  * You should have received a copy of the GNU Lesser General Public
  48.  * License along with FFmpeg; if not, write to the Free Software
  49.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  50.  */
  51.  
  52. /**
  53.  * @file
  54.  * Reference: libavcodec/sbrdsp.c
  55.  */
  56.  
  57. #include "config.h"
  58. #include "libavcodec/sbrdsp.h"
  59.  
  60. #if HAVE_INLINE_ASM
  61. static void sbr_neg_odd_64_mips(float *x)
  62. {
  63.     int Temp1, Temp2, Temp3, Temp4, Temp5;
  64.     float *x1    = &x[1];
  65.     float *x_end = x1 + 64;
  66.  
  67.     /* loop unrolled 4 times */
  68.     __asm__ volatile (
  69.         "lui    %[Temp5],   0x8000                  \n\t"
  70.     "1:                                             \n\t"
  71.         "lw     %[Temp1],   0(%[x1])                \n\t"
  72.         "lw     %[Temp2],   8(%[x1])                \n\t"
  73.         "lw     %[Temp3],   16(%[x1])               \n\t"
  74.         "lw     %[Temp4],   24(%[x1])               \n\t"
  75.         "xor    %[Temp1],   %[Temp1],   %[Temp5]    \n\t"
  76.         "xor    %[Temp2],   %[Temp2],   %[Temp5]    \n\t"
  77.         "xor    %[Temp3],   %[Temp3],   %[Temp5]    \n\t"
  78.         "xor    %[Temp4],   %[Temp4],   %[Temp5]    \n\t"
  79.         "sw     %[Temp1],   0(%[x1])                \n\t"
  80.         "sw     %[Temp2],   8(%[x1])                \n\t"
  81.         "sw     %[Temp3],   16(%[x1])               \n\t"
  82.         "sw     %[Temp4],   24(%[x1])               \n\t"
  83.         "addiu  %[x1],      %[x1],      32          \n\t"
  84.         "bne    %[x1],      %[x_end],   1b          \n\t"
  85.  
  86.         : [Temp1]"=&r"(Temp1), [Temp2]"=&r"(Temp2),
  87.           [Temp3]"=&r"(Temp3), [Temp4]"=&r"(Temp4),
  88.           [Temp5]"=&r"(Temp5), [x1]"+r"(x1)
  89.         : [x_end]"r"(x_end)
  90.         : "memory"
  91.     );
  92. }
  93.  
  94. static void sbr_qmf_pre_shuffle_mips(float *z)
  95. {
  96.     int Temp1, Temp2, Temp3, Temp4, Temp5, Temp6;
  97.     float *z1 = &z[66];
  98.     float *z2 = &z[59];
  99.     float *z3 = &z[2];
  100.     float *z4 = z1 + 60;
  101.  
  102.     /* loop unrolled 5 times */
  103.     __asm__ volatile (
  104.         "lui    %[Temp6],   0x8000                  \n\t"
  105.     "1:                                             \n\t"
  106.         "lw     %[Temp1],   0(%[z2])                \n\t"
  107.         "lw     %[Temp2],   4(%[z2])                \n\t"
  108.         "lw     %[Temp3],   8(%[z2])                \n\t"
  109.         "lw     %[Temp4],   12(%[z2])               \n\t"
  110.         "lw     %[Temp5],   16(%[z2])               \n\t"
  111.         "xor    %[Temp1],   %[Temp1],   %[Temp6]    \n\t"
  112.         "xor    %[Temp2],   %[Temp2],   %[Temp6]    \n\t"
  113.         "xor    %[Temp3],   %[Temp3],   %[Temp6]    \n\t"
  114.         "xor    %[Temp4],   %[Temp4],   %[Temp6]    \n\t"
  115.         "xor    %[Temp5],   %[Temp5],   %[Temp6]    \n\t"
  116.         "addiu  %[z2],      %[z2],      -20         \n\t"
  117.         "sw     %[Temp1],   32(%[z1])               \n\t"
  118.         "sw     %[Temp2],   24(%[z1])               \n\t"
  119.         "sw     %[Temp3],   16(%[z1])               \n\t"
  120.         "sw     %[Temp4],   8(%[z1])                \n\t"
  121.         "sw     %[Temp5],   0(%[z1])                \n\t"
  122.         "lw     %[Temp1],   0(%[z3])                \n\t"
  123.         "lw     %[Temp2],   4(%[z3])                \n\t"
  124.         "lw     %[Temp3],   8(%[z3])                \n\t"
  125.         "lw     %[Temp4],   12(%[z3])               \n\t"
  126.         "lw     %[Temp5],   16(%[z3])               \n\t"
  127.         "sw     %[Temp1],   4(%[z1])                \n\t"
  128.         "sw     %[Temp2],   12(%[z1])               \n\t"
  129.         "sw     %[Temp3],   20(%[z1])               \n\t"
  130.         "sw     %[Temp4],   28(%[z1])               \n\t"
  131.         "sw     %[Temp5],   36(%[z1])               \n\t"
  132.         "addiu  %[z3],      %[z3],      20          \n\t"
  133.         "addiu  %[z1],      %[z1],      40          \n\t"
  134.         "bne    %[z1],      %[z4],      1b          \n\t"
  135.         "lw     %[Temp1],   132(%[z])               \n\t"
  136.         "lw     %[Temp2],   128(%[z])               \n\t"
  137.         "lw     %[Temp3],   0(%[z])                 \n\t"
  138.         "lw     %[Temp4],   4(%[z])                 \n\t"
  139.         "xor    %[Temp1],   %[Temp1],   %[Temp6]    \n\t"
  140.         "sw     %[Temp1],   504(%[z])               \n\t"
  141.         "sw     %[Temp2],   508(%[z])               \n\t"
  142.         "sw     %[Temp3],   256(%[z])               \n\t"
  143.         "sw     %[Temp4],   260(%[z])               \n\t"
  144.  
  145.         : [Temp1]"=&r"(Temp1), [Temp2]"=&r"(Temp2),
  146.           [Temp3]"=&r"(Temp3), [Temp4]"=&r"(Temp4),
  147.           [Temp5]"=&r"(Temp5), [Temp6]"=&r"(Temp6),
  148.           [z1]"+r"(z1), [z2]"+r"(z2), [z3]"+r"(z3)
  149.         : [z4]"r"(z4), [z]"r"(z)
  150.         : "memory"
  151.     );
  152. }
  153.  
  154. static void sbr_qmf_post_shuffle_mips(float W[32][2], const float *z)
  155. {
  156.     int Temp1, Temp2, Temp3, Temp4, Temp5;
  157.     float *W_ptr = (float *)W;
  158.     float *z1    = (float *)z;
  159.     float *z2    = (float *)&z[60];
  160.     float *z_end = z1 + 32;
  161.  
  162.      /* loop unrolled 4 times */
  163.     __asm__ volatile (
  164.         "lui    %[Temp5],   0x8000                  \n\t"
  165.     "1:                                             \n\t"
  166.         "lw     %[Temp1],   0(%[z2])                \n\t"
  167.         "lw     %[Temp2],   4(%[z2])                \n\t"
  168.         "lw     %[Temp3],   8(%[z2])                \n\t"
  169.         "lw     %[Temp4],   12(%[z2])               \n\t"
  170.         "xor    %[Temp1],   %[Temp1],   %[Temp5]    \n\t"
  171.         "xor    %[Temp2],   %[Temp2],   %[Temp5]    \n\t"
  172.         "xor    %[Temp3],   %[Temp3],   %[Temp5]    \n\t"
  173.         "xor    %[Temp4],   %[Temp4],   %[Temp5]    \n\t"
  174.         "addiu  %[z2],      %[z2],      -16         \n\t"
  175.         "sw     %[Temp1],   24(%[W_ptr])            \n\t"
  176.         "sw     %[Temp2],   16(%[W_ptr])            \n\t"
  177.         "sw     %[Temp3],   8(%[W_ptr])             \n\t"
  178.         "sw     %[Temp4],   0(%[W_ptr])             \n\t"
  179.         "lw     %[Temp1],   0(%[z1])                \n\t"
  180.         "lw     %[Temp2],   4(%[z1])                \n\t"
  181.         "lw     %[Temp3],   8(%[z1])                \n\t"
  182.         "lw     %[Temp4],   12(%[z1])               \n\t"
  183.         "sw     %[Temp1],   4(%[W_ptr])             \n\t"
  184.         "sw     %[Temp2],   12(%[W_ptr])            \n\t"
  185.         "sw     %[Temp3],   20(%[W_ptr])            \n\t"
  186.         "sw     %[Temp4],   28(%[W_ptr])            \n\t"
  187.         "addiu  %[z1],      %[z1],      16          \n\t"
  188.         "addiu  %[W_ptr],   %[W_ptr],   32          \n\t"
  189.         "bne    %[z1],      %[z_end],   1b          \n\t"
  190.  
  191.         : [Temp1]"=&r"(Temp1), [Temp2]"=&r"(Temp2),
  192.           [Temp3]"=&r"(Temp3), [Temp4]"=&r"(Temp4),
  193.           [Temp5]"=&r"(Temp5), [z1]"+r"(z1),
  194.           [z2]"+r"(z2), [W_ptr]"+r"(W_ptr)
  195.         : [z_end]"r"(z_end)
  196.         : "memory"
  197.     );
  198. }
  199.  
  200. #if HAVE_MIPSFPU
  201. static void sbr_sum64x5_mips(float *z)
  202. {
  203.     int k;
  204.     float *z1;
  205.     float f1, f2, f3, f4, f5, f6, f7, f8;
  206.     for (k = 0; k < 64; k += 8) {
  207.  
  208.         z1 = &z[k];
  209.  
  210.          /* loop unrolled 8 times */
  211.         __asm__ volatile (
  212.             "lwc1   $f0,    0(%[z1])        \n\t"
  213.             "lwc1   $f1,    256(%[z1])      \n\t"
  214.             "lwc1   $f2,    4(%[z1])        \n\t"
  215.             "lwc1   $f3,    260(%[z1])      \n\t"
  216.             "lwc1   $f4,    8(%[z1])        \n\t"
  217.             "add.s  %[f1],  $f0,    $f1     \n\t"
  218.             "lwc1   $f5,    264(%[z1])      \n\t"
  219.             "add.s  %[f2],  $f2,    $f3     \n\t"
  220.             "lwc1   $f6,    12(%[z1])       \n\t"
  221.             "lwc1   $f7,    268(%[z1])      \n\t"
  222.             "add.s  %[f3],  $f4,    $f5     \n\t"
  223.             "lwc1   $f8,    16(%[z1])       \n\t"
  224.             "lwc1   $f9,    272(%[z1])      \n\t"
  225.             "add.s  %[f4],  $f6,    $f7     \n\t"
  226.             "lwc1   $f10,   20(%[z1])       \n\t"
  227.             "lwc1   $f11,   276(%[z1])      \n\t"
  228.             "add.s  %[f5],  $f8,    $f9     \n\t"
  229.             "lwc1   $f12,   24(%[z1])       \n\t"
  230.             "lwc1   $f13,   280(%[z1])      \n\t"
  231.             "add.s  %[f6],  $f10,   $f11    \n\t"
  232.             "lwc1   $f14,   28(%[z1])       \n\t"
  233.             "lwc1   $f15,   284(%[z1])      \n\t"
  234.             "add.s  %[f7],  $f12,   $f13    \n\t"
  235.             "lwc1   $f0,    512(%[z1])      \n\t"
  236.             "lwc1   $f1,    516(%[z1])      \n\t"
  237.             "add.s  %[f8],  $f14,   $f15    \n\t"
  238.             "lwc1   $f2,    520(%[z1])      \n\t"
  239.             "add.s  %[f1],  %[f1],  $f0     \n\t"
  240.             "add.s  %[f2],  %[f2],  $f1     \n\t"
  241.             "lwc1   $f3,    524(%[z1])      \n\t"
  242.             "add.s  %[f3],  %[f3],  $f2     \n\t"
  243.             "lwc1   $f4,    528(%[z1])      \n\t"
  244.             "lwc1   $f5,    532(%[z1])      \n\t"
  245.             "add.s  %[f4],  %[f4],  $f3     \n\t"
  246.             "lwc1   $f6,    536(%[z1])      \n\t"
  247.             "add.s  %[f5],  %[f5],  $f4     \n\t"
  248.             "add.s  %[f6],  %[f6],  $f5     \n\t"
  249.             "lwc1   $f7,    540(%[z1])      \n\t"
  250.             "add.s  %[f7],  %[f7],  $f6     \n\t"
  251.             "lwc1   $f0,    768(%[z1])      \n\t"
  252.             "lwc1   $f1,    772(%[z1])      \n\t"
  253.             "add.s  %[f8],  %[f8],  $f7     \n\t"
  254.             "lwc1   $f2,    776(%[z1])      \n\t"
  255.             "add.s  %[f1],  %[f1],  $f0     \n\t"
  256.             "add.s  %[f2],  %[f2],  $f1     \n\t"
  257.             "lwc1   $f3,    780(%[z1])      \n\t"
  258.             "add.s  %[f3],  %[f3],  $f2     \n\t"
  259.             "lwc1   $f4,    784(%[z1])      \n\t"
  260.             "lwc1   $f5,    788(%[z1])      \n\t"
  261.             "add.s  %[f4],  %[f4],  $f3     \n\t"
  262.             "lwc1   $f6,    792(%[z1])      \n\t"
  263.             "add.s  %[f5],  %[f5],  $f4     \n\t"
  264.             "add.s  %[f6],  %[f6],  $f5     \n\t"
  265.             "lwc1   $f7,    796(%[z1])      \n\t"
  266.             "add.s  %[f7],  %[f7],  $f6     \n\t"
  267.             "lwc1   $f0,    1024(%[z1])     \n\t"
  268.             "lwc1   $f1,    1028(%[z1])     \n\t"
  269.             "add.s  %[f8],  %[f8],  $f7     \n\t"
  270.             "lwc1   $f2,    1032(%[z1])     \n\t"
  271.             "add.s  %[f1],  %[f1],  $f0     \n\t"
  272.             "add.s  %[f2],  %[f2],  $f1     \n\t"
  273.             "lwc1   $f3,    1036(%[z1])     \n\t"
  274.             "add.s  %[f3],  %[f3],  $f2     \n\t"
  275.             "lwc1   $f4,    1040(%[z1])     \n\t"
  276.             "lwc1   $f5,    1044(%[z1])     \n\t"
  277.             "add.s  %[f4],  %[f4],  $f3     \n\t"
  278.             "lwc1   $f6,    1048(%[z1])     \n\t"
  279.             "add.s  %[f5],  %[f5],  $f4     \n\t"
  280.             "add.s  %[f6],  %[f6],  $f5     \n\t"
  281.             "lwc1   $f7,    1052(%[z1])     \n\t"
  282.             "add.s  %[f7],  %[f7],  $f6     \n\t"
  283.             "swc1   %[f1],  0(%[z1])        \n\t"
  284.             "swc1   %[f2],  4(%[z1])        \n\t"
  285.             "add.s  %[f8],  %[f8],  $f7     \n\t"
  286.             "swc1   %[f3],  8(%[z1])        \n\t"
  287.             "swc1   %[f4],  12(%[z1])       \n\t"
  288.             "swc1   %[f5],  16(%[z1])       \n\t"
  289.             "swc1   %[f6],  20(%[z1])       \n\t"
  290.             "swc1   %[f7],  24(%[z1])       \n\t"
  291.             "swc1   %[f8],  28(%[z1])       \n\t"
  292.  
  293.             : [f1]"=&f"(f1), [f2]"=&f"(f2), [f3]"=&f"(f3),
  294.               [f4]"=&f"(f4), [f5]"=&f"(f5), [f6]"=&f"(f6),
  295.               [f7]"=&f"(f7), [f8]"=&f"(f8)
  296.             : [z1]"r"(z1)
  297.             : "$f0", "$f1", "$f2", "$f3", "$f4", "$f5",
  298.               "$f6", "$f7", "$f8", "$f9", "$f10", "$f11",
  299.               "$f12", "$f13", "$f14", "$f15",
  300.               "memory"
  301.         );
  302.     }
  303. }
  304.  
  305. static float sbr_sum_square_mips(float (*x)[2], int n)
  306. {
  307.     float sum0 = 0.0f, sum1 = 0.0f;
  308.     float *p_x;
  309.     float temp0, temp1, temp2, temp3;
  310.     float *loop_end;
  311.     p_x = &x[0][0];
  312.     loop_end = p_x + (n >> 1)*4 - 4;
  313.  
  314.     __asm__ volatile (
  315.         ".set      push                                             \n\t"
  316.         ".set      noreorder                                        \n\t"
  317.         "lwc1      %[temp0],   0(%[p_x])                            \n\t"
  318.         "lwc1      %[temp1],   4(%[p_x])                            \n\t"
  319.         "lwc1      %[temp2],   8(%[p_x])                            \n\t"
  320.         "lwc1      %[temp3],   12(%[p_x])                           \n\t"
  321.     "1:                                                             \n\t"
  322.         "addiu     %[p_x],     %[p_x],       16                     \n\t"
  323.         "madd.s    %[sum0],    %[sum0],      %[temp0],   %[temp0]   \n\t"
  324.         "lwc1      %[temp0],   0(%[p_x])                            \n\t"
  325.         "madd.s    %[sum1],    %[sum1],      %[temp1],   %[temp1]   \n\t"
  326.         "lwc1      %[temp1],   4(%[p_x])                            \n\t"
  327.         "madd.s    %[sum0],    %[sum0],      %[temp2],   %[temp2]   \n\t"
  328.         "lwc1      %[temp2],   8(%[p_x])                            \n\t"
  329.         "madd.s    %[sum1],    %[sum1],      %[temp3],   %[temp3]   \n\t"
  330.         "bne       %[p_x],     %[loop_end],  1b                     \n\t"
  331.         " lwc1     %[temp3],   12(%[p_x])                           \n\t"
  332.         "madd.s    %[sum0],    %[sum0],      %[temp0],   %[temp0]   \n\t"
  333.         "madd.s    %[sum1],    %[sum1],      %[temp1],   %[temp1]   \n\t"
  334.         "madd.s    %[sum0],    %[sum0],      %[temp2],   %[temp2]   \n\t"
  335.         "madd.s    %[sum1],    %[sum1],      %[temp3],   %[temp3]   \n\t"
  336.         ".set      pop                                              \n\t"
  337.  
  338.         : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
  339.           [temp3]"=&f"(temp3), [sum0]"+f"(sum0), [sum1]"+f"(sum1),
  340.           [p_x]"+r"(p_x)
  341.         : [loop_end]"r"(loop_end)
  342.         : "memory"
  343.     );
  344.     return sum0 + sum1;
  345. }
  346.  
  347. static void sbr_qmf_deint_bfly_mips(float *v, const float *src0, const float *src1)
  348. {
  349.     int i;
  350.     float temp0, temp1, temp2, temp3, temp4, temp5;
  351.     float temp6, temp7, temp8, temp9, temp10, temp11;
  352.     float *v0 = v;
  353.     float *v1 = &v[127];
  354.     float *psrc0 = (float*)src0;
  355.     float *psrc1 = (float*)&src1[63];
  356.  
  357.     for (i = 0; i < 4; i++) {
  358.  
  359.          /* loop unrolled 16 times */
  360.         __asm__ volatile(
  361.             "lwc1       %[temp0],   0(%[src0])             \n\t"
  362.             "lwc1       %[temp1],   0(%[src1])             \n\t"
  363.             "lwc1       %[temp3],   4(%[src0])             \n\t"
  364.             "lwc1       %[temp4],   -4(%[src1])            \n\t"
  365.             "lwc1       %[temp6],   8(%[src0])             \n\t"
  366.             "lwc1       %[temp7],   -8(%[src1])            \n\t"
  367.             "lwc1       %[temp9],   12(%[src0])            \n\t"
  368.             "lwc1       %[temp10],  -12(%[src1])           \n\t"
  369.             "add.s      %[temp2],   %[temp0],   %[temp1]   \n\t"
  370.             "add.s      %[temp5],   %[temp3],   %[temp4]   \n\t"
  371.             "add.s      %[temp8],   %[temp6],   %[temp7]   \n\t"
  372.             "add.s      %[temp11],  %[temp9],   %[temp10]  \n\t"
  373.             "sub.s      %[temp0],   %[temp0],   %[temp1]   \n\t"
  374.             "sub.s      %[temp3],   %[temp3],   %[temp4]   \n\t"
  375.             "sub.s      %[temp6],   %[temp6],   %[temp7]   \n\t"
  376.             "sub.s      %[temp9],   %[temp9],   %[temp10]  \n\t"
  377.             "swc1       %[temp2],   0(%[v1])               \n\t"
  378.             "swc1       %[temp0],   0(%[v0])               \n\t"
  379.             "swc1       %[temp5],   -4(%[v1])              \n\t"
  380.             "swc1       %[temp3],   4(%[v0])               \n\t"
  381.             "swc1       %[temp8],   -8(%[v1])              \n\t"
  382.             "swc1       %[temp6],   8(%[v0])               \n\t"
  383.             "swc1       %[temp11],  -12(%[v1])             \n\t"
  384.             "swc1       %[temp9],   12(%[v0])              \n\t"
  385.             "lwc1       %[temp0],   16(%[src0])            \n\t"
  386.             "lwc1       %[temp1],   -16(%[src1])           \n\t"
  387.             "lwc1       %[temp3],   20(%[src0])            \n\t"
  388.             "lwc1       %[temp4],   -20(%[src1])           \n\t"
  389.             "lwc1       %[temp6],   24(%[src0])            \n\t"
  390.             "lwc1       %[temp7],   -24(%[src1])           \n\t"
  391.             "lwc1       %[temp9],   28(%[src0])            \n\t"
  392.             "lwc1       %[temp10],  -28(%[src1])           \n\t"
  393.             "add.s      %[temp2],   %[temp0],   %[temp1]   \n\t"
  394.             "add.s      %[temp5],   %[temp3],   %[temp4]   \n\t"
  395.             "add.s      %[temp8],   %[temp6],   %[temp7]   \n\t"
  396.             "add.s      %[temp11],  %[temp9],   %[temp10]  \n\t"
  397.             "sub.s      %[temp0],   %[temp0],   %[temp1]   \n\t"
  398.             "sub.s      %[temp3],   %[temp3],   %[temp4]   \n\t"
  399.             "sub.s      %[temp6],   %[temp6],   %[temp7]   \n\t"
  400.             "sub.s      %[temp9],   %[temp9],   %[temp10]  \n\t"
  401.             "swc1       %[temp2],   -16(%[v1])             \n\t"
  402.             "swc1       %[temp0],   16(%[v0])              \n\t"
  403.             "swc1       %[temp5],   -20(%[v1])             \n\t"
  404.             "swc1       %[temp3],   20(%[v0])              \n\t"
  405.             "swc1       %[temp8],   -24(%[v1])             \n\t"
  406.             "swc1       %[temp6],   24(%[v0])              \n\t"
  407.             "swc1       %[temp11],  -28(%[v1])             \n\t"
  408.             "swc1       %[temp9],   28(%[v0])              \n\t"
  409.             "lwc1       %[temp0],   32(%[src0])            \n\t"
  410.             "lwc1       %[temp1],   -32(%[src1])           \n\t"
  411.             "lwc1       %[temp3],   36(%[src0])            \n\t"
  412.             "lwc1       %[temp4],   -36(%[src1])           \n\t"
  413.             "lwc1       %[temp6],   40(%[src0])            \n\t"
  414.             "lwc1       %[temp7],   -40(%[src1])           \n\t"
  415.             "lwc1       %[temp9],   44(%[src0])            \n\t"
  416.             "lwc1       %[temp10],  -44(%[src1])           \n\t"
  417.             "add.s      %[temp2],   %[temp0],   %[temp1]   \n\t"
  418.             "add.s      %[temp5],   %[temp3],   %[temp4]   \n\t"
  419.             "add.s      %[temp8],   %[temp6],   %[temp7]   \n\t"
  420.             "add.s      %[temp11],  %[temp9],   %[temp10]  \n\t"
  421.             "sub.s      %[temp0],   %[temp0],   %[temp1]   \n\t"
  422.             "sub.s      %[temp3],   %[temp3],   %[temp4]   \n\t"
  423.             "sub.s      %[temp6],   %[temp6],   %[temp7]   \n\t"
  424.             "sub.s      %[temp9],   %[temp9],   %[temp10]  \n\t"
  425.             "swc1       %[temp2],   -32(%[v1])             \n\t"
  426.             "swc1       %[temp0],   32(%[v0])              \n\t"
  427.             "swc1       %[temp5],   -36(%[v1])             \n\t"
  428.             "swc1       %[temp3],   36(%[v0])              \n\t"
  429.             "swc1       %[temp8],   -40(%[v1])             \n\t"
  430.             "swc1       %[temp6],   40(%[v0])              \n\t"
  431.             "swc1       %[temp11],  -44(%[v1])             \n\t"
  432.             "swc1       %[temp9],   44(%[v0])              \n\t"
  433.             "lwc1       %[temp0],   48(%[src0])            \n\t"
  434.             "lwc1       %[temp1],   -48(%[src1])           \n\t"
  435.             "lwc1       %[temp3],   52(%[src0])            \n\t"
  436.             "lwc1       %[temp4],   -52(%[src1])           \n\t"
  437.             "lwc1       %[temp6],   56(%[src0])            \n\t"
  438.             "lwc1       %[temp7],   -56(%[src1])           \n\t"
  439.             "lwc1       %[temp9],   60(%[src0])            \n\t"
  440.             "lwc1       %[temp10],  -60(%[src1])           \n\t"
  441.             "add.s      %[temp2],   %[temp0],   %[temp1]   \n\t"
  442.             "add.s      %[temp5],   %[temp3],   %[temp4]   \n\t"
  443.             "add.s      %[temp8],   %[temp6],   %[temp7]   \n\t"
  444.             "add.s      %[temp11],  %[temp9],   %[temp10]  \n\t"
  445.             "sub.s      %[temp0],   %[temp0],   %[temp1]   \n\t"
  446.             "sub.s      %[temp3],   %[temp3],   %[temp4]   \n\t"
  447.             "sub.s      %[temp6],   %[temp6],   %[temp7]   \n\t"
  448.             "sub.s      %[temp9],   %[temp9],   %[temp10]  \n\t"
  449.             "swc1       %[temp2],   -48(%[v1])             \n\t"
  450.             "swc1       %[temp0],   48(%[v0])              \n\t"
  451.             "swc1       %[temp5],   -52(%[v1])             \n\t"
  452.             "swc1       %[temp3],   52(%[v0])              \n\t"
  453.             "swc1       %[temp8],   -56(%[v1])             \n\t"
  454.             "swc1       %[temp6],   56(%[v0])              \n\t"
  455.             "swc1       %[temp11],  -60(%[v1])             \n\t"
  456.             "swc1       %[temp9],   60(%[v0])              \n\t"
  457.             "addiu      %[src0],    %[src0],    64         \n\t"
  458.             "addiu      %[src1],    %[src1],    -64        \n\t"
  459.             "addiu      %[v0],      %[v0],      64         \n\t"
  460.             "addiu      %[v1],      %[v1],      -64        \n\t"
  461.  
  462.             : [v0]"+r"(v0), [v1]"+r"(v1), [src0]"+r"(psrc0), [src1]"+r"(psrc1),
  463.               [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
  464.               [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
  465.               [temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
  466.               [temp9]"=&f"(temp9), [temp10]"=&f"(temp10), [temp11]"=&f"(temp11)
  467.             :
  468.             :"memory"
  469.         );
  470.     }
  471. }
  472.  
  473. static void sbr_autocorrelate_mips(const float x[40][2], float phi[3][2][2])
  474. {
  475.     int i;
  476.     float real_sum_0 = 0.0f;
  477.     float real_sum_1 = 0.0f;
  478.     float real_sum_2 = 0.0f;
  479.     float imag_sum_1 = 0.0f;
  480.     float imag_sum_2 = 0.0f;
  481.     float *p_x, *p_phi;
  482.     float temp0, temp1, temp2, temp3, temp4, temp5, temp6;
  483.     float temp7, temp_r, temp_r1, temp_r2, temp_r3, temp_r4;
  484.     p_x = (float*)&x[0][0];
  485.     p_phi = &phi[0][0][0];
  486.  
  487.     __asm__ volatile (
  488.         "lwc1    %[temp0],      8(%[p_x])                           \n\t"
  489.         "lwc1    %[temp1],      12(%[p_x])                          \n\t"
  490.         "lwc1    %[temp2],      16(%[p_x])                          \n\t"
  491.         "lwc1    %[temp3],      20(%[p_x])                          \n\t"
  492.         "lwc1    %[temp4],      24(%[p_x])                          \n\t"
  493.         "lwc1    %[temp5],      28(%[p_x])                          \n\t"
  494.         "mul.s   %[temp_r],     %[temp1],      %[temp1]             \n\t"
  495.         "mul.s   %[temp_r1],    %[temp1],      %[temp3]             \n\t"
  496.         "mul.s   %[temp_r2],    %[temp1],      %[temp2]             \n\t"
  497.         "mul.s   %[temp_r3],    %[temp1],      %[temp5]             \n\t"
  498.         "mul.s   %[temp_r4],    %[temp1],      %[temp4]             \n\t"
  499.         "madd.s  %[temp_r],     %[temp_r],     %[temp0],  %[temp0]  \n\t"
  500.         "madd.s  %[temp_r1],    %[temp_r1],    %[temp0],  %[temp2]  \n\t"
  501.         "msub.s  %[temp_r2],    %[temp_r2],    %[temp0],  %[temp3]  \n\t"
  502.         "madd.s  %[temp_r3],    %[temp_r3],    %[temp0],  %[temp4]  \n\t"
  503.         "msub.s  %[temp_r4],    %[temp_r4],    %[temp0],  %[temp5]  \n\t"
  504.         "add.s   %[real_sum_0], %[real_sum_0], %[temp_r]            \n\t"
  505.         "add.s   %[real_sum_1], %[real_sum_1], %[temp_r1]           \n\t"
  506.         "add.s   %[imag_sum_1], %[imag_sum_1], %[temp_r2]           \n\t"
  507.         "add.s   %[real_sum_2], %[real_sum_2], %[temp_r3]           \n\t"
  508.         "add.s   %[imag_sum_2], %[imag_sum_2], %[temp_r4]           \n\t"
  509.         "addiu   %[p_x],        %[p_x],        8                    \n\t"
  510.  
  511.         : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
  512.           [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
  513.           [real_sum_0]"+f"(real_sum_0), [real_sum_1]"+f"(real_sum_1),
  514.           [imag_sum_1]"+f"(imag_sum_1), [real_sum_2]"+f"(real_sum_2),
  515.           [temp_r]"=&f"(temp_r), [temp_r1]"=&f"(temp_r1), [temp_r2]"=&f"(temp_r2),
  516.           [temp_r3]"=&f"(temp_r3), [temp_r4]"=&f"(temp_r4),
  517.           [p_x]"+r"(p_x), [imag_sum_2]"+f"(imag_sum_2)
  518.         :
  519.         : "memory"
  520.     );
  521.  
  522.     for (i = 0; i < 12; i++) {
  523.         __asm__ volatile (
  524.             "lwc1    %[temp0],      8(%[p_x])                           \n\t"
  525.             "lwc1    %[temp1],      12(%[p_x])                          \n\t"
  526.             "lwc1    %[temp2],      16(%[p_x])                          \n\t"
  527.             "lwc1    %[temp3],      20(%[p_x])                          \n\t"
  528.             "lwc1    %[temp4],      24(%[p_x])                          \n\t"
  529.             "lwc1    %[temp5],      28(%[p_x])                          \n\t"
  530.             "mul.s   %[temp_r],     %[temp1],      %[temp1]             \n\t"
  531.             "mul.s   %[temp_r1],    %[temp1],      %[temp3]             \n\t"
  532.             "mul.s   %[temp_r2],    %[temp1],      %[temp2]             \n\t"
  533.             "mul.s   %[temp_r3],    %[temp1],      %[temp5]             \n\t"
  534.             "mul.s   %[temp_r4],    %[temp1],      %[temp4]             \n\t"
  535.             "madd.s  %[temp_r],     %[temp_r],     %[temp0],  %[temp0]  \n\t"
  536.             "madd.s  %[temp_r1],    %[temp_r1],    %[temp0],  %[temp2]  \n\t"
  537.             "msub.s  %[temp_r2],    %[temp_r2],    %[temp0],  %[temp3]  \n\t"
  538.             "madd.s  %[temp_r3],    %[temp_r3],    %[temp0],  %[temp4]  \n\t"
  539.             "msub.s  %[temp_r4],    %[temp_r4],    %[temp0],  %[temp5]  \n\t"
  540.             "add.s   %[real_sum_0], %[real_sum_0], %[temp_r]            \n\t"
  541.             "add.s   %[real_sum_1], %[real_sum_1], %[temp_r1]           \n\t"
  542.             "add.s   %[imag_sum_1], %[imag_sum_1], %[temp_r2]           \n\t"
  543.             "add.s   %[real_sum_2], %[real_sum_2], %[temp_r3]           \n\t"
  544.             "add.s   %[imag_sum_2], %[imag_sum_2], %[temp_r4]           \n\t"
  545.             "lwc1    %[temp0],      32(%[p_x])                          \n\t"
  546.             "lwc1    %[temp1],      36(%[p_x])                          \n\t"
  547.             "mul.s   %[temp_r],     %[temp3],      %[temp3]             \n\t"
  548.             "mul.s   %[temp_r1],    %[temp3],      %[temp5]             \n\t"
  549.             "mul.s   %[temp_r2],    %[temp3],      %[temp4]             \n\t"
  550.             "mul.s   %[temp_r3],    %[temp3],      %[temp1]             \n\t"
  551.             "mul.s   %[temp_r4],    %[temp3],      %[temp0]             \n\t"
  552.             "madd.s  %[temp_r],     %[temp_r],     %[temp2],  %[temp2]  \n\t"
  553.             "madd.s  %[temp_r1],    %[temp_r1],    %[temp2],  %[temp4]  \n\t"
  554.             "msub.s  %[temp_r2],    %[temp_r2],    %[temp2],  %[temp5]  \n\t"
  555.             "madd.s  %[temp_r3],    %[temp_r3],    %[temp2],  %[temp0]  \n\t"
  556.             "msub.s  %[temp_r4],    %[temp_r4],    %[temp2],  %[temp1]  \n\t"
  557.             "add.s   %[real_sum_0], %[real_sum_0], %[temp_r]            \n\t"
  558.             "add.s   %[real_sum_1], %[real_sum_1], %[temp_r1]           \n\t"
  559.             "add.s   %[imag_sum_1], %[imag_sum_1], %[temp_r2]           \n\t"
  560.             "add.s   %[real_sum_2], %[real_sum_2], %[temp_r3]           \n\t"
  561.             "add.s   %[imag_sum_2], %[imag_sum_2], %[temp_r4]           \n\t"
  562.             "lwc1    %[temp2],      40(%[p_x])                          \n\t"
  563.             "lwc1    %[temp3],      44(%[p_x])                          \n\t"
  564.             "mul.s   %[temp_r],     %[temp5],      %[temp5]             \n\t"
  565.             "mul.s   %[temp_r1],    %[temp5],      %[temp1]             \n\t"
  566.             "mul.s   %[temp_r2],    %[temp5],      %[temp0]             \n\t"
  567.             "mul.s   %[temp_r3],    %[temp5],      %[temp3]             \n\t"
  568.             "mul.s   %[temp_r4],    %[temp5],      %[temp2]             \n\t"
  569.             "madd.s  %[temp_r],     %[temp_r],     %[temp4],  %[temp4]  \n\t"
  570.             "madd.s  %[temp_r1],    %[temp_r1],    %[temp4],  %[temp0]  \n\t"
  571.             "msub.s  %[temp_r2],    %[temp_r2],    %[temp4],  %[temp1]  \n\t"
  572.             "madd.s  %[temp_r3],    %[temp_r3],    %[temp4],  %[temp2]  \n\t"
  573.             "msub.s  %[temp_r4],    %[temp_r4],    %[temp4],  %[temp3]  \n\t"
  574.             "add.s   %[real_sum_0], %[real_sum_0], %[temp_r]            \n\t"
  575.             "add.s   %[real_sum_1], %[real_sum_1], %[temp_r1]           \n\t"
  576.             "add.s   %[imag_sum_1], %[imag_sum_1], %[temp_r2]           \n\t"
  577.             "add.s   %[real_sum_2], %[real_sum_2], %[temp_r3]           \n\t"
  578.             "add.s   %[imag_sum_2], %[imag_sum_2], %[temp_r4]           \n\t"
  579.             "addiu   %[p_x],        %[p_x],        24                   \n\t"
  580.  
  581.             : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
  582.               [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
  583.               [real_sum_0]"+f"(real_sum_0), [real_sum_1]"+f"(real_sum_1),
  584.               [imag_sum_1]"+f"(imag_sum_1), [real_sum_2]"+f"(real_sum_2),
  585.               [temp_r]"=&f"(temp_r), [temp_r1]"=&f"(temp_r1),
  586.               [temp_r2]"=&f"(temp_r2), [temp_r3]"=&f"(temp_r3),
  587.               [temp_r4]"=&f"(temp_r4), [p_x]"+r"(p_x),
  588.               [imag_sum_2]"+f"(imag_sum_2)
  589.             :
  590.             : "memory"
  591.         );
  592.     }
  593.     __asm__ volatile (
  594.         "lwc1    %[temp0],    -296(%[p_x])                        \n\t"
  595.         "lwc1    %[temp1],    -292(%[p_x])                        \n\t"
  596.         "lwc1    %[temp2],    8(%[p_x])                           \n\t"
  597.         "lwc1    %[temp3],    12(%[p_x])                          \n\t"
  598.         "lwc1    %[temp4],    -288(%[p_x])                        \n\t"
  599.         "lwc1    %[temp5],    -284(%[p_x])                        \n\t"
  600.         "lwc1    %[temp6],    -280(%[p_x])                        \n\t"
  601.         "lwc1    %[temp7],    -276(%[p_x])                        \n\t"
  602.         "madd.s  %[temp_r],   %[real_sum_0], %[temp0],  %[temp0]  \n\t"
  603.         "madd.s  %[temp_r1],  %[real_sum_0], %[temp2],  %[temp2]  \n\t"
  604.         "madd.s  %[temp_r2],  %[real_sum_1], %[temp0],  %[temp4]  \n\t"
  605.         "madd.s  %[temp_r3],  %[imag_sum_1], %[temp0],  %[temp5]  \n\t"
  606.         "madd.s  %[temp_r],   %[temp_r],     %[temp1],  %[temp1]  \n\t"
  607.         "madd.s  %[temp_r1],  %[temp_r1],    %[temp3],  %[temp3]  \n\t"
  608.         "madd.s  %[temp_r2],  %[temp_r2],    %[temp1],  %[temp5]  \n\t"
  609.         "nmsub.s  %[temp_r3], %[temp_r3],    %[temp1],  %[temp4]  \n\t"
  610.         "lwc1    %[temp4],    16(%[p_x])                          \n\t"
  611.         "lwc1    %[temp5],    20(%[p_x])                          \n\t"
  612.         "swc1    %[temp_r],   40(%[p_phi])                        \n\t"
  613.         "swc1    %[temp_r1],  16(%[p_phi])                        \n\t"
  614.         "swc1    %[temp_r2],  24(%[p_phi])                        \n\t"
  615.         "swc1    %[temp_r3],  28(%[p_phi])                        \n\t"
  616.         "madd.s  %[temp_r],   %[real_sum_1], %[temp2],  %[temp4]  \n\t"
  617.         "madd.s  %[temp_r1],  %[imag_sum_1], %[temp2],  %[temp5]  \n\t"
  618.         "madd.s  %[temp_r2],  %[real_sum_2], %[temp0],  %[temp6]  \n\t"
  619.         "madd.s  %[temp_r3],  %[imag_sum_2], %[temp0],  %[temp7]  \n\t"
  620.         "madd.s  %[temp_r],   %[temp_r],     %[temp3],  %[temp5]  \n\t"
  621.         "nmsub.s %[temp_r1],  %[temp_r1],    %[temp3],  %[temp4]  \n\t"
  622.         "madd.s  %[temp_r2],  %[temp_r2],    %[temp1],  %[temp7]  \n\t"
  623.         "nmsub.s %[temp_r3],  %[temp_r3],    %[temp1],  %[temp6]  \n\t"
  624.         "swc1    %[temp_r],   0(%[p_phi])                         \n\t"
  625.         "swc1    %[temp_r1],  4(%[p_phi])                         \n\t"
  626.         "swc1    %[temp_r2],  8(%[p_phi])                         \n\t"
  627.         "swc1    %[temp_r3],  12(%[p_phi])                        \n\t"
  628.  
  629.         : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
  630.           [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
  631.           [temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp_r]"=&f"(temp_r),
  632.           [real_sum_0]"+f"(real_sum_0), [real_sum_1]"+f"(real_sum_1),
  633.           [real_sum_2]"+f"(real_sum_2), [imag_sum_1]"+f"(imag_sum_1),
  634.           [temp_r2]"=&f"(temp_r2), [temp_r3]"=&f"(temp_r3),
  635.           [temp_r1]"=&f"(temp_r1), [p_phi]"+r"(p_phi),
  636.           [imag_sum_2]"+f"(imag_sum_2)
  637.         : [p_x]"r"(p_x)
  638.         : "memory"
  639.     );
  640. }
  641.  
  642. static void sbr_hf_gen_mips(float (*X_high)[2], const float (*X_low)[2],
  643.                          const float alpha0[2], const float alpha1[2],
  644.                          float bw, int start, int end)
  645. {
  646.     float alpha[4];
  647.     int i;
  648.     float *p_x_low = (float*)&X_low[0][0] + 2*start;
  649.     float *p_x_high = &X_high[0][0] + 2*start;
  650.     float temp0, temp1, temp2, temp3, temp4, temp5, temp6;
  651.     float temp7, temp8, temp9, temp10, temp11, temp12;
  652.  
  653.     alpha[0] = alpha1[0] * bw * bw;
  654.     alpha[1] = alpha1[1] * bw * bw;
  655.     alpha[2] = alpha0[0] * bw;
  656.     alpha[3] = alpha0[1] * bw;
  657.  
  658.     for (i = start; i < end; i++) {
  659.         __asm__ volatile (
  660.             "lwc1    %[temp0],    -16(%[p_x_low])                        \n\t"
  661.             "lwc1    %[temp1],    -12(%[p_x_low])                        \n\t"
  662.             "lwc1    %[temp2],    -8(%[p_x_low])                         \n\t"
  663.             "lwc1    %[temp3],    -4(%[p_x_low])                         \n\t"
  664.             "lwc1    %[temp5],    0(%[p_x_low])                          \n\t"
  665.             "lwc1    %[temp6],    4(%[p_x_low])                          \n\t"
  666.             "lwc1    %[temp7],    0(%[alpha])                            \n\t"
  667.             "lwc1    %[temp8],    4(%[alpha])                            \n\t"
  668.             "lwc1    %[temp9],    8(%[alpha])                            \n\t"
  669.             "lwc1    %[temp10],   12(%[alpha])                           \n\t"
  670.             "addiu   %[p_x_high], %[p_x_high],     8                     \n\t"
  671.             "addiu   %[p_x_low],  %[p_x_low],      8                     \n\t"
  672.             "mul.s   %[temp11],   %[temp1],        %[temp8]              \n\t"
  673.             "msub.s  %[temp11],   %[temp11],       %[temp0],  %[temp7]   \n\t"
  674.             "madd.s  %[temp11],   %[temp11],       %[temp2],  %[temp9]   \n\t"
  675.             "nmsub.s %[temp11],   %[temp11],       %[temp3],  %[temp10]  \n\t"
  676.             "add.s   %[temp11],   %[temp11],       %[temp5]              \n\t"
  677.             "swc1    %[temp11],   -8(%[p_x_high])                        \n\t"
  678.             "mul.s   %[temp12],   %[temp1],        %[temp7]              \n\t"
  679.             "madd.s  %[temp12],   %[temp12],       %[temp0],  %[temp8]   \n\t"
  680.             "madd.s  %[temp12],   %[temp12],       %[temp3],  %[temp9]   \n\t"
  681.             "madd.s  %[temp12],   %[temp12],       %[temp2],  %[temp10]  \n\t"
  682.             "add.s   %[temp12],   %[temp12],       %[temp6]              \n\t"
  683.             "swc1    %[temp12],   -4(%[p_x_high])                        \n\t"
  684.  
  685.             : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
  686.               [temp3]"=&f"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5),
  687.               [temp6]"=&f"(temp6), [temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
  688.               [temp9]"=&f"(temp9), [temp10]"=&f"(temp10), [temp11]"=&f"(temp11),
  689.               [temp12]"=&f"(temp12), [p_x_high]"+r"(p_x_high),
  690.               [p_x_low]"+r"(p_x_low)
  691.             : [alpha]"r"(alpha)
  692.             : "memory"
  693.         );
  694.     }
  695. }
  696.  
  697. static void sbr_hf_g_filt_mips(float (*Y)[2], const float (*X_high)[40][2],
  698.                             const float *g_filt, int m_max, intptr_t ixh)
  699. {
  700.     float *p_y, *p_x, *p_g;
  701.     float temp0, temp1, temp2;
  702.     int loop_end;
  703.  
  704.     p_g = (float*)&g_filt[0];
  705.     p_y = &Y[0][0];
  706.     p_x = (float*)&X_high[0][ixh][0];
  707.     loop_end = (int)((int*)p_g + m_max);
  708.  
  709.     __asm__ volatile(
  710.         ".set    push                                \n\t"
  711.         ".set    noreorder                           \n\t"
  712.     "1:                                              \n\t"
  713.         "lwc1    %[temp0],   0(%[p_g])               \n\t"
  714.         "lwc1    %[temp1],   0(%[p_x])               \n\t"
  715.         "lwc1    %[temp2],   4(%[p_x])               \n\t"
  716.         "mul.s   %[temp1],   %[temp1],     %[temp0]  \n\t"
  717.         "mul.s   %[temp2],   %[temp2],     %[temp0]  \n\t"
  718.         "addiu   %[p_g],     %[p_g],       4         \n\t"
  719.         "addiu   %[p_x],     %[p_x],       320       \n\t"
  720.         "swc1    %[temp1],   0(%[p_y])               \n\t"
  721.         "swc1    %[temp2],   4(%[p_y])               \n\t"
  722.         "bne     %[p_g],     %[loop_end],  1b        \n\t"
  723.         " addiu  %[p_y],     %[p_y],       8         \n\t"
  724.         ".set    pop                                 \n\t"
  725.  
  726.         : [temp0]"=&f"(temp0), [temp1]"=&f"(temp1),
  727.           [temp2]"=&f"(temp2), [p_x]"+r"(p_x),
  728.           [p_y]"+r"(p_y), [p_g]"+r"(p_g)
  729.         : [loop_end]"r"(loop_end)
  730.         : "memory"
  731.     );
  732. }
  733.  
  734. static void sbr_hf_apply_noise_0_mips(float (*Y)[2], const float *s_m,
  735.                                  const float *q_filt, int noise,
  736.                                  int kx, int m_max)
  737. {
  738.     int m;
  739.  
  740.     for (m = 0; m < m_max; m++){
  741.  
  742.         float *Y1=&Y[m][0];
  743.         float *ff_table;
  744.         float y0,y1, temp1, temp2, temp4, temp5;
  745.         int temp0, temp3;
  746.         const float *s_m1=&s_m[m];
  747.         const float *q_filt1= &q_filt[m];
  748.  
  749.         __asm__ volatile(
  750.             "lwc1    %[y0],       0(%[Y1])                                    \n\t"
  751.             "lwc1    %[temp1],    0(%[s_m1])                                  \n\t"
  752.             "addiu   %[noise],    %[noise],              1                    \n\t"
  753.             "andi    %[noise],    %[noise],              0x1ff                \n\t"
  754.             "sll     %[temp0],    %[noise], 3                                 \n\t"
  755.             "addu    %[ff_table], %[ff_sbr_noise_table], %[temp0]             \n\t"
  756.             "add.s   %[y0],       %[y0],                 %[temp1]             \n\t"
  757.             "mfc1    %[temp3],    %[temp1]                                    \n\t"
  758.             "bne     %[temp3],    $0,                    1f                   \n\t"
  759.             "lwc1    %[y1],       4(%[Y1])                                    \n\t"
  760.             "lwc1    %[temp2],    0(%[q_filt1])                               \n\t"
  761.             "lwc1    %[temp4],    0(%[ff_table])                              \n\t"
  762.             "lwc1    %[temp5],    4(%[ff_table])                              \n\t"
  763.             "madd.s  %[y0],       %[y0],                 %[temp2],  %[temp4]  \n\t"
  764.             "madd.s  %[y1],       %[y1],                 %[temp2],  %[temp5]  \n\t"
  765.             "swc1    %[y1],       4(%[Y1])                                    \n\t"
  766.         "1:                                                                   \n\t"
  767.             "swc1    %[y0],       0(%[Y1])                                    \n\t"
  768.  
  769.             : [ff_table]"=&r"(ff_table), [y0]"=&f"(y0), [y1]"=&f"(y1),
  770.               [temp0]"=&r"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
  771.               [temp3]"=&r"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5)
  772.             : [ff_sbr_noise_table]"r"(ff_sbr_noise_table), [noise]"r"(noise),
  773.               [Y1]"r"(Y1), [s_m1]"r"(s_m1), [q_filt1]"r"(q_filt1)
  774.             : "memory"
  775.         );
  776.     }
  777. }
  778.  
  779. static void sbr_hf_apply_noise_1_mips(float (*Y)[2], const float *s_m,
  780.                                  const float *q_filt, int noise,
  781.                                  int kx, int m_max)
  782. {
  783.     float y0,y1,temp1, temp2, temp4, temp5;
  784.     int temp0, temp3, m;
  785.     float phi_sign = 1 - 2 * (kx & 1);
  786.  
  787.     for (m = 0; m < m_max; m++) {
  788.  
  789.         float *ff_table;
  790.         float *Y1=&Y[m][0];
  791.         const float *s_m1=&s_m[m];
  792.         const float *q_filt1= &q_filt[m];
  793.  
  794.         __asm__ volatile(
  795.             "lwc1   %[y1],       4(%[Y1])                                     \n\t"
  796.             "lwc1   %[temp1],    0(%[s_m1])                                   \n\t"
  797.             "lw     %[temp3],    0(%[s_m1])                                   \n\t"
  798.             "addiu  %[noise],    %[noise],               1                    \n\t"
  799.             "andi   %[noise],    %[noise],               0x1ff                \n\t"
  800.             "sll    %[temp0],    %[noise],               3                    \n\t"
  801.             "addu   %[ff_table], %[ff_sbr_noise_table], %[temp0]              \n\t"
  802.             "madd.s %[y1],       %[y1],                 %[temp1], %[phi_sign] \n\t"
  803.             "bne    %[temp3],    $0,                    1f                    \n\t"
  804.             "lwc1   %[y0],       0(%[Y1])                                     \n\t"
  805.             "lwc1   %[temp2],    0(%[q_filt1])                                \n\t"
  806.             "lwc1   %[temp4],    0(%[ff_table])                               \n\t"
  807.             "lwc1   %[temp5],    4(%[ff_table])                               \n\t"
  808.             "madd.s %[y0],       %[y0],                 %[temp2], %[temp4]    \n\t"
  809.             "madd.s %[y1],       %[y1],                 %[temp2], %[temp5]    \n\t"
  810.             "swc1   %[y0],       0(%[Y1])                                     \n\t"
  811.         "1:                                                                   \n\t"
  812.             "swc1   %[y1],       4(%[Y1])                                     \n\t"
  813.  
  814.             : [ff_table] "=&r" (ff_table), [y0] "=&f" (y0), [y1] "=&f" (y1),
  815.               [temp0] "=&r" (temp0), [temp1] "=&f" (temp1), [temp2] "=&f" (temp2),
  816.               [temp3] "=&r" (temp3), [temp4] "=&f" (temp4), [temp5] "=&f" (temp5)
  817.             : [ff_sbr_noise_table] "r" (ff_sbr_noise_table), [noise] "r" (noise),
  818.               [Y1] "r" (Y1), [s_m1] "r" (s_m1), [q_filt1] "r" (q_filt1),
  819.               [phi_sign] "f" (phi_sign)
  820.             : "memory"
  821.         );
  822.         phi_sign = -phi_sign;
  823.     }
  824. }
  825.  
  826. static void sbr_hf_apply_noise_2_mips(float (*Y)[2], const float *s_m,
  827.                                  const float *q_filt, int noise,
  828.                                  int kx, int m_max)
  829. {
  830.     int m;
  831.     float *ff_table;
  832.     float y0,y1, temp0, temp1, temp2, temp3, temp4, temp5;
  833.  
  834.     for (m = 0; m < m_max; m++) {
  835.  
  836.         float *Y1=&Y[m][0];
  837.         const float *s_m1=&s_m[m];
  838.         const float *q_filt1= &q_filt[m];
  839.  
  840.         __asm__ volatile(
  841.             "lwc1   %[y0],       0(%[Y1])                                  \n\t"
  842.             "lwc1   %[temp1],    0(%[s_m1])                                \n\t"
  843.             "addiu  %[noise],    %[noise],              1                  \n\t"
  844.             "andi   %[noise],    %[noise],              0x1ff              \n\t"
  845.             "sll    %[temp0],    %[noise],              3                  \n\t"
  846.             "addu   %[ff_table], %[ff_sbr_noise_table], %[temp0]           \n\t"
  847.             "sub.s  %[y0],       %[y0],                 %[temp1]           \n\t"
  848.             "mfc1   %[temp3],    %[temp1]                                  \n\t"
  849.             "bne    %[temp3],    $0,                    1f                 \n\t"
  850.             "lwc1   %[y1],       4(%[Y1])                                  \n\t"
  851.             "lwc1   %[temp2],    0(%[q_filt1])                             \n\t"
  852.             "lwc1   %[temp4],    0(%[ff_table])                            \n\t"
  853.             "lwc1   %[temp5],    4(%[ff_table])                            \n\t"
  854.             "madd.s %[y0],       %[y0],                 %[temp2], %[temp4] \n\t"
  855.             "madd.s %[y1],       %[y1],                 %[temp2], %[temp5] \n\t"
  856.             "swc1   %[y1],       4(%[Y1])                                  \n\t"
  857.         "1:                                                                \n\t"
  858.             "swc1   %[y0],       0(%[Y1])                                  \n\t"
  859.  
  860.             : [temp0]"=&r"(temp0), [ff_table]"=&r"(ff_table), [y0]"=&f"(y0),
  861.               [y1]"=&f"(y1), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
  862.               [temp3]"=&r"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5)
  863.             : [ff_sbr_noise_table]"r"(ff_sbr_noise_table), [noise]"r"(noise),
  864.               [Y1]"r"(Y1), [s_m1]"r"(s_m1), [q_filt1]"r"(q_filt1)
  865.             : "memory"
  866.         );
  867.     }
  868. }
  869.  
  870. static void sbr_hf_apply_noise_3_mips(float (*Y)[2], const float *s_m,
  871.                                  const float *q_filt, int noise,
  872.                                  int kx, int m_max)
  873. {
  874.     float phi_sign = 1 - 2 * (kx & 1);
  875.     int m;
  876.  
  877.     for (m = 0; m < m_max; m++) {
  878.  
  879.         float *Y1=&Y[m][0];
  880.         float *ff_table;
  881.         float y0,y1, temp1, temp2, temp4, temp5;
  882.         int temp0, temp3;
  883.         const float *s_m1=&s_m[m];
  884.         const float *q_filt1= &q_filt[m];
  885.  
  886.         __asm__ volatile(
  887.             "lwc1    %[y1],       4(%[Y1])                                     \n\t"
  888.             "lwc1    %[temp1],    0(%[s_m1])                                   \n\t"
  889.             "addiu   %[noise],    %[noise],              1                     \n\t"
  890.             "andi    %[noise],    %[noise],              0x1ff                 \n\t"
  891.             "sll     %[temp0],    %[noise],              3                     \n\t"
  892.             "addu    %[ff_table], %[ff_sbr_noise_table], %[temp0]              \n\t"
  893.             "nmsub.s %[y1],       %[y1],                 %[temp1], %[phi_sign] \n\t"
  894.             "mfc1    %[temp3],    %[temp1]                                     \n\t"
  895.             "bne     %[temp3],    $0,                    1f                    \n\t"
  896.             "lwc1    %[y0],       0(%[Y1])                                     \n\t"
  897.             "lwc1    %[temp2],    0(%[q_filt1])                                \n\t"
  898.             "lwc1    %[temp4],    0(%[ff_table])                               \n\t"
  899.             "lwc1    %[temp5],    4(%[ff_table])                               \n\t"
  900.             "madd.s  %[y0],       %[y0],                 %[temp2], %[temp4]    \n\t"
  901.             "madd.s  %[y1],       %[y1],                 %[temp2], %[temp5]    \n\t"
  902.             "swc1    %[y0],       0(%[Y1])                                     \n\t"
  903.             "1:                                                                \n\t"
  904.             "swc1    %[y1],       4(%[Y1])                                     \n\t"
  905.  
  906.             : [ff_table]"=&r"(ff_table), [y0]"=&f"(y0), [y1]"=&f"(y1),
  907.               [temp0]"=&r"(temp0), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
  908.               [temp3]"=&r"(temp3), [temp4]"=&f"(temp4), [temp5]"=&f"(temp5)
  909.             : [ff_sbr_noise_table]"r"(ff_sbr_noise_table), [noise]"r"(noise),
  910.               [Y1]"r"(Y1), [s_m1]"r"(s_m1), [q_filt1]"r"(q_filt1),
  911.               [phi_sign]"f"(phi_sign)
  912.             : "memory"
  913.         );
  914.        phi_sign = -phi_sign;
  915.     }
  916. }
  917. #endif /* HAVE_MIPSFPU */
  918. #endif /* HAVE_INLINE_ASM */
  919.  
  920. void ff_sbrdsp_init_mips(SBRDSPContext *s)
  921. {
  922. #if HAVE_INLINE_ASM
  923.     s->neg_odd_64 = sbr_neg_odd_64_mips;
  924.     s->qmf_pre_shuffle = sbr_qmf_pre_shuffle_mips;
  925.     s->qmf_post_shuffle = sbr_qmf_post_shuffle_mips;
  926. #if HAVE_MIPSFPU
  927.     s->sum64x5 = sbr_sum64x5_mips;
  928.     s->sum_square = sbr_sum_square_mips;
  929.     s->qmf_deint_bfly = sbr_qmf_deint_bfly_mips;
  930.     s->autocorrelate = sbr_autocorrelate_mips;
  931.     s->hf_gen = sbr_hf_gen_mips;
  932.     s->hf_g_filt = sbr_hf_g_filt_mips;
  933.  
  934.     s->hf_apply_noise[0] = sbr_hf_apply_noise_0_mips;
  935.     s->hf_apply_noise[1] = sbr_hf_apply_noise_1_mips;
  936.     s->hf_apply_noise[2] = sbr_hf_apply_noise_2_mips;
  937.     s->hf_apply_noise[3] = sbr_hf_apply_noise_3_mips;
  938. #endif /* HAVE_MIPSFPU */
  939. #endif /* HAVE_INLINE_ASM */
  940. }
  941.