cannam@154
|
1 /* Copyright (C) 2007-2009 Xiph.Org Foundation
|
cannam@154
|
2 Copyright (C) 2003-2008 Jean-Marc Valin
|
cannam@154
|
3 Copyright (C) 2007-2008 CSIRO
|
cannam@154
|
4 Copyright (C) 2013 Parrot */
|
cannam@154
|
5 /*
|
cannam@154
|
6 Redistribution and use in source and binary forms, with or without
|
cannam@154
|
7 modification, are permitted provided that the following conditions
|
cannam@154
|
8 are met:
|
cannam@154
|
9
|
cannam@154
|
10 - Redistributions of source code must retain the above copyright
|
cannam@154
|
11 notice, this list of conditions and the following disclaimer.
|
cannam@154
|
12
|
cannam@154
|
13 - Redistributions in binary form must reproduce the above copyright
|
cannam@154
|
14 notice, this list of conditions and the following disclaimer in the
|
cannam@154
|
15 documentation and/or other materials provided with the distribution.
|
cannam@154
|
16
|
cannam@154
|
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
cannam@154
|
18 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
cannam@154
|
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
cannam@154
|
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
cannam@154
|
21 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
cannam@154
|
22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
cannam@154
|
23 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
cannam@154
|
24 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
cannam@154
|
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
cannam@154
|
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
cannam@154
|
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
cannam@154
|
28 */
|
cannam@154
|
29
|
cannam@154
|
30 #ifndef FIXED_ARMv5E_H
|
cannam@154
|
31 #define FIXED_ARMv5E_H
|
cannam@154
|
32
|
cannam@154
|
33 #include "fixed_armv4.h"
|
cannam@154
|
34
|
cannam@154
|
35 /** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
|
cannam@154
|
36 #undef MULT16_32_Q16
|
cannam@154
|
37 static OPUS_INLINE opus_val32 MULT16_32_Q16_armv5e(opus_val16 a, opus_val32 b)
|
cannam@154
|
38 {
|
cannam@154
|
39 int res;
|
cannam@154
|
40 __asm__(
|
cannam@154
|
41 "#MULT16_32_Q16\n\t"
|
cannam@154
|
42 "smulwb %0, %1, %2\n\t"
|
cannam@154
|
43 : "=r"(res)
|
cannam@154
|
44 : "r"(b),"r"(a)
|
cannam@154
|
45 );
|
cannam@154
|
46 return res;
|
cannam@154
|
47 }
|
cannam@154
|
48 #define MULT16_32_Q16(a, b) (MULT16_32_Q16_armv5e(a, b))
|
cannam@154
|
49
|
cannam@154
|
50
|
cannam@154
|
51 /** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */
|
cannam@154
|
52 #undef MULT16_32_Q15
|
cannam@154
|
53 static OPUS_INLINE opus_val32 MULT16_32_Q15_armv5e(opus_val16 a, opus_val32 b)
|
cannam@154
|
54 {
|
cannam@154
|
55 int res;
|
cannam@154
|
56 __asm__(
|
cannam@154
|
57 "#MULT16_32_Q15\n\t"
|
cannam@154
|
58 "smulwb %0, %1, %2\n\t"
|
cannam@154
|
59 : "=r"(res)
|
cannam@154
|
60 : "r"(b), "r"(a)
|
cannam@154
|
61 );
|
cannam@154
|
62 return SHL32(res,1);
|
cannam@154
|
63 }
|
cannam@154
|
64 #define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv5e(a, b))
|
cannam@154
|
65
|
cannam@154
|
66
|
cannam@154
|
67 /** 16x32 multiply, followed by a 15-bit shift right and 32-bit add.
|
cannam@154
|
68 b must fit in 31 bits.
|
cannam@154
|
69 Result fits in 32 bits. */
|
cannam@154
|
70 #undef MAC16_32_Q15
|
cannam@154
|
71 static OPUS_INLINE opus_val32 MAC16_32_Q15_armv5e(opus_val32 c, opus_val16 a,
|
cannam@154
|
72 opus_val32 b)
|
cannam@154
|
73 {
|
cannam@154
|
74 int res;
|
cannam@154
|
75 __asm__(
|
cannam@154
|
76 "#MAC16_32_Q15\n\t"
|
cannam@154
|
77 "smlawb %0, %1, %2, %3;\n"
|
cannam@154
|
78 : "=r"(res)
|
cannam@154
|
79 : "r"(SHL32(b,1)), "r"(a), "r"(c)
|
cannam@154
|
80 );
|
cannam@154
|
81 return res;
|
cannam@154
|
82 }
|
cannam@154
|
83 #define MAC16_32_Q15(c, a, b) (MAC16_32_Q15_armv5e(c, a, b))
|
cannam@154
|
84
|
cannam@154
|
85 /** 16x32 multiply, followed by a 16-bit shift right and 32-bit add.
|
cannam@154
|
86 Result fits in 32 bits. */
|
cannam@154
|
87 #undef MAC16_32_Q16
|
cannam@154
|
88 static OPUS_INLINE opus_val32 MAC16_32_Q16_armv5e(opus_val32 c, opus_val16 a,
|
cannam@154
|
89 opus_val32 b)
|
cannam@154
|
90 {
|
cannam@154
|
91 int res;
|
cannam@154
|
92 __asm__(
|
cannam@154
|
93 "#MAC16_32_Q16\n\t"
|
cannam@154
|
94 "smlawb %0, %1, %2, %3;\n"
|
cannam@154
|
95 : "=r"(res)
|
cannam@154
|
96 : "r"(b), "r"(a), "r"(c)
|
cannam@154
|
97 );
|
cannam@154
|
98 return res;
|
cannam@154
|
99 }
|
cannam@154
|
100 #define MAC16_32_Q16(c, a, b) (MAC16_32_Q16_armv5e(c, a, b))
|
cannam@154
|
101
|
cannam@154
|
102 /** 16x16 multiply-add where the result fits in 32 bits */
|
cannam@154
|
103 #undef MAC16_16
|
cannam@154
|
104 static OPUS_INLINE opus_val32 MAC16_16_armv5e(opus_val32 c, opus_val16 a,
|
cannam@154
|
105 opus_val16 b)
|
cannam@154
|
106 {
|
cannam@154
|
107 int res;
|
cannam@154
|
108 __asm__(
|
cannam@154
|
109 "#MAC16_16\n\t"
|
cannam@154
|
110 "smlabb %0, %1, %2, %3;\n"
|
cannam@154
|
111 : "=r"(res)
|
cannam@154
|
112 : "r"(a), "r"(b), "r"(c)
|
cannam@154
|
113 );
|
cannam@154
|
114 return res;
|
cannam@154
|
115 }
|
cannam@154
|
116 #define MAC16_16(c, a, b) (MAC16_16_armv5e(c, a, b))
|
cannam@154
|
117
|
cannam@154
|
118 /** 16x16 multiplication where the result fits in 32 bits */
|
cannam@154
|
119 #undef MULT16_16
|
cannam@154
|
120 static OPUS_INLINE opus_val32 MULT16_16_armv5e(opus_val16 a, opus_val16 b)
|
cannam@154
|
121 {
|
cannam@154
|
122 int res;
|
cannam@154
|
123 __asm__(
|
cannam@154
|
124 "#MULT16_16\n\t"
|
cannam@154
|
125 "smulbb %0, %1, %2;\n"
|
cannam@154
|
126 : "=r"(res)
|
cannam@154
|
127 : "r"(a), "r"(b)
|
cannam@154
|
128 );
|
cannam@154
|
129 return res;
|
cannam@154
|
130 }
|
cannam@154
|
131 #define MULT16_16(a, b) (MULT16_16_armv5e(a, b))
|
cannam@154
|
132
|
cannam@154
|
133 #ifdef OPUS_ARM_INLINE_MEDIA
|
cannam@154
|
134
|
cannam@154
|
135 #undef SIG2WORD16
|
cannam@154
|
136 static OPUS_INLINE opus_val16 SIG2WORD16_armv6(opus_val32 x)
|
cannam@154
|
137 {
|
cannam@154
|
138 celt_sig res;
|
cannam@154
|
139 __asm__(
|
cannam@154
|
140 "#SIG2WORD16\n\t"
|
cannam@154
|
141 "ssat %0, #16, %1, ASR #12\n\t"
|
cannam@154
|
142 : "=r"(res)
|
cannam@154
|
143 : "r"(x+2048)
|
cannam@154
|
144 );
|
cannam@154
|
145 return EXTRACT16(res);
|
cannam@154
|
146 }
|
cannam@154
|
147 #define SIG2WORD16(x) (SIG2WORD16_armv6(x))
|
cannam@154
|
148
|
cannam@154
|
149 #endif /* OPUS_ARM_INLINE_MEDIA */
|
cannam@154
|
150
|
cannam@154
|
151 #endif
|