Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
frama-c
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
pub
frama-c
Commits
1e0e5e92
Commit
1e0e5e92
authored
3 years ago
by
Virgile Prevosto
Browse files
Options
Downloads
Patches
Plain Diff
[libc] add prototypes and spec for gcc __atomic_* specialized operations
parent
59d43635
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
share/libc/__fc_gcc_builtins.h
+393
-0
393 additions, 0 deletions
share/libc/__fc_gcc_builtins.h
with
393 additions
and
0 deletions
share/libc/__fc_gcc_builtins.h
+
393
−
0
View file @
1e0e5e92
...
...
@@ -27,6 +27,7 @@
#define __FC_GCC_BUILTINS
#include
"features.h"
#include
"__fc_machdep.h"
#include
"__fc_define_size_t.h"
__PUSH_FC_STDLIB
...
...
@@ -254,6 +255,398 @@ int __builtin_popcountl (unsigned long x);
*/
int
__builtin_popcountll
(
unsigned
long
long
x
);
// GCC specialized __atomic_* functions.
// TODO: add generic counterpart with some help from cabs2cil for typing
// NB: __atomic_* operations do not seem to make a distinction between
// signed and unsigned: this may lead to some warnings by Frama-C
/*@
requires validity: \valid_read(mem);
assigns \result \from *mem, indirect:model;
*/
__INT8_T
__atomic_load_1
(
__INT8_T
*
mem
,
int
model
);
/*@
requires validity: \valid_read(mem);
assigns \result \from *mem, indirect: model;
*/
__INT16_T
__atomic_load_2
(
__INT16_T
*
mem
,
int
model
);
/*@
requires validity: \valid_read(mem);
assigns \result \from *mem, indirect:model;
*/
__INT32_T
__atomic_load_4
(
__INT32_T
*
mem
,
int
model
);
/*@
requires validity: \valid_read(mem);
assigns \result \from *mem, indirect:model;
*/
__INT64_T
__atomic_load_8
(
__INT64_T
*
mem
,
int
model
);
/*@
requires validity: \valid(mem);
assigns *mem \from val, indirect: model;
*/
void
__atomic_store_1
(
__INT8_T
*
mem
,
__INT8_T
val
,
int
model
);
/*@
requires validity: \valid(mem);
assigns *mem \from val, indirect: model;
*/
void
__atomic_store_2
(
__INT16_T
*
mem
,
__INT16_T
val
,
int
model
);
/*@
requires validity: \valid(mem);
assigns *mem \from val, indirect: model;
*/
void
__atomic_store_4
(
__INT32_T
*
mem
,
__INT32_T
val
,
int
model
);
/*@
requires validity: \valid(mem);
assigns *mem \from val, indirect: model;
*/
void
__atomic_store_8
(
__INT64_T
*
mem
,
__INT64_T
val
,
int
model
);
/*@ requires validity: \valid(mem);
assigns *mem \from val, indirect:model;
assigns \result \from *mem, indirect:model;
*/
__INT8_T
__atomic_exchange_1
(
__INT8_T
*
mem
,
__INT8_T
val
,
int
model
);
/*@ requires validity: \valid(mem);
assigns *mem \from val, indirect:model;
assigns \result \from *mem, indirect:model;
*/
__INT16_T
__atomic_exchange_2
(
__INT16_T
*
mem
,
__INT16_T
val
,
int
model
);
/*@ requires validity: \valid(mem);
assigns *mem \from val, indirect:model;
assigns \result \from *mem, indirect:model;
*/
__INT32_T
__atomic_exchange_4
(
__INT32_T
*
mem
,
__INT32_T
val
,
int
model
);
/*@ requires validity: \valid(mem);
assigns *mem \from val, indirect:model;
assigns \result \from *mem, indirect:model;
*/
__INT64_T
__atomic_exchange_8
(
__INT64_T
*
mem
,
__INT64_T
val
,
int
model
);
/*@ requires validity: \valid(mem) && \valid_read(expected);
assigns *mem \from *mem, indirect: *expected, desired,
indirect: success_model, indirect: weak;
assigns *expected \from *expected, indirect: *mem, desired,
indirect: failure_model, indirect: weak;
assigns \result \from indirect: *mem, indirect: *expected;
*/
_Bool
__atomic_compare_exchange_1
(
__INT8_T
*
mem
,
__INT8_T
*
expected
,
__INT8_T
desired
,
_Bool
weak
,
int
success_model
,
int
failure_model
);
/*@ requires validity: \valid(mem) && \valid_read(expected);
assigns *mem \from *mem, indirect: *expected, desired,
indirect: success_model, indirect: weak;
assigns *expected \from *expected, indirect: *mem, desired,
indirect: failure_model, indirect: weak;
assigns \result \from indirect: *mem, indirect: *expected;
*/
_Bool
__atomic_compare_exchange_2
(
__INT16_T
*
mem
,
__INT16_T
*
expected
,
__INT16_T
desired
,
_Bool
weak
,
int
success_model
,
int
failure_model
);
/*@ requires validity: \valid(mem) && \valid_read(expected);
assigns *mem \from *mem, indirect: *expected, desired,
indirect: success_model, indirect: weak;
assigns *expected \from *expected, indirect: *mem, desired,
indirect: failure_model, indirect: weak;
assigns \result \from indirect: *mem, indirect: *expected;
*/
_Bool
__atomic_compare_exchange_4
(
__INT32_T
*
mem
,
__INT32_T
*
expected
,
__INT32_T
desired
,
_Bool
weak
,
int
success_model
,
int
failure_model
);
/*@ requires validity: \valid(mem) && \valid_read(expected);
assigns *mem \from *mem, indirect: *expected, desired,
indirect: success_model, indirect: weak;
assigns *expected \from *expected, indirect: *mem, desired,
indirect: failure_model, indirect: weak;
assigns \result \from indirect: *mem, indirect: *expected;
*/
_Bool
__atomic_compare_exchange_8
(
__INT64_T
*
mem
,
__INT64_T
*
expected
,
__INT64_T
desired
,
_Bool
weak
,
int
success_model
,
int
failure_model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT8_T
__atomic_add_fetch_1
(
__INT8_T
*
ptr
,
__INT8_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT8_T
__atomic_sub_fetch_1
(
__INT8_T
*
ptr
,
__INT8_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT8_T
__atomic_and_fetch_1
(
__INT8_T
*
ptr
,
__INT8_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT8_T
__atomic_xor_fetch_1
(
__INT8_T
*
ptr
,
__INT8_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT8_T
__atomic_or_fetch_1
(
__INT8_T
*
ptr
,
__INT8_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT8_T
__atomic_nand_fetch_1
(
__INT8_T
*
ptr
,
__INT8_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT16_T
__atomic_add_fetch_2
(
__INT16_T
*
ptr
,
__INT16_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT16_T
__atomic_sub_fetch_2
(
__INT16_T
*
ptr
,
__INT16_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT16_T
__atomic_and_fetch_2
(
__INT16_T
*
ptr
,
__INT16_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT16_T
__atomic_xor_fetch_2
(
__INT16_T
*
ptr
,
__INT16_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT16_T
__atomic_or_fetch_2
(
__INT16_T
*
ptr
,
__INT16_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT16_T
__atomic_nand_fetch_2
(
__INT16_T
*
ptr
,
__INT16_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT32_T
__atomic_add_fetch_4
(
__INT32_T
*
ptr
,
__INT32_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT32_T
__atomic_sub_fetch_4
(
__INT32_T
*
ptr
,
__INT32_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT32_T
__atomic_and_fetch_4
(
__INT32_T
*
ptr
,
__INT32_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT32_T
__atomic_xor_fetch_4
(
__INT32_T
*
ptr
,
__INT32_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT32_T
__atomic_or_fetch_4
(
__INT32_T
*
ptr
,
__INT32_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT32_T
__atomic_nand_fetch_4
(
__INT32_T
*
ptr
,
__INT32_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT64_T
__atomic_add_fetch_8
(
__INT64_T
*
ptr
,
__INT64_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT64_T
__atomic_sub_fetch_8
(
__INT64_T
*
ptr
,
__INT64_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT64_T
__atomic_and_fetch_8
(
__INT64_T
*
ptr
,
__INT64_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT64_T
__atomic_xor_fetch_8
(
__INT64_T
*
ptr
,
__INT64_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT64_T
__atomic_or_fetch_8
(
__INT64_T
*
ptr
,
__INT64_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT64_T
__atomic_nand_fetch_8
(
__INT64_T
*
ptr
,
__INT64_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT8_T
__atomic_fetch_add_1
(
__INT8_T
*
ptr
,
__INT8_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT8_T
__atomic_fetch_sub_1
(
__INT8_T
*
ptr
,
__INT8_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT8_T
__atomic_fetch_and_1
(
__INT8_T
*
ptr
,
__INT8_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT8_T
__atomic_fetch_xor_1
(
__INT8_T
*
ptr
,
__INT8_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT8_T
__atomic_fetch_or_1
(
__INT8_T
*
ptr
,
__INT8_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT8_T
__atomic_fetch_nand_1
(
__INT8_T
*
ptr
,
__INT8_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT16_T
__atomic_fetch_add_2
(
__INT16_T
*
ptr
,
__INT16_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT16_T
__atomic_fetch_sub_2
(
__INT16_T
*
ptr
,
__INT16_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT16_T
__atomic_fetch_and_2
(
__INT16_T
*
ptr
,
__INT16_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT16_T
__atomic_fetch_xor_2
(
__INT16_T
*
ptr
,
__INT16_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT16_T
__atomic_fetch_or_2
(
__INT16_T
*
ptr
,
__INT16_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT16_T
__atomic_fetch_nand_2
(
__INT16_T
*
ptr
,
__INT16_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT32_T
__atomic_fetch_add_4
(
__INT32_T
*
ptr
,
__INT32_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT32_T
__atomic_fetch_sub_4
(
__INT32_T
*
ptr
,
__INT32_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT32_T
__atomic_fetch_and_4
(
__INT32_T
*
ptr
,
__INT32_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT32_T
__atomic_fetch_xor_4
(
__INT32_T
*
ptr
,
__INT32_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT32_T
__atomic_fetch_or_4
(
__INT32_T
*
ptr
,
__INT32_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT32_T
__atomic_fetch_nand_4
(
__INT32_T
*
ptr
,
__INT32_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT64_T
__atomic_fetch_add_8
(
__INT64_T
*
ptr
,
__INT64_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT64_T
__atomic_fetch_sub__8
(
__INT64_T
*
ptr
,
__INT64_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT64_T
__atomic_fetch_and_8
(
__INT64_T
*
ptr
,
__INT64_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT64_T
__atomic_fetch_xor_8
(
__INT64_T
*
ptr
,
__INT64_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT64_T
__atomic_fetch_or_8
(
__INT64_T
*
ptr
,
__INT64_T
val
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns \result, *ptr \from *ptr, val, indirect: model;
*/
__INT64_T
__atomic_fetch_nand_8
(
__INT64_T
*
ptr
,
__INT64_T
val
,
int
model
);
/*@ requires validity: \valid((char*)ptr);
assigns \result \from *((char*)ptr);
assigns *((char*)ptr) \from \nothing;
*/
_Bool
__atomic_test_and_set
(
void
*
ptr
,
int
model
);
/*@ requires validity: \valid(ptr);
assigns *ptr \from \nothing;
*/
void
__atomic_clear
(
_Bool
*
ptr
,
int
model
);
/*@ assigns \nothing; */
void
__atomic_thread_fence
(
int
model
);
/*@ assigns \nothing; */
void
__atomic_signal_fence
(
int
model
);
/*@ assigns \result \from indirect: size, indirect: ptr; */
_Bool
__atomic_always_lock_free
(
size_t
size
,
void
*
ptr
);
/*@ assigns \result \from indirect: size, indirect: ptr; */
_Bool
__atomic_lock_free
(
size_t
size
,
void
*
ptr
);
// According to the GCC docs
// (https://gcc.gnu.org/onlinedocs/gcc/_005f_005fsync-Builtins.html),
// this creates a 'full memory barrier'; we do not model the concurrency
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment