1
- use rustc_middle:: { mir, mir:: BinOp } ;
1
+ use rustc_middle:: { mir, mir:: BinOp , ty } ;
2
2
use rustc_target:: abi:: Align ;
3
3
4
4
use crate :: * ;
5
5
use helpers:: check_arg_count;
6
6
7
7
pub enum AtomicOp {
8
+ /// The `bool` indicates whether the result of the operation should be negated
9
+ /// (must be a boolean-typed operation).
8
10
MirOp ( mir:: BinOp , bool ) ,
9
11
Max ,
10
12
Min ,
@@ -20,236 +22,99 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
20
22
dest : & PlaceTy < ' tcx , Tag > ,
21
23
) -> InterpResult < ' tcx > {
22
24
let this = self . eval_context_mut ( ) ;
23
- match intrinsic_name {
24
- "load_seqcst" => this. atomic_load ( args, dest, AtomicReadOrd :: SeqCst ) ?,
25
- "load_relaxed" => this. atomic_load ( args, dest, AtomicReadOrd :: Relaxed ) ?,
26
- "load_acquire" => this. atomic_load ( args, dest, AtomicReadOrd :: Acquire ) ?,
27
-
28
- "store_seqcst" => this. atomic_store ( args, AtomicWriteOrd :: SeqCst ) ?,
29
- "store_relaxed" => this. atomic_store ( args, AtomicWriteOrd :: Relaxed ) ?,
30
- "store_release" => this. atomic_store ( args, AtomicWriteOrd :: Release ) ?,
31
-
32
- "fence_acquire" => this. atomic_fence ( args, AtomicFenceOrd :: Acquire ) ?,
33
- "fence_release" => this. atomic_fence ( args, AtomicFenceOrd :: Release ) ?,
34
- "fence_acqrel" => this. atomic_fence ( args, AtomicFenceOrd :: AcqRel ) ?,
35
- "fence_seqcst" => this. atomic_fence ( args, AtomicFenceOrd :: SeqCst ) ?,
36
-
37
- "singlethreadfence_acquire" => this. compiler_fence ( args, AtomicFenceOrd :: Acquire ) ?,
38
- "singlethreadfence_release" => this. compiler_fence ( args, AtomicFenceOrd :: Release ) ?,
39
- "singlethreadfence_acqrel" => this. compiler_fence ( args, AtomicFenceOrd :: AcqRel ) ?,
40
- "singlethreadfence_seqcst" => this. compiler_fence ( args, AtomicFenceOrd :: SeqCst ) ?,
41
-
42
- "xchg_seqcst" => this. atomic_exchange ( args, dest, AtomicRwOrd :: SeqCst ) ?,
43
- "xchg_acquire" => this. atomic_exchange ( args, dest, AtomicRwOrd :: Acquire ) ?,
44
- "xchg_release" => this. atomic_exchange ( args, dest, AtomicRwOrd :: Release ) ?,
45
- "xchg_acqrel" => this. atomic_exchange ( args, dest, AtomicRwOrd :: AcqRel ) ?,
46
- "xchg_relaxed" => this. atomic_exchange ( args, dest, AtomicRwOrd :: Relaxed ) ?,
47
-
48
- #[ rustfmt:: skip]
49
- "cxchg_seqcst_seqcst" =>
50
- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: SeqCst , AtomicReadOrd :: SeqCst ) ?,
51
- #[ rustfmt:: skip]
52
- "cxchg_seqcst_acquire" =>
53
- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: SeqCst , AtomicReadOrd :: Acquire ) ?,
54
- #[ rustfmt:: skip]
55
- "cxchg_seqcst_relaxed" =>
56
- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: SeqCst , AtomicReadOrd :: Relaxed ) ?,
57
- #[ rustfmt:: skip]
58
- "cxchg_acqrel_seqcst" =>
59
- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: AcqRel , AtomicReadOrd :: SeqCst ) ?,
60
- #[ rustfmt:: skip]
61
- "cxchg_acqrel_acquire" =>
62
- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: AcqRel , AtomicReadOrd :: Acquire ) ?,
63
- #[ rustfmt:: skip]
64
- "cxchg_acqrel_relaxed" =>
65
- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: AcqRel , AtomicReadOrd :: Relaxed ) ?,
66
- #[ rustfmt:: skip]
67
- "cxchg_acquire_seqcst" =>
68
- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Acquire , AtomicReadOrd :: SeqCst ) ?,
69
- #[ rustfmt:: skip]
70
- "cxchg_acquire_acquire" =>
71
- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Acquire , AtomicReadOrd :: Acquire ) ?,
72
- #[ rustfmt:: skip]
73
- "cxchg_acquire_relaxed" =>
74
- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Acquire , AtomicReadOrd :: Relaxed ) ?,
75
- #[ rustfmt:: skip]
76
- "cxchg_release_seqcst" =>
77
- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Release , AtomicReadOrd :: SeqCst ) ?,
78
- #[ rustfmt:: skip]
79
- "cxchg_release_acquire" =>
80
- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Release , AtomicReadOrd :: Acquire ) ?,
81
- #[ rustfmt:: skip]
82
- "cxchg_release_relaxed" =>
83
- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Release , AtomicReadOrd :: Relaxed ) ?,
84
- #[ rustfmt:: skip]
85
- "cxchg_relaxed_seqcst" =>
86
- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Relaxed , AtomicReadOrd :: SeqCst ) ?,
87
- #[ rustfmt:: skip]
88
- "cxchg_relaxed_acquire" =>
89
- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Relaxed , AtomicReadOrd :: Acquire ) ?,
90
- #[ rustfmt:: skip]
91
- "cxchg_relaxed_relaxed" =>
92
- this. atomic_compare_exchange ( args, dest, AtomicRwOrd :: Relaxed , AtomicReadOrd :: Relaxed ) ?,
93
-
94
- #[ rustfmt:: skip]
95
- "cxchgweak_seqcst_seqcst" =>
96
- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: SeqCst , AtomicReadOrd :: SeqCst ) ?,
97
- #[ rustfmt:: skip]
98
- "cxchgweak_seqcst_acquire" =>
99
- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: SeqCst , AtomicReadOrd :: Acquire ) ?,
100
- #[ rustfmt:: skip]
101
- "cxchgweak_seqcst_relaxed" =>
102
- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: SeqCst , AtomicReadOrd :: Relaxed ) ?,
103
- #[ rustfmt:: skip]
104
- "cxchgweak_acqrel_seqcst" =>
105
- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: AcqRel , AtomicReadOrd :: SeqCst ) ?,
106
- #[ rustfmt:: skip]
107
- "cxchgweak_acqrel_acquire" =>
108
- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: AcqRel , AtomicReadOrd :: Acquire ) ?,
109
- #[ rustfmt:: skip]
110
- "cxchgweak_acqrel_relaxed" =>
111
- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: AcqRel , AtomicReadOrd :: Relaxed ) ?,
112
- #[ rustfmt:: skip]
113
- "cxchgweak_acquire_seqcst" =>
114
- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Acquire , AtomicReadOrd :: SeqCst ) ?,
115
- #[ rustfmt:: skip]
116
- "cxchgweak_acquire_acquire" =>
117
- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Acquire , AtomicReadOrd :: Acquire ) ?,
118
- #[ rustfmt:: skip]
119
- "cxchgweak_acquire_relaxed" =>
120
- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Acquire , AtomicReadOrd :: Relaxed ) ?,
121
- #[ rustfmt:: skip]
122
- "cxchgweak_release_seqcst" =>
123
- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Release , AtomicReadOrd :: SeqCst ) ?,
124
- #[ rustfmt:: skip]
125
- "cxchgweak_release_acquire" =>
126
- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Release , AtomicReadOrd :: Acquire ) ?,
127
- #[ rustfmt:: skip]
128
- "cxchgweak_release_relaxed" =>
129
- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Release , AtomicReadOrd :: Relaxed ) ?,
130
- #[ rustfmt:: skip]
131
- "cxchgweak_relaxed_seqcst" =>
132
- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Relaxed , AtomicReadOrd :: SeqCst ) ?,
133
- #[ rustfmt:: skip]
134
- "cxchgweak_relaxed_acquire" =>
135
- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Relaxed , AtomicReadOrd :: Acquire ) ?,
136
- #[ rustfmt:: skip]
137
- "cxchgweak_relaxed_relaxed" =>
138
- this. atomic_compare_exchange_weak ( args, dest, AtomicRwOrd :: Relaxed , AtomicReadOrd :: Relaxed ) ?,
139
-
140
- #[ rustfmt:: skip]
141
- "or_seqcst" =>
142
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitOr , false ) , AtomicRwOrd :: SeqCst ) ?,
143
- #[ rustfmt:: skip]
144
- "or_acquire" =>
145
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitOr , false ) , AtomicRwOrd :: Acquire ) ?,
146
- #[ rustfmt:: skip]
147
- "or_release" =>
148
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitOr , false ) , AtomicRwOrd :: Release ) ?,
149
- #[ rustfmt:: skip]
150
- "or_acqrel" =>
151
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitOr , false ) , AtomicRwOrd :: AcqRel ) ?,
152
- #[ rustfmt:: skip]
153
- "or_relaxed" =>
154
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitOr , false ) , AtomicRwOrd :: Relaxed ) ?,
155
- #[ rustfmt:: skip]
156
- "xor_seqcst" =>
157
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitXor , false ) , AtomicRwOrd :: SeqCst ) ?,
158
- #[ rustfmt:: skip]
159
- "xor_acquire" =>
160
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitXor , false ) , AtomicRwOrd :: Acquire ) ?,
161
- #[ rustfmt:: skip]
162
- "xor_release" =>
163
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitXor , false ) , AtomicRwOrd :: Release ) ?,
164
- #[ rustfmt:: skip]
165
- "xor_acqrel" =>
166
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitXor , false ) , AtomicRwOrd :: AcqRel ) ?,
167
- #[ rustfmt:: skip]
168
- "xor_relaxed" =>
169
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitXor , false ) , AtomicRwOrd :: Relaxed ) ?,
170
- #[ rustfmt:: skip]
171
- "and_seqcst" =>
172
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , false ) , AtomicRwOrd :: SeqCst ) ?,
173
- #[ rustfmt:: skip]
174
- "and_acquire" =>
175
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , false ) , AtomicRwOrd :: Acquire ) ?,
176
- #[ rustfmt:: skip]
177
- "and_release" =>
178
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , false ) , AtomicRwOrd :: Release ) ?,
179
- #[ rustfmt:: skip]
180
- "and_acqrel" =>
181
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , false ) , AtomicRwOrd :: AcqRel ) ?,
182
- #[ rustfmt:: skip]
183
- "and_relaxed" =>
184
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , false ) , AtomicRwOrd :: Relaxed ) ?,
185
- #[ rustfmt:: skip]
186
- "nand_seqcst" =>
187
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , true ) , AtomicRwOrd :: SeqCst ) ?,
188
- #[ rustfmt:: skip]
189
- "nand_acquire" =>
190
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , true ) , AtomicRwOrd :: Acquire ) ?,
191
- #[ rustfmt:: skip]
192
- "nand_release" =>
193
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , true ) , AtomicRwOrd :: Release ) ?,
194
- #[ rustfmt:: skip]
195
- "nand_acqrel" =>
196
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , true ) , AtomicRwOrd :: AcqRel ) ?,
197
- #[ rustfmt:: skip]
198
- "nand_relaxed" =>
199
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , true ) , AtomicRwOrd :: Relaxed ) ?,
200
- #[ rustfmt:: skip]
201
- "xadd_seqcst" =>
202
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Add , false ) , AtomicRwOrd :: SeqCst ) ?,
203
- #[ rustfmt:: skip]
204
- "xadd_acquire" =>
205
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Add , false ) , AtomicRwOrd :: Acquire ) ?,
206
- #[ rustfmt:: skip]
207
- "xadd_release" =>
208
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Add , false ) , AtomicRwOrd :: Release ) ?,
209
- #[ rustfmt:: skip]
210
- "xadd_acqrel" =>
211
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Add , false ) , AtomicRwOrd :: AcqRel ) ?,
212
- #[ rustfmt:: skip]
213
- "xadd_relaxed" =>
214
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Add , false ) , AtomicRwOrd :: Relaxed ) ?,
215
- #[ rustfmt:: skip]
216
- "xsub_seqcst" =>
217
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Sub , false ) , AtomicRwOrd :: SeqCst ) ?,
218
- #[ rustfmt:: skip]
219
- "xsub_acquire" =>
220
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Sub , false ) , AtomicRwOrd :: Acquire ) ?,
221
- #[ rustfmt:: skip]
222
- "xsub_release" =>
223
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Sub , false ) , AtomicRwOrd :: Release ) ?,
224
- #[ rustfmt:: skip]
225
- "xsub_acqrel" =>
226
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Sub , false ) , AtomicRwOrd :: AcqRel ) ?,
227
- #[ rustfmt:: skip]
228
- "xsub_relaxed" =>
229
- this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Sub , false ) , AtomicRwOrd :: Relaxed ) ?,
230
-
231
- "min_seqcst" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: SeqCst ) ?,
232
- "min_acquire" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: Acquire ) ?,
233
- "min_release" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: Release ) ?,
234
- "min_acqrel" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: AcqRel ) ?,
235
- "min_relaxed" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: Relaxed ) ?,
236
- "max_seqcst" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: SeqCst ) ?,
237
- "max_acquire" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: Acquire ) ?,
238
- "max_release" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: Release ) ?,
239
- "max_acqrel" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: AcqRel ) ?,
240
- "max_relaxed" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: Relaxed ) ?,
241
- "umin_seqcst" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: SeqCst ) ?,
242
- "umin_acquire" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: Acquire ) ?,
243
- "umin_release" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: Release ) ?,
244
- "umin_acqrel" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: AcqRel ) ?,
245
- "umin_relaxed" => this. atomic_op ( args, dest, AtomicOp :: Min , AtomicRwOrd :: Relaxed ) ?,
246
- "umax_seqcst" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: SeqCst ) ?,
247
- "umax_acquire" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: Acquire ) ?,
248
- "umax_release" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: Release ) ?,
249
- "umax_acqrel" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: AcqRel ) ?,
250
- "umax_relaxed" => this. atomic_op ( args, dest, AtomicOp :: Max , AtomicRwOrd :: Relaxed ) ?,
251
-
252
- name => throw_unsup_format ! ( "unimplemented intrinsic: `atomic_{name}`" ) ,
25
+
26
+ let intrinsic_structure: Vec < _ > = intrinsic_name. split ( '_' ) . collect ( ) ;
27
+
28
+ fn read_ord < ' tcx > ( ord : & str ) -> InterpResult < ' tcx , AtomicReadOrd > {
29
+ Ok ( match ord {
30
+ "seqcst" => AtomicReadOrd :: SeqCst ,
31
+ "acquire" => AtomicReadOrd :: Acquire ,
32
+ "relaxed" => AtomicReadOrd :: Relaxed ,
33
+ _ => throw_unsup_format ! ( "unsupported read ordering `{ord}`" ) ,
34
+ } )
35
+ }
36
+
37
+ fn write_ord < ' tcx > ( ord : & str ) -> InterpResult < ' tcx , AtomicWriteOrd > {
38
+ Ok ( match ord {
39
+ "seqcst" => AtomicWriteOrd :: SeqCst ,
40
+ "release" => AtomicWriteOrd :: Release ,
41
+ "relaxed" => AtomicWriteOrd :: Relaxed ,
42
+ _ => throw_unsup_format ! ( "unsupported write ordering `{ord}`" ) ,
43
+ } )
44
+ }
45
+
46
+ fn rw_ord < ' tcx > ( ord : & str ) -> InterpResult < ' tcx , AtomicRwOrd > {
47
+ Ok ( match ord {
48
+ "seqcst" => AtomicRwOrd :: SeqCst ,
49
+ "acqrel" => AtomicRwOrd :: AcqRel ,
50
+ "acquire" => AtomicRwOrd :: Acquire ,
51
+ "release" => AtomicRwOrd :: Release ,
52
+ "relaxed" => AtomicRwOrd :: Relaxed ,
53
+ _ => throw_unsup_format ! ( "unsupported read-write ordering `{ord}`" ) ,
54
+ } )
55
+ }
56
+
57
+ fn fence_ord < ' tcx > ( ord : & str ) -> InterpResult < ' tcx , AtomicFenceOrd > {
58
+ Ok ( match ord {
59
+ "seqcst" => AtomicFenceOrd :: SeqCst ,
60
+ "acqrel" => AtomicFenceOrd :: AcqRel ,
61
+ "acquire" => AtomicFenceOrd :: Acquire ,
62
+ "release" => AtomicFenceOrd :: Release ,
63
+ _ => throw_unsup_format ! ( "unsupported fence ordering `{ord}`" ) ,
64
+ } )
65
+ }
66
+
67
+ match & * intrinsic_structure {
68
+ [ "load" , ord] => this. atomic_load ( args, dest, read_ord ( ord) ?) ?,
69
+ [ "store" , ord] => this. atomic_store ( args, write_ord ( ord) ?) ?,
70
+
71
+ [ "fence" , ord] => this. atomic_fence ( args, fence_ord ( ord) ?) ?,
72
+ [ "singlethreadfence" , ord] => this. compiler_fence ( args, fence_ord ( ord) ?) ?,
73
+
74
+ [ "xchg" , ord] => this. atomic_exchange ( args, dest, rw_ord ( ord) ?) ?,
75
+ [ "cxchg" , ord1, ord2] =>
76
+ this. atomic_compare_exchange ( args, dest, rw_ord ( ord1) ?, read_ord ( ord2) ?) ?,
77
+ [ "cxchgweak" , ord1, ord2] =>
78
+ this. atomic_compare_exchange_weak ( args, dest, rw_ord ( ord1) ?, read_ord ( ord2) ?) ?,
79
+
80
+ [ "or" , ord] =>
81
+ this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitOr , false ) , rw_ord ( ord) ?) ?,
82
+ [ "xor" , ord] =>
83
+ this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitXor , false ) , rw_ord ( ord) ?) ?,
84
+ [ "and" , ord] =>
85
+ this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , false ) , rw_ord ( ord) ?) ?,
86
+ [ "nand" , ord] =>
87
+ this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: BitAnd , true ) , rw_ord ( ord) ?) ?,
88
+ [ "xadd" , ord] =>
89
+ this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Add , false ) , rw_ord ( ord) ?) ?,
90
+ [ "xsub" , ord] =>
91
+ this. atomic_op ( args, dest, AtomicOp :: MirOp ( BinOp :: Sub , false ) , rw_ord ( ord) ?) ?,
92
+ [ "min" , ord] => {
93
+ // Later we will use the type to indicate signed vs unsigned,
94
+ // so make sure it matches the intrinsic name.
95
+ assert ! ( matches!( args[ 1 ] . layout. ty. kind( ) , ty:: Int ( _) ) ) ;
96
+ this. atomic_op ( args, dest, AtomicOp :: Min , rw_ord ( ord) ?) ?;
97
+ }
98
+ [ "umin" , ord] => {
99
+ // Later we will use the type to indicate signed vs unsigned,
100
+ // so make sure it matches the intrinsic name.
101
+ assert ! ( matches!( args[ 1 ] . layout. ty. kind( ) , ty:: Uint ( _) ) ) ;
102
+ this. atomic_op ( args, dest, AtomicOp :: Min , rw_ord ( ord) ?) ?;
103
+ }
104
+ [ "max" , ord] => {
105
+ // Later we will use the type to indicate signed vs unsigned,
106
+ // so make sure it matches the intrinsic name.
107
+ assert ! ( matches!( args[ 1 ] . layout. ty. kind( ) , ty:: Int ( _) ) ) ;
108
+ this. atomic_op ( args, dest, AtomicOp :: Max , rw_ord ( ord) ?) ?;
109
+ }
110
+ [ "umax" , ord] => {
111
+ // Later we will use the type to indicate signed vs unsigned,
112
+ // so make sure it matches the intrinsic name.
113
+ assert ! ( matches!( args[ 1 ] . layout. ty. kind( ) , ty:: Uint ( _) ) ) ;
114
+ this. atomic_op ( args, dest, AtomicOp :: Max , rw_ord ( ord) ?) ?;
115
+ }
116
+
117
+ _ => throw_unsup_format ! ( "unimplemented intrinsic: `atomic_{intrinsic_name}`" ) ,
253
118
}
254
119
Ok ( ( ) )
255
120
}
@@ -343,14 +208,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
343
208
344
209
let [ place, rhs] = check_arg_count ( args) ?;
345
210
let place = this. deref_operand ( place) ?;
211
+ let rhs = this. read_immediate ( rhs) ?;
346
212
347
213
if !place. layout . ty . is_integral ( ) && !place. layout . ty . is_unsafe_ptr ( ) {
348
214
span_bug ! (
349
215
this. cur_span( ) ,
350
216
"atomic arithmetic operations only work on integer and raw pointer types" ,
351
217
) ;
352
218
}
353
- let rhs = this. read_immediate ( rhs) ?;
219
+ if rhs. layout . ty != place. layout . ty {
220
+ span_bug ! ( this. cur_span( ) , "atomic arithmetic operation type mismatch" ) ;
221
+ }
354
222
355
223
// Check alignment requirements. Atomics must always be aligned to their size,
356
224
// even if the type they wrap would be less aligned (e.g. AtomicU64 on 32bit must
0 commit comments