OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 17 matching lines...) Expand all Loading... | |
28 int16_t out16 = (int16_t) value32; | 28 int16_t out16 = (int16_t) value32; |
29 | 29 |
30 if (value32 > 32767) | 30 if (value32 > 32767) |
31 out16 = 32767; | 31 out16 = 32767; |
32 else if (value32 < -32768) | 32 else if (value32 < -32768) |
33 out16 = -32768; | 33 out16 = -32768; |
34 | 34 |
35 return out16; | 35 return out16; |
36 } | 36 } |
37 | 37 |
38 static __inline int32_t WebRtcSpl_AddSatW32(int32_t l_var1, int32_t l_var2) { | 38 static __inline int32_t WebRtcSpl_AddSatW32(int32_t a, int32_t b) { |
39 int32_t l_sum; | 39 // Do the addition in unsigned numbers, since signed overflow is UB. |
tlegrand-webrtc
2016/05/20 11:07:14
UB? Please write undefined behavior instead.
kwiberg-webrtc
2016/05/23 08:30:04
Done.
| |
40 const int32_t sum = (int32_t)((uint32_t)a + (uint32_t)b); | |
40 | 41 |
41 // Perform long addition | 42 // a + b can't overflow if a and b have different signs. If they have the |
42 l_sum = l_var1 + l_var2; | 43 // same sign, a + b also has the same sign iff it didn't overflow. |
43 | 44 if ((a < 0) == (b < 0) && (a < 0) != (sum < 0)) { |
44 if (l_var1 < 0) { // Check for underflow. | 45 // The direction of the overflow is obvious from the sign of a + b. |
45 if ((l_var2 < 0) && (l_sum >= 0)) { | 46 return sum < 0 ? INT32_MAX : INT32_MIN; |
tlegrand-webrtc
2016/05/20 11:07:14
Clever!
kwiberg-webrtc
2016/05/23 08:30:04
Acknowledged.
| |
46 l_sum = (int32_t)0x80000000; | |
47 } | |
48 } else { // Check for overflow. | |
49 if ((l_var2 > 0) && (l_sum < 0)) { | |
50 l_sum = (int32_t)0x7FFFFFFF; | |
51 } | |
52 } | 47 } |
53 | 48 return sum; |
54 return l_sum; | |
55 } | 49 } |
56 | 50 |
57 static __inline int32_t WebRtcSpl_SubSatW32(int32_t l_var1, int32_t l_var2) { | 51 static __inline int32_t WebRtcSpl_SubSatW32(int32_t a, int32_t b) { |
58 int32_t l_diff; | 52 // Do the subtraction in unsigned numbers, since signed overflow is UB. |
tlegrand-webrtc
2016/05/20 11:07:14
Here as well.
kwiberg-webrtc
2016/05/23 08:30:04
Done.
| |
53 const int32_t diff = (int32_t)((uint32_t)a - (uint32_t)b); | |
59 | 54 |
60 // Perform subtraction. | 55 // a - b can't overflow if a and b have the same sign. If they have different |
61 l_diff = l_var1 - l_var2; | 56 // signs, a - b has the same sign as a iff it didn't overflow. |
62 | 57 if ((a < 0) != (b < 0) && (a < 0) != (diff < 0)) { |
63 if (l_var1 < 0) { // Check for underflow. | 58 // The direction of the overflow is obvious from the sign of a - b. |
64 if ((l_var2 > 0) && (l_diff > 0)) { | 59 return diff < 0 ? INT32_MAX : INT32_MIN; |
65 l_diff = (int32_t)0x80000000; | |
66 } | |
67 } else { // Check for overflow. | |
68 if ((l_var2 < 0) && (l_diff < 0)) { | |
69 l_diff = (int32_t)0x7FFFFFFF; | |
70 } | |
71 } | 60 } |
72 | 61 return diff; |
73 return l_diff; | |
74 } | 62 } |
75 | 63 |
76 static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) { | 64 static __inline int16_t WebRtcSpl_AddSatW16(int16_t a, int16_t b) { |
77 return WebRtcSpl_SatW32ToW16((int32_t) a + (int32_t) b); | 65 return WebRtcSpl_SatW32ToW16((int32_t) a + (int32_t) b); |
78 } | 66 } |
79 | 67 |
80 static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) { | 68 static __inline int16_t WebRtcSpl_SubSatW16(int16_t var1, int16_t var2) { |
81 return WebRtcSpl_SatW32ToW16((int32_t) var1 - (int32_t) var2); | 69 return WebRtcSpl_SatW32ToW16((int32_t) var1 - (int32_t) var2); |
82 } | 70 } |
83 #endif // #if !defined(MIPS_DSP_R1_LE) | 71 #endif // #if !defined(MIPS_DSP_R1_LE) |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
164 } | 152 } |
165 | 153 |
166 static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) { | 154 static __inline int32_t WebRtc_MulAccumW16(int16_t a, int16_t b, int32_t c) { |
167 return (a * b + c); | 155 return (a * b + c); |
168 } | 156 } |
169 #endif // #if !defined(MIPS32_LE) | 157 #endif // #if !defined(MIPS32_LE) |
170 | 158 |
171 #endif // WEBRTC_ARCH_ARM_V7 | 159 #endif // WEBRTC_ARCH_ARM_V7 |
172 | 160 |
173 #endif // WEBRTC_SPL_SPL_INL_H_ | 161 #endif // WEBRTC_SPL_SPL_INL_H_ |
OLD | NEW |