1 // -*- C++ -*- 2 /** @file */ 3 #pragma once 4 5 /** \addtogroup GenericNumber 6 * \ingroup NUMBER 7 * @{ 8 * \addtogroup GenericQ15Number Q15 9 * \ingroup GenericNumber 10 * @{ 11 */ 12 13 /** 14 * @brief Q15 features 15 */ 16 template<> 17 struct number_traits<Q15> 18 { 19 //! Is not float 20 static constexpr bool is_float = false; 21 //! Is fixed point 22 static constexpr bool is_fixed = true; 23 //! Accumulator datatype 24 typedef Q<33,30> accumulator; 25 /** 26 * @brief One value 27 * 28 * @return One value in Q15 29 */ onenumber_traits30 static constexpr Q15 one() {return Q15::one();}; 31 //! Compute type 32 typedef Q15 compute_type; 33 }; 34 35 /** 36 * @brief Vector features for Q15 when no vector architecture 37 * 38 * @tparam arch Current architecture 39 */ 40 template<typename arch> 41 struct vector_traits<Q15,arch, 42 typename std::enable_if<!std::is_base_of<Helium,arch>::value && 43 !std::is_base_of<Neon,arch>::value && 44 !std::is_base_of<DSP,arch>::value>::type> { 45 //! Compute type 46 typedef Q15 type; 47 48 //! Storage datatype (int16_t) 49 typedef type::value_type storage_type; 50 51 // No vector type but must still be defined 52 //! Dummy type when no vector instructions 53 typedef bool vector; 54 //! Dummy type when no vector instructions 55 typedef bool temp_accumulator; 56 //! Dummy type when no vector instructions 57 typedef uint32_t predicate_t; 58 59 60 //! Has no vector instructions 61 static constexpr bool has_vector = false; 62 //! Is not float 63 static constexpr bool is_float = false; 64 //! Is fixed point 65 static constexpr bool is_fixed = true; 66 //! Has no predicated loop 67 static constexpr bool has_predicate = false; 68 69 }; 70 71 /** 72 * Inner implementation of generic intrinsics 73 * \ingroup GenericNumber 74 */ 75 namespace inner { 76 #if defined(ARM_MATH_MVEI) 77 /** 78 * @brief Convert from accumulator type 79 * 80 * @param[in] a The accumulator value 81 * 82 * @return The converted value (with saturation) 83 */ from_accumulator(const Q<33,30> a)84 __STATIC_FORCEINLINE Q15 from_accumulator(const Q<33,30> a) 85 { 86 //return(saturate(toFrac<15>(a))); 87 return(Q15((sqrshrl_sat48(a.v, -(32-15)) >> 32) & 0xffffffff)); 88 }; 89 #else 90 /** 91 * @brief Convert from accumulator type 92 * 93 * @param[in] a The accumulator value 94 * 95 * @return The converted value (with saturation) 96 */ 97 __STATIC_FORCEINLINE Q15 from_accumulator(const Q<33,30> a) 98 { 99 return(saturate(toFrac<15>(a))); 100 }; 101 #endif 102 103 /** 104 * @brief Multiply and accumulate 105 * 106 * @param[in] acc Accumulator 107 * @param[in] a First operand 108 * @param[in] b Second operand 109 * 110 * @return acc + a*b 111 */ mac(const Q<33,30> acc,const Q15 a,const Q15 b)112 __STATIC_FORCEINLINE Q<33,30> mac(const Q<33,30> acc,const Q15 a,const Q15 b) 113 { 114 return(accumulate(acc , mult(a,b))); 115 }; 116 } 117 118 /*! @} */ 119 /*! @} */