1use crate::{
4 arch::word::Word,
5 math::shr_word,
6 primitive::{extend_word, split_dword, WORD_BITS},
7};
8
9pub fn shl_in_place(words: &mut [Word], shift: u32) -> Word {
12 debug_assert!(shift < WORD_BITS);
13 if shift == 0 {
14 return 0;
15 }
16 let mut carry = 0;
17 for word in words {
18 let (new_word, new_carry) = split_dword(extend_word(*word) << shift);
19 *word = new_word | carry;
20 carry = new_carry;
21 }
22 carry
23}
24
25#[inline]
28pub fn shr_in_place(words: &mut [Word], shift: u32) -> Word {
29 debug_assert!(shift <= WORD_BITS);
30 if shift == WORD_BITS {
31 shr_in_place_one_word(words)
32 } else {
33 shr_in_place_with_carry(words, shift, 0)
34 }
35}
36
37pub fn shr_in_place_with_carry(words: &mut [Word], shift: u32, mut carry: Word) -> Word {
41 debug_assert!(shift < WORD_BITS);
42 if shift == 0 {
43 debug_assert_eq!(carry, 0);
44 return 0;
45 }
46 for word in words.iter_mut().rev() {
47 let (new_word, new_carry) = shr_word(*word, shift);
48 *word = new_word | carry;
49 carry = new_carry;
50 }
51 carry
52}
53
54pub fn shr_in_place_one_word(words: &mut [Word]) -> Word {
56 unsafe {
58 let ptr = words.as_mut_ptr();
59 let rem = ptr.read();
60 ptr.copy_from(ptr.add(1), words.len() - 1);
61 ptr.add(words.len() - 1).write(0);
62 rem
63 }
64}