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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use int::Int;
trait Div: Int {
fn div(self, other: Self) -> Self {
let s_a = self >> (Self::BITS - 1);
let s_b = other >> (Self::BITS - 1);
let a = (self ^ s_a).wrapping_sub(s_a);
let b = (other ^ s_b).wrapping_sub(s_b);
let s = s_a ^ s_b;
let r = a.unsigned().aborting_div(b.unsigned());
(Self::from_unsigned(r) ^ s) - s
}
}
impl Div for i32 {}
impl Div for i64 {}
impl Div for i128 {}
trait Mod: Int {
fn mod_(self, other: Self) -> Self {
let s = other >> (Self::BITS - 1);
let b = (other ^ s).wrapping_sub(s);
let s = self >> (Self::BITS - 1);
let a = (self ^ s).wrapping_sub(s);
let r = a.unsigned().aborting_rem(b.unsigned());
(Self::from_unsigned(r) ^ s) - s
}
}
impl Mod for i32 {}
impl Mod for i64 {}
impl Mod for i128 {}
trait Divmod: Int {
fn divmod<F>(self, other: Self, rem: &mut Self, div: F) -> Self
where
F: Fn(Self, Self) -> Self,
{
let r = div(self, other);
*rem = self - r.wrapping_mul(other);
r
}
}
impl Divmod for i32 {}
impl Divmod for i64 {}
intrinsics! {
#[maybe_use_optimized_c_shim]
#[arm_aeabi_alias = __aeabi_idiv]
pub extern "C" fn __divsi3(a: i32, b: i32) -> i32 {
a.div(b)
}
#[maybe_use_optimized_c_shim]
pub extern "C" fn __divdi3(a: i64, b: i64) -> i64 {
a.div(b)
}
#[win64_128bit_abi_hack]
pub extern "C" fn __divti3(a: i128, b: i128) -> i128 {
a.div(b)
}
#[maybe_use_optimized_c_shim]
pub extern "C" fn __modsi3(a: i32, b: i32) -> i32 {
a.mod_(b)
}
#[maybe_use_optimized_c_shim]
pub extern "C" fn __moddi3(a: i64, b: i64) -> i64 {
a.mod_(b)
}
#[win64_128bit_abi_hack]
pub extern "C" fn __modti3(a: i128, b: i128) -> i128 {
a.mod_(b)
}
#[maybe_use_optimized_c_shim]
pub extern "C" fn __divmodsi4(a: i32, b: i32, rem: &mut i32) -> i32 {
a.divmod(b, rem, |a, b| __divsi3(a, b))
}
#[aapcs_on_arm]
pub extern "C" fn __divmoddi4(a: i64, b: i64, rem: &mut i64) -> i64 {
a.divmod(b, rem, |a, b| __divdi3(a, b))
}
}
u128_lang_items! {
#[lang = "i128_div"]
pub fn rust_i128_div(a: i128, b: i128) -> i128 {
__divti3(a, b)
}
#[lang = "i128_rem"]
pub fn rust_i128_rem(a: i128, b: i128) -> i128 {
__modti3(a, b)
}
}