Chromium Code Reviews| 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 |