@@ -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,19 @@ 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" => {
180
213
let expected =
181
214
val1. expect ( "__atomic_compare_exchange must have a expected argument" ) ;
182
215
let desired = val2. expect ( "__atomic_compare_exchange must have a desired argument" ) ;
216
+ // Some C11 atomic operations encode the weak property in the name
217
+ let weak = match ( name, weak) {
218
+ ( "__c11_atomic_compare_exchange_strong" , None ) => Some ( false ) ,
219
+ ( "__c11_atomic_compare_exchange_weak" , None ) => Some ( true ) ,
220
+ _ => weak,
221
+ } ;
222
+
183
223
ptr. and_then ( |ptr| {
184
224
expected. and_then ( |expected| {
185
225
desired. and_then ( |desired| {
@@ -258,7 +298,13 @@ impl<'c> Translation<'c> {
258
298
| "__atomic_fetch_and"
259
299
| "__atomic_fetch_xor"
260
300
| "__atomic_fetch_or"
261
- | "__atomic_fetch_nand" => {
301
+ | "__atomic_fetch_nand"
302
+ | "__c11_atomic_fetch_add"
303
+ | "__c11_atomic_fetch_sub"
304
+ | "__c11_atomic_fetch_and"
305
+ | "__c11_atomic_fetch_xor"
306
+ | "__c11_atomic_fetch_or"
307
+ | "__c11_atomic_fetch_nand" => {
262
308
let intrinsic_name = if name. contains ( "_add" ) {
263
309
"atomic_xadd"
264
310
} else if name. contains ( "_sub" ) {
@@ -285,7 +331,7 @@ impl<'c> Translation<'c> {
285
331
} )
286
332
}
287
333
288
- _ => unimplemented ! ( "atomic not implemented" ) ,
334
+ _ => unimplemented ! ( "atomic not implemented: {}" , name ) ,
289
335
}
290
336
}
291
337
0 commit comments