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 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 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 39template<typename T, typename U> 40struct is_same 41{ 42 static const bool value = false; 43}; 44 45template<typename T> 46struct is_same<T, T> // partial specialization 47{ 48 static const bool value = true; 49}; 50 51static inline 52int32_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 74static inline 75int32_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 89static inline 90int32_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 104static inline 105int32_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 119static inline 120int32_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 142static inline 143int32_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