@@ -27,29 +27,53 @@ pub(crate) fn maybe_codegen<'tcx>(
2727 None
2828 }
2929 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" ,
4266 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 ) ,
4569 AbiParam :: new( fx. pointer_type) ,
4670 ] ,
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 ) ) )
5377 }
5478 }
5579 BinOp :: Add | BinOp :: Sub | BinOp :: Mul => {
@@ -85,7 +109,6 @@ pub(crate) fn maybe_codegen<'tcx>(
85109 ( BinOp :: Sub , false ) => "__rust_u128_subo" ,
86110 ( BinOp :: Sub , true ) => "__rust_i128_subo" ,
87111 ( BinOp :: Mul , false ) => "__rust_u128_mulo" ,
88- ( BinOp :: Mul , true ) => "__rust_i128_mulo" ,
89112 _ => unreachable ! ( ) ,
90113 } ;
91114 fx. lib_call ( name, param_types, vec ! [ ] , & args) ;
0 commit comments