1 /*
2  * Copyright (c) 2011-2019 Belledonne Communications SARL.
3  *
4  * This file is part of bcg729.
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  */
19 #ifndef FIXEDPOINTMACROS_H
20 #define FIXEDPOINTMACROS_H
21 
22 #define EXTEND32(x) ((word32_t)(x))
23 #define NEG16(x) (-(x))
24 #define NEG32(x) (-(x))
25 #define NEG64(x) (-(x))
26 
27 /*** shifts ***/
28 #define SHR(a,shift) ((a) >> (shift))
29 #define SHL(a,shift) ((word32_t)(a) << (shift))
30 /* Signed shift left, C standard claims shifting left a negative value lead to undetermined status,
31  * recent compiler shall not have any problem, but just in case, shift a positive value and back */
32 #define SSHL(a,shift) ((a < 0)?(NEG32((word32_t)(NEG32(a)) << (shift))):((word32_t)(a) << (shift)))
33 #define USHL(a,shift) ((uword32_t)(a) << (shift))
34 /* shift right with rounding: used to extract the integer value of a Qa number */
35 #define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift))
36 /* shift right with checking on sign of shift value */
37 #define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
38 #define SVSHR32(a, shift) (((shift)>0) ? SHR32((word32_t)(a), shift) : SSHL((word32_t)(a), -(shift)))
39 #define SHR16(a,shift) ((a) >> (shift))
40 #define SHL16(a,shift) ((a) << (shift))
41 #define SHR32(a,shift) ((a) >> (shift))
42 #define SHL32(a,shift) ((a) << (shift))
43 #define SHR64(a,shift) ((a) >> (shift))
44 #define SHL64(a,shift) ((a) << (shift))
45 #define SSHL64(a,shift) ((a < 0)?(NEG64((word64_t)(NEG64(a)) << (shift))):((word64_t)(a) << (shift)))
46 
47 /* avoid overflows: a+1 is used to check on negative value because range of a 2n signed bits int is -2pow(n) - 2pow(n)-1 */
48 /* SATURATE Macro shall be called with MAXINT(nbits). Ex: SATURATE(x,MAXINT16) with MAXINT16  defined to 2pow(16) - 1 */
49 #define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a+1) ? -(a+1) : (x)))
50 /* same but for unsigned values only */
51 #define USATURATE(x,a) ((x)>(a) ? (a) : (x))
52 
53 /* absolute value */
54 #define ABS(a) (((a)>0) ? (a) : -(a))
55 
56 /*** add and sub ***/
57 #define ADD16(a,b) ((word16_t)((word16_t)(a)+(word16_t)(b)))
58 #define SUB16(a,b) ((word16_t)(a)-(word16_t)(b))
59 #define ADD32(a,b) ((word32_t)(a)+(word32_t)(b))
60 #define UADD32(a,b) ((uword32_t)(a)+(uword32_t)(b))
61 #define SUB32(a,b) ((word32_t)(a)-(word32_t)(b))
62 
63 /*** Multiplications/Accumulations ***/
64 /* WARNING: MULT16_32_QX use MULT16_16 macro but the first multiplication must actually be a 16bits * 32bits with result on 32 bits and not a 16*16 */
65 /*  MULT16_16 is then implemented here as a 32*32 bits giving result on 32 bits */
66 #define MULT16_16(a,b)     ((word32_t)((word32_t)(a))*((word32_t)(b)))
67 #define MULT16_32(a,b)     ((word32_t)((word16_t)(a))*((word32_t)(b)))
68 #define UMULT16_16(a,b)     ((uword32_t)((word32_t)(a))*((word32_t)(b)))
69 #define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))
70 #define UMAC16_16(c,a,b) (UADD32((c),UMULT16_16((a),(b))))
71 #define MSU16_16(c,a,b) (SUB32((c),MULT16_16((a),(b))))
72 #define DIV32(a,b) (((word32_t)(a))/((word32_t)(b)))
73 #define UDIV32(a,b) (((uword32_t)(a))/((uword32_t)(b)))
74 
75 /* Q3 operations */
76 #define MULT16_16_Q3(a,b) (SHR(MULT16_16((a),(b)),3))
77 #define MULT16_32_Q3(a,b) ADD32(MULT16_16((a),SHR((b),3)), SHR(MULT16_16((a),((b)&0x00000007)),3))
78 #define MAC16_16_Q3(c,a,b) ADD32(c,MULT16_16_Q3(a,b))
79 
80 /* Q4 operations */
81 #define MULT16_16_Q4(a,b) (SHR(MULT16_16((a),(b)),4))
82 #define UMULT16_16_Q4(a,b) (SHR(UMULT16_16((a),(b)),4))
83 #define UMAC16_16_Q4(c,a,b) ADD32(c,UMULT16_16_Q4(a,b))
84 #define MAC16_16_Q4(c,a,b) ADD32(c,MULT16_16_Q4(a,b))
85 
86 /* Q11 operations */
87 #define MULT16_16_Q11(a,b) (SHR(MULT16_16((a),(b)),11))
88 #define MULT16_16_P11(a,b) (SHR(ADD32(1024,MULT16_16((a),(b))),11))
89 
90 /* Q12 operations */
91 #define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12))
92 #define MAC16_32_Q12(c,a,b) ADD32(c,MULT16_32_Q12(a,b))
93 #define MULT16_16_Q12(a,b) (SHR(MULT16_16((a),(b)),12))
94 #define MAC16_16_Q12(c,a,b) ADD32(c,MULT16_16_Q12(a,b))
95 #define MSU16_16_Q12(c,a,b) SUB32(c,MULT16_16_Q12(a,b))
96 
97 /* Q13 operations */
98 #define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13))
99 #define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13))
100 #define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13))
101 #define MAC16_16_Q13(c,a,b) ADD32(c,MULT16_16_Q13(a,b))
102 #define MAC16_32_Q13(c,a,b) ADD32(c,MULT16_32_Q13(a,b))
103 
104 /* Q14 operations */
105 #define MULT16_32_P14(a,b) ADD32(MULT16_16((a),SHR((b),14)), PSHR(MULT16_16((a),((b)&0x00003fff)),14))
106 #define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14))
107 #define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14))
108 #define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14))
109 #define MAC16_16_Q14(c,a,b) ADD32(c,MULT16_16_Q14(a,b))
110 #define MSU16_16_Q14(c,a,b) SUB32(c,MULT16_16_Q14(a,b))
111 #define MAC16_32_Q14(c,a,b) ADD32(c,MULT16_32_Q14(a,b))
112 
113 /* Q15 operations */
114 #define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15))
115 #define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15))
116 #define MULT16_32_P15(a,b) ADD32(MULT16_16((a),SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15))
117 #define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))
118 #define MAC16_32_P15(c,a,b) ADD32(c,MULT16_32_P15(a,b))
119 
120 /* 64 bits operations */
121 #define ADD64(a,b) ((word64_t)(a)+(word64_t)(b))
122 #define SUB64(a,b) ((word64_t)(a)-(word32_t)(b))
123 #define ADD64_32(a,b) ((word64_t)(a)+(word32_t)(b))
124 #define MULT32_32(a,b) ((word64_t)((word64_t)(a)*((word64_t)(b))))
125 #define DIV64(a,b) ((word64_t)(a)/(word64_t)(b))
126 #define MAC64(c,a,b) ((word64_t)c+(word64_t)((word64_t)a*(word64_t)b))
127 
128 /* Divisions: input numbers with similar scale(Q) output according to operation. Warning: Make use of 64 bits variables */
129 #define DIV32_32_Q24(a,b) (((word64_t)(a)<<24)/((word32_t)(b)))
130 #define DIV32_32_Q27(a,b) ((SSHL64((word64_t)(a),27))/((word32_t)(b)))
131 #define DIV32_32_Q31(a,b) ((SSHL64((word64_t)(a),31))/((word32_t)(b)))
132 
133 #define MULT32_32_Q23(a,b) ((word32_t)(SHR64(((word64_t)a*(word64_t)b),23)))
134 
135 #define MULT32_32_Q31(a,b) ((word32_t)(SHR64(((word64_t)a*(word64_t)b),31)))
136 #define MAC32_32_Q31(c,a,b) ADD32(c,MULT32_32_Q31(a,b))
137 
138 #endif /* ifndef FIXEDPOINTMACROS_H */
139