@@ -96,23 +96,45 @@ pub extern "C" fn __udivmodsi4(n: u32, d: u32, rem: Option<&mut u32>) -> u32 {
96
96
q
97
97
}
98
98
99
- /// Returns `n / d`
100
- #[ cfg_attr( not( test) , no_mangle) ]
101
- #[ cfg( not( all( feature = "c" , target_arch = "x86" ) ) ) ]
102
- pub extern "C" fn __udivdi3 ( n : u64 , d : u64 ) -> u64 {
103
- __udivmoddi4 ( n, d, None )
99
+ macro_rules! div_mod_intrinsics {
100
+ ( $udiv_intr: ident, $umod_intr: ident : $ty: ty) => {
101
+ div_mod_intrinsics!( $udiv_intr, $umod_intr : $ty,
102
+ __udivmoddi4) ;
103
+ } ;
104
+ ( $udiv_intr: ident, $umod_intr: ident : $ty: ty, $divmod_intr: expr) => {
105
+ div_mod_intrinsics!( $udiv_intr, $umod_intr : $ty,
106
+ $divmod_intr, $ty, |i|{ i } ) ;
107
+ } ;
108
+ ( $udiv_intr: ident, $umod_intr: ident : $ty: ty, $divmod_intr: expr,
109
+ $tyret: ty, $conv: expr) => {
110
+ /// Returns `n / d`
111
+ pub extern "C" fn $udiv_intr( n: $ty, d: $ty) -> $tyret {
112
+ let r = $divmod_intr( n, d, None ) ;
113
+ ( $conv) ( r)
114
+ }
115
+
116
+ /// Returns `n % d`
117
+ pub extern "C" fn $umod_intr( a: $ty, b: $ty) -> $tyret {
118
+ use core:: mem;
119
+
120
+ let mut rem = unsafe { mem:: uninitialized( ) } ;
121
+ $divmod_intr( a, b, Some ( & mut rem) ) ;
122
+ ( $conv) ( rem)
123
+ }
124
+ }
104
125
}
105
126
106
- /// Returns `n % d`
107
- #[ cfg( not( all( feature = "c" , target_arch = "x86" ) ) ) ]
108
127
#[ cfg_attr( not( test) , no_mangle) ]
109
- pub extern "C" fn __umoddi3 ( a : u64 , b : u64 ) -> u64 {
110
- use core :: mem ;
128
+ # [ cfg ( not ( all ( feature = "c" , target_arch = "x86" ) ) ) ]
129
+ div_mod_intrinsics ! ( __udivdi3 , __umoddi3 : u64 ) ;
111
130
112
- let mut rem = unsafe { mem:: uninitialized ( ) } ;
113
- __udivmoddi4 ( a, b, Some ( & mut rem) ) ;
114
- rem
115
- }
131
+ #[ cfg( not( stage0) ) ]
132
+ #[ cfg( not( all( windows, target_pointer_width="64" ) ) ) ]
133
+ div_mod_intrinsics ! ( __udivti3, __umodti3: u128 , u128_div_mod) ;
134
+
135
+ #[ cfg( not( stage0) ) ]
136
+ #[ cfg( all( windows, target_pointer_width="64" ) ) ]
137
+ div_mod_intrinsics ! ( __udivti3, __umodti3: u128 , u128_div_mod, :: U64x2 , :: conv) ;
116
138
117
139
macro_rules! udivmod_inner {
118
140
( $n: expr, $d: expr, $rem: expr, $ty: ty) => { {
@@ -269,6 +291,31 @@ pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 {
269
291
udivmod_inner ! ( n, d, rem, u64 )
270
292
}
271
293
294
+ macro_rules! udivmodti4 {
295
+ ( $tyret: ty, $conv: expr) => {
296
+ /// Returns `n / d` and sets `*rem = n % d`
297
+ #[ cfg_attr( not( test) , no_mangle) ]
298
+ pub extern "C" fn __udivmodti4( n: u128 , d: u128 , rem: Option <& mut u128 >) -> $tyret {
299
+ let r = u128_div_mod( n, d, rem) ;
300
+ ( $conv) ( r)
301
+ }
302
+ }
303
+ }
304
+
305
+ /// Returns `n / d` and sets `*rem = n % d`
306
+ #[ cfg( not( stage0) ) ]
307
+ fn u128_div_mod ( n : u128 , d : u128 , rem : Option < & mut u128 > ) -> u128 {
308
+ udivmod_inner ! ( n, d, rem, u128 )
309
+ }
310
+
311
+ #[ cfg( not( stage0) ) ]
312
+ #[ cfg( all( windows, target_pointer_width="64" ) ) ]
313
+ udivmodti4 ! ( :: U64x2 , :: conv) ;
314
+
315
+ #[ cfg( not( stage0) ) ]
316
+ #[ cfg( not( all( windows, target_pointer_width="64" ) ) ) ]
317
+ udivmodti4 ! ( u128 , |i|{ i } ) ;
318
+
272
319
#[ cfg( test) ]
273
320
mod tests {
274
321
use qc:: { U32 , U64 } ;
0 commit comments