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