1
- use int:: Int ;
2
-
3
- trait Div : Int {
4
- /// Returns `a / b`
5
- fn div ( self , other : Self ) -> Self {
6
- let s_a = self >> ( Self :: BITS - 1 ) ;
7
- let s_b = other >> ( Self :: BITS - 1 ) ;
8
- // NOTE it's OK to overflow here because of the `.unsigned()` below.
9
- // This whole operation is computing the absolute value of the inputs
10
- // So some overflow will happen when dealing with e.g. `i64::MIN`
11
- // where the absolute value is `(-i64::MIN) as u64`
12
- let a = ( self ^ s_a) . wrapping_sub ( s_a) ;
13
- let b = ( other ^ s_b) . wrapping_sub ( s_b) ;
14
- let s = s_a ^ s_b;
15
-
16
- let r = a. unsigned ( ) . aborting_div ( b. unsigned ( ) ) ;
17
- ( Self :: from_unsigned ( r) ^ s) - s
1
+ // see udiv.rs for more documentation
2
+
3
+ #[ cfg( not( target = "x86_64" ) ) ]
4
+ intrinsics ! {
5
+ #[ maybe_use_optimized_c_shim]
6
+ #[ arm_aeabi_alias = __aeabi_idiv]
7
+ pub extern "C" fn __divsi3( a: i32 , b: i32 ) -> i32 {
8
+ specialized_div_rem:: i32_div_rem_binary_long( a, b) . 0
18
9
}
19
- }
20
10
21
- impl Div for i32 { }
22
- impl Div for i64 { }
23
- impl Div for i128 { }
11
+ #[ maybe_use_optimized_c_shim]
12
+ pub extern "C" fn __modsi3( a: i32 , b: i32 ) -> i32 {
13
+ specialized_div_rem:: i32_div_rem_binary_long( a, b) . 1
14
+ }
15
+
16
+ #[ maybe_use_optimized_c_shim]
17
+ pub extern "C" fn __divmodsi4( a: i32 , b: i32 , rem: & mut i32 ) -> i32 {
18
+ let quo_rem = specialized_div_rem:: i32_div_rem_binary_long( a, b) ;
19
+ * rem = quo_rem. 1 ;
20
+ quo_rem. 0
21
+ }
24
22
25
- trait Mod : Int {
26
- /// Returns `a % b`
27
- fn mod_ ( self , other : Self ) -> Self {
28
- let s = other >> ( Self :: BITS - 1 ) ;
29
- // NOTE(wrapping_sub) see comment in the `div`
30
- let b = ( other ^ s) . wrapping_sub ( s) ;
31
- let s = self >> ( Self :: BITS - 1 ) ;
32
- let a = ( self ^ s) . wrapping_sub ( s) ;
23
+ #[ maybe_use_optimized_c_shim]
24
+ pub extern "C" fn __divdi3( a: i64 , b: i64 ) -> i64 {
25
+ specialized_div_rem:: i64_div_rem_delegate( a, b) . 0
26
+ }
33
27
34
- let r = a. unsigned ( ) . aborting_rem ( b. unsigned ( ) ) ;
35
- ( Self :: from_unsigned ( r) ^ s) - s
28
+ #[ maybe_use_optimized_c_shim]
29
+ pub extern "C" fn __moddi3( a: i64 , b: i64 ) -> i64 {
30
+ specialized_div_rem:: i64_div_rem_delegate( a, b) . 1
36
31
}
37
- }
38
32
39
- impl Mod for i32 { }
40
- impl Mod for i64 { }
41
- impl Mod for i128 { }
42
-
43
- trait Divmod : Int {
44
- /// Returns `a / b` and sets `*rem = n % d`
45
- fn divmod < F > ( self , other : Self , rem : & mut Self , div : F ) -> Self
46
- where
47
- F : Fn ( Self , Self ) -> Self ,
48
- {
49
- let r = div ( self , other) ;
50
- // NOTE won't overflow because it's using the result from the
51
- // previous division
52
- * rem = self - r. wrapping_mul ( other) ;
53
- r
33
+ #[ aapcs_on_arm]
34
+ pub extern "C" fn __divmoddi4( a: i64 , b: i64 , rem: & mut i64 ) -> i64 {
35
+ let quo_rem = specialized_div_rem:: i64_div_rem_delegate( a, b) ;
36
+ * rem = quo_rem. 1 ;
37
+ quo_rem. 0
54
38
}
55
- }
56
39
57
- impl Divmod for i32 { }
58
- impl Divmod for i64 { }
40
+ #[ win64_128bit_abi_hack]
41
+ pub extern "C" fn __divti3( a: i128 , b: i128 ) -> i128 {
42
+ specialized_div_rem:: i128_div_rem_trifecta( a, b) . 0
43
+ }
59
44
45
+ #[ win64_128bit_abi_hack]
46
+ pub extern "C" fn __modti3( a: i128 , b: i128 ) -> i128 {
47
+ specialized_div_rem:: i128_div_rem_trifecta( a, b) . 1
48
+ }
49
+ }
50
+
51
+ #[ cfg( target = "x86_64" ) ]
60
52
intrinsics ! {
61
53
#[ maybe_use_optimized_c_shim]
62
54
#[ arm_aeabi_alias = __aeabi_idiv]
63
55
pub extern "C" fn __divsi3( a: i32 , b: i32 ) -> i32 {
64
- a . div ( b )
56
+ specialized_div_rem :: i32_div_rem_binary_long ( a , b ) . 0
65
57
}
66
58
67
59
#[ maybe_use_optimized_c_shim]
68
- pub extern "C" fn __divdi3 ( a: i64 , b: i64 ) -> i64 {
69
- a . div ( b )
60
+ pub extern "C" fn __modsi3 ( a: i32 , b: i32 ) -> i32 {
61
+ specialized_div_rem :: i32_div_rem_binary_long ( a , b ) . 1
70
62
}
71
63
72
- #[ win64_128bit_abi_hack]
73
- pub extern "C" fn __divti3( a: i128 , b: i128 ) -> i128 {
74
- a. div( b)
64
+ #[ maybe_use_optimized_c_shim]
65
+ pub extern "C" fn __divmodsi4( a: i32 , b: i32 , rem: & mut i32 ) -> i32 {
66
+ let quo_rem = specialized_div_rem:: i32_div_rem_binary_long( a, b) ;
67
+ * rem = quo_rem. 1 ;
68
+ quo_rem. 0
75
69
}
76
70
77
71
#[ maybe_use_optimized_c_shim]
78
- pub extern "C" fn __modsi3 ( a: i32 , b: i32 ) -> i32 {
79
- a . mod_ ( b )
72
+ pub extern "C" fn __divdi3 ( a: i64 , b: i64 ) -> i64 {
73
+ specialized_div_rem :: i64_div_rem_delegate ( a , b ) . 0
80
74
}
81
75
82
76
#[ maybe_use_optimized_c_shim]
83
77
pub extern "C" fn __moddi3( a: i64 , b: i64 ) -> i64 {
84
- a . mod_ ( b )
78
+ specialized_div_rem :: i64_div_rem_delegate ( a , b ) . 1
85
79
}
86
80
87
- #[ win64_128bit_abi_hack]
88
- pub extern "C" fn __modti3( a: i128 , b: i128 ) -> i128 {
89
- a. mod_( b)
81
+ #[ aapcs_on_arm]
82
+ pub extern "C" fn __divmoddi4( a: i64 , b: i64 , rem: & mut i64 ) -> i64 {
83
+ let quo_rem = specialized_div_rem:: i64_div_rem_delegate( a, b) ;
84
+ * rem = quo_rem. 1 ;
85
+ quo_rem. 0
90
86
}
91
87
92
- #[ maybe_use_optimized_c_shim ]
93
- pub extern "C" fn __divmodsi4 ( a: i32 , b: i32 , rem : & mut i32 ) -> i32 {
94
- a . divmod ( b , rem , | a, b| __divsi3 ( a , b ) )
88
+ #[ win64_128bit_abi_hack ]
89
+ pub extern "C" fn __divti3 ( a: i128 , b: i128 ) -> i128 {
90
+ specialized_div_rem :: i128_div_rem_asymmetric ( a, b) . 0
95
91
}
96
92
97
- #[ aapcs_on_arm ]
98
- pub extern "C" fn __divmoddi4 ( a: i64 , b: i64 , rem : & mut i64 ) -> i64 {
99
- a . divmod ( b , rem , | a, b| __divdi3 ( a , b ) )
93
+ #[ win64_128bit_abi_hack ]
94
+ pub extern "C" fn __modti3 ( a: i128 , b: i128 ) -> i128 {
95
+ specialized_div_rem :: i128_div_rem_asymmetric ( a, b) . 1
100
96
}
101
- }
97
+ }
0 commit comments