@@ -96,23 +96,49 @@ 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
+ #[ 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
+ }
104
127
}
105
128
106
- /// Returns `n % d`
107
129
#[ 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 ) ;
111
131
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) ;
116
142
117
143
macro_rules! udivmod_inner {
118
144
( $n: expr, $d: expr, $rem: expr, $ty: ty) => { {
@@ -269,6 +295,29 @@ pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 {
269
295
udivmod_inner ! ( n, d, rem, u64 )
270
296
}
271
297
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
+ #[ cfg( not( stage0) ) ]
311
+ fn u128_div_mod ( n : u128 , d : u128 , rem : Option < & mut u128 > ) -> u128 {
312
+ udivmod_inner ! ( n, d, rem, u128 )
313
+ }
314
+
315
+ #[ cfg( all( windows, target_pointer_width="64" , not( stage0) ) ) ]
316
+ udivmodti4 ! ( :: U64x2 , :: conv) ;
317
+
318
+ #[ cfg( not( all( windows, target_pointer_width="64" , not( stage0) ) ) ) ]
319
+ udivmodti4 ! ( :: U128_ , |i|{ i } ) ;
320
+
272
321
#[ cfg( test) ]
273
322
mod tests {
274
323
use qc:: { U32 , U64 } ;
0 commit comments