@@ -96,23 +96,46 @@ pub extern "C" fn __udivmodsi4(n: u32, d: u32, rem: Option<&mut u32>) -> u32 {
9696 q
9797}
9898
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+ #[ cfg_attr( not( test) , no_mangle) ]
112+ pub extern "C" fn $udiv_intr( n: $ty, d: $ty) -> $tyret {
113+ let r = $divmod_intr( n, d, None ) ;
114+ ( $conv) ( r)
115+ }
116+
117+ /// Returns `n % d`
118+ #[ cfg_attr( not( test) , no_mangle) ]
119+ pub extern "C" fn $umod_intr( a: $ty, b: $ty) -> $tyret {
120+ use core:: mem;
121+
122+ let mut rem = unsafe { mem:: uninitialized( ) } ;
123+ $divmod_intr( a, b, Some ( & mut rem) ) ;
124+ ( $conv) ( rem)
125+ }
126+ }
104127}
105128
106- /// Returns `n % d`
107129#[ cfg( not( all( feature = "c" , target_arch = "x86" ) ) ) ]
108- #[ cfg_attr( not( test) , no_mangle) ]
109- pub extern "C" fn __umoddi3 ( a : u64 , b : u64 ) -> u64 {
110- use core:: mem;
130+ div_mod_intrinsics ! ( __udivdi3, __umoddi3: u64 ) ;
111131
112- let mut rem = unsafe { mem:: uninitialized ( ) } ;
113- __udivmoddi4 ( a, b, Some ( & mut rem) ) ;
114- rem
115- }
132+ #[ cfg( not( stage0) ) ]
133+ #[ cfg( not( all( windows, target_pointer_width="64" ) ) ) ]
134+ div_mod_intrinsics ! ( __udivti3, __umodti3: u128 , u128_div_mod) ;
135+
136+ #[ cfg( not( stage0) ) ]
137+ #[ cfg( all( windows, target_pointer_width="64" ) ) ]
138+ div_mod_intrinsics ! ( __udivti3, __umodti3: u128 , u128_div_mod, :: U64x2 , :: conv) ;
116139
117140macro_rules! udivmod_inner {
118141 ( $n: expr, $d: expr, $rem: expr, $ty: ty) => { {
@@ -269,6 +292,31 @@ pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 {
269292 udivmod_inner ! ( n, d, rem, u64 )
270293}
271294
295+ macro_rules! udivmodti4 {
296+ ( $tyret: ty, $conv: expr) => {
297+ /// Returns `n / d` and sets `*rem = n % d`
298+ #[ cfg_attr( not( test) , no_mangle) ]
299+ pub extern "C" fn __udivmodti4( n: u128 , d: u128 , rem: Option <& mut u128 >) -> $tyret {
300+ let r = u128_div_mod( n, d, rem) ;
301+ ( $conv) ( r)
302+ }
303+ }
304+ }
305+
306+ /// Returns `n / d` and sets `*rem = n % d`
307+ #[ cfg( not( stage0) ) ]
308+ fn u128_div_mod ( n : u128 , d : u128 , rem : Option < & mut u128 > ) -> u128 {
309+ udivmod_inner ! ( n, d, rem, u128 )
310+ }
311+
312+ #[ cfg( not( stage0) ) ]
313+ #[ cfg( all( windows, target_pointer_width="64" ) ) ]
314+ udivmodti4 ! ( :: U64x2 , :: conv) ;
315+
316+ #[ cfg( not( stage0) ) ]
317+ #[ cfg( not( all( windows, target_pointer_width="64" ) ) ) ]
318+ udivmodti4 ! ( u128 , |i|{ i } ) ;
319+
272320#[ cfg( test) ]
273321mod tests {
274322 use qc:: { U32 , U64 } ;
0 commit comments