HiFi intrinsics: Inline the confusingly named SaturatingMultiply function.
24bit x 24bit => 56 bit multiplications never saturate. PiperOrigin-RevId: 305728765 Change-Id: Id77a6414dad99810fc87a2820713f43bca1cee98
This commit is contained in:
parent
a6e10b6e09
commit
1f9d744e66
@ -31,22 +31,6 @@ namespace micro {
|
|||||||
namespace xtensa {
|
namespace xtensa {
|
||||||
namespace hifimini {
|
namespace hifimini {
|
||||||
|
|
||||||
//
|
|
||||||
// Product of two fixed-point 24bit integers with right shift.
|
|
||||||
//
|
|
||||||
// Two 24bit integers from the HH side of a PR register entry are MAC into a QR
|
|
||||||
// register. That value will be right shifted if |shift_length| is greater than
|
|
||||||
// 0.
|
|
||||||
//
|
|
||||||
inline ae_q56s SaturatingMultiply(ae_p24x2s a_56, ae_p24x2s b_56,
|
|
||||||
int shift_length) {
|
|
||||||
ae_q56s result_56 = AE_MULP24S_HH(a_56, b_56);
|
|
||||||
if (shift_length > 0) {
|
|
||||||
return AE_Q56S_SRA(result_56, shift_length);
|
|
||||||
}
|
|
||||||
return result_56;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Multiply 32bit value by a quantized multiplier (w/ shift) and returns a 48bit
|
// Multiply 32bit value by a quantized multiplier (w/ shift) and returns a 48bit
|
||||||
// aligned value in the QR register.
|
// aligned value in the QR register.
|
||||||
@ -57,7 +41,7 @@ inline ae_q56s MultiplyByQuantizedMultiplier(int32_t x,
|
|||||||
// These boolean factors will carry an additional 2^8 (e.g 256) factor
|
// These boolean factors will carry an additional 2^8 (e.g 256) factor
|
||||||
// throughout the equation to cover the missing 8 bits of precision when a
|
// throughout the equation to cover the missing 8 bits of precision when a
|
||||||
// 32bit integer is outside the bounds of INT24. The additional scaling factor
|
// 32bit integer is outside the bounds of INT24. The additional scaling factor
|
||||||
// will be adjusted on the final SaturatingMultiply() call in this method.
|
// will be adjusted after the final multiplication in this method.
|
||||||
//
|
//
|
||||||
// The Q-notation comments in this method describe the calculations that take
|
// The Q-notation comments in this method describe the calculations that take
|
||||||
// place when both |x| and the shifted value of |1| overflow the INT24 limits.
|
// place when both |x| and the shifted value of |1| overflow the INT24 limits.
|
||||||
@ -110,8 +94,10 @@ inline ae_q56s MultiplyByQuantizedMultiplier(int32_t x,
|
|||||||
// to 48bit aligned.
|
// to 48bit aligned.
|
||||||
// (Q23.0 / 2^16) * Q23.0 = Q47.0 / 2^16
|
// (Q23.0 / 2^16) * Q23.0 = Q47.0 / 2^16
|
||||||
// (Q47.0 / 2^16) >> 7 = Q47.0
|
// (Q47.0 / 2^16) >> 7 = Q47.0
|
||||||
ae_q56s result_56 =
|
ae_q56s result_56 = AE_MULP24S_HH(x_24x2, quantized_multiplier_24x2);
|
||||||
SaturatingMultiply(x_24x2, quantized_multiplier_24x2, shift_amount);
|
if (shift_amount > 0) {
|
||||||
|
result_56 = AE_Q56S_SRA(result_56, shift_amount);
|
||||||
|
}
|
||||||
|
|
||||||
if (shift < 0) {
|
if (shift < 0) {
|
||||||
// Handle any negative shift directly on the 48 bit value.
|
// Handle any negative shift directly on the 48 bit value.
|
||||||
@ -134,8 +120,7 @@ inline ae_q56s MultiplyByQuantizedMultiplier(ae_p24x2s x_24x2,
|
|||||||
// the limits of INT24, which requires |AE_CONVERT_INT32_24x2()| to load the
|
// the limits of INT24, which requires |AE_CONVERT_INT32_24x2()| to load the
|
||||||
// left-most 24 bits of a 32bit integer. When this occurs, all Q values here
|
// left-most 24 bits of a 32bit integer. When this occurs, all Q values here
|
||||||
// carry an additional division of 2^8 to account for this loss in precision.
|
// carry an additional division of 2^8 to account for this loss in precision.
|
||||||
// This division will be applied to the final shift of the result in
|
// This division will be applied to the final shift after multiplication.
|
||||||
// |SaturatingMultiply()|.
|
|
||||||
//
|
//
|
||||||
// The Q-notation comments in this method describe the calculations that take
|
// The Q-notation comments in this method describe the calculations that take
|
||||||
// place when both |x| and the shifted value of |1| overflow the INT24 limits.
|
// place when both |x| and the shifted value of |1| overflow the INT24 limits.
|
||||||
@ -176,8 +161,8 @@ inline ae_q56s MultiplyByQuantizedMultiplier(ae_p24x2s x_24x2,
|
|||||||
// function:
|
// function:
|
||||||
// (Q23.0 / 2^8) * Q23.0 = Q47.0 / 2^8
|
// (Q23.0 / 2^8) * Q23.0 = Q47.0 / 2^8
|
||||||
// (Q47.0 / 2^8) >> 7 = Q47.0
|
// (Q47.0 / 2^8) >> 7 = Q47.0
|
||||||
ae_q56s result = SaturatingMultiply(x_shifted_24x2, quantized_multiplier_24x2,
|
ae_q56s result = AE_MULP24S_HH(x_shifted_24x2, quantized_multiplier_24x2);
|
||||||
shift_exceeds_24bits ? 15 : 23);
|
result = AE_Q56S_SRA(result, shift_exceeds_24bits ? 15 : 23);
|
||||||
|
|
||||||
if (shift < 0) {
|
if (shift < 0) {
|
||||||
// Handle any negative shift directly on the 48 bit value.
|
// Handle any negative shift directly on the 48 bit value.
|
||||||
|
Loading…
Reference in New Issue
Block a user