1
- #[ cfg( not( all( feature = "c" , target_arch = "x86" ) ) ) ]
2
1
use int:: LargeInt ;
3
2
use int:: Int ;
4
3
5
4
macro_rules! mul {
6
- ( $intrinsic: ident: $ty: ty) => {
5
+ ( $intrinsic: ident: $ty: ty, $tyh : ty ) => {
7
6
/// Returns `a * b`
8
7
#[ cfg_attr( not( test) , no_mangle) ]
9
8
pub extern "C" fn $intrinsic( a: $ty, b: $ty) -> $ty {
@@ -14,24 +13,29 @@ macro_rules! mul {
14
13
low &= lower_mask;
15
14
t += ( a. low( ) >> half_bits) . wrapping_mul( b. low( ) & lower_mask) ;
16
15
low += ( t & lower_mask) << half_bits;
17
- let mut high = t >> half_bits;
16
+ let mut high = ( t >> half_bits) as $tyh ;
18
17
t = low >> half_bits;
19
18
low &= lower_mask;
20
19
t += ( b. low( ) >> half_bits) . wrapping_mul( a. low( ) & lower_mask) ;
21
20
low += ( t & lower_mask) << half_bits;
22
- high += t >> half_bits;
23
- high += ( a. low( ) >> half_bits) . wrapping_mul( b. low( ) >> half_bits) ;
24
- high = high. wrapping_add( a. high( ) . wrapping_mul( b. low( ) ) . wrapping_add( a. low( ) . wrapping_mul( b. high( ) ) ) ) ;
21
+ high += ( t >> half_bits) as $tyh;
22
+ high += ( a. low( ) >> half_bits) . wrapping_mul( b. low( ) >> half_bits) as $tyh;
23
+ high = high. wrapping_add( a. high( ) . wrapping_mul( b. low( ) as $tyh) )
24
+ . wrapping_add( ( a. low( ) as $tyh) . wrapping_mul( b. high( ) ) ) ;
25
25
<$ty>:: from_parts( low, high)
26
26
}
27
27
}
28
28
}
29
29
30
30
macro_rules! mulo {
31
31
( $intrinsic: ident: $ty: ty) => {
32
+ // Default is "C" ABI
33
+ mulo!( $intrinsic: $ty, "C" ) ;
34
+ } ;
35
+ ( $intrinsic: ident: $ty: ty, $abi: tt) => {
32
36
/// Returns `a * b` and sets `*overflow = 1` if `a * b` overflows
33
37
#[ cfg_attr( not( test) , no_mangle) ]
34
- pub extern "C" fn $intrinsic( a: $ty, b: $ty, overflow: & mut i32 ) -> $ty {
38
+ pub extern $abi fn $intrinsic( a: $ty, b: $ty, overflow: & mut i32 ) -> $ty {
35
39
* overflow = 0 ;
36
40
let result = a. wrapping_mul( b) ;
37
41
if a == <$ty>:: min_value( ) {
@@ -69,11 +73,25 @@ macro_rules! mulo {
69
73
}
70
74
71
75
#[ cfg( not( all( feature = "c" , target_arch = "x86" ) ) ) ]
72
- mul ! ( __muldi3: u64 ) ;
76
+ mul ! ( __muldi3: u64 , u32 ) ;
77
+
78
+ #[ cfg( stage0) ]
79
+ mul ! ( __multi3: u64 , u32 ) ;
80
+ #[ cfg( not( stage0) ) ]
81
+ mul ! ( __multi3: i128 , i64 ) ;
73
82
74
83
mulo ! ( __mulosi4: i32 ) ;
75
84
mulo ! ( __mulodi4: i64 ) ;
76
85
86
+ #[ cfg( stage0) ]
87
+ mulo ! ( __muloti4: i64 ) ;
88
+ #[ cfg( not( stage0) ) ]
89
+ #[ cfg( all( windows, target_pointer_width="64" ) ) ]
90
+ mulo ! ( __muloti4: i128 , "unadjusted" ) ;
91
+ #[ cfg( not( stage0) ) ]
92
+ #[ cfg( not( all( windows, target_pointer_width="64" ) ) ) ]
93
+ mulo ! ( __muloti4: i128 ) ;
94
+
77
95
#[ cfg( test) ]
78
96
mod tests {
79
97
use qc:: { I32 , I64 , U64 } ;
0 commit comments