blob: 7a60186e0de78959f1749935dddd3b9cdd086949 [file] [log] [blame]
Andy Hung86eae0e2013-12-09 12:12:46 -08001/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_AUDIO_RESAMPLER_FIR_OPS_H
18#define ANDROID_AUDIO_RESAMPLER_FIR_OPS_H
19
20namespace android {
21
22#if defined(__arm__) && !defined(__thumb__)
23#define USE_INLINE_ASSEMBLY (true)
24#else
25#define USE_INLINE_ASSEMBLY (false)
26#endif
27
Andy Hung6b667dd2015-02-06 15:05:37 -080028#if defined(__aarch64__) || defined(__ARM_NEON__)
Andy Hung86eae0e2013-12-09 12:12:46 -080029#define USE_NEON (true)
30#include <arm_neon.h>
31#else
32#define USE_NEON (false)
33#endif
34
Henrik Smiding841920d2016-02-15 16:20:45 +010035#if defined(__SSSE3__) // Should be supported in x86 ABI for both 32 & 64-bit.
36#define USE_SSE (true)
37#include <tmmintrin.h>
38#else
39#define USE_SSE (false)
40#endif
41
Andy Hung86eae0e2013-12-09 12:12:46 -080042template<typename T, typename U>
43struct is_same
44{
45 static const bool value = false;
46};
47
48template<typename T>
49struct is_same<T, T> // partial specialization
50{
51 static const bool value = true;
52};
53
54static inline
55int32_t mulRL(int left, int32_t in, uint32_t vRL)
56{
57#if USE_INLINE_ASSEMBLY
58 int32_t out;
59 if (left) {
60 asm( "smultb %[out], %[in], %[vRL] \n"
61 : [out]"=r"(out)
62 : [in]"%r"(in), [vRL]"r"(vRL)
63 : );
64 } else {
65 asm( "smultt %[out], %[in], %[vRL] \n"
66 : [out]"=r"(out)
67 : [in]"%r"(in), [vRL]"r"(vRL)
68 : );
69 }
70 return out;
71#else
72 int16_t v = left ? static_cast<int16_t>(vRL) : static_cast<int16_t>(vRL>>16);
73 return static_cast<int32_t>((static_cast<int64_t>(in) * v) >> 16);
74#endif
75}
76
77static inline
78int32_t mulAdd(int16_t in, int16_t v, int32_t a)
79{
80#if USE_INLINE_ASSEMBLY
81 int32_t out;
82 asm( "smlabb %[out], %[v], %[in], %[a] \n"
83 : [out]"=r"(out)
84 : [in]"%r"(in), [v]"r"(v), [a]"r"(a)
85 : );
86 return out;
87#else
88 return a + v * in;
89#endif
90}
91
92static inline
93int32_t mulAdd(int16_t in, int32_t v, int32_t a)
94{
95#if USE_INLINE_ASSEMBLY
96 int32_t out;
97 asm( "smlawb %[out], %[v], %[in], %[a] \n"
98 : [out]"=r"(out)
99 : [in]"%r"(in), [v]"r"(v), [a]"r"(a)
100 : );
101 return out;
102#else
103 return a + static_cast<int32_t>((static_cast<int64_t>(v) * in) >> 16);
104#endif
105}
106
107static inline
108int32_t mulAdd(int32_t in, int32_t v, int32_t a)
109{
110#if USE_INLINE_ASSEMBLY
111 int32_t out;
112 asm( "smmla %[out], %[v], %[in], %[a] \n"
113 : [out]"=r"(out)
114 : [in]"%r"(in), [v]"r"(v), [a]"r"(a)
115 : );
116 return out;
117#else
118 return a + static_cast<int32_t>((static_cast<int64_t>(v) * in) >> 32);
119#endif
120}
121
122static inline
123int32_t mulAddRL(int left, uint32_t inRL, int16_t v, int32_t a)
124{
125#if USE_INLINE_ASSEMBLY
126 int32_t out;
127 if (left) {
128 asm( "smlabb %[out], %[v], %[inRL], %[a] \n"
129 : [out]"=r"(out)
130 : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a)
131 : );
132 } else {
133 asm( "smlabt %[out], %[v], %[inRL], %[a] \n"
134 : [out]"=r"(out)
135 : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a)
136 : );
137 }
138 return out;
139#else
140 int16_t s = left ? static_cast<int16_t>(inRL) : static_cast<int16_t>(inRL>>16);
141 return a + v * s;
142#endif
143}
144
145static inline
146int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a)
147{
148#if USE_INLINE_ASSEMBLY
149 int32_t out;
150 if (left) {
151 asm( "smlawb %[out], %[v], %[inRL], %[a] \n"
152 : [out]"=r"(out)
153 : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a)
154 : );
155 } else {
156 asm( "smlawt %[out], %[v], %[inRL], %[a] \n"
157 : [out]"=r"(out)
158 : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a)
159 : );
160 }
161 return out;
162#else
163 int16_t s = left ? static_cast<int16_t>(inRL) : static_cast<int16_t>(inRL>>16);
164 return a + static_cast<int32_t>((static_cast<int64_t>(v) * s) >> 16);
165#endif
166}
167
Glenn Kasten63238ef2015-03-02 15:50:29 -0800168} // namespace android
Andy Hung86eae0e2013-12-09 12:12:46 -0800169
170#endif /*ANDROID_AUDIO_RESAMPLER_FIR_OPS_H*/