1 /*
2 * Copyright (c) 2013 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 // This header file includes the inline functions in
12 // the fix point signal processing library.
13
14 #ifndef COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_MIPS_H_
15 #define COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_MIPS_H_
16
WEBRTC_SPL_MUL_16_16(int32_t a,int32_t b)17 static __inline int32_t WEBRTC_SPL_MUL_16_16(int32_t a, int32_t b) {
18 int32_t value32 = 0;
19 int32_t a1 = 0, b1 = 0;
20
21 __asm __volatile(
22 #if defined(MIPS32_R2_LE)
23 "seh %[a1], %[a] \n\t"
24 "seh %[b1], %[b] \n\t"
25 #else
26 "sll %[a1], %[a], 16 \n\t"
27 "sll %[b1], %[b], 16 \n\t"
28 "sra %[a1], %[a1], 16 \n\t"
29 "sra %[b1], %[b1], 16 \n\t"
30 #endif
31 "mul %[value32], %[a1], %[b1] \n\t"
32 : [value32] "=r"(value32), [a1] "=&r"(a1), [b1] "=&r"(b1)
33 : [a] "r"(a), [b] "r"(b)
34 : "hi", "lo");
35 return value32;
36 }
37
WEBRTC_SPL_MUL_16_32_RSFT16(int16_t a,int32_t b)38 static __inline int32_t WEBRTC_SPL_MUL_16_32_RSFT16(int16_t a, int32_t b) {
39 int32_t value32 = 0, b1 = 0, b2 = 0;
40 int32_t a1 = 0;
41
42 __asm __volatile(
43 #if defined(MIPS32_R2_LE)
44 "seh %[a1], %[a] \n\t"
45 #else
46 "sll %[a1], %[a], 16 \n\t"
47 "sra %[a1], %[a1], 16 \n\t"
48 #endif
49 "andi %[b2], %[b], 0xFFFF \n\t"
50 "sra %[b1], %[b], 16 \n\t"
51 "sra %[b2], %[b2], 1 \n\t"
52 "mul %[value32], %[a1], %[b1] \n\t"
53 "mul %[b2], %[a1], %[b2] \n\t"
54 "addiu %[b2], %[b2], 0x4000 \n\t"
55 "sra %[b2], %[b2], 15 \n\t"
56 "addu %[value32], %[value32], %[b2] \n\t"
57 : [value32] "=&r"(value32), [b1] "=&r"(b1), [b2] "=&r"(b2), [a1] "=&r"(a1)
58 : [a] "r"(a), [b] "r"(b)
59 : "hi", "lo");
60 return value32;
61 }
62
63 #if defined(MIPS_DSP_R1_LE)
WebRtcSpl_SatW32ToW16(int32_t value32)64 static __inline int16_t WebRtcSpl_SatW32ToW16(int32_t value32) {
65 __asm __volatile(
66 "shll_s.w %[value32], %[value32], 16 \n\t"
67 "sra %[value32], %[value32], 16 \n\t"
68 : [value32] "+r"(value32)
69 :);
70 int16_t out16 = (int16_t)value32;
71 return out16;
72 }
73
WebRtcSpl_AddSatW16(int16_t a,int16_t b)74 static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) {
75 int32_t value32 = 0;
76
77 __asm __volatile("addq_s.ph %[value32], %[a], %[b] \n\t"
78 : [value32] "=r"(value32)
79 : [a] "r"(a), [b] "r"(b));
80 return (int16_t)value32;
81 }
82
WebRtcSpl_AddSatW32(int32_t l_var1,int32_t l_var2)83 static __inline int32_t WebRtcSpl_AddSatW32(int32_t l_var1, int32_t l_var2) {
84 int32_t l_sum;
85
86 __asm __volatile(
87 "addq_s.w %[l_sum], %[l_var1], %[l_var2] \n\t"
88 : [l_sum] "=r"(l_sum)
89 : [l_var1] "r"(l_var1), [l_var2] "r"(l_var2));
90
91 return l_sum;
92 }
93
WebRtcSpl_SubSatW16(int16_t var1,int16_t var2)94 static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) {
95 int32_t value32;
96
97 __asm __volatile("subq_s.ph %[value32], %[var1], %[var2] \n\t"
98 : [value32] "=r"(value32)
99 : [var1] "r"(var1), [var2] "r"(var2));
100
101 return (int16_t)value32;
102 }
103
WebRtcSpl_SubSatW32(int32_t l_var1,int32_t l_var2)104 static __inline int32_t WebRtcSpl_SubSatW32(int32_t l_var1, int32_t l_var2) {
105 int32_t l_diff;
106
107 __asm __volatile(
108 "subq_s.w %[l_diff], %[l_var1], %[l_var2] \n\t"
109 : [l_diff] "=r"(l_diff)
110 : [l_var1] "r"(l_var1), [l_var2] "r"(l_var2));
111
112 return l_diff;
113 }
114 #endif
115
WebRtcSpl_GetSizeInBits(uint32_t n)116 static __inline int16_t WebRtcSpl_GetSizeInBits(uint32_t n) {
117 int bits = 0;
118 int i32 = 32;
119
120 __asm __volatile(
121 "clz %[bits], %[n] \n\t"
122 "subu %[bits], %[i32], %[bits] \n\t"
123 : [bits] "=&r"(bits)
124 : [n] "r"(n), [i32] "r"(i32));
125
126 return (int16_t)bits;
127 }
128
WebRtcSpl_NormW32(int32_t a)129 static __inline int16_t WebRtcSpl_NormW32(int32_t a) {
130 int zeros = 0;
131
132 __asm __volatile(
133 ".set push \n\t"
134 ".set noreorder \n\t"
135 "bnez %[a], 1f \n\t"
136 " sra %[zeros], %[a], 31 \n\t"
137 "b 2f \n\t"
138 " move %[zeros], $zero \n\t"
139 "1: \n\t"
140 "xor %[zeros], %[a], %[zeros] \n\t"
141 "clz %[zeros], %[zeros] \n\t"
142 "addiu %[zeros], %[zeros], -1 \n\t"
143 "2: \n\t"
144 ".set pop \n\t"
145 : [zeros] "=&r"(zeros)
146 : [a] "r"(a));
147
148 return (int16_t)zeros;
149 }
150
WebRtcSpl_NormU32(uint32_t a)151 static __inline int16_t WebRtcSpl_NormU32(uint32_t a) {
152 int zeros = 0;
153
154 __asm __volatile("clz %[zeros], %[a] \n\t"
155 : [zeros] "=r"(zeros)
156 : [a] "r"(a));
157
158 return (int16_t)(zeros & 0x1f);
159 }
160
WebRtcSpl_NormW16(int16_t a)161 static __inline int16_t WebRtcSpl_NormW16(int16_t a) {
162 int zeros = 0;
163 int a0 = a << 16;
164
165 __asm __volatile(
166 ".set push \n\t"
167 ".set noreorder \n\t"
168 "bnez %[a0], 1f \n\t"
169 " sra %[zeros], %[a0], 31 \n\t"
170 "b 2f \n\t"
171 " move %[zeros], $zero \n\t"
172 "1: \n\t"
173 "xor %[zeros], %[a0], %[zeros] \n\t"
174 "clz %[zeros], %[zeros] \n\t"
175 "addiu %[zeros], %[zeros], -1 \n\t"
176 "2: \n\t"
177 ".set pop \n\t"
178 : [zeros] "=&r"(zeros)
179 : [a0] "r"(a0));
180
181 return (int16_t)zeros;
182 }
183
WebRtc_MulAccumW16(int16_t a,int16_t b,int32_t c)184 static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) {
185 int32_t res = 0, c1 = 0;
186 __asm __volatile(
187 #if defined(MIPS32_R2_LE)
188 "seh %[a], %[a] \n\t"
189 "seh %[b], %[b] \n\t"
190 #else
191 "sll %[a], %[a], 16 \n\t"
192 "sll %[b], %[b], 16 \n\t"
193 "sra %[a], %[a], 16 \n\t"
194 "sra %[b], %[b], 16 \n\t"
195 #endif
196 "mul %[res], %[a], %[b] \n\t"
197 "addu %[c1], %[c], %[res] \n\t"
198 : [c1] "=r"(c1), [res] "=&r"(res)
199 : [a] "r"(a), [b] "r"(b), [c] "r"(c)
200 : "hi", "lo");
201 return (c1);
202 }
203
204 #endif // COMMON_AUDIO_SIGNAL_PROCESSING_INCLUDE_SPL_INL_MIPS_H_
205