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