@@ -16,6 +16,19 @@ impl<'c> Translation<'c> {
16
16
let memorder = & self . ast_context [ expr] ;
17
17
let i = match memorder. kind {
18
18
CExprKind :: Literal ( _, CLiteral :: Integer ( i, _) ) => Some ( i) ,
19
+ CExprKind :: DeclRef ( _, decl_id, LRValue :: RValue ) => {
20
+ let decl = self . ast_context . get_decl ( & decl_id) . unwrap ( ) ;
21
+ match decl. kind {
22
+ CDeclKind :: EnumConstant { name : _, value : v } => match v {
23
+ ConstIntExpr :: I ( i) => {
24
+ assert ! ( 0 <= i) ;
25
+ Some ( i as u64 )
26
+ }
27
+ ConstIntExpr :: U ( u) => Some ( u) ,
28
+ } ,
29
+ _ => unimplemented ! ( ) ,
30
+ }
31
+ }
19
32
_ => None ,
20
33
} ?;
21
34
use Ordering :: * ;
@@ -76,7 +89,7 @@ impl<'c> Translation<'c> {
76
89
}
77
90
78
91
match name {
79
- "__atomic_load" | "__atomic_load_n" => ptr. and_then ( |ptr| {
92
+ "__atomic_load" | "__atomic_load_n" | "__c11_atomic_load" => ptr. and_then ( |ptr| {
80
93
let intrinsic_name = format ! ( "atomic_load_{}" , order_name( static_order( order) ) ) ;
81
94
82
95
self . use_feature ( "core_intrinsics" ) ;
@@ -105,7 +118,7 @@ impl<'c> Translation<'c> {
105
118
}
106
119
} ) ,
107
120
108
- "__atomic_store" | "__atomic_store_n" => {
121
+ "__atomic_store" | "__atomic_store_n" | "__c11_atomic_store" => {
109
122
let val = val1. expect ( "__atomic_store must have a val argument" ) ;
110
123
ptr. and_then ( |ptr| {
111
124
val. and_then ( |val| {
@@ -131,7 +144,25 @@ impl<'c> Translation<'c> {
131
144
} )
132
145
}
133
146
134
- "__atomic_exchange" | "__atomic_exchange_n" => {
147
+ // NOTE: there is no corresponding __atomic_init builtin in clang
148
+ "__c11_atomic_init" => {
149
+ let val = val1. expect ( & format ! ( "__atomic_init must have a val argument" ) ) ;
150
+ ptr. and_then ( |ptr| {
151
+ val. and_then ( |val| {
152
+ let assignment = mk ( ) . assign_expr (
153
+ mk ( ) . unary_expr ( UnOp :: Deref ( Default :: default ( ) ) , ptr) ,
154
+ val,
155
+ ) ;
156
+ self . convert_side_effects_expr (
157
+ ctx,
158
+ WithStmts :: new_val ( assignment) ,
159
+ "Builtin is not supposed to be used" ,
160
+ )
161
+ } )
162
+ } )
163
+ }
164
+
165
+ "__atomic_exchange" | "__atomic_exchange_n" | "__c11_atomic_exchange" => {
135
166
let val = val1. expect ( "__atomic_store must have a val argument" ) ;
136
167
ptr. and_then ( |ptr| {
137
168
val. and_then ( |val| {
@@ -176,10 +207,22 @@ impl<'c> Translation<'c> {
176
207
} )
177
208
}
178
209
179
- "__atomic_compare_exchange" | "__atomic_compare_exchange_n" => {
210
+ "__atomic_compare_exchange"
211
+ | "__atomic_compare_exchange_n"
212
+ | "__c11_atomic_compare_exchange_strong" => {
213
+ // TODO(perl): __c11_atomic_compare_exchange_strong does not
214
+ // seem to produce correct code. It produces a deref operation
215
+ // on the `src` argument to atomic_cxchg_seqcst_seqcst.
180
216
let expected =
181
217
val1. expect ( "__atomic_compare_exchange must have a expected argument" ) ;
182
218
let desired = val2. expect ( "__atomic_compare_exchange must have a desired argument" ) ;
219
+ // Some C11 atomic operations encode the weak property in the name
220
+ let weak = match ( name, weak) {
221
+ ( "__c11_atomic_compare_exchange_strong" , None ) => Some ( false ) ,
222
+ ( "__c11_atomic_compare_exchange_weak" , None ) => Some ( true ) ,
223
+ _ => weak,
224
+ } ;
225
+
183
226
ptr. and_then ( |ptr| {
184
227
expected. and_then ( |expected| {
185
228
desired. and_then ( |desired| {
@@ -258,7 +301,13 @@ impl<'c> Translation<'c> {
258
301
| "__atomic_fetch_and"
259
302
| "__atomic_fetch_xor"
260
303
| "__atomic_fetch_or"
261
- | "__atomic_fetch_nand" => {
304
+ | "__atomic_fetch_nand"
305
+ | "__c11_atomic_fetch_add"
306
+ | "__c11_atomic_fetch_sub"
307
+ | "__c11_atomic_fetch_and"
308
+ | "__c11_atomic_fetch_xor"
309
+ | "__c11_atomic_fetch_or"
310
+ | "__c11_atomic_fetch_nand" => {
262
311
let intrinsic_name = if name. contains ( "_add" ) {
263
312
"atomic_xadd"
264
313
} else if name. contains ( "_sub" ) {
@@ -276,7 +325,7 @@ impl<'c> Translation<'c> {
276
325
let intrinsic_suffix = order_name ( static_order ( order) ) ;
277
326
let intrinsic_name = format ! ( "{intrinsic_name}_{intrinsic_suffix}" ) ;
278
327
279
- let fetch_first = name. starts_with ( "__atomic_fetch" ) ;
328
+ let fetch_first = name. starts_with ( "__atomic_fetch" ) || name . starts_with ( "__c11_atomic_fetch" ) ;
280
329
let val = val1. expect ( "__atomic arithmetic operations must have a val argument" ) ;
281
330
ptr. and_then ( |ptr| {
282
331
val. and_then ( |val| {
@@ -285,7 +334,7 @@ impl<'c> Translation<'c> {
285
334
} )
286
335
}
287
336
288
- _ => unimplemented ! ( "atomic not implemented" ) ,
337
+ _ => unimplemented ! ( "atomic not implemented: {}" , name ) ,
289
338
}
290
339
}
291
340
0 commit comments