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