1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//! Module containing logical right shift intrinsic.

use crate::{int::I256, uint::U256};
use core::mem::MaybeUninit;

#[inline]
pub fn sar2(r: &mut I256, a: u32) {
    debug_assert!(a < 256, "shr intrinsic called with overflowing shift");

    let (hi, lo) = if a == 0 {
        return;
    } else if a < 128 {
        (
            r.high() >> a,
            ((*r.low() as u128) >> a | ((*r.high() as u128) << (128 - a))) as i128,
        )
    } else {
        (r.high() >> 127, (r.high() >> (a & 0x7f)))
    };

    *r = I256::from_words(hi, lo);
}

#[inline]
pub fn sar3(r: &mut MaybeUninit<I256>, a: &I256, b: u32) {
    debug_assert!(b < 256, "shr intrinsic called with overflowing shift");

    let (hi, lo) = if b == 0 {
        (*a.high(), *a.low())
    } else if b < 128 {
        (
            a.high() >> b,
            ((*a.low() as u128) >> b | ((*a.high() as u128) << (128 - b))) as i128,
        )
    } else {
        (a.high() >> 127, a.high() >> (b & 0x7f))
    };

    r.write(I256::from_words(hi, lo));
}

#[inline]
pub fn shr2(r: &mut U256, a: u32) {
    debug_assert!(a < 256, "shr intrinsic called with overflowing shift");

    let (hi, lo) = if a == 0 {
        return;
    } else if a < 128 {
        (r.high() >> a, r.low() >> a | (r.high() << (128 - a)))
    } else {
        (0, r.high() >> (a & 0x7f))
    };

    *r = U256::from_words(hi, lo);
}

#[inline]
pub fn shr3(r: &mut MaybeUninit<U256>, a: &U256, b: u32) {
    debug_assert!(b < 256, "shr intrinsic called with overflowing shift");

    let (hi, lo) = if b == 0 {
        (*a.high(), *a.low())
    } else if b < 128 {
        (a.high() >> b, a.low() >> b | (a.high() << (128 - b)))
    } else {
        (0, a.high() >> (b & 0x7f))
    };

    r.write(U256::from_words(hi, lo));
}