@@ -96,23 +96,45 @@ 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+ 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+ }
104125}
105126
106- /// Returns `n % d`
107- #[ cfg( not( all( feature = "c" , target_arch = "x86" ) ) ) ]
108127#[ 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 ) ;
111130
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) ;
116138
117139macro_rules! udivmod_inner {
118140 ( $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 {
269291 udivmod_inner ! ( n, d, rem, u64 )
270292}
271293
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+
272319#[ cfg( test) ]
273320mod tests {
274321 use qc:: { U32 , U64 } ;
0 commit comments