mod.rs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. use core::ops;
  2. mod specialized_div_rem;
  3. pub mod addsub;
  4. pub mod leading_zeros;
  5. pub mod mul;
  6. pub mod sdiv;
  7. pub mod shift;
  8. pub mod udiv;
  9. pub use self::leading_zeros::__clzsi2;
  10. /// Trait for some basic operations on integers
  11. #[doc(hidden)]
  12. pub trait Int:
  13. Copy
  14. + PartialEq
  15. + PartialOrd
  16. + ops::AddAssign
  17. + ops::BitAndAssign
  18. + ops::BitOrAssign
  19. + ops::BitXorAssign
  20. + ops::ShlAssign<i32>
  21. + ops::ShrAssign<u32>
  22. + ops::Add<Output = Self>
  23. + ops::Sub<Output = Self>
  24. + ops::Div<Output = Self>
  25. + ops::Shl<u32, Output = Self>
  26. + ops::Shr<u32, Output = Self>
  27. + ops::BitOr<Output = Self>
  28. + ops::BitXor<Output = Self>
  29. + ops::BitAnd<Output = Self>
  30. + ops::Not<Output = Self>
  31. {
  32. /// Type with the same width but other signedness
  33. type OtherSign: Int;
  34. /// Unsigned version of Self
  35. type UnsignedInt: Int;
  36. /// The bitwidth of the int type
  37. const BITS: u32;
  38. const ZERO: Self;
  39. const ONE: Self;
  40. const MIN: Self;
  41. /// LUT used for maximizing the space covered and minimizing the computational cost of fuzzing
  42. /// in `testcrate`. For example, Self = u128 produces [0,1,2,7,8,15,16,31,32,63,64,95,96,111,
  43. /// 112,119,120,125,126,127].
  44. const FUZZ_LENGTHS: [u8; 20];
  45. /// The number of entries of `FUZZ_LENGTHS` actually used. The maximum is 20 for u128.
  46. const FUZZ_NUM: usize;
  47. /// Extracts the sign from self and returns a tuple.
  48. ///
  49. /// # Examples
  50. ///
  51. /// ```rust,ignore
  52. /// let i = -25_i32;
  53. /// let (sign, u) = i.extract_sign();
  54. /// assert_eq!(sign, true);
  55. /// assert_eq!(u, 25_u32);
  56. /// ```
  57. fn extract_sign(self) -> (bool, Self::UnsignedInt);
  58. fn unsigned(self) -> Self::UnsignedInt;
  59. fn from_unsigned(unsigned: Self::UnsignedInt) -> Self;
  60. fn from_bool(b: bool) -> Self;
  61. /// Prevents the need for excessive conversions between signed and unsigned
  62. fn logical_shr(self, other: u32) -> Self;
  63. // copied from primitive integers, but put in a trait
  64. fn is_zero(self) -> bool;
  65. fn max_value() -> Self;
  66. fn min_value() -> Self;
  67. fn wrapping_neg(self) -> Self;
  68. fn wrapping_add(self, other: Self) -> Self;
  69. fn wrapping_mul(self, other: Self) -> Self;
  70. fn wrapping_sub(self, other: Self) -> Self;
  71. fn wrapping_shl(self, other: u32) -> Self;
  72. fn wrapping_shr(self, other: u32) -> Self;
  73. fn rotate_left(self, other: u32) -> Self;
  74. fn overflowing_add(self, other: Self) -> (Self, bool);
  75. fn aborting_div(self, other: Self) -> Self;
  76. fn aborting_rem(self, other: Self) -> Self;
  77. fn leading_zeros(self) -> u32;
  78. fn count_ones(self) -> u32;
  79. }
  80. fn unwrap<T>(t: Option<T>) -> T {
  81. match t {
  82. Some(t) => t,
  83. None => ::abort(),
  84. }
  85. }
  86. macro_rules! int_impl_common {
  87. ($ty:ty, $bits:expr) => {
  88. const BITS: u32 = $bits;
  89. const ZERO: Self = 0;
  90. const ONE: Self = 1;
  91. const MIN: Self = <Self>::MIN;
  92. const FUZZ_LENGTHS: [u8; 20] = {
  93. let bits = <Self as Int>::BITS;
  94. let mut v = [0u8; 20];
  95. v[0] = 0;
  96. v[1] = 1;
  97. v[2] = 2; // important for parity and the iX::MIN case when reversed
  98. let mut i = 3;
  99. // No need for any more until the byte boundary, because there should be no algorithms
  100. // that are sensitive to anything not next to byte boundaries after 2. We also scale
  101. // in powers of two, which is important to prevent u128 corner tests from getting too
  102. // big.
  103. let mut l = 8;
  104. loop {
  105. if l >= ((bits / 2) as u8) {
  106. break;
  107. }
  108. // get both sides of the byte boundary
  109. v[i] = l - 1;
  110. i += 1;
  111. v[i] = l;
  112. i += 1;
  113. l *= 2;
  114. }
  115. if bits != 8 {
  116. // add the lower side of the middle boundary
  117. v[i] = ((bits / 2) - 1) as u8;
  118. i += 1;
  119. }
  120. // We do not want to jump directly from the Self::BITS/2 boundary to the Self::BITS
  121. // boundary because of algorithms that split the high part up. We reverse the scaling
  122. // as we go to Self::BITS.
  123. let mid = i;
  124. let mut j = 1;
  125. loop {
  126. v[i] = (bits as u8) - (v[mid - j]) - 1;
  127. if j == mid {
  128. break;
  129. }
  130. i += 1;
  131. j += 1;
  132. }
  133. v
  134. };
  135. const FUZZ_NUM: usize = {
  136. let log2 = (<Self as Int>::BITS - 1).count_ones() as usize;
  137. if log2 == 3 {
  138. // case for u8
  139. 6
  140. } else {
  141. // 3 entries on each extreme, 2 in the middle, and 4 for each scale of intermediate
  142. // boundaries.
  143. 8 + (4 * (log2 - 4))
  144. }
  145. };
  146. fn from_bool(b: bool) -> Self {
  147. b as $ty
  148. }
  149. fn logical_shr(self, other: u32) -> Self {
  150. Self::from_unsigned(self.unsigned().wrapping_shr(other))
  151. }
  152. fn is_zero(self) -> bool {
  153. self == Self::ZERO
  154. }
  155. fn max_value() -> Self {
  156. <Self>::max_value()
  157. }
  158. fn min_value() -> Self {
  159. <Self>::min_value()
  160. }
  161. fn wrapping_neg(self) -> Self {
  162. <Self>::wrapping_neg(self)
  163. }
  164. fn wrapping_add(self, other: Self) -> Self {
  165. <Self>::wrapping_add(self, other)
  166. }
  167. fn wrapping_mul(self, other: Self) -> Self {
  168. <Self>::wrapping_mul(self, other)
  169. }
  170. fn wrapping_sub(self, other: Self) -> Self {
  171. <Self>::wrapping_sub(self, other)
  172. }
  173. fn wrapping_shl(self, other: u32) -> Self {
  174. <Self>::wrapping_shl(self, other)
  175. }
  176. fn wrapping_shr(self, other: u32) -> Self {
  177. <Self>::wrapping_shr(self, other)
  178. }
  179. fn rotate_left(self, other: u32) -> Self {
  180. <Self>::rotate_left(self, other)
  181. }
  182. fn overflowing_add(self, other: Self) -> (Self, bool) {
  183. <Self>::overflowing_add(self, other)
  184. }
  185. fn aborting_div(self, other: Self) -> Self {
  186. unwrap(<Self>::checked_div(self, other))
  187. }
  188. fn aborting_rem(self, other: Self) -> Self {
  189. unwrap(<Self>::checked_rem(self, other))
  190. }
  191. fn leading_zeros(self) -> u32 {
  192. <Self>::leading_zeros(self)
  193. }
  194. fn count_ones(self) -> u32 {
  195. <Self>::count_ones(self)
  196. }
  197. };
  198. }
  199. macro_rules! int_impl {
  200. ($ity:ty, $uty:ty, $bits:expr) => {
  201. impl Int for $uty {
  202. type OtherSign = $ity;
  203. type UnsignedInt = $uty;
  204. fn extract_sign(self) -> (bool, $uty) {
  205. (false, self)
  206. }
  207. fn unsigned(self) -> $uty {
  208. self
  209. }
  210. fn from_unsigned(me: $uty) -> Self {
  211. me
  212. }
  213. int_impl_common!($uty, $bits);
  214. }
  215. impl Int for $ity {
  216. type OtherSign = $uty;
  217. type UnsignedInt = $uty;
  218. fn extract_sign(self) -> (bool, $uty) {
  219. if self < 0 {
  220. (true, (!(self as $uty)).wrapping_add(1))
  221. } else {
  222. (false, self as $uty)
  223. }
  224. }
  225. fn unsigned(self) -> $uty {
  226. self as $uty
  227. }
  228. fn from_unsigned(me: $uty) -> Self {
  229. me as $ity
  230. }
  231. int_impl_common!($ity, $bits);
  232. }
  233. };
  234. }
  235. int_impl!(isize, usize, usize::MAX.count_ones());
  236. int_impl!(i8, u8, 8);
  237. int_impl!(i16, u16, 16);
  238. int_impl!(i32, u32, 32);
  239. int_impl!(i64, u64, 64);
  240. int_impl!(i128, u128, 128);
  241. /// Trait for integers twice the bit width of another integer. This is implemented for all
  242. /// primitives except for `u8`, because there is not a smaller primitive.
  243. #[doc(hidden)]
  244. pub trait DInt: Int {
  245. /// Integer that is half the bit width of the integer this trait is implemented for
  246. type H: HInt<D = Self> + Int;
  247. /// Returns the low half of `self`
  248. fn lo(self) -> Self::H;
  249. /// Returns the high half of `self`
  250. fn hi(self) -> Self::H;
  251. /// Returns the low and high halves of `self` as a tuple
  252. fn lo_hi(self) -> (Self::H, Self::H);
  253. /// Constructs an integer using lower and higher half parts
  254. fn from_lo_hi(lo: Self::H, hi: Self::H) -> Self;
  255. }
  256. /// Trait for integers half the bit width of another integer. This is implemented for all
  257. /// primitives except for `u128`, because it there is not a larger primitive.
  258. #[doc(hidden)]
  259. pub trait HInt: Int {
  260. /// Integer that is double the bit width of the integer this trait is implemented for
  261. type D: DInt<H = Self> + Int;
  262. /// Widens (using default extension) the integer to have double bit width
  263. fn widen(self) -> Self::D;
  264. /// Widens (zero extension only) the integer to have double bit width. This is needed to get
  265. /// around problems with associated type bounds (such as `Int<Othersign: DInt>`) being unstable
  266. fn zero_widen(self) -> Self::D;
  267. /// Widens the integer to have double bit width and shifts the integer into the higher bits
  268. fn widen_hi(self) -> Self::D;
  269. /// Widening multiplication with zero widening. This cannot overflow.
  270. fn zero_widen_mul(self, rhs: Self) -> Self::D;
  271. /// Widening multiplication. This cannot overflow.
  272. fn widen_mul(self, rhs: Self) -> Self::D;
  273. }
  274. macro_rules! impl_d_int {
  275. ($($X:ident $D:ident),*) => {
  276. $(
  277. impl DInt for $D {
  278. type H = $X;
  279. fn lo(self) -> Self::H {
  280. self as $X
  281. }
  282. fn hi(self) -> Self::H {
  283. (self >> <$X as Int>::BITS) as $X
  284. }
  285. fn lo_hi(self) -> (Self::H, Self::H) {
  286. (self.lo(), self.hi())
  287. }
  288. fn from_lo_hi(lo: Self::H, hi: Self::H) -> Self {
  289. lo.zero_widen() | hi.widen_hi()
  290. }
  291. }
  292. )*
  293. };
  294. }
  295. macro_rules! impl_h_int {
  296. ($($H:ident $uH:ident $X:ident),*) => {
  297. $(
  298. impl HInt for $H {
  299. type D = $X;
  300. fn widen(self) -> Self::D {
  301. self as $X
  302. }
  303. fn zero_widen(self) -> Self::D {
  304. (self as $uH) as $X
  305. }
  306. fn widen_hi(self) -> Self::D {
  307. (self as $X) << <$H as Int>::BITS
  308. }
  309. fn zero_widen_mul(self, rhs: Self) -> Self::D {
  310. self.zero_widen().wrapping_mul(rhs.zero_widen())
  311. }
  312. fn widen_mul(self, rhs: Self) -> Self::D {
  313. self.widen().wrapping_mul(rhs.widen())
  314. }
  315. }
  316. )*
  317. };
  318. }
  319. impl_d_int!(u8 u16, u16 u32, u32 u64, u64 u128, i8 i16, i16 i32, i32 i64, i64 i128);
  320. impl_h_int!(
  321. u8 u8 u16,
  322. u16 u16 u32,
  323. u32 u32 u64,
  324. u64 u64 u128,
  325. i8 u8 i16,
  326. i16 u16 i32,
  327. i32 u32 i64,
  328. i64 u64 i128
  329. );
  330. /// Trait to convert an integer to/from smaller parts
  331. pub(crate) trait LargeInt: Int {
  332. type LowHalf: Int;
  333. type HighHalf: Int;
  334. fn low(self) -> Self::LowHalf;
  335. fn low_as_high(low: Self::LowHalf) -> Self::HighHalf;
  336. fn high(self) -> Self::HighHalf;
  337. fn high_as_low(low: Self::HighHalf) -> Self::LowHalf;
  338. fn from_parts(low: Self::LowHalf, high: Self::HighHalf) -> Self;
  339. }
  340. macro_rules! large_int {
  341. ($ty:ty, $tylow:ty, $tyhigh:ty, $halfbits:expr) => {
  342. impl LargeInt for $ty {
  343. type LowHalf = $tylow;
  344. type HighHalf = $tyhigh;
  345. fn low(self) -> $tylow {
  346. self as $tylow
  347. }
  348. fn low_as_high(low: $tylow) -> $tyhigh {
  349. low as $tyhigh
  350. }
  351. fn high(self) -> $tyhigh {
  352. (self >> $halfbits) as $tyhigh
  353. }
  354. fn high_as_low(high: $tyhigh) -> $tylow {
  355. high as $tylow
  356. }
  357. fn from_parts(low: $tylow, high: $tyhigh) -> $ty {
  358. low as $ty | ((high as $ty) << $halfbits)
  359. }
  360. }
  361. };
  362. }
  363. large_int!(u32, u16, u16, 16);
  364. large_int!(i32, u16, i16, 16);
  365. large_int!(u64, u32, u32, 32);
  366. large_int!(i64, u32, i32, 32);
  367. large_int!(u128, u64, u64, 64);
  368. large_int!(i128, u64, i64, 64);
  369. /// Trait to express (possibly lossy) casting of integers
  370. pub(crate) trait CastInto<T: Copy>: Copy {
  371. fn cast(self) -> T;
  372. }
  373. macro_rules! cast_into {
  374. ($ty:ty) => {
  375. cast_into!($ty; usize, isize, u32, i32, u64, i64, u128, i128);
  376. };
  377. ($ty:ty; $($into:ty),*) => {$(
  378. impl CastInto<$into> for $ty {
  379. fn cast(self) -> $into {
  380. self as $into
  381. }
  382. }
  383. )*};
  384. }
  385. cast_into!(u32);
  386. cast_into!(i32);
  387. cast_into!(u64);
  388. cast_into!(i64);
  389. cast_into!(u128);
  390. cast_into!(i128);
  391. pub(crate) trait WideInt: Int {
  392. type Output: Int;
  393. fn wide_mul(self, other: Self) -> (Self, Self);
  394. fn wide_shift_left(&mut self, low: &mut Self, count: i32);
  395. fn wide_shift_right_with_sticky(&mut self, low: &mut Self, count: i32);
  396. }
  397. macro_rules! impl_wide_int {
  398. ($ty:ty, $tywide:ty, $bits:expr) => {
  399. impl WideInt for $ty {
  400. type Output = $ty;
  401. fn wide_mul(self, other: Self) -> (Self, Self) {
  402. let product = (self as $tywide).wrapping_mul(other as $tywide);
  403. ((product >> ($bits as $ty)) as $ty, product as $ty)
  404. }
  405. fn wide_shift_left(&mut self, low: &mut Self, count: i32) {
  406. *self = (*self << count) | (*low >> ($bits - count));
  407. *low = *low << count;
  408. }
  409. fn wide_shift_right_with_sticky(&mut self, low: &mut Self, count: i32) {
  410. if count < $bits {
  411. let sticky = *low << ($bits - count);
  412. *low = *self << ($bits - count) | *low >> count | sticky;
  413. *self = *self >> count;
  414. } else if count < 2 * $bits {
  415. let sticky = *self << (2 * $bits - count) | *low;
  416. *low = *self >> (count - $bits) | sticky;
  417. *self = 0;
  418. } else {
  419. let sticky = *self | *low;
  420. *self = sticky;
  421. *self = 0;
  422. }
  423. }
  424. }
  425. };
  426. }
  427. impl_wide_int!(u32, u64, 32);
  428. impl_wide_int!(u64, u128, 64);