@@ -96,23 +96,49 @@ 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( stage0) ]
133+ div_mod_intrinsics ! ( __udivti3, __umodti3: u64 ) ;
134+
135+ #[ cfg( not( stage0) ) ]
136+ #[ cfg( not( all( windows, target_pointer_width="64" ) ) ) ]
137+ div_mod_intrinsics ! ( __udivti3, __umodti3: u128 , u128_div_mod) ;
138+
139+ #[ cfg( not( stage0) ) ]
140+ #[ cfg( all( windows, target_pointer_width="64" ) ) ]
141+ div_mod_intrinsics ! ( __udivti3, __umodti3: u128 , u128_div_mod, :: U64x2 , :: conv) ;
116142
117143macro_rules! udivmod_inner {
118144 ( $n: expr, $d: expr, $rem: expr, $ty: ty) => { {
@@ -269,6 +295,28 @@ pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 {
269295 udivmod_inner ! ( n, d, rem, u64 )
270296}
271297
298+ macro_rules! udivmodti4 {
299+ ( $tyret: ty, $conv: expr) => {
300+ /// Returns `n / d` and sets `*rem = n % d`
301+ #[ cfg_attr( not( test) , no_mangle) ]
302+ pub extern "C" fn __udivmodti4( n: :: U128_ , d: :: U128_ , rem: Option <& mut :: U128_ >) -> $tyret {
303+ let r = u128_div_mod( n, d, rem) ;
304+ ( $conv) ( r)
305+ }
306+ }
307+ }
308+
309+ /// Returns `n / d` and sets `*rem = n % d`
310+ fn u128_div_mod ( n : :: U128_ , d : :: U128_ , rem : Option < & mut :: U128_ > ) -> :: U128_ {
311+ udivmod_inner ! ( n, d, rem, :: U128_ )
312+ }
313+
314+ #[ cfg( all( windows, target_pointer_width="64" , not( stage0) ) ) ]
315+ udivmodti4 ! ( :: U64x2 , :: conv) ;
316+
317+ #[ cfg( not( all( windows, target_pointer_width="64" , not( stage0) ) ) ) ]
318+ udivmodti4 ! ( :: U128_ , |i|{ i } ) ;
319+
272320#[ cfg( test) ]
273321mod tests {
274322 use qc:: { U32 , U64 } ;
0 commit comments