@@ -32,22 +32,67 @@ pub(crate) fn maybe_codegen<'tcx>(
32
32
} else {
33
33
fx. tcx . types . u128
34
34
} ;
35
- Some ( fx. easy_call ( "__multi3" , & [ lhs, rhs] , val_ty) )
35
+ if fx. tcx . sess . target . is_like_windows {
36
+ let ret_place = CPlace :: new_stack_slot ( fx, lhs. layout ( ) ) ;
37
+ let ( lhs_ptr, lhs_extra) = lhs. force_stack ( fx) ;
38
+ let ( rhs_ptr, rhs_extra) = rhs. force_stack ( fx) ;
39
+ assert ! ( lhs_extra. is_none( ) ) ;
40
+ assert ! ( rhs_extra. is_none( ) ) ;
41
+ let args = [
42
+ ret_place. to_ptr ( ) . get_addr ( fx) ,
43
+ lhs_ptr. get_addr ( fx) ,
44
+ rhs_ptr. get_addr ( fx) ,
45
+ ] ;
46
+ fx. lib_call (
47
+ "__multi3" ,
48
+ vec ! [
49
+ AbiParam :: special( pointer_ty( fx. tcx) , ArgumentPurpose :: StructReturn ) ,
50
+ AbiParam :: new( pointer_ty( fx. tcx) ) ,
51
+ AbiParam :: new( pointer_ty( fx. tcx) ) ,
52
+ ] ,
53
+ vec ! [ ] ,
54
+ & args,
55
+ ) ;
56
+ Some ( ret_place. to_cvalue ( fx) )
57
+ } else {
58
+ Some ( fx. easy_call ( "__multi3" , & [ lhs, rhs] , val_ty) )
59
+ }
36
60
}
37
61
BinOp :: Add | BinOp :: Sub | BinOp :: Mul => {
38
62
assert ! ( checked) ;
39
63
let out_ty = fx. tcx . mk_tup ( [ lhs. layout ( ) . ty , fx. tcx . types . bool ] . iter ( ) ) ;
40
64
let out_place = CPlace :: new_stack_slot ( fx, fx. layout_of ( out_ty) ) ;
41
- let param_types = vec ! [
42
- AbiParam :: special( pointer_ty( fx. tcx) , ArgumentPurpose :: StructReturn ) ,
43
- AbiParam :: new( types:: I128 ) ,
44
- AbiParam :: new( types:: I128 ) ,
45
- ] ;
46
- let args = [
47
- out_place. to_ptr ( ) . get_addr ( fx) ,
48
- lhs. load_scalar ( fx) ,
49
- rhs. load_scalar ( fx) ,
50
- ] ;
65
+ let ( param_types, args) = if fx. tcx . sess . target . is_like_windows {
66
+ let ( lhs_ptr, lhs_extra) = lhs. force_stack ( fx) ;
67
+ let ( rhs_ptr, rhs_extra) = rhs. force_stack ( fx) ;
68
+ assert ! ( lhs_extra. is_none( ) ) ;
69
+ assert ! ( rhs_extra. is_none( ) ) ;
70
+ (
71
+ vec ! [
72
+ AbiParam :: special( pointer_ty( fx. tcx) , ArgumentPurpose :: StructReturn ) ,
73
+ AbiParam :: new( pointer_ty( fx. tcx) ) ,
74
+ AbiParam :: new( pointer_ty( fx. tcx) ) ,
75
+ ] ,
76
+ [
77
+ out_place. to_ptr ( ) . get_addr ( fx) ,
78
+ lhs_ptr. get_addr ( fx) ,
79
+ rhs_ptr. get_addr ( fx) ,
80
+ ] ,
81
+ )
82
+ } else {
83
+ (
84
+ vec ! [
85
+ AbiParam :: special( pointer_ty( fx. tcx) , ArgumentPurpose :: StructReturn ) ,
86
+ AbiParam :: new( types:: I128 ) ,
87
+ AbiParam :: new( types:: I128 ) ,
88
+ ] ,
89
+ [
90
+ out_place. to_ptr ( ) . get_addr ( fx) ,
91
+ lhs. load_scalar ( fx) ,
92
+ rhs. load_scalar ( fx) ,
93
+ ] ,
94
+ )
95
+ } ;
51
96
let name = match ( bin_op, is_signed) {
52
97
( BinOp :: Add , false ) => "__rust_u128_addo" ,
53
98
( BinOp :: Add , true ) => "__rust_i128_addo" ,
@@ -61,20 +106,36 @@ pub(crate) fn maybe_codegen<'tcx>(
61
106
Some ( out_place. to_cvalue ( fx) )
62
107
}
63
108
BinOp :: Offset => unreachable ! ( "offset should only be used on pointers, not 128bit ints" ) ,
64
- BinOp :: Div => {
65
- assert ! ( !checked) ;
66
- if is_signed {
67
- Some ( fx. easy_call ( "__divti3" , & [ lhs, rhs] , fx. tcx . types . i128 ) )
68
- } else {
69
- Some ( fx. easy_call ( "__udivti3" , & [ lhs, rhs] , fx. tcx . types . u128 ) )
70
- }
71
- }
72
- BinOp :: Rem => {
109
+ BinOp :: Div | BinOp :: Rem => {
73
110
assert ! ( !checked) ;
74
- if is_signed {
75
- Some ( fx. easy_call ( "__modti3" , & [ lhs, rhs] , fx. tcx . types . i128 ) )
111
+ let name = match ( bin_op, is_signed) {
112
+ ( BinOp :: Div , false ) => "__udivti3" ,
113
+ ( BinOp :: Div , true ) => "__divti3" ,
114
+ ( BinOp :: Rem , false ) => "__umodti3" ,
115
+ ( BinOp :: Rem , true ) => "__modti3" ,
116
+ _ => unreachable ! ( ) ,
117
+ } ;
118
+ if fx. tcx . sess . target . is_like_windows {
119
+ let ( lhs_ptr, lhs_extra) = lhs. force_stack ( fx) ;
120
+ let ( rhs_ptr, rhs_extra) = rhs. force_stack ( fx) ;
121
+ assert ! ( lhs_extra. is_none( ) ) ;
122
+ assert ! ( rhs_extra. is_none( ) ) ;
123
+ let args = [ lhs_ptr. get_addr ( fx) , rhs_ptr. get_addr ( fx) ] ;
124
+ let ret = fx. lib_call (
125
+ name,
126
+ vec ! [
127
+ AbiParam :: new( pointer_ty( fx. tcx) ) ,
128
+ AbiParam :: new( pointer_ty( fx. tcx) ) ,
129
+ ] ,
130
+ vec ! [ AbiParam :: new( types:: I64X2 ) ] ,
131
+ & args,
132
+ ) [ 0 ] ;
133
+ // FIXME use bitcast instead of store to get from i64x2 to i128
134
+ let ret_place = CPlace :: new_stack_slot ( fx, lhs. layout ( ) ) ;
135
+ ret_place. to_ptr ( ) . store ( fx, ret, MemFlags :: trusted ( ) ) ;
136
+ Some ( ret_place. to_cvalue ( fx) )
76
137
} else {
77
- Some ( fx. easy_call ( "__umodti3" , & [ lhs, rhs] , fx . tcx . types . u128 ) )
138
+ Some ( fx. easy_call ( name , & [ lhs, rhs] , lhs . layout ( ) . ty ) )
78
139
}
79
140
}
80
141
BinOp :: Lt | BinOp :: Le | BinOp :: Eq | BinOp :: Ge | BinOp :: Gt | BinOp :: Ne => {
@@ -140,20 +201,24 @@ pub(crate) fn maybe_codegen<'tcx>(
140
201
141
202
let truncated_rhs = clif_intcast ( fx, rhs_val, types:: I32 , false ) ;
142
203
let truncated_rhs = CValue :: by_val ( truncated_rhs, fx. layout_of ( fx. tcx . types . u32 ) ) ;
143
- let val = match ( bin_op, is_signed) {
144
- ( BinOp :: Shl , false ) => {
145
- fx. easy_call ( "__ashlti3" , & [ lhs, truncated_rhs] , fx. tcx . types . u128 )
146
- }
147
- ( BinOp :: Shl , true ) => {
148
- fx. easy_call ( "__ashlti3" , & [ lhs, truncated_rhs] , fx. tcx . types . i128 )
149
- }
150
- ( BinOp :: Shr , false ) => {
151
- fx. easy_call ( "__lshrti3" , & [ lhs, truncated_rhs] , fx. tcx . types . u128 )
152
- }
153
- ( BinOp :: Shr , true ) => {
154
- fx. easy_call ( "__ashrti3" , & [ lhs, truncated_rhs] , fx. tcx . types . i128 )
155
- }
156
- ( _, _) => unreachable ! ( ) ,
204
+ let name = match ( bin_op, is_signed) {
205
+ ( BinOp :: Shl , false ) => "__ashlti3" ,
206
+ ( BinOp :: Shl , true ) => "__ashlti3" ,
207
+ ( BinOp :: Shr , false ) => "__lshrti3" ,
208
+ ( BinOp :: Shr , true ) => "__ashrti3" ,
209
+ _ => unreachable ! ( ) ,
210
+ } ;
211
+ let val = if fx. tcx . sess . target . is_like_windows {
212
+ crate :: trap:: trap_unimplemented_ret_value (
213
+ fx,
214
+ lhs. layout ( ) ,
215
+ & format ! (
216
+ "{:?} is not implemented on Windows for 128bit ints." ,
217
+ bin_op,
218
+ ) ,
219
+ )
220
+ } else {
221
+ fx. easy_call ( name, & [ lhs, truncated_rhs] , lhs. layout ( ) . ty )
157
222
} ;
158
223
if let Some ( is_overflow) = is_overflow {
159
224
let out_ty = fx. tcx . mk_tup ( [ lhs. layout ( ) . ty , fx. tcx . types . bool ] . iter ( ) ) ;
0 commit comments