@@ -27,29 +27,53 @@ pub(crate) fn maybe_codegen<'tcx>(
27
27
None
28
28
}
29
29
BinOp :: Add | BinOp :: Sub if !checked => None ,
30
- BinOp :: Mul if !checked => {
31
- let val_ty = if is_signed { fx. tcx . types . i128 } else { fx. tcx . types . u128 } ;
32
- if fx. tcx . sess . target . is_like_windows {
33
- let ret_place = CPlace :: new_stack_slot ( fx, lhs. layout ( ) ) ;
34
- let ( lhs_ptr, lhs_extra) = lhs. force_stack ( fx) ;
35
- let ( rhs_ptr, rhs_extra) = rhs. force_stack ( fx) ;
36
- assert ! ( lhs_extra. is_none( ) ) ;
37
- assert ! ( rhs_extra. is_none( ) ) ;
38
- let args =
39
- [ ret_place. to_ptr ( ) . get_addr ( fx) , lhs_ptr. get_addr ( fx) , rhs_ptr. get_addr ( fx) ] ;
40
- fx. lib_call (
41
- "__multi3" ,
30
+ BinOp :: Mul if !checked || is_signed => {
31
+ if !checked {
32
+ let val_ty = if is_signed { fx. tcx . types . i128 } else { fx. tcx . types . u128 } ;
33
+ if fx. tcx . sess . target . is_like_windows {
34
+ let ret_place = CPlace :: new_stack_slot ( fx, lhs. layout ( ) ) ;
35
+ let ( lhs_ptr, lhs_extra) = lhs. force_stack ( fx) ;
36
+ let ( rhs_ptr, rhs_extra) = rhs. force_stack ( fx) ;
37
+ assert ! ( lhs_extra. is_none( ) ) ;
38
+ assert ! ( rhs_extra. is_none( ) ) ;
39
+ let args = [
40
+ ret_place. to_ptr ( ) . get_addr ( fx) ,
41
+ lhs_ptr. get_addr ( fx) ,
42
+ rhs_ptr. get_addr ( fx) ,
43
+ ] ;
44
+ fx. lib_call (
45
+ "__multi3" ,
46
+ vec ! [
47
+ AbiParam :: special( fx. pointer_type, ArgumentPurpose :: StructReturn ) ,
48
+ AbiParam :: new( fx. pointer_type) ,
49
+ AbiParam :: new( fx. pointer_type) ,
50
+ ] ,
51
+ vec ! [ ] ,
52
+ & args,
53
+ ) ;
54
+ Some ( ret_place. to_cvalue ( fx) )
55
+ } else {
56
+ Some ( fx. easy_call ( "__multi3" , & [ lhs, rhs] , val_ty) )
57
+ }
58
+ } else {
59
+ let out_ty = fx. tcx . mk_tup ( [ lhs. layout ( ) . ty , fx. tcx . types . bool ] . iter ( ) ) ;
60
+ let oflow = CPlace :: new_stack_slot ( fx, fx. layout_of ( fx. tcx . types . i32 ) ) ;
61
+ let lhs = lhs. load_scalar ( fx) ;
62
+ let rhs = rhs. load_scalar ( fx) ;
63
+ let oflow_ptr = oflow. to_ptr ( ) . get_addr ( fx) ;
64
+ let res = fx. lib_call (
65
+ "__muloti4" ,
42
66
vec ! [
43
- AbiParam :: special ( fx . pointer_type , ArgumentPurpose :: StructReturn ) ,
44
- AbiParam :: new( fx . pointer_type ) ,
67
+ AbiParam :: new ( types :: I128 ) ,
68
+ AbiParam :: new( types :: I128 ) ,
45
69
AbiParam :: new( fx. pointer_type) ,
46
70
] ,
47
- vec ! [ ] ,
48
- & args ,
49
- ) ;
50
- Some ( ret_place . to_cvalue ( fx) )
51
- } else {
52
- Some ( fx . easy_call ( "__multi3" , & [ lhs , rhs ] , val_ty ) )
71
+ vec ! [ AbiParam :: new ( types :: I128 ) ] ,
72
+ & [ lhs , rhs , oflow_ptr ] ,
73
+ ) [ 0 ] ;
74
+ let oflow = oflow . to_cvalue ( fx) . load_scalar ( fx ) ;
75
+ let oflow = fx . bcx . ins ( ) . ireduce ( types :: I8 , oflow ) ;
76
+ Some ( CValue :: by_val_pair ( res , oflow , fx . layout_of ( out_ty ) ) )
53
77
}
54
78
}
55
79
BinOp :: Add | BinOp :: Sub | BinOp :: Mul => {
@@ -85,7 +109,6 @@ pub(crate) fn maybe_codegen<'tcx>(
85
109
( BinOp :: Sub , false ) => "__rust_u128_subo" ,
86
110
( BinOp :: Sub , true ) => "__rust_i128_subo" ,
87
111
( BinOp :: Mul , false ) => "__rust_u128_mulo" ,
88
- ( BinOp :: Mul , true ) => "__rust_i128_mulo" ,
89
112
_ => unreachable ! ( ) ,
90
113
} ;
91
114
fx. lib_call ( name, param_types, vec ! [ ] , & args) ;
0 commit comments