annotate ffmpeg/libavcodec/mips/fft_mips.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Copyright (c) 2012
yading@10 3 * MIPS Technologies, Inc., California.
yading@10 4 *
yading@10 5 * Redistribution and use in source and binary forms, with or without
yading@10 6 * modification, are permitted provided that the following conditions
yading@10 7 * are met:
yading@10 8 * 1. Redistributions of source code must retain the above copyright
yading@10 9 * notice, this list of conditions and the following disclaimer.
yading@10 10 * 2. Redistributions in binary form must reproduce the above copyright
yading@10 11 * notice, this list of conditions and the following disclaimer in the
yading@10 12 * documentation and/or other materials provided with the distribution.
yading@10 13 * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
yading@10 14 * contributors may be used to endorse or promote products derived from
yading@10 15 * this software without specific prior written permission.
yading@10 16 *
yading@10 17 * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
yading@10 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
yading@10 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
yading@10 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
yading@10 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
yading@10 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
yading@10 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
yading@10 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
yading@10 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
yading@10 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
yading@10 27 * SUCH DAMAGE.
yading@10 28 *
yading@10 29 * Author: Stanislav Ocovaj (socovaj@mips.com)
yading@10 30 * Author: Zoran Lukic (zoranl@mips.com)
yading@10 31 *
yading@10 32 * Optimized MDCT/IMDCT and FFT transforms
yading@10 33 *
yading@10 34 * This file is part of FFmpeg.
yading@10 35 *
yading@10 36 * FFmpeg is free software; you can redistribute it and/or
yading@10 37 * modify it under the terms of the GNU Lesser General Public
yading@10 38 * License as published by the Free Software Foundation; either
yading@10 39 * version 2.1 of the License, or (at your option) any later version.
yading@10 40 *
yading@10 41 * FFmpeg is distributed in the hope that it will be useful,
yading@10 42 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 43 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 44 * Lesser General Public License for more details.
yading@10 45 *
yading@10 46 * You should have received a copy of the GNU Lesser General Public
yading@10 47 * License along with FFmpeg; if not, write to the Free Software
yading@10 48 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 49 */
yading@10 50 #include "config.h"
yading@10 51 #include "libavcodec/fft.h"
yading@10 52 #include "fft_table.h"
yading@10 53
yading@10 54 /**
yading@10 55 * FFT transform
yading@10 56 */
yading@10 57
yading@10 58 #if HAVE_INLINE_ASM
yading@10 59 static void ff_fft_calc_mips(FFTContext *s, FFTComplex *z)
yading@10 60 {
yading@10 61 int nbits, i, n, num_transforms, offset, step;
yading@10 62 int n4, n2, n34;
yading@10 63 FFTSample tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
yading@10 64 FFTComplex *tmpz;
yading@10 65 float w_re, w_im;
yading@10 66 float *w_re_ptr, *w_im_ptr;
yading@10 67 const int fft_size = (1 << s->nbits);
yading@10 68 int s_n = s->nbits;
yading@10 69 int tem1, tem2;
yading@10 70 float pom, pom1, pom2, pom3;
yading@10 71 float temp, temp1, temp3, temp4;
yading@10 72 FFTComplex * tmpz_n2, * tmpz_n34, * tmpz_n4;
yading@10 73 FFTComplex * tmpz_n2_i, * tmpz_n34_i, * tmpz_n4_i, * tmpz_i;
yading@10 74
yading@10 75 /**
yading@10 76 *num_transforms = (0x2aab >> (16 - s->nbits)) | 1;
yading@10 77 */
yading@10 78 __asm__ volatile (
yading@10 79 "li %[tem1], 16 \n\t"
yading@10 80 "sub %[s_n], %[tem1], %[s_n] \n\t"
yading@10 81 "li %[tem2], 10923 \n\t"
yading@10 82 "srav %[tem2], %[tem2], %[s_n] \n\t"
yading@10 83 "ori %[num_t],%[tem2], 1 \n\t"
yading@10 84 : [num_t]"=r"(num_transforms), [s_n]"+r"(s_n),
yading@10 85 [tem1]"=&r"(tem1), [tem2]"=&r"(tem2)
yading@10 86 );
yading@10 87
yading@10 88
yading@10 89 for (n=0; n<num_transforms; n++) {
yading@10 90 offset = fft_offsets_lut[n] << 2;
yading@10 91 tmpz = z + offset;
yading@10 92
yading@10 93 tmp1 = tmpz[0].re + tmpz[1].re;
yading@10 94 tmp5 = tmpz[2].re + tmpz[3].re;
yading@10 95 tmp2 = tmpz[0].im + tmpz[1].im;
yading@10 96 tmp6 = tmpz[2].im + tmpz[3].im;
yading@10 97 tmp3 = tmpz[0].re - tmpz[1].re;
yading@10 98 tmp8 = tmpz[2].im - tmpz[3].im;
yading@10 99 tmp4 = tmpz[0].im - tmpz[1].im;
yading@10 100 tmp7 = tmpz[2].re - tmpz[3].re;
yading@10 101
yading@10 102 tmpz[0].re = tmp1 + tmp5;
yading@10 103 tmpz[2].re = tmp1 - tmp5;
yading@10 104 tmpz[0].im = tmp2 + tmp6;
yading@10 105 tmpz[2].im = tmp2 - tmp6;
yading@10 106 tmpz[1].re = tmp3 + tmp8;
yading@10 107 tmpz[3].re = tmp3 - tmp8;
yading@10 108 tmpz[1].im = tmp4 - tmp7;
yading@10 109 tmpz[3].im = tmp4 + tmp7;
yading@10 110
yading@10 111 }
yading@10 112
yading@10 113 if (fft_size < 8)
yading@10 114 return;
yading@10 115
yading@10 116 num_transforms = (num_transforms >> 1) | 1;
yading@10 117
yading@10 118 for (n=0; n<num_transforms; n++) {
yading@10 119 offset = fft_offsets_lut[n] << 3;
yading@10 120 tmpz = z + offset;
yading@10 121
yading@10 122 __asm__ volatile (
yading@10 123 "lwc1 %[tmp1], 32(%[tmpz]) \n\t"
yading@10 124 "lwc1 %[pom], 40(%[tmpz]) \n\t"
yading@10 125 "lwc1 %[tmp3], 48(%[tmpz]) \n\t"
yading@10 126 "lwc1 %[pom1], 56(%[tmpz]) \n\t"
yading@10 127 "lwc1 %[tmp2], 36(%[tmpz]) \n\t"
yading@10 128 "lwc1 %[pom2], 44(%[tmpz]) \n\t"
yading@10 129 "lwc1 %[pom3], 60(%[tmpz]) \n\t"
yading@10 130 "lwc1 %[tmp4], 52(%[tmpz]) \n\t"
yading@10 131 "add.s %[tmp1], %[tmp1], %[pom] \n\t" // tmp1 = tmpz[4].re + tmpz[5].re;
yading@10 132 "add.s %[tmp3], %[tmp3], %[pom1] \n\t" // tmp3 = tmpz[6].re + tmpz[7].re;
yading@10 133 "add.s %[tmp2], %[tmp2], %[pom2] \n\t" // tmp2 = tmpz[4].im + tmpz[5].im;
yading@10 134 "lwc1 %[pom], 40(%[tmpz]) \n\t"
yading@10 135 "add.s %[tmp4], %[tmp4], %[pom3] \n\t" // tmp4 = tmpz[6].im + tmpz[7].im;
yading@10 136 "add.s %[tmp5], %[tmp1], %[tmp3] \n\t" // tmp5 = tmp1 + tmp3;
yading@10 137 "sub.s %[tmp7], %[tmp1], %[tmp3] \n\t" // tmp7 = tmp1 - tmp3;
yading@10 138 "lwc1 %[tmp1], 32(%[tmpz]) \n\t"
yading@10 139 "lwc1 %[pom1], 44(%[tmpz]) \n\t"
yading@10 140 "add.s %[tmp6], %[tmp2], %[tmp4] \n\t" // tmp6 = tmp2 + tmp4;
yading@10 141 "sub.s %[tmp8], %[tmp2], %[tmp4] \n\t" // tmp8 = tmp2 - tmp4;
yading@10 142 "lwc1 %[tmp2], 36(%[tmpz]) \n\t"
yading@10 143 "lwc1 %[pom2], 56(%[tmpz]) \n\t"
yading@10 144 "lwc1 %[pom3], 60(%[tmpz]) \n\t"
yading@10 145 "lwc1 %[tmp3], 48(%[tmpz]) \n\t"
yading@10 146 "lwc1 %[tmp4], 52(%[tmpz]) \n\t"
yading@10 147 "sub.s %[tmp1], %[tmp1], %[pom] \n\t" // tmp1 = tmpz[4].re - tmpz[5].re;
yading@10 148 "lwc1 %[pom], 0(%[tmpz]) \n\t"
yading@10 149 "sub.s %[tmp2], %[tmp2], %[pom1] \n\t" // tmp2 = tmpz[4].im - tmpz[5].im;
yading@10 150 "sub.s %[tmp3], %[tmp3], %[pom2] \n\t" // tmp3 = tmpz[6].re - tmpz[7].re;
yading@10 151 "lwc1 %[pom2], 4(%[tmpz]) \n\t"
yading@10 152 "sub.s %[pom1], %[pom], %[tmp5] \n\t"
yading@10 153 "sub.s %[tmp4], %[tmp4], %[pom3] \n\t" // tmp4 = tmpz[6].im - tmpz[7].im;
yading@10 154 "add.s %[pom3], %[pom], %[tmp5] \n\t"
yading@10 155 "sub.s %[pom], %[pom2], %[tmp6] \n\t"
yading@10 156 "add.s %[pom2], %[pom2], %[tmp6] \n\t"
yading@10 157 "swc1 %[pom1], 32(%[tmpz]) \n\t" // tmpz[4].re = tmpz[0].re - tmp5;
yading@10 158 "swc1 %[pom3], 0(%[tmpz]) \n\t" // tmpz[0].re = tmpz[0].re + tmp5;
yading@10 159 "swc1 %[pom], 36(%[tmpz]) \n\t" // tmpz[4].im = tmpz[0].im - tmp6;
yading@10 160 "swc1 %[pom2], 4(%[tmpz]) \n\t" // tmpz[0].im = tmpz[0].im + tmp6;
yading@10 161 "lwc1 %[pom1], 16(%[tmpz]) \n\t"
yading@10 162 "lwc1 %[pom3], 20(%[tmpz]) \n\t"
yading@10 163 "li.s %[pom], 0.7071067812 \n\t" // float pom = 0.7071067812f;
yading@10 164 "add.s %[temp1],%[tmp1], %[tmp2] \n\t"
yading@10 165 "sub.s %[temp], %[pom1], %[tmp8] \n\t"
yading@10 166 "add.s %[pom2], %[pom3], %[tmp7] \n\t"
yading@10 167 "sub.s %[temp3],%[tmp3], %[tmp4] \n\t"
yading@10 168 "sub.s %[temp4],%[tmp2], %[tmp1] \n\t"
yading@10 169 "swc1 %[temp], 48(%[tmpz]) \n\t" // tmpz[6].re = tmpz[2].re - tmp8;
yading@10 170 "swc1 %[pom2], 52(%[tmpz]) \n\t" // tmpz[6].im = tmpz[2].im + tmp7;
yading@10 171 "add.s %[pom1], %[pom1], %[tmp8] \n\t"
yading@10 172 "sub.s %[pom3], %[pom3], %[tmp7] \n\t"
yading@10 173 "add.s %[tmp3], %[tmp3], %[tmp4] \n\t"
yading@10 174 "mul.s %[tmp5], %[pom], %[temp1] \n\t" // tmp5 = pom * (tmp1 + tmp2);
yading@10 175 "mul.s %[tmp7], %[pom], %[temp3] \n\t" // tmp7 = pom * (tmp3 - tmp4);
yading@10 176 "mul.s %[tmp6], %[pom], %[temp4] \n\t" // tmp6 = pom * (tmp2 - tmp1);
yading@10 177 "mul.s %[tmp8], %[pom], %[tmp3] \n\t" // tmp8 = pom * (tmp3 + tmp4);
yading@10 178 "swc1 %[pom1], 16(%[tmpz]) \n\t" // tmpz[2].re = tmpz[2].re + tmp8;
yading@10 179 "swc1 %[pom3], 20(%[tmpz]) \n\t" // tmpz[2].im = tmpz[2].im - tmp7;
yading@10 180 "add.s %[tmp1], %[tmp5], %[tmp7] \n\t" // tmp1 = tmp5 + tmp7;
yading@10 181 "sub.s %[tmp3], %[tmp5], %[tmp7] \n\t" // tmp3 = tmp5 - tmp7;
yading@10 182 "add.s %[tmp2], %[tmp6], %[tmp8] \n\t" // tmp2 = tmp6 + tmp8;
yading@10 183 "sub.s %[tmp4], %[tmp6], %[tmp8] \n\t" // tmp4 = tmp6 - tmp8;
yading@10 184 "lwc1 %[temp], 8(%[tmpz]) \n\t"
yading@10 185 "lwc1 %[temp1],12(%[tmpz]) \n\t"
yading@10 186 "lwc1 %[pom], 24(%[tmpz]) \n\t"
yading@10 187 "lwc1 %[pom2], 28(%[tmpz]) \n\t"
yading@10 188 "sub.s %[temp4],%[temp], %[tmp1] \n\t"
yading@10 189 "sub.s %[temp3],%[temp1], %[tmp2] \n\t"
yading@10 190 "add.s %[temp], %[temp], %[tmp1] \n\t"
yading@10 191 "add.s %[temp1],%[temp1], %[tmp2] \n\t"
yading@10 192 "sub.s %[pom1], %[pom], %[tmp4] \n\t"
yading@10 193 "add.s %[pom3], %[pom2], %[tmp3] \n\t"
yading@10 194 "add.s %[pom], %[pom], %[tmp4] \n\t"
yading@10 195 "sub.s %[pom2], %[pom2], %[tmp3] \n\t"
yading@10 196 "swc1 %[temp4],40(%[tmpz]) \n\t" // tmpz[5].re = tmpz[1].re - tmp1;
yading@10 197 "swc1 %[temp3],44(%[tmpz]) \n\t" // tmpz[5].im = tmpz[1].im - tmp2;
yading@10 198 "swc1 %[temp], 8(%[tmpz]) \n\t" // tmpz[1].re = tmpz[1].re + tmp1;
yading@10 199 "swc1 %[temp1],12(%[tmpz]) \n\t" // tmpz[1].im = tmpz[1].im + tmp2;
yading@10 200 "swc1 %[pom1], 56(%[tmpz]) \n\t" // tmpz[7].re = tmpz[3].re - tmp4;
yading@10 201 "swc1 %[pom3], 60(%[tmpz]) \n\t" // tmpz[7].im = tmpz[3].im + tmp3;
yading@10 202 "swc1 %[pom], 24(%[tmpz]) \n\t" // tmpz[3].re = tmpz[3].re + tmp4;
yading@10 203 "swc1 %[pom2], 28(%[tmpz]) \n\t" // tmpz[3].im = tmpz[3].im - tmp3;
yading@10 204 : [tmp1]"=&f"(tmp1), [pom]"=&f"(pom), [pom1]"=&f"(pom1), [pom2]"=&f"(pom2),
yading@10 205 [tmp3]"=&f"(tmp3), [tmp2]"=&f"(tmp2), [tmp4]"=&f"(tmp4), [tmp5]"=&f"(tmp5), [tmp7]"=&f"(tmp7),
yading@10 206 [tmp6]"=&f"(tmp6), [tmp8]"=&f"(tmp8), [pom3]"=&f"(pom3),[temp]"=&f"(temp), [temp1]"=&f"(temp1),
yading@10 207 [temp3]"=&f"(temp3), [temp4]"=&f"(temp4)
yading@10 208 : [tmpz]"r"(tmpz)
yading@10 209 : "memory"
yading@10 210 );
yading@10 211 }
yading@10 212
yading@10 213 step = 1 << (MAX_LOG2_NFFT - 4);
yading@10 214 n4 = 4;
yading@10 215
yading@10 216 for (nbits=4; nbits<=s->nbits; nbits++) {
yading@10 217 /*
yading@10 218 * num_transforms = (num_transforms >> 1) | 1;
yading@10 219 */
yading@10 220 __asm__ volatile (
yading@10 221 "sra %[num_t], %[num_t], 1 \n\t"
yading@10 222 "ori %[num_t], %[num_t], 1 \n\t"
yading@10 223
yading@10 224 : [num_t] "+r" (num_transforms)
yading@10 225 );
yading@10 226 n2 = 2 * n4;
yading@10 227 n34 = 3 * n4;
yading@10 228
yading@10 229 for (n=0; n<num_transforms; n++) {
yading@10 230 offset = fft_offsets_lut[n] << nbits;
yading@10 231 tmpz = z + offset;
yading@10 232
yading@10 233 tmpz_n2 = tmpz + n2;
yading@10 234 tmpz_n4 = tmpz + n4;
yading@10 235 tmpz_n34 = tmpz + n34;
yading@10 236
yading@10 237 __asm__ volatile (
yading@10 238 "lwc1 %[pom1], 0(%[tmpz_n2]) \n\t"
yading@10 239 "lwc1 %[pom], 0(%[tmpz_n34]) \n\t"
yading@10 240 "lwc1 %[pom2], 4(%[tmpz_n2]) \n\t"
yading@10 241 "lwc1 %[pom3], 4(%[tmpz_n34]) \n\t"
yading@10 242 "lwc1 %[temp1],0(%[tmpz]) \n\t"
yading@10 243 "lwc1 %[temp3],4(%[tmpz]) \n\t"
yading@10 244 "add.s %[tmp5], %[pom1], %[pom] \n\t" // tmp5 = tmpz[ n2].re + tmpz[n34].re;
yading@10 245 "sub.s %[tmp1], %[pom1], %[pom] \n\t" // tmp1 = tmpz[ n2].re - tmpz[n34].re;
yading@10 246 "add.s %[tmp6], %[pom2], %[pom3] \n\t" // tmp6 = tmpz[ n2].im + tmpz[n34].im;
yading@10 247 "sub.s %[tmp2], %[pom2], %[pom3] \n\t" // tmp2 = tmpz[ n2].im - tmpz[n34].im;
yading@10 248 "sub.s %[temp], %[temp1], %[tmp5] \n\t"
yading@10 249 "add.s %[temp1],%[temp1], %[tmp5] \n\t"
yading@10 250 "sub.s %[temp4],%[temp3], %[tmp6] \n\t"
yading@10 251 "add.s %[temp3],%[temp3], %[tmp6] \n\t"
yading@10 252 "swc1 %[temp], 0(%[tmpz_n2]) \n\t" // tmpz[ n2].re = tmpz[ 0].re - tmp5;
yading@10 253 "swc1 %[temp1],0(%[tmpz]) \n\t" // tmpz[ 0].re = tmpz[ 0].re + tmp5;
yading@10 254 "lwc1 %[pom1], 0(%[tmpz_n4]) \n\t"
yading@10 255 "swc1 %[temp4],4(%[tmpz_n2]) \n\t" // tmpz[ n2].im = tmpz[ 0].im - tmp6;
yading@10 256 "lwc1 %[temp], 4(%[tmpz_n4]) \n\t"
yading@10 257 "swc1 %[temp3],4(%[tmpz]) \n\t" // tmpz[ 0].im = tmpz[ 0].im + tmp6;
yading@10 258 "sub.s %[pom], %[pom1], %[tmp2] \n\t"
yading@10 259 "add.s %[pom1], %[pom1], %[tmp2] \n\t"
yading@10 260 "add.s %[temp1],%[temp], %[tmp1] \n\t"
yading@10 261 "sub.s %[temp], %[temp], %[tmp1] \n\t"
yading@10 262 "swc1 %[pom], 0(%[tmpz_n34]) \n\t" // tmpz[n34].re = tmpz[n4].re - tmp2;
yading@10 263 "swc1 %[pom1], 0(%[tmpz_n4]) \n\t" // tmpz[ n4].re = tmpz[n4].re + tmp2;
yading@10 264 "swc1 %[temp1],4(%[tmpz_n34]) \n\t" // tmpz[n34].im = tmpz[n4].im + tmp1;
yading@10 265 "swc1 %[temp], 4(%[tmpz_n4]) \n\t" // tmpz[ n4].im = tmpz[n4].im - tmp1;
yading@10 266 : [tmp5]"=&f"(tmp5),
yading@10 267 [tmp1]"=&f"(tmp1), [pom]"=&f"(pom), [pom1]"=&f"(pom1), [pom2]"=&f"(pom2),
yading@10 268 [tmp2]"=&f"(tmp2), [tmp6]"=&f"(tmp6), [pom3]"=&f"(pom3),
yading@10 269 [temp]"=&f"(temp), [temp1]"=&f"(temp1), [temp3]"=&f"(temp3), [temp4]"=&f"(temp4)
yading@10 270 : [tmpz]"r"(tmpz), [tmpz_n2]"r"(tmpz_n2), [tmpz_n34]"r"(tmpz_n34), [tmpz_n4]"r"(tmpz_n4)
yading@10 271 : "memory"
yading@10 272 );
yading@10 273
yading@10 274 w_re_ptr = (float*)(ff_cos_65536 + step);
yading@10 275 w_im_ptr = (float*)(ff_cos_65536 + MAX_FFT_SIZE/4 - step);
yading@10 276
yading@10 277 for (i=1; i<n4; i++) {
yading@10 278 w_re = w_re_ptr[0];
yading@10 279 w_im = w_im_ptr[0];
yading@10 280 tmpz_n2_i = tmpz_n2 + i;
yading@10 281 tmpz_n4_i = tmpz_n4 + i;
yading@10 282 tmpz_n34_i= tmpz_n34 + i;
yading@10 283 tmpz_i = tmpz + i;
yading@10 284
yading@10 285 __asm__ volatile (
yading@10 286 "lwc1 %[temp], 0(%[tmpz_n2_i]) \n\t"
yading@10 287 "lwc1 %[temp1], 4(%[tmpz_n2_i]) \n\t"
yading@10 288 "lwc1 %[pom], 0(%[tmpz_n34_i]) \n\t"
yading@10 289 "lwc1 %[pom1], 4(%[tmpz_n34_i]) \n\t"
yading@10 290 "mul.s %[temp3], %[w_im], %[temp] \n\t"
yading@10 291 "mul.s %[temp4], %[w_im], %[temp1] \n\t"
yading@10 292 "mul.s %[pom2], %[w_im], %[pom1] \n\t"
yading@10 293 "mul.s %[pom3], %[w_im], %[pom] \n\t"
yading@10 294 "msub.s %[tmp2], %[temp3], %[w_re], %[temp1] \n\t" // tmp2 = w_re * tmpz[ n2+i].im - w_im * tmpz[ n2+i].re;
yading@10 295 "madd.s %[tmp1], %[temp4], %[w_re], %[temp] \n\t" // tmp1 = w_re * tmpz[ n2+i].re + w_im * tmpz[ n2+i].im;
yading@10 296 "msub.s %[tmp3], %[pom2], %[w_re], %[pom] \n\t" // tmp3 = w_re * tmpz[n34+i].re - w_im * tmpz[n34+i].im;
yading@10 297 "madd.s %[tmp4], %[pom3], %[w_re], %[pom1] \n\t" // tmp4 = w_re * tmpz[n34+i].im + w_im * tmpz[n34+i].re;
yading@10 298 "lwc1 %[temp], 0(%[tmpz_i]) \n\t"
yading@10 299 "lwc1 %[pom], 4(%[tmpz_i]) \n\t"
yading@10 300 "add.s %[tmp5], %[tmp1], %[tmp3] \n\t" // tmp5 = tmp1 + tmp3;
yading@10 301 "sub.s %[tmp1], %[tmp1], %[tmp3] \n\t" // tmp1 = tmp1 - tmp3;
yading@10 302 "add.s %[tmp6], %[tmp2], %[tmp4] \n\t" // tmp6 = tmp2 + tmp4;
yading@10 303 "sub.s %[tmp2], %[tmp2], %[tmp4] \n\t" // tmp2 = tmp2 - tmp4;
yading@10 304 "sub.s %[temp1], %[temp], %[tmp5] \n\t"
yading@10 305 "add.s %[temp], %[temp], %[tmp5] \n\t"
yading@10 306 "sub.s %[pom1], %[pom], %[tmp6] \n\t"
yading@10 307 "add.s %[pom], %[pom], %[tmp6] \n\t"
yading@10 308 "lwc1 %[temp3], 0(%[tmpz_n4_i]) \n\t"
yading@10 309 "lwc1 %[pom2], 4(%[tmpz_n4_i]) \n\t"
yading@10 310 "swc1 %[temp1], 0(%[tmpz_n2_i]) \n\t" // tmpz[ n2+i].re = tmpz[ i].re - tmp5;
yading@10 311 "swc1 %[temp], 0(%[tmpz_i]) \n\t" // tmpz[ i].re = tmpz[ i].re + tmp5;
yading@10 312 "swc1 %[pom1], 4(%[tmpz_n2_i]) \n\t" // tmpz[ n2+i].im = tmpz[ i].im - tmp6;
yading@10 313 "swc1 %[pom] , 4(%[tmpz_i]) \n\t" // tmpz[ i].im = tmpz[ i].im + tmp6;
yading@10 314 "sub.s %[temp4], %[temp3], %[tmp2] \n\t"
yading@10 315 "add.s %[pom3], %[pom2], %[tmp1] \n\t"
yading@10 316 "add.s %[temp3], %[temp3], %[tmp2] \n\t"
yading@10 317 "sub.s %[pom2], %[pom2], %[tmp1] \n\t"
yading@10 318 "swc1 %[temp4], 0(%[tmpz_n34_i]) \n\t" // tmpz[n34+i].re = tmpz[n4+i].re - tmp2;
yading@10 319 "swc1 %[pom3], 4(%[tmpz_n34_i]) \n\t" // tmpz[n34+i].im = tmpz[n4+i].im + tmp1;
yading@10 320 "swc1 %[temp3], 0(%[tmpz_n4_i]) \n\t" // tmpz[ n4+i].re = tmpz[n4+i].re + tmp2;
yading@10 321 "swc1 %[pom2], 4(%[tmpz_n4_i]) \n\t" // tmpz[ n4+i].im = tmpz[n4+i].im - tmp1;
yading@10 322 : [tmp1]"=&f"(tmp1), [tmp2]"=&f" (tmp2), [temp]"=&f"(temp), [tmp3]"=&f"(tmp3),
yading@10 323 [tmp4]"=&f"(tmp4), [tmp5]"=&f"(tmp5), [tmp6]"=&f"(tmp6),
yading@10 324 [temp1]"=&f"(temp1), [temp3]"=&f"(temp3), [temp4]"=&f"(temp4),
yading@10 325 [pom]"=&f"(pom), [pom1]"=&f"(pom1), [pom2]"=&f"(pom2), [pom3]"=&f"(pom3)
yading@10 326 : [w_re]"f"(w_re), [w_im]"f"(w_im),
yading@10 327 [tmpz_i]"r"(tmpz_i),[tmpz_n2_i]"r"(tmpz_n2_i),
yading@10 328 [tmpz_n34_i]"r"(tmpz_n34_i), [tmpz_n4_i]"r"(tmpz_n4_i)
yading@10 329 : "memory"
yading@10 330 );
yading@10 331 w_re_ptr += step;
yading@10 332 w_im_ptr -= step;
yading@10 333 }
yading@10 334 }
yading@10 335 step >>= 1;
yading@10 336 n4 <<= 1;
yading@10 337 }
yading@10 338 }
yading@10 339
yading@10 340 /**
yading@10 341 * MDCT/IMDCT transforms.
yading@10 342 */
yading@10 343
yading@10 344 static void ff_imdct_half_mips(FFTContext *s, FFTSample *output, const FFTSample *input)
yading@10 345 {
yading@10 346 int k, n8, n4, n2, n, j;
yading@10 347 const uint16_t *revtab = s->revtab;
yading@10 348 const FFTSample *tcos = s->tcos;
yading@10 349 const FFTSample *tsin = s->tsin;
yading@10 350 const FFTSample *in1, *in2, *in3, *in4;
yading@10 351 FFTComplex *z = (FFTComplex *)output;
yading@10 352
yading@10 353 int j1;
yading@10 354 const float *tcos1, *tsin1, *tcos2, *tsin2;
yading@10 355 float temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8,
yading@10 356 temp9, temp10, temp11, temp12, temp13, temp14, temp15, temp16;
yading@10 357 FFTComplex *z1, *z2;
yading@10 358
yading@10 359 n = 1 << s->mdct_bits;
yading@10 360 n2 = n >> 1;
yading@10 361 n4 = n >> 2;
yading@10 362 n8 = n >> 3;
yading@10 363
yading@10 364 /* pre rotation */
yading@10 365 in1 = input;
yading@10 366 in2 = input + n2 - 1;
yading@10 367 in3 = input + 2;
yading@10 368 in4 = input + n2 - 3;
yading@10 369
yading@10 370 tcos1 = tcos;
yading@10 371 tsin1 = tsin;
yading@10 372
yading@10 373 /* n4 = 64 or 128 */
yading@10 374 for(k = 0; k < n4; k += 2) {
yading@10 375 j = revtab[k ];
yading@10 376 j1 = revtab[k + 1];
yading@10 377
yading@10 378 __asm__ volatile (
yading@10 379 "lwc1 %[temp1], 0(%[in2]) \t\n"
yading@10 380 "lwc1 %[temp2], 0(%[tcos1]) \t\n"
yading@10 381 "lwc1 %[temp3], 0(%[tsin1]) \t\n"
yading@10 382 "lwc1 %[temp4], 0(%[in1]) \t\n"
yading@10 383 "lwc1 %[temp5], 0(%[in4]) \t\n"
yading@10 384 "mul.s %[temp9], %[temp1], %[temp2] \t\n"
yading@10 385 "mul.s %[temp10], %[temp1], %[temp3] \t\n"
yading@10 386 "lwc1 %[temp6], 4(%[tcos1]) \t\n"
yading@10 387 "lwc1 %[temp7], 4(%[tsin1]) \t\n"
yading@10 388 "nmsub.s %[temp9], %[temp9], %[temp4], %[temp3] \t\n"
yading@10 389 "madd.s %[temp10], %[temp10], %[temp4], %[temp2] \t\n"
yading@10 390 "mul.s %[temp11], %[temp5], %[temp6] \t\n"
yading@10 391 "mul.s %[temp12], %[temp5], %[temp7] \t\n"
yading@10 392 "lwc1 %[temp8], 0(%[in3]) \t\n"
yading@10 393 "addiu %[tcos1], %[tcos1], 8 \t\n"
yading@10 394 "addiu %[tsin1], %[tsin1], 8 \t\n"
yading@10 395 "addiu %[in1], %[in1], 16 \t\n"
yading@10 396 "nmsub.s %[temp11], %[temp11], %[temp8], %[temp7] \t\n"
yading@10 397 "madd.s %[temp12], %[temp12], %[temp8], %[temp6] \t\n"
yading@10 398 "addiu %[in2], %[in2], -16 \t\n"
yading@10 399 "addiu %[in3], %[in3], 16 \t\n"
yading@10 400 "addiu %[in4], %[in4], -16 \t\n"
yading@10 401
yading@10 402 : [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
yading@10 403 [temp3]"=&f"(temp3), [temp4]"=&f"(temp4),
yading@10 404 [temp5]"=&f"(temp5), [temp6]"=&f"(temp6),
yading@10 405 [temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
yading@10 406 [temp9]"=&f"(temp9), [temp10]"=&f"(temp10),
yading@10 407 [temp11]"=&f"(temp11), [temp12]"=&f"(temp12),
yading@10 408 [tsin1]"+r"(tsin1), [tcos1]"+r"(tcos1),
yading@10 409 [in1]"+r"(in1), [in2]"+r"(in2),
yading@10 410 [in3]"+r"(in3), [in4]"+r"(in4)
yading@10 411 :
yading@10 412 : "memory"
yading@10 413 );
yading@10 414
yading@10 415 z[j ].re = temp9;
yading@10 416 z[j ].im = temp10;
yading@10 417 z[j1].re = temp11;
yading@10 418 z[j1].im = temp12;
yading@10 419 }
yading@10 420
yading@10 421 s->fft_calc(s, z);
yading@10 422
yading@10 423 /* post rotation + reordering */
yading@10 424 /* n8 = 32 or 64 */
yading@10 425 for(k = 0; k < n8; k += 2) {
yading@10 426 tcos1 = &tcos[n8 - k - 2];
yading@10 427 tsin1 = &tsin[n8 - k - 2];
yading@10 428 tcos2 = &tcos[n8 + k];
yading@10 429 tsin2 = &tsin[n8 + k];
yading@10 430 z1 = &z[n8 - k - 2];
yading@10 431 z2 = &z[n8 + k ];
yading@10 432
yading@10 433 __asm__ volatile (
yading@10 434 "lwc1 %[temp1], 12(%[z1]) \t\n"
yading@10 435 "lwc1 %[temp2], 4(%[tsin1]) \t\n"
yading@10 436 "lwc1 %[temp3], 4(%[tcos1]) \t\n"
yading@10 437 "lwc1 %[temp4], 8(%[z1]) \t\n"
yading@10 438 "lwc1 %[temp5], 4(%[z1]) \t\n"
yading@10 439 "mul.s %[temp9], %[temp1], %[temp2] \t\n"
yading@10 440 "mul.s %[temp10], %[temp1], %[temp3] \t\n"
yading@10 441 "lwc1 %[temp6], 0(%[tsin1]) \t\n"
yading@10 442 "lwc1 %[temp7], 0(%[tcos1]) \t\n"
yading@10 443 "nmsub.s %[temp9], %[temp9], %[temp4], %[temp3] \t\n"
yading@10 444 "madd.s %[temp10], %[temp10], %[temp4], %[temp2] \t\n"
yading@10 445 "mul.s %[temp11], %[temp5], %[temp6] \t\n"
yading@10 446 "mul.s %[temp12], %[temp5], %[temp7] \t\n"
yading@10 447 "lwc1 %[temp8], 0(%[z1]) \t\n"
yading@10 448 "lwc1 %[temp1], 4(%[z2]) \t\n"
yading@10 449 "lwc1 %[temp2], 0(%[tsin2]) \t\n"
yading@10 450 "lwc1 %[temp3], 0(%[tcos2]) \t\n"
yading@10 451 "nmsub.s %[temp11], %[temp11], %[temp8], %[temp7] \t\n"
yading@10 452 "madd.s %[temp12], %[temp12], %[temp8], %[temp6] \t\n"
yading@10 453 "mul.s %[temp13], %[temp1], %[temp2] \t\n"
yading@10 454 "mul.s %[temp14], %[temp1], %[temp3] \t\n"
yading@10 455 "lwc1 %[temp4], 0(%[z2]) \t\n"
yading@10 456 "lwc1 %[temp5], 12(%[z2]) \t\n"
yading@10 457 "lwc1 %[temp6], 4(%[tsin2]) \t\n"
yading@10 458 "lwc1 %[temp7], 4(%[tcos2]) \t\n"
yading@10 459 "nmsub.s %[temp13], %[temp13], %[temp4], %[temp3] \t\n"
yading@10 460 "madd.s %[temp14], %[temp14], %[temp4], %[temp2] \t\n"
yading@10 461 "mul.s %[temp15], %[temp5], %[temp6] \t\n"
yading@10 462 "mul.s %[temp16], %[temp5], %[temp7] \t\n"
yading@10 463 "lwc1 %[temp8], 8(%[z2]) \t\n"
yading@10 464 "nmsub.s %[temp15], %[temp15], %[temp8], %[temp7] \t\n"
yading@10 465 "madd.s %[temp16], %[temp16], %[temp8], %[temp6] \t\n"
yading@10 466 : [temp1]"=&f"(temp1), [temp2]"=&f"(temp2),
yading@10 467 [temp3]"=&f"(temp3), [temp4]"=&f"(temp4),
yading@10 468 [temp5]"=&f"(temp5), [temp6]"=&f"(temp6),
yading@10 469 [temp7]"=&f"(temp7), [temp8]"=&f"(temp8),
yading@10 470 [temp9]"=&f"(temp9), [temp10]"=&f"(temp10),
yading@10 471 [temp11]"=&f"(temp11), [temp12]"=&f"(temp12),
yading@10 472 [temp13]"=&f"(temp13), [temp14]"=&f"(temp14),
yading@10 473 [temp15]"=&f"(temp15), [temp16]"=&f"(temp16)
yading@10 474 : [z1]"r"(z1), [z2]"r"(z2),
yading@10 475 [tsin1]"r"(tsin1), [tcos1]"r"(tcos1),
yading@10 476 [tsin2]"r"(tsin2), [tcos2]"r"(tcos2)
yading@10 477 : "memory"
yading@10 478 );
yading@10 479
yading@10 480 z1[1].re = temp9;
yading@10 481 z1[1].im = temp14;
yading@10 482 z2[0].re = temp13;
yading@10 483 z2[0].im = temp10;
yading@10 484
yading@10 485 z1[0].re = temp11;
yading@10 486 z1[0].im = temp16;
yading@10 487 z2[1].re = temp15;
yading@10 488 z2[1].im = temp12;
yading@10 489 }
yading@10 490 }
yading@10 491
yading@10 492 /**
yading@10 493 * Compute inverse MDCT of size N = 2^nbits
yading@10 494 * @param output N samples
yading@10 495 * @param input N/2 samples
yading@10 496 */
yading@10 497 static void ff_imdct_calc_mips(FFTContext *s, FFTSample *output, const FFTSample *input)
yading@10 498 {
yading@10 499 int k;
yading@10 500 int n = 1 << s->mdct_bits;
yading@10 501 int n2 = n >> 1;
yading@10 502 int n4 = n >> 2;
yading@10 503
yading@10 504 ff_imdct_half_mips(s, output+n4, input);
yading@10 505
yading@10 506 for(k = 0; k < n4; k+=4) {
yading@10 507 output[k] = -output[n2-k-1];
yading@10 508 output[k+1] = -output[n2-k-2];
yading@10 509 output[k+2] = -output[n2-k-3];
yading@10 510 output[k+3] = -output[n2-k-4];
yading@10 511
yading@10 512 output[n-k-1] = output[n2+k];
yading@10 513 output[n-k-2] = output[n2+k+1];
yading@10 514 output[n-k-3] = output[n2+k+2];
yading@10 515 output[n-k-4] = output[n2+k+3];
yading@10 516 }
yading@10 517 }
yading@10 518 #endif /* HAVE_INLINE_ASM */
yading@10 519
yading@10 520 av_cold void ff_fft_init_mips(FFTContext *s)
yading@10 521 {
yading@10 522 int n=0;
yading@10 523
yading@10 524 ff_fft_lut_init(fft_offsets_lut, 0, 1 << 16, &n);
yading@10 525 ff_init_ff_cos_tabs(16);
yading@10 526
yading@10 527 #if HAVE_INLINE_ASM
yading@10 528 s->fft_calc = ff_fft_calc_mips;
yading@10 529 #if CONFIG_MDCT
yading@10 530 s->imdct_calc = ff_imdct_calc_mips;
yading@10 531 s->imdct_half = ff_imdct_half_mips;
yading@10 532 #endif
yading@10 533 #endif
yading@10 534 }