1 /* 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/modules/audio_coding/codecs/isac/fix/source/filterbank_internal.h" 12 13 // WebRtcIsacfix_AllpassFilter2FixDec16 function optimized for MIPSDSP platform 14 // Bit-exact with WebRtcIsacfix_AllpassFilter2FixDec16C from filterbanks.c 15 void WebRtcIsacfix_AllpassFilter2FixDec16MIPS( 16 int16_t *data_ch1, // Input and output in channel 1, in Q0 17 int16_t *data_ch2, // Input and output in channel 2, in Q0 18 const int16_t *factor_ch1, // Scaling factor for channel 1, in Q15 19 const int16_t *factor_ch2, // Scaling factor for channel 2, in Q15 20 const int length, // Length of the data buffers 21 int32_t *filter_state_ch1, // Filter state for channel 1, in Q16 22 int32_t *filter_state_ch2) { // Filter state for channel 2, in Q16 23 24 int32_t st0_ch1, st1_ch1; // channel1 state variables 25 int32_t st0_ch2, st1_ch2; // channel2 state variables 26 int32_t f_ch10, f_ch11, f_ch20, f_ch21; // factor variables 27 int32_t r0, r1, r2, r3, r4, r5; // temporary ragister variables 28 29 __asm __volatile ( 30 ".set push \n\t" 31 ".set noreorder \n\t" 32 // Load all the state and factor variables 33 "lh %[f_ch10], 0(%[factor_ch1]) \n\t" 34 "lh %[f_ch20], 0(%[factor_ch2]) \n\t" 35 "lh %[f_ch11], 2(%[factor_ch1]) \n\t" 36 "lh %[f_ch21], 2(%[factor_ch2]) \n\t" 37 "lw %[st0_ch1], 0(%[filter_state_ch1]) \n\t" 38 "lw %[st1_ch1], 4(%[filter_state_ch1]) \n\t" 39 "lw %[st0_ch2], 0(%[filter_state_ch2]) \n\t" 40 "lw %[st1_ch2], 4(%[filter_state_ch2]) \n\t" 41 // Allpass filtering loop 42 "1: \n\t" 43 "lh %[r0], 0(%[data_ch1]) \n\t" 44 "lh %[r1], 0(%[data_ch2]) \n\t" 45 "addiu %[length], %[length], -1 \n\t" 46 "mul %[r2], %[r0], %[f_ch10] \n\t" 47 "mul %[r3], %[r1], %[f_ch20] \n\t" 48 "sll %[r0], %[r0], 16 \n\t" 49 "sll %[r1], %[r1], 16 \n\t" 50 "sll %[r2], %[r2], 1 \n\t" 51 "addq_s.w %[r2], %[r2], %[st0_ch1] \n\t" 52 "sll %[r3], %[r3], 1 \n\t" 53 "addq_s.w %[r3], %[r3], %[st0_ch2] \n\t" 54 "sra %[r2], %[r2], 16 \n\t" 55 "mul %[st0_ch1], %[f_ch10], %[r2] \n\t" 56 "sra %[r3], %[r3], 16 \n\t" 57 "mul %[st0_ch2], %[f_ch20], %[r3] \n\t" 58 "mul %[r4], %[r2], %[f_ch11] \n\t" 59 "mul %[r5], %[r3], %[f_ch21] \n\t" 60 "sll %[st0_ch1], %[st0_ch1], 1 \n\t" 61 "subq_s.w %[st0_ch1], %[r0], %[st0_ch1] \n\t" 62 "sll %[st0_ch2], %[st0_ch2], 1 \n\t" 63 "subq_s.w %[st0_ch2], %[r1], %[st0_ch2] \n\t" 64 "sll %[r4], %[r4], 1 \n\t" 65 "addq_s.w %[r4], %[r4], %[st1_ch1] \n\t" 66 "sll %[r5], %[r5], 1 \n\t" 67 "addq_s.w %[r5], %[r5], %[st1_ch2] \n\t" 68 "sra %[r4], %[r4], 16 \n\t" 69 "mul %[r0], %[r4], %[f_ch11] \n\t" 70 "sra %[r5], %[r5], 16 \n\t" 71 "mul %[r1], %[r5], %[f_ch21] \n\t" 72 "sh %[r4], 0(%[data_ch1]) \n\t" 73 "sh %[r5], 0(%[data_ch2]) \n\t" 74 "addiu %[data_ch1], %[data_ch1], 2 \n\t" 75 "sll %[r2], %[r2], 16 \n\t" 76 "sll %[r0], %[r0], 1 \n\t" 77 "subq_s.w %[st1_ch1], %[r2], %[r0] \n\t" 78 "sll %[r3], %[r3], 16 \n\t" 79 "sll %[r1], %[r1], 1 \n\t" 80 "subq_s.w %[st1_ch2], %[r3], %[r1] \n\t" 81 "bgtz %[length], 1b \n\t" 82 " addiu %[data_ch2], %[data_ch2], 2 \n\t" 83 // Store channel states 84 "sw %[st0_ch1], 0(%[filter_state_ch1]) \n\t" 85 "sw %[st1_ch1], 4(%[filter_state_ch1]) \n\t" 86 "sw %[st0_ch2], 0(%[filter_state_ch2]) \n\t" 87 "sw %[st1_ch2], 4(%[filter_state_ch2]) \n\t" 88 ".set pop \n\t" 89 : [f_ch10] "=&r" (f_ch10), [f_ch20] "=&r" (f_ch20), 90 [f_ch11] "=&r" (f_ch11), [f_ch21] "=&r" (f_ch21), 91 [st0_ch1] "=&r" (st0_ch1), [st1_ch1] "=&r" (st1_ch1), 92 [st0_ch2] "=&r" (st0_ch2), [st1_ch2] "=&r" (st1_ch2), 93 [r0] "=&r" (r0), [r1] "=&r" (r1), [r2] "=&r" (r2), 94 [r3] "=&r" (r3), [r4] "=&r" (r4), [r5] "=&r" (r5) 95 : [factor_ch1] "r" (factor_ch1), [factor_ch2] "r" (factor_ch2), 96 [filter_state_ch1] "r" (filter_state_ch1), 97 [filter_state_ch2] "r" (filter_state_ch2), 98 [data_ch1] "r" (data_ch1), [data_ch2] "r" (data_ch2), 99 [length] "r" (length) 100 : "memory", "hi", "lo" 101 ); 102 } 103