mul.rs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. use float::Float;
  2. use int::{CastInto, DInt, HInt, Int};
  3. fn mul<F: Float>(a: F, b: F) -> F
  4. where
  5. u32: CastInto<F::Int>,
  6. F::Int: CastInto<u32>,
  7. i32: CastInto<F::Int>,
  8. F::Int: CastInto<i32>,
  9. F::Int: HInt,
  10. {
  11. let one = F::Int::ONE;
  12. let zero = F::Int::ZERO;
  13. let bits = F::BITS;
  14. let significand_bits = F::SIGNIFICAND_BITS;
  15. let max_exponent = F::EXPONENT_MAX;
  16. let exponent_bias = F::EXPONENT_BIAS;
  17. let implicit_bit = F::IMPLICIT_BIT;
  18. let significand_mask = F::SIGNIFICAND_MASK;
  19. let sign_bit = F::SIGN_MASK as F::Int;
  20. let abs_mask = sign_bit - one;
  21. let exponent_mask = F::EXPONENT_MASK;
  22. let inf_rep = exponent_mask;
  23. let quiet_bit = implicit_bit >> 1;
  24. let qnan_rep = exponent_mask | quiet_bit;
  25. let exponent_bits = F::EXPONENT_BITS;
  26. let a_rep = a.repr();
  27. let b_rep = b.repr();
  28. let a_exponent = (a_rep >> significand_bits) & max_exponent.cast();
  29. let b_exponent = (b_rep >> significand_bits) & max_exponent.cast();
  30. let product_sign = (a_rep ^ b_rep) & sign_bit;
  31. let mut a_significand = a_rep & significand_mask;
  32. let mut b_significand = b_rep & significand_mask;
  33. let mut scale = 0;
  34. // Detect if a or b is zero, denormal, infinity, or NaN.
  35. if a_exponent.wrapping_sub(one) >= (max_exponent - 1).cast()
  36. || b_exponent.wrapping_sub(one) >= (max_exponent - 1).cast()
  37. {
  38. let a_abs = a_rep & abs_mask;
  39. let b_abs = b_rep & abs_mask;
  40. // NaN + anything = qNaN
  41. if a_abs > inf_rep {
  42. return F::from_repr(a_rep | quiet_bit);
  43. }
  44. // anything + NaN = qNaN
  45. if b_abs > inf_rep {
  46. return F::from_repr(b_rep | quiet_bit);
  47. }
  48. if a_abs == inf_rep {
  49. if b_abs != zero {
  50. // infinity * non-zero = +/- infinity
  51. return F::from_repr(a_abs | product_sign);
  52. } else {
  53. // infinity * zero = NaN
  54. return F::from_repr(qnan_rep);
  55. }
  56. }
  57. if b_abs == inf_rep {
  58. if a_abs != zero {
  59. // infinity * non-zero = +/- infinity
  60. return F::from_repr(b_abs | product_sign);
  61. } else {
  62. // infinity * zero = NaN
  63. return F::from_repr(qnan_rep);
  64. }
  65. }
  66. // zero * anything = +/- zero
  67. if a_abs == zero {
  68. return F::from_repr(product_sign);
  69. }
  70. // anything * zero = +/- zero
  71. if b_abs == zero {
  72. return F::from_repr(product_sign);
  73. }
  74. // one or both of a or b is denormal, the other (if applicable) is a
  75. // normal number. Renormalize one or both of a and b, and set scale to
  76. // include the necessary exponent adjustment.
  77. if a_abs < implicit_bit {
  78. let (exponent, significand) = F::normalize(a_significand);
  79. scale += exponent;
  80. a_significand = significand;
  81. }
  82. if b_abs < implicit_bit {
  83. let (exponent, significand) = F::normalize(b_significand);
  84. scale += exponent;
  85. b_significand = significand;
  86. }
  87. }
  88. // Or in the implicit significand bit. (If we fell through from the
  89. // denormal path it was already set by normalize( ), but setting it twice
  90. // won't hurt anything.)
  91. a_significand |= implicit_bit;
  92. b_significand |= implicit_bit;
  93. // Get the significand of a*b. Before multiplying the significands, shift
  94. // one of them left to left-align it in the field. Thus, the product will
  95. // have (exponentBits + 2) integral digits, all but two of which must be
  96. // zero. Normalizing this result is just a conditional left-shift by one
  97. // and bumping the exponent accordingly.
  98. let (mut product_low, mut product_high) = a_significand
  99. .widen_mul(b_significand << exponent_bits)
  100. .lo_hi();
  101. let a_exponent_i32: i32 = a_exponent.cast();
  102. let b_exponent_i32: i32 = b_exponent.cast();
  103. let mut product_exponent: i32 = a_exponent_i32
  104. .wrapping_add(b_exponent_i32)
  105. .wrapping_add(scale)
  106. .wrapping_sub(exponent_bias as i32);
  107. // Normalize the significand, adjust exponent if needed.
  108. if (product_high & implicit_bit) != zero {
  109. product_exponent = product_exponent.wrapping_add(1);
  110. } else {
  111. product_high = (product_high << 1) | (product_low >> (bits - 1));
  112. product_low <<= 1;
  113. }
  114. // If we have overflowed the type, return +/- infinity.
  115. if product_exponent >= max_exponent as i32 {
  116. return F::from_repr(inf_rep | product_sign);
  117. }
  118. if product_exponent <= 0 {
  119. // Result is denormal before rounding
  120. //
  121. // If the result is so small that it just underflows to zero, return
  122. // a zero of the appropriate sign. Mathematically there is no need to
  123. // handle this case separately, but we make it a special case to
  124. // simplify the shift logic.
  125. let shift = one.wrapping_sub(product_exponent.cast()).cast();
  126. if shift >= bits {
  127. return F::from_repr(product_sign);
  128. }
  129. // Otherwise, shift the significand of the result so that the round
  130. // bit is the high bit of productLo.
  131. if shift < bits {
  132. let sticky = product_low << (bits - shift);
  133. product_low = product_high << (bits - shift) | product_low >> shift | sticky;
  134. product_high >>= shift;
  135. } else if shift < (2 * bits) {
  136. let sticky = product_high << (2 * bits - shift) | product_low;
  137. product_low = product_high >> (shift - bits) | sticky;
  138. product_high = zero;
  139. } else {
  140. product_high = zero;
  141. }
  142. } else {
  143. // Result is normal before rounding; insert the exponent.
  144. product_high &= significand_mask;
  145. product_high |= product_exponent.cast() << significand_bits;
  146. }
  147. // Insert the sign of the result:
  148. product_high |= product_sign;
  149. // Final rounding. The final result may overflow to infinity, or underflow
  150. // to zero, but those are the correct results in those cases. We use the
  151. // default IEEE-754 round-to-nearest, ties-to-even rounding mode.
  152. if product_low > sign_bit {
  153. product_high += one;
  154. }
  155. if product_low == sign_bit {
  156. product_high += product_high & one;
  157. }
  158. return F::from_repr(product_high);
  159. }
  160. intrinsics! {
  161. #[aapcs_on_arm]
  162. #[arm_aeabi_alias = __aeabi_fmul]
  163. pub extern "C" fn __mulsf3(a: f32, b: f32) -> f32 {
  164. mul(a, b)
  165. }
  166. #[aapcs_on_arm]
  167. #[arm_aeabi_alias = __aeabi_dmul]
  168. pub extern "C" fn __muldf3(a: f64, b: f64) -> f64 {
  169. mul(a, b)
  170. }
  171. #[cfg(target_arch = "arm")]
  172. pub extern "C" fn __mulsf3vfp(a: f32, b: f32) -> f32 {
  173. a * b
  174. }
  175. #[cfg(target_arch = "arm")]
  176. pub extern "C" fn __muldf3vfp(a: f64, b: f64) -> f64 {
  177. a * b
  178. }
  179. }