1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Copyright (c) 2012
3cabdff1aSopenharmony_ci *      MIPS Technologies, Inc., California.
4cabdff1aSopenharmony_ci *
5cabdff1aSopenharmony_ci * Redistribution and use in source and binary forms, with or without
6cabdff1aSopenharmony_ci * modification, are permitted provided that the following conditions
7cabdff1aSopenharmony_ci * are met:
8cabdff1aSopenharmony_ci * 1. Redistributions of source code must retain the above copyright
9cabdff1aSopenharmony_ci *    notice, this list of conditions and the following disclaimer.
10cabdff1aSopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright
11cabdff1aSopenharmony_ci *    notice, this list of conditions and the following disclaimer in the
12cabdff1aSopenharmony_ci *    documentation and/or other materials provided with the distribution.
13cabdff1aSopenharmony_ci * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
14cabdff1aSopenharmony_ci *    contributors may be used to endorse or promote products derived from
15cabdff1aSopenharmony_ci *    this software without specific prior written permission.
16cabdff1aSopenharmony_ci *
17cabdff1aSopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
18cabdff1aSopenharmony_ci * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19cabdff1aSopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20cabdff1aSopenharmony_ci * ARE DISCLAIMED.  IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
21cabdff1aSopenharmony_ci * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22cabdff1aSopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23cabdff1aSopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24cabdff1aSopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25cabdff1aSopenharmony_ci * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26cabdff1aSopenharmony_ci * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27cabdff1aSopenharmony_ci * SUCH DAMAGE.
28cabdff1aSopenharmony_ci *
29cabdff1aSopenharmony_ci * Authors:  Branimir Vasic (bvasic@mips.com)
30cabdff1aSopenharmony_ci *           Nedeljko Babic (nbabic@mips.com)
31cabdff1aSopenharmony_ci *
32cabdff1aSopenharmony_ci * Various AC-3 DSP Utils optimized for MIPS
33cabdff1aSopenharmony_ci *
34cabdff1aSopenharmony_ci * This file is part of FFmpeg.
35cabdff1aSopenharmony_ci *
36cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
37cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
38cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
39cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
40cabdff1aSopenharmony_ci *
41cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
42cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
43cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
44cabdff1aSopenharmony_ci * Lesser General Public License for more details.
45cabdff1aSopenharmony_ci *
46cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
47cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
48cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
49cabdff1aSopenharmony_ci */
50cabdff1aSopenharmony_ci
51cabdff1aSopenharmony_ci/**
52cabdff1aSopenharmony_ci * @file
53cabdff1aSopenharmony_ci * Reference: libavcodec/ac3dsp.c
54cabdff1aSopenharmony_ci */
55cabdff1aSopenharmony_ci
56cabdff1aSopenharmony_ci#include "config.h"
57cabdff1aSopenharmony_ci#include "libavcodec/ac3dsp.h"
58cabdff1aSopenharmony_ci#include "libavcodec/ac3.h"
59cabdff1aSopenharmony_ci#include "libavcodec/ac3tab.h"
60cabdff1aSopenharmony_ci#include "libavutil/mips/asmdefs.h"
61cabdff1aSopenharmony_ci
62cabdff1aSopenharmony_ci#if HAVE_INLINE_ASM
63cabdff1aSopenharmony_ci#if HAVE_MIPSDSP
64cabdff1aSopenharmony_cistatic void ac3_bit_alloc_calc_bap_mips(int16_t *mask, int16_t *psd,
65cabdff1aSopenharmony_ci                                        int start, int end,
66cabdff1aSopenharmony_ci                                        int snr_offset, int floor,
67cabdff1aSopenharmony_ci                                        const uint8_t *bap_tab, uint8_t *bap)
68cabdff1aSopenharmony_ci{
69cabdff1aSopenharmony_ci    int band, band_end, cond;
70cabdff1aSopenharmony_ci    int m, address1, address2;
71cabdff1aSopenharmony_ci    int16_t *psd1, *psd_end;
72cabdff1aSopenharmony_ci    uint8_t *bap1;
73cabdff1aSopenharmony_ci
74cabdff1aSopenharmony_ci    if (snr_offset == -960) {
75cabdff1aSopenharmony_ci        memset(bap, 0, AC3_MAX_COEFS);
76cabdff1aSopenharmony_ci        return;
77cabdff1aSopenharmony_ci    }
78cabdff1aSopenharmony_ci
79cabdff1aSopenharmony_ci    psd1 = &psd[start];
80cabdff1aSopenharmony_ci    bap1 = &bap[start];
81cabdff1aSopenharmony_ci    band = ff_ac3_bin_to_band_tab[start];
82cabdff1aSopenharmony_ci
83cabdff1aSopenharmony_ci    do {
84cabdff1aSopenharmony_ci        m = (FFMAX(mask[band] - snr_offset - floor, 0) & 0x1FE0) + floor;
85cabdff1aSopenharmony_ci        band_end = ff_ac3_band_start_tab[++band];
86cabdff1aSopenharmony_ci        band_end = FFMIN(band_end, end);
87cabdff1aSopenharmony_ci        psd_end = psd + band_end - 1;
88cabdff1aSopenharmony_ci
89cabdff1aSopenharmony_ci        __asm__ volatile (
90cabdff1aSopenharmony_ci            "slt        %[cond],        %[psd1],        %[psd_end]  \n\t"
91cabdff1aSopenharmony_ci            "beqz       %[cond],        1f                          \n\t"
92cabdff1aSopenharmony_ci            "2:                                                     \n\t"
93cabdff1aSopenharmony_ci            "lh         %[address1],    0(%[psd1])                  \n\t"
94cabdff1aSopenharmony_ci            "lh         %[address2],    2(%[psd1])                  \n\t"
95cabdff1aSopenharmony_ci            PTR_ADDIU " %[psd1],        %[psd1],        4           \n\t"
96cabdff1aSopenharmony_ci            "subu       %[address1],    %[address1],    %[m]        \n\t"
97cabdff1aSopenharmony_ci            "sra        %[address1],    %[address1],    5           \n\t"
98cabdff1aSopenharmony_ci            "addiu      %[address1],    %[address1],    -32         \n\t"
99cabdff1aSopenharmony_ci            "shll_s.w   %[address1],    %[address1],    26          \n\t"
100cabdff1aSopenharmony_ci            "subu       %[address2],    %[address2],    %[m]        \n\t"
101cabdff1aSopenharmony_ci            "sra        %[address2],    %[address2],    5           \n\t"
102cabdff1aSopenharmony_ci            "sra        %[address1],    %[address1],    26          \n\t"
103cabdff1aSopenharmony_ci            "addiu      %[address1],    %[address1],    32          \n\t"
104cabdff1aSopenharmony_ci            "lbux       %[address1],    %[address1](%[bap_tab])     \n\t"
105cabdff1aSopenharmony_ci            "addiu      %[address2],    %[address2],    -32         \n\t"
106cabdff1aSopenharmony_ci            "shll_s.w   %[address2],    %[address2],    26          \n\t"
107cabdff1aSopenharmony_ci            "sb         %[address1],    0(%[bap1])                  \n\t"
108cabdff1aSopenharmony_ci            "slt        %[cond],        %[psd1],        %[psd_end]  \n\t"
109cabdff1aSopenharmony_ci            "sra        %[address2],    %[address2],    26          \n\t"
110cabdff1aSopenharmony_ci            "addiu      %[address2],    %[address2],    32          \n\t"
111cabdff1aSopenharmony_ci            "lbux       %[address2],    %[address2](%[bap_tab])     \n\t"
112cabdff1aSopenharmony_ci            "sb         %[address2],    1(%[bap1])                  \n\t"
113cabdff1aSopenharmony_ci            PTR_ADDIU " %[bap1],        %[bap1],        2           \n\t"
114cabdff1aSopenharmony_ci            "bnez       %[cond],        2b                          \n\t"
115cabdff1aSopenharmony_ci            PTR_ADDIU " %[psd_end],     %[psd_end],     2           \n\t"
116cabdff1aSopenharmony_ci            "slt        %[cond],        %[psd1],        %[psd_end]  \n\t"
117cabdff1aSopenharmony_ci            "beqz       %[cond],        3f                          \n\t"
118cabdff1aSopenharmony_ci            "1:                                                     \n\t"
119cabdff1aSopenharmony_ci            "lh         %[address1],    0(%[psd1])                  \n\t"
120cabdff1aSopenharmony_ci            PTR_ADDIU " %[psd1],        %[psd1],        2           \n\t"
121cabdff1aSopenharmony_ci            "subu       %[address1],    %[address1],    %[m]        \n\t"
122cabdff1aSopenharmony_ci            "sra        %[address1],    %[address1],    5           \n\t"
123cabdff1aSopenharmony_ci            "addiu      %[address1],    %[address1],    -32         \n\t"
124cabdff1aSopenharmony_ci            "shll_s.w   %[address1],    %[address1],    26          \n\t"
125cabdff1aSopenharmony_ci            "sra        %[address1],    %[address1],    26          \n\t"
126cabdff1aSopenharmony_ci            "addiu      %[address1],    %[address1],    32          \n\t"
127cabdff1aSopenharmony_ci            "lbux       %[address1],    %[address1](%[bap_tab])     \n\t"
128cabdff1aSopenharmony_ci            "sb         %[address1],    0(%[bap1])                  \n\t"
129cabdff1aSopenharmony_ci            PTR_ADDIU " %[bap1],        %[bap1],        1           \n\t"
130cabdff1aSopenharmony_ci            "3:                                                     \n\t"
131cabdff1aSopenharmony_ci
132cabdff1aSopenharmony_ci            : [address1]"=&r"(address1), [address2]"=&r"(address2),
133cabdff1aSopenharmony_ci              [cond]"=&r"(cond), [bap1]"+r"(bap1),
134cabdff1aSopenharmony_ci              [psd1]"+r"(psd1), [psd_end]"+r"(psd_end)
135cabdff1aSopenharmony_ci            : [m]"r"(m), [bap_tab]"r"(bap_tab)
136cabdff1aSopenharmony_ci            : "memory"
137cabdff1aSopenharmony_ci        );
138cabdff1aSopenharmony_ci    } while (end > band_end);
139cabdff1aSopenharmony_ci}
140cabdff1aSopenharmony_ci
141cabdff1aSopenharmony_cistatic void ac3_update_bap_counts_mips(uint16_t mant_cnt[16], uint8_t *bap,
142cabdff1aSopenharmony_ci                                       int len)
143cabdff1aSopenharmony_ci{
144cabdff1aSopenharmony_ci    void *temp0, *temp2, *temp4, *temp5, *temp6, *temp7;
145cabdff1aSopenharmony_ci    int temp1, temp3;
146cabdff1aSopenharmony_ci
147cabdff1aSopenharmony_ci    __asm__ volatile (
148cabdff1aSopenharmony_ci        "andi   %[temp3],   %[len],         3               \n\t"
149cabdff1aSopenharmony_ci        PTR_ADDU "%[temp2], %[bap],         %[len]          \n\t"
150cabdff1aSopenharmony_ci        PTR_ADDU "%[temp4], %[bap],         %[temp3]        \n\t"
151cabdff1aSopenharmony_ci        "beq    %[temp2],   %[temp4],       4f              \n\t"
152cabdff1aSopenharmony_ci        "1:                                                 \n\t"
153cabdff1aSopenharmony_ci        "lbu    %[temp0],   -1(%[temp2])                    \n\t"
154cabdff1aSopenharmony_ci        "lbu    %[temp5],   -2(%[temp2])                    \n\t"
155cabdff1aSopenharmony_ci        "lbu    %[temp6],   -3(%[temp2])                    \n\t"
156cabdff1aSopenharmony_ci        "sll    %[temp0],   %[temp0],       1               \n\t"
157cabdff1aSopenharmony_ci        PTR_ADDU "%[temp0], %[mant_cnt],    %[temp0]        \n\t"
158cabdff1aSopenharmony_ci        "sll    %[temp5],   %[temp5],       1               \n\t"
159cabdff1aSopenharmony_ci        PTR_ADDU "%[temp5], %[mant_cnt],    %[temp5]        \n\t"
160cabdff1aSopenharmony_ci        "lhu    %[temp1],   0(%[temp0])                     \n\t"
161cabdff1aSopenharmony_ci        "sll    %[temp6],   %[temp6],       1               \n\t"
162cabdff1aSopenharmony_ci        PTR_ADDU "%[temp6], %[mant_cnt],    %[temp6]        \n\t"
163cabdff1aSopenharmony_ci        "addiu  %[temp1],   %[temp1],       1               \n\t"
164cabdff1aSopenharmony_ci        "sh     %[temp1],   0(%[temp0])                     \n\t"
165cabdff1aSopenharmony_ci        "lhu    %[temp1],   0(%[temp5])                     \n\t"
166cabdff1aSopenharmony_ci        "lbu    %[temp7],   -4(%[temp2])                    \n\t"
167cabdff1aSopenharmony_ci        PTR_ADDIU "%[temp2],%[temp2],       -4              \n\t"
168cabdff1aSopenharmony_ci        "addiu  %[temp1],   %[temp1],       1               \n\t"
169cabdff1aSopenharmony_ci        "sh     %[temp1],   0(%[temp5])                     \n\t"
170cabdff1aSopenharmony_ci        "lhu    %[temp1],   0(%[temp6])                     \n\t"
171cabdff1aSopenharmony_ci        "sll    %[temp7],   %[temp7],       1               \n\t"
172cabdff1aSopenharmony_ci        PTR_ADDU "%[temp7], %[mant_cnt],    %[temp7]        \n\t"
173cabdff1aSopenharmony_ci        "addiu  %[temp1],   %[temp1],1                      \n\t"
174cabdff1aSopenharmony_ci        "sh     %[temp1],   0(%[temp6])                     \n\t"
175cabdff1aSopenharmony_ci        "lhu    %[temp1],   0(%[temp7])                     \n\t"
176cabdff1aSopenharmony_ci        "addiu  %[temp1],   %[temp1],       1               \n\t"
177cabdff1aSopenharmony_ci        "sh     %[temp1],   0(%[temp7])                     \n\t"
178cabdff1aSopenharmony_ci        "bne    %[temp2],   %[temp4],       1b              \n\t"
179cabdff1aSopenharmony_ci        "4:                                                 \n\t"
180cabdff1aSopenharmony_ci        "beqz   %[temp3],   2f                              \n\t"
181cabdff1aSopenharmony_ci        "3:                                                 \n\t"
182cabdff1aSopenharmony_ci        "addiu  %[temp3],   %[temp3],       -1              \n\t"
183cabdff1aSopenharmony_ci        "lbu    %[temp0],   -1(%[temp2])                    \n\t"
184cabdff1aSopenharmony_ci        PTR_ADDIU "%[temp2],%[temp2],       -1              \n\t"
185cabdff1aSopenharmony_ci        "sll    %[temp0],   %[temp0],       1               \n\t"
186cabdff1aSopenharmony_ci        PTR_ADDU "%[temp0], %[mant_cnt],    %[temp0]        \n\t"
187cabdff1aSopenharmony_ci        "lhu    %[temp1],   0(%[temp0])                     \n\t"
188cabdff1aSopenharmony_ci        "addiu  %[temp1],   %[temp1],       1               \n\t"
189cabdff1aSopenharmony_ci        "sh     %[temp1],   0(%[temp0])                     \n\t"
190cabdff1aSopenharmony_ci        "bgtz   %[temp3],   3b                              \n\t"
191cabdff1aSopenharmony_ci        "2:                                                 \n\t"
192cabdff1aSopenharmony_ci
193cabdff1aSopenharmony_ci        : [temp0] "=&r" (temp0), [temp1] "=&r" (temp1),
194cabdff1aSopenharmony_ci          [temp2] "=&r" (temp2), [temp3] "=&r" (temp3),
195cabdff1aSopenharmony_ci          [temp4] "=&r" (temp4), [temp5] "=&r" (temp5),
196cabdff1aSopenharmony_ci          [temp6] "=&r" (temp6), [temp7] "=&r" (temp7)
197cabdff1aSopenharmony_ci        : [len] "r" (len), [bap] "r" (bap),
198cabdff1aSopenharmony_ci          [mant_cnt] "r" (mant_cnt)
199cabdff1aSopenharmony_ci        : "memory"
200cabdff1aSopenharmony_ci    );
201cabdff1aSopenharmony_ci}
202cabdff1aSopenharmony_ci#endif
203cabdff1aSopenharmony_ci
204cabdff1aSopenharmony_ci#if HAVE_MIPSFPU
205cabdff1aSopenharmony_ci#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
206cabdff1aSopenharmony_cistatic void float_to_fixed24_mips(int32_t *dst, const float *src, unsigned int len)
207cabdff1aSopenharmony_ci{
208cabdff1aSopenharmony_ci    const float scale = 1 << 24;
209cabdff1aSopenharmony_ci    float src0, src1, src2, src3, src4, src5, src6, src7;
210cabdff1aSopenharmony_ci    int temp0, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
211cabdff1aSopenharmony_ci
212cabdff1aSopenharmony_ci    do {
213cabdff1aSopenharmony_ci        __asm__ volatile (
214cabdff1aSopenharmony_ci            "lwc1       %[src0],    0(%[src])               \n\t"
215cabdff1aSopenharmony_ci            "lwc1       %[src1],    4(%[src])               \n\t"
216cabdff1aSopenharmony_ci            "lwc1       %[src2],    8(%[src])               \n\t"
217cabdff1aSopenharmony_ci            "lwc1       %[src3],    12(%[src])              \n\t"
218cabdff1aSopenharmony_ci            "lwc1       %[src4],    16(%[src])              \n\t"
219cabdff1aSopenharmony_ci            "lwc1       %[src5],    20(%[src])              \n\t"
220cabdff1aSopenharmony_ci            "lwc1       %[src6],    24(%[src])              \n\t"
221cabdff1aSopenharmony_ci            "lwc1       %[src7],    28(%[src])              \n\t"
222cabdff1aSopenharmony_ci            "mul.s      %[src0],    %[src0],    %[scale]    \n\t"
223cabdff1aSopenharmony_ci            "mul.s      %[src1],    %[src1],    %[scale]    \n\t"
224cabdff1aSopenharmony_ci            "mul.s      %[src2],    %[src2],    %[scale]    \n\t"
225cabdff1aSopenharmony_ci            "mul.s      %[src3],    %[src3],    %[scale]    \n\t"
226cabdff1aSopenharmony_ci            "mul.s      %[src4],    %[src4],    %[scale]    \n\t"
227cabdff1aSopenharmony_ci            "mul.s      %[src5],    %[src5],    %[scale]    \n\t"
228cabdff1aSopenharmony_ci            "mul.s      %[src6],    %[src6],    %[scale]    \n\t"
229cabdff1aSopenharmony_ci            "mul.s      %[src7],    %[src7],    %[scale]    \n\t"
230cabdff1aSopenharmony_ci            "cvt.w.s    %[src0],    %[src0]                 \n\t"
231cabdff1aSopenharmony_ci            "cvt.w.s    %[src1],    %[src1]                 \n\t"
232cabdff1aSopenharmony_ci            "cvt.w.s    %[src2],    %[src2]                 \n\t"
233cabdff1aSopenharmony_ci            "cvt.w.s    %[src3],    %[src3]                 \n\t"
234cabdff1aSopenharmony_ci            "cvt.w.s    %[src4],    %[src4]                 \n\t"
235cabdff1aSopenharmony_ci            "cvt.w.s    %[src5],    %[src5]                 \n\t"
236cabdff1aSopenharmony_ci            "cvt.w.s    %[src6],    %[src6]                 \n\t"
237cabdff1aSopenharmony_ci            "cvt.w.s    %[src7],    %[src7]                 \n\t"
238cabdff1aSopenharmony_ci            "mfc1       %[temp0],   %[src0]                 \n\t"
239cabdff1aSopenharmony_ci            "mfc1       %[temp1],   %[src1]                 \n\t"
240cabdff1aSopenharmony_ci            "mfc1       %[temp2],   %[src2]                 \n\t"
241cabdff1aSopenharmony_ci            "mfc1       %[temp3],   %[src3]                 \n\t"
242cabdff1aSopenharmony_ci            "mfc1       %[temp4],   %[src4]                 \n\t"
243cabdff1aSopenharmony_ci            "mfc1       %[temp5],   %[src5]                 \n\t"
244cabdff1aSopenharmony_ci            "mfc1       %[temp6],   %[src6]                 \n\t"
245cabdff1aSopenharmony_ci            "mfc1       %[temp7],   %[src7]                 \n\t"
246cabdff1aSopenharmony_ci            "sw         %[temp0],   0(%[dst])               \n\t"
247cabdff1aSopenharmony_ci            "sw         %[temp1],   4(%[dst])               \n\t"
248cabdff1aSopenharmony_ci            "sw         %[temp2],   8(%[dst])               \n\t"
249cabdff1aSopenharmony_ci            "sw         %[temp3],   12(%[dst])              \n\t"
250cabdff1aSopenharmony_ci            "sw         %[temp4],   16(%[dst])              \n\t"
251cabdff1aSopenharmony_ci            "sw         %[temp5],   20(%[dst])              \n\t"
252cabdff1aSopenharmony_ci            "sw         %[temp6],   24(%[dst])              \n\t"
253cabdff1aSopenharmony_ci            "sw         %[temp7],   28(%[dst])              \n\t"
254cabdff1aSopenharmony_ci
255cabdff1aSopenharmony_ci            : [dst] "+r" (dst), [src] "+r" (src),
256cabdff1aSopenharmony_ci              [src0] "=&f" (src0), [src1] "=&f" (src1),
257cabdff1aSopenharmony_ci              [src2] "=&f" (src2), [src3] "=&f" (src3),
258cabdff1aSopenharmony_ci              [src4] "=&f" (src4), [src5] "=&f" (src5),
259cabdff1aSopenharmony_ci              [src6] "=&f" (src6), [src7] "=&f" (src7),
260cabdff1aSopenharmony_ci              [temp0] "=r" (temp0), [temp1] "=r" (temp1),
261cabdff1aSopenharmony_ci              [temp2] "=r" (temp2), [temp3] "=r" (temp3),
262cabdff1aSopenharmony_ci              [temp4] "=r" (temp4), [temp5] "=r" (temp5),
263cabdff1aSopenharmony_ci              [temp6] "=r" (temp6), [temp7] "=r" (temp7)
264cabdff1aSopenharmony_ci            : [scale] "f" (scale)
265cabdff1aSopenharmony_ci            : "memory"
266cabdff1aSopenharmony_ci        );
267cabdff1aSopenharmony_ci        src = src + 8;
268cabdff1aSopenharmony_ci        dst = dst + 8;
269cabdff1aSopenharmony_ci        len -= 8;
270cabdff1aSopenharmony_ci    } while (len > 0);
271cabdff1aSopenharmony_ci}
272cabdff1aSopenharmony_ci
273cabdff1aSopenharmony_cistatic void ac3_downmix_mips(float **samples, float (*matrix)[2],
274cabdff1aSopenharmony_ci                          int out_ch, int in_ch, int len)
275cabdff1aSopenharmony_ci{
276cabdff1aSopenharmony_ci    int i, j, i1, i2, i3;
277cabdff1aSopenharmony_ci    float v0, v1, v2, v3;
278cabdff1aSopenharmony_ci    float v4, v5, v6, v7;
279cabdff1aSopenharmony_ci    float samples0, samples1, samples2, samples3, matrix_j, matrix_j2;
280cabdff1aSopenharmony_ci    float *samples_p, *samples_sw, *matrix_p, **samples_x, **samples_end;
281cabdff1aSopenharmony_ci
282cabdff1aSopenharmony_ci    __asm__ volatile(
283cabdff1aSopenharmony_ci        ".set   push                                                \n\t"
284cabdff1aSopenharmony_ci        ".set   noreorder                                           \n\t"
285cabdff1aSopenharmony_ci
286cabdff1aSopenharmony_ci        "li     %[i1],          2                                   \n\t"
287cabdff1aSopenharmony_ci        "sll    %[len],         2                                   \n\t"
288cabdff1aSopenharmony_ci        "move   %[i],           $zero                               \n\t"
289cabdff1aSopenharmony_ci        "sll    %[j],           %[in_ch],             " PTRLOG "    \n\t"
290cabdff1aSopenharmony_ci
291cabdff1aSopenharmony_ci        "bne    %[out_ch],      %[i1],                  3f          \n\t"   // if (out_ch == 2)
292cabdff1aSopenharmony_ci        " li    %[i2],          1                                   \n\t"
293cabdff1aSopenharmony_ci
294cabdff1aSopenharmony_ci        "2:                                                         \n\t"   // start of the for loop (for (i = 0; i < len; i+=4))
295cabdff1aSopenharmony_ci        "move   %[matrix_p],    %[matrix]                           \n\t"
296cabdff1aSopenharmony_ci        "move   %[samples_x],   %[samples]                          \n\t"
297cabdff1aSopenharmony_ci        "mtc1   $zero,          %[v0]                               \n\t"
298cabdff1aSopenharmony_ci        "mtc1   $zero,          %[v1]                               \n\t"
299cabdff1aSopenharmony_ci        "mtc1   $zero,          %[v2]                               \n\t"
300cabdff1aSopenharmony_ci        "mtc1   $zero,          %[v3]                               \n\t"
301cabdff1aSopenharmony_ci        "mtc1   $zero,          %[v4]                               \n\t"
302cabdff1aSopenharmony_ci        "mtc1   $zero,          %[v5]                               \n\t"
303cabdff1aSopenharmony_ci        "mtc1   $zero,          %[v6]                               \n\t"
304cabdff1aSopenharmony_ci        "mtc1   $zero,          %[v7]                               \n\t"
305cabdff1aSopenharmony_ci        "addiu  %[i1],          %[i],                  4            \n\t"
306cabdff1aSopenharmony_ci        "addiu  %[i2],          %[i],                  8            \n\t"
307cabdff1aSopenharmony_ci        PTR_L " %[samples_p],   0(%[samples_x])                     \n\t"
308cabdff1aSopenharmony_ci        "addiu  %[i3],          %[i],                  12           \n\t"
309cabdff1aSopenharmony_ci        PTR_ADDU "%[samples_end],%[samples_x],         %[j]         \n\t"
310cabdff1aSopenharmony_ci        "move   %[samples_sw],  %[samples_p]                        \n\t"
311cabdff1aSopenharmony_ci
312cabdff1aSopenharmony_ci        "1:                                                         \n\t"   // start of the inner for loop (for (j = 0; j < in_ch; j++))
313cabdff1aSopenharmony_ci        "lwc1   %[matrix_j],    0(%[matrix_p])                      \n\t"
314cabdff1aSopenharmony_ci        "lwc1   %[matrix_j2],   4(%[matrix_p])                      \n\t"
315cabdff1aSopenharmony_ci        "lwxc1  %[samples0],    %[i](%[samples_p])                  \n\t"
316cabdff1aSopenharmony_ci        "lwxc1  %[samples1],    %[i1](%[samples_p])                 \n\t"
317cabdff1aSopenharmony_ci        "lwxc1  %[samples2],    %[i2](%[samples_p])                 \n\t"
318cabdff1aSopenharmony_ci        "lwxc1  %[samples3],    %[i3](%[samples_p])                 \n\t"
319cabdff1aSopenharmony_ci        PTR_ADDIU "%[matrix_p], 8                                   \n\t"
320cabdff1aSopenharmony_ci        PTR_ADDIU "%[samples_x]," PTRSIZE "                         \n\t"
321cabdff1aSopenharmony_ci        "madd.s %[v0],          %[v0],  %[samples0],    %[matrix_j] \n\t"
322cabdff1aSopenharmony_ci        "madd.s %[v1],          %[v1],  %[samples1],    %[matrix_j] \n\t"
323cabdff1aSopenharmony_ci        "madd.s %[v2],          %[v2],  %[samples2],    %[matrix_j] \n\t"
324cabdff1aSopenharmony_ci        "madd.s %[v3],          %[v3],  %[samples3],    %[matrix_j] \n\t"
325cabdff1aSopenharmony_ci        "madd.s %[v4],          %[v4],  %[samples0],    %[matrix_j2]\n\t"
326cabdff1aSopenharmony_ci        "madd.s %[v5],          %[v5],  %[samples1],    %[matrix_j2]\n\t"
327cabdff1aSopenharmony_ci        "madd.s %[v6],          %[v6],  %[samples2],    %[matrix_j2]\n\t"
328cabdff1aSopenharmony_ci        "madd.s %[v7],          %[v7],  %[samples3],    %[matrix_j2]\n\t"
329cabdff1aSopenharmony_ci        "bne    %[samples_x],   %[samples_end],         1b          \n\t"
330cabdff1aSopenharmony_ci        PTR_L " %[samples_p],   0(%[samples_x])                     \n\t"
331cabdff1aSopenharmony_ci
332cabdff1aSopenharmony_ci        PTR_L " %[samples_p],  " PTRSIZE "(%[samples])              \n\t"
333cabdff1aSopenharmony_ci        "swxc1  %[v0],          %[i](%[samples_sw])                 \n\t"
334cabdff1aSopenharmony_ci        "swxc1  %[v1],          %[i1](%[samples_sw])                \n\t"
335cabdff1aSopenharmony_ci        "swxc1  %[v2],          %[i2](%[samples_sw])                \n\t"
336cabdff1aSopenharmony_ci        "swxc1  %[v3],          %[i3](%[samples_sw])                \n\t"
337cabdff1aSopenharmony_ci        "swxc1  %[v4],          %[i](%[samples_p])                  \n\t"
338cabdff1aSopenharmony_ci        "addiu  %[i],           16                                  \n\t"
339cabdff1aSopenharmony_ci        "swxc1  %[v5],          %[i1](%[samples_p])                 \n\t"
340cabdff1aSopenharmony_ci        "swxc1  %[v6],          %[i2](%[samples_p])                 \n\t"
341cabdff1aSopenharmony_ci        "bne    %[i],           %[len],                 2b          \n\t"
342cabdff1aSopenharmony_ci        " swxc1 %[v7],          %[i3](%[samples_p])                 \n\t"
343cabdff1aSopenharmony_ci
344cabdff1aSopenharmony_ci        "3:                                                         \n\t"
345cabdff1aSopenharmony_ci        "bne    %[out_ch],      %[i2],                  6f          \n\t"   // if (out_ch == 1)
346cabdff1aSopenharmony_ci        " nop                                                       \n\t"
347cabdff1aSopenharmony_ci
348cabdff1aSopenharmony_ci        "5:                                                         \n\t"   // start of the outer for loop (for (i = 0; i < len; i+=4))
349cabdff1aSopenharmony_ci        "move   %[matrix_p],    %[matrix]                           \n\t"
350cabdff1aSopenharmony_ci        "move   %[samples_x],   %[samples]                          \n\t"
351cabdff1aSopenharmony_ci        "mtc1   $zero,          %[v0]                               \n\t"
352cabdff1aSopenharmony_ci        "mtc1   $zero,          %[v1]                               \n\t"
353cabdff1aSopenharmony_ci        "mtc1   $zero,          %[v2]                               \n\t"
354cabdff1aSopenharmony_ci        "mtc1   $zero,          %[v3]                               \n\t"
355cabdff1aSopenharmony_ci        "addiu  %[i1],          %[i],                  4            \n\t"
356cabdff1aSopenharmony_ci        "addiu  %[i2],          %[i],                  8            \n\t"
357cabdff1aSopenharmony_ci        PTR_L " %[samples_p],   0(%[samples_x])                     \n\t"
358cabdff1aSopenharmony_ci        "addiu  %[i3],          %[i],                  12           \n\t"
359cabdff1aSopenharmony_ci        PTR_ADDU "%[samples_end],%[samples_x],         %[j]         \n\t"
360cabdff1aSopenharmony_ci        "move   %[samples_sw],  %[samples_p]                        \n\t"
361cabdff1aSopenharmony_ci
362cabdff1aSopenharmony_ci        "4:                                                         \n\t"   // start of the inner for loop (for (j = 0; j < in_ch; j++))
363cabdff1aSopenharmony_ci        "lwc1   %[matrix_j],    0(%[matrix_p])                      \n\t"
364cabdff1aSopenharmony_ci        "lwxc1  %[samples0],    %[i](%[samples_p])                  \n\t"
365cabdff1aSopenharmony_ci        "lwxc1  %[samples1],    %[i1](%[samples_p])                 \n\t"
366cabdff1aSopenharmony_ci        "lwxc1  %[samples2],    %[i2](%[samples_p])                 \n\t"
367cabdff1aSopenharmony_ci        "lwxc1  %[samples3],    %[i3](%[samples_p])                 \n\t"
368cabdff1aSopenharmony_ci        PTR_ADDIU "%[matrix_p], 8                                   \n\t"
369cabdff1aSopenharmony_ci        PTR_ADDIU "%[samples_x]," PTRSIZE "                         \n\t"
370cabdff1aSopenharmony_ci        "madd.s %[v0],          %[v0],  %[samples0],    %[matrix_j] \n\t"
371cabdff1aSopenharmony_ci        "madd.s %[v1],          %[v1],  %[samples1],    %[matrix_j] \n\t"
372cabdff1aSopenharmony_ci        "madd.s %[v2],          %[v2],  %[samples2],    %[matrix_j] \n\t"
373cabdff1aSopenharmony_ci        "madd.s %[v3],          %[v3],  %[samples3],    %[matrix_j] \n\t"
374cabdff1aSopenharmony_ci        "bne    %[samples_x],   %[samples_end],         4b          \n\t"
375cabdff1aSopenharmony_ci        PTR_L " %[samples_p],   0(%[samples_x])                     \n\t"
376cabdff1aSopenharmony_ci
377cabdff1aSopenharmony_ci        "swxc1  %[v0],          %[i](%[samples_sw])                 \n\t"
378cabdff1aSopenharmony_ci        "addiu  %[i],           16                                  \n\t"
379cabdff1aSopenharmony_ci        "swxc1  %[v1],          %[i1](%[samples_sw])                \n\t"
380cabdff1aSopenharmony_ci        "swxc1  %[v2],          %[i2](%[samples_sw])                \n\t"
381cabdff1aSopenharmony_ci        "bne    %[i],           %[len],                 5b          \n\t"
382cabdff1aSopenharmony_ci        " swxc1 %[v3],          %[i3](%[samples_sw])                \n\t"
383cabdff1aSopenharmony_ci        "6:                                                         \n\t"
384cabdff1aSopenharmony_ci
385cabdff1aSopenharmony_ci        ".set   pop"
386cabdff1aSopenharmony_ci        :[samples_p]"=&r"(samples_p), [matrix_j]"=&f"(matrix_j), [matrix_j2]"=&f"(matrix_j2),
387cabdff1aSopenharmony_ci         [samples0]"=&f"(samples0), [samples1]"=&f"(samples1),
388cabdff1aSopenharmony_ci         [samples2]"=&f"(samples2), [samples3]"=&f"(samples3),
389cabdff1aSopenharmony_ci         [v0]"=&f"(v0), [v1]"=&f"(v1), [v2]"=&f"(v2), [v3]"=&f"(v3),
390cabdff1aSopenharmony_ci         [v4]"=&f"(v4), [v5]"=&f"(v5), [v6]"=&f"(v6), [v7]"=&f"(v7),
391cabdff1aSopenharmony_ci         [samples_x]"=&r"(samples_x), [matrix_p]"=&r"(matrix_p),
392cabdff1aSopenharmony_ci         [samples_end]"=&r"(samples_end), [samples_sw]"=&r"(samples_sw),
393cabdff1aSopenharmony_ci         [i1]"=&r"(i1), [i2]"=&r"(i2), [i3]"=&r"(i3), [i]"=&r"(i),
394cabdff1aSopenharmony_ci         [j]"=&r"(j), [len]"+r"(len)
395cabdff1aSopenharmony_ci        :[samples]"r"(samples), [matrix]"r"(matrix),
396cabdff1aSopenharmony_ci         [in_ch]"r"(in_ch), [out_ch]"r"(out_ch)
397cabdff1aSopenharmony_ci        :"memory"
398cabdff1aSopenharmony_ci    );
399cabdff1aSopenharmony_ci}
400cabdff1aSopenharmony_ci#endif /* !HAVE_MIPS32R6 && !HAVE_MIPS64R6 */
401cabdff1aSopenharmony_ci#endif /* HAVE_MIPSFPU */
402cabdff1aSopenharmony_ci#endif /* HAVE_INLINE_ASM */
403cabdff1aSopenharmony_ci
404cabdff1aSopenharmony_civoid ff_ac3dsp_init_mips(AC3DSPContext *c, int bit_exact) {
405cabdff1aSopenharmony_ci#if HAVE_INLINE_ASM
406cabdff1aSopenharmony_ci#if HAVE_MIPSDSP
407cabdff1aSopenharmony_ci    c->bit_alloc_calc_bap = ac3_bit_alloc_calc_bap_mips;
408cabdff1aSopenharmony_ci    c->update_bap_counts  = ac3_update_bap_counts_mips;
409cabdff1aSopenharmony_ci#endif
410cabdff1aSopenharmony_ci#if HAVE_MIPSFPU
411cabdff1aSopenharmony_ci#if !HAVE_MIPS32R6 && !HAVE_MIPS64R6
412cabdff1aSopenharmony_ci    c->float_to_fixed24 = float_to_fixed24_mips;
413cabdff1aSopenharmony_ci    //c->downmix          = ac3_downmix_mips;
414cabdff1aSopenharmony_ci#endif
415cabdff1aSopenharmony_ci#endif
416cabdff1aSopenharmony_ci
417cabdff1aSopenharmony_ci#endif
418cabdff1aSopenharmony_ci}
419