1 /* 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 20 namespace 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 28 #if defined(__aarch64__) || defined(__ARM_NEON__) 29 #ifndef USE_NEON 30 #define USE_NEON (true) 31 #endif 32 #else 33 #define USE_NEON (false) 34 #endif 35 #if USE_NEON 36 #include <arm_neon.h> 37 #endif 38 39 template<typename T, typename U> 40 struct is_same 41 { 42 static const bool value = false; 43 }; 44 45 template<typename T> 46 struct is_same<T, T> // partial specialization 47 { 48 static const bool value = true; 49 }; 50 51 static inline 52 int32_t mulRL(int left, int32_t in, uint32_t vRL) 53 { 54 #if USE_INLINE_ASSEMBLY 55 int32_t out; 56 if (left) { 57 asm( "smultb %[out], %[in], %[vRL] \n" 58 : [out]"=r"(out) 59 : [in]"%r"(in), [vRL]"r"(vRL) 60 : ); 61 } else { 62 asm( "smultt %[out], %[in], %[vRL] \n" 63 : [out]"=r"(out) 64 : [in]"%r"(in), [vRL]"r"(vRL) 65 : ); 66 } 67 return out; 68 #else 69 int16_t v = left ? static_cast<int16_t>(vRL) : static_cast<int16_t>(vRL>>16); 70 return static_cast<int32_t>((static_cast<int64_t>(in) * v) >> 16); 71 #endif 72 } 73 74 static inline 75 int32_t mulAdd(int16_t in, int16_t v, int32_t a) 76 { 77 #if USE_INLINE_ASSEMBLY 78 int32_t out; 79 asm( "smlabb %[out], %[v], %[in], %[a] \n" 80 : [out]"=r"(out) 81 : [in]"%r"(in), [v]"r"(v), [a]"r"(a) 82 : ); 83 return out; 84 #else 85 return a + v * in; 86 #endif 87 } 88 89 static inline 90 int32_t mulAdd(int16_t in, int32_t v, int32_t a) 91 { 92 #if USE_INLINE_ASSEMBLY 93 int32_t out; 94 asm( "smlawb %[out], %[v], %[in], %[a] \n" 95 : [out]"=r"(out) 96 : [in]"%r"(in), [v]"r"(v), [a]"r"(a) 97 : ); 98 return out; 99 #else 100 return a + static_cast<int32_t>((static_cast<int64_t>(v) * in) >> 16); 101 #endif 102 } 103 104 static inline 105 int32_t mulAdd(int32_t in, int32_t v, int32_t a) 106 { 107 #if USE_INLINE_ASSEMBLY 108 int32_t out; 109 asm( "smmla %[out], %[v], %[in], %[a] \n" 110 : [out]"=r"(out) 111 : [in]"%r"(in), [v]"r"(v), [a]"r"(a) 112 : ); 113 return out; 114 #else 115 return a + static_cast<int32_t>((static_cast<int64_t>(v) * in) >> 32); 116 #endif 117 } 118 119 static inline 120 int32_t mulAddRL(int left, uint32_t inRL, int16_t v, int32_t a) 121 { 122 #if USE_INLINE_ASSEMBLY 123 int32_t out; 124 if (left) { 125 asm( "smlabb %[out], %[v], %[inRL], %[a] \n" 126 : [out]"=r"(out) 127 : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a) 128 : ); 129 } else { 130 asm( "smlabt %[out], %[v], %[inRL], %[a] \n" 131 : [out]"=r"(out) 132 : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a) 133 : ); 134 } 135 return out; 136 #else 137 int16_t s = left ? static_cast<int16_t>(inRL) : static_cast<int16_t>(inRL>>16); 138 return a + v * s; 139 #endif 140 } 141 142 static inline 143 int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a) 144 { 145 #if USE_INLINE_ASSEMBLY 146 int32_t out; 147 if (left) { 148 asm( "smlawb %[out], %[v], %[inRL], %[a] \n" 149 : [out]"=r"(out) 150 : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a) 151 : ); 152 } else { 153 asm( "smlawt %[out], %[v], %[inRL], %[a] \n" 154 : [out]"=r"(out) 155 : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a) 156 : ); 157 } 158 return out; 159 #else 160 int16_t s = left ? static_cast<int16_t>(inRL) : static_cast<int16_t>(inRL>>16); 161 return a + static_cast<int32_t>((static_cast<int64_t>(v) * s) >> 16); 162 #endif 163 } 164 165 } // namespace android 166 167 #endif /*ANDROID_AUDIO_RESAMPLER_FIR_OPS_H*/ 168