]>
Commit | Line | Data |
---|---|---|
5869c6ff | 1 | use int::{DInt, HInt, Int}; |
041b39d2 | 2 | |
5869c6ff | 3 | trait Ashl: DInt { |
ea8adc8c | 4 | /// Returns `a << b`, requires `b < Self::BITS` |
5869c6ff XL |
5 | fn ashl(self, shl: u32) -> Self { |
6 | let n_h = Self::H::BITS; | |
7 | if shl & n_h != 0 { | |
8 | // we only need `self.lo()` because `self.hi()` will be shifted out entirely | |
136023e0 | 9 | self.lo().wrapping_shl(shl - n_h).widen_hi() |
5869c6ff | 10 | } else if shl == 0 { |
041b39d2 XL |
11 | self |
12 | } else { | |
5869c6ff | 13 | Self::from_lo_hi( |
136023e0 XL |
14 | self.lo().wrapping_shl(shl), |
15 | self.lo().logical_shr(n_h - shl) | self.hi().wrapping_shl(shl), | |
48663c56 | 16 | ) |
041b39d2 XL |
17 | } |
18 | } | |
19 | } | |
20 | ||
29967ef6 | 21 | impl Ashl for u32 {} |
041b39d2 XL |
22 | impl Ashl for u64 {} |
23 | impl Ashl for u128 {} | |
24 | ||
5869c6ff | 25 | trait Ashr: DInt { |
ea8adc8c | 26 | /// Returns arithmetic `a >> b`, requires `b < Self::BITS` |
5869c6ff XL |
27 | fn ashr(self, shr: u32) -> Self { |
28 | let n_h = Self::H::BITS; | |
29 | if shr & n_h != 0 { | |
30 | Self::from_lo_hi( | |
136023e0 | 31 | self.hi().wrapping_shr(shr - n_h), |
5869c6ff | 32 | // smear the sign bit |
136023e0 | 33 | self.hi().wrapping_shr(n_h - 1), |
48663c56 | 34 | ) |
5869c6ff | 35 | } else if shr == 0 { |
041b39d2 XL |
36 | self |
37 | } else { | |
5869c6ff | 38 | Self::from_lo_hi( |
136023e0 XL |
39 | self.lo().logical_shr(shr) | self.hi().wrapping_shl(n_h - shr), |
40 | self.hi().wrapping_shr(shr), | |
48663c56 | 41 | ) |
041b39d2 XL |
42 | } |
43 | } | |
44 | } | |
45 | ||
29967ef6 | 46 | impl Ashr for i32 {} |
041b39d2 XL |
47 | impl Ashr for i64 {} |
48 | impl Ashr for i128 {} | |
49 | ||
5869c6ff | 50 | trait Lshr: DInt { |
ea8adc8c | 51 | /// Returns logical `a >> b`, requires `b < Self::BITS` |
5869c6ff XL |
52 | fn lshr(self, shr: u32) -> Self { |
53 | let n_h = Self::H::BITS; | |
54 | if shr & n_h != 0 { | |
55 | self.hi().logical_shr(shr - n_h).zero_widen() | |
56 | } else if shr == 0 { | |
041b39d2 XL |
57 | self |
58 | } else { | |
5869c6ff | 59 | Self::from_lo_hi( |
136023e0 | 60 | self.lo().logical_shr(shr) | self.hi().wrapping_shl(n_h - shr), |
5869c6ff | 61 | self.hi().logical_shr(shr), |
48663c56 | 62 | ) |
041b39d2 XL |
63 | } |
64 | } | |
65 | } | |
66 | ||
29967ef6 | 67 | impl Lshr for u32 {} |
041b39d2 XL |
68 | impl Lshr for u64 {} |
69 | impl Lshr for u128 {} | |
70 | ||
71 | intrinsics! { | |
29967ef6 XL |
72 | #[maybe_use_optimized_c_shim] |
73 | pub extern "C" fn __ashlsi3(a: u32, b: u32) -> u32 { | |
74 | a.ashl(b) | |
75 | } | |
76 | ||
48663c56 | 77 | #[maybe_use_optimized_c_shim] |
041b39d2 XL |
78 | #[arm_aeabi_alias = __aeabi_llsl] |
79 | pub extern "C" fn __ashldi3(a: u64, b: u32) -> u64 { | |
80 | a.ashl(b) | |
81 | } | |
82 | ||
83 | pub extern "C" fn __ashlti3(a: u128, b: u32) -> u128 { | |
84 | a.ashl(b) | |
85 | } | |
86 | ||
29967ef6 XL |
87 | #[maybe_use_optimized_c_shim] |
88 | pub extern "C" fn __ashrsi3(a: i32, b: u32) -> i32 { | |
89 | a.ashr(b) | |
90 | } | |
91 | ||
48663c56 | 92 | #[maybe_use_optimized_c_shim] |
041b39d2 XL |
93 | #[arm_aeabi_alias = __aeabi_lasr] |
94 | pub extern "C" fn __ashrdi3(a: i64, b: u32) -> i64 { | |
95 | a.ashr(b) | |
96 | } | |
97 | ||
98 | pub extern "C" fn __ashrti3(a: i128, b: u32) -> i128 { | |
99 | a.ashr(b) | |
100 | } | |
101 | ||
29967ef6 XL |
102 | #[maybe_use_optimized_c_shim] |
103 | pub extern "C" fn __lshrsi3(a: u32, b: u32) -> u32 { | |
104 | a.lshr(b) | |
105 | } | |
106 | ||
48663c56 | 107 | #[maybe_use_optimized_c_shim] |
041b39d2 XL |
108 | #[arm_aeabi_alias = __aeabi_llsr] |
109 | pub extern "C" fn __lshrdi3(a: u64, b: u32) -> u64 { | |
110 | a.lshr(b) | |
111 | } | |
112 | ||
113 | pub extern "C" fn __lshrti3(a: u128, b: u32) -> u128 { | |
114 | a.lshr(b) | |
115 | } | |
ff7c6d11 | 116 | } |