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 /*! @} */