A bit hackish, but it has to since atomic builtins are overloaded to work on multiple types. Types are not checked very carefully, but the parameters are cast properly, according to the type of the first one. http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html --- src/check.ml | 2 + src/cil.ml | 23 ++++ src/frontc/cabs2cil.ml | 53 ++++++++- test/small1/sync-1.c | 280 ++++++++++++++++++++++++++++++++++++++++++++++++ test/small1/sync-2.c | 169 +++++++++++++++++++++++++++++ test/small1/sync-3.c | 188 ++++++++++++++++++++++++++++++++ test/testcil.pl | 3 + 7 files changed, 712 insertions(+), 6 deletions(-) create mode 100644 test/small1/sync-1.c create mode 100644 test/small1/sync-2.c create mode 100644 test/small1/sync-3.c
diff --git a/src/check.ml b/src/check.ml index cda292c..736287f 100644 --- a/src/check.ml +++ b/src/check.ml @@ -805,6 +805,8 @@ and checkInstr (i: instr) = (* Now check the return value*) (match dest, unrollType rt with None, TVoid _ -> () + (* Avoid spurious warnings for atomic builtins *) + | Some _, TVoid [Attr ("overloaded", [])] -> () | Some _, TVoid _ -> ignore (warn "void value is assigned") | None, _ -> () (* "Call of function is not assigned" *) | Some destlv, rt' -> diff --git a/src/cil.ml b/src/cil.ml index a7bb129..a4602a4 100644 --- a/src/cil.ml +++ b/src/cil.ml @@ -3025,6 +3025,29 @@ let initGccBuiltins () : unit = H.add h "__builtin_ia32_unpcklps" (v4sfType, [v4sfType; v4sfType], false); H.add h "__builtin_ia32_maxps" (v4sfType, [v4sfType; v4sfType], false); + (* Atomic Builtins *) + (* These builtins are overloaded, hence the "magic" void type with + __overloaded__ attribute, used to suppress warnings in cabs2cil.ml. + For the same reason, we do not specify the type of the parameters. *) + H.add h "__sync_fetch_and_add" (TVoid[Attr("overloaded",[])], [ ], true); + H.add h "__sync_fetch_and_sub" (TVoid[Attr("overloaded",[])], [ ], true); + H.add h "__sync_fetch_and_or" (TVoid[Attr("overloaded",[])], [ ], true); + H.add h "__sync_fetch_and_and" (TVoid[Attr("overloaded",[])], [ ], true); + H.add h "__sync_fetch_and_xor" (TVoid[Attr("overloaded",[])], [ ], true); + H.add h "__sync_fetch_and_nand" (TVoid[Attr("overloaded",[])], [ ], true); + H.add h "__sync_add_and_fetch" (TVoid[Attr("overloaded",[])], [ ], true); + H.add h "__sync_sub_and_fetch" (TVoid[Attr("overloaded",[])], [ ], true); + H.add h "__sync_or_and_fetch" (TVoid[Attr("overloaded",[])], [ ], true); + H.add h "__sync_and_and_fetch" (TVoid[Attr("overloaded",[])], [ ], true); + H.add h "__sync_xor_and_fetch" (TVoid[Attr("overloaded",[])], [ ], true); + H.add h "__sync_nand_and_fetch" (TVoid[Attr("overloaded",[])], [ ], true); + H.add h "__sync_bool_compare_and_swap" (TInt (IBool, []), [ ], true); + H.add h "__sync_val_compare_and_swap" (TVoid[Attr("overloaded",[])], [ ], + true); + H.add h "__sync_synchronize" (voidType, [ ], true); + H.add h "__sync_lock_test_and_set" (TVoid[Attr("overloaded",[])], [ ], true); + H.add h "__sync_lock_release" (voidType, [ ], true); + if hasbva then begin H.add h "__builtin_va_end" (voidType, [ TBuiltin_va_list [] ], false); H.add h "__builtin_varargs_start" diff --git a/src/frontc/cabs2cil.ml b/src/frontc/cabs2cil.ml index d6002bd..8b940cc 100644 --- a/src/frontc/cabs2cil.ml +++ b/src/frontc/cabs2cil.ml @@ -3968,7 +3968,8 @@ and doExp (asconst: bool) (* This expression is used as a constant *) in let argTypesList = argsToList argTypes in (* Drop certain qualifiers from the result type *) - let resType' = typeRemoveAttributes ["warn_unused_result"] resType in + let resType' = + ref (typeRemoveAttributes ["warn_unused_result"] resType) in (* Before we do the arguments we try to intercept a few builtins. For * these we have defined then with a different type, so we do not * want to give warnings. We'll just leave the arguments of these @@ -4073,7 +4074,47 @@ and doExp (asconst: bool) (* This expression is used as a constant *) (* Try to intercept some builtins *) (match !pf with Lval(Var fv, NoOffset) -> begin - if fv.vname = "__builtin_va_arg" then begin + (* Atomic builtins are overloaded: check the type of the + arguments and fix the return type accordingly. + No trick needed for __sync_synchronize, + __sync_bool_compare_and_swap and __sync_lock_release. + Some consistency checks are left to the compiler, we do + as few as we can here to ensure a correct translation. *) + if fv.vname = "__sync_fetch_and_add" || + fv.vname = "__sync_fetch_and_sub" || + fv.vname = "__sync_fetch_and_or" || + fv.vname = "__sync_fetch_and_and" || + fv.vname = "__sync_fetch_and_xor" || + fv.vname = "__sync_fetch_and_nand"|| + fv.vname = "__sync_add_and_fetch" || + fv.vname = "__sync_sub_and_fetch" || + fv.vname = "__sync_or_and_fetch" || + fv.vname = "__sync_and_and_fetch" || + fv.vname = "__sync_xor_and_fetch" || + fv.vname = "__sync_nand_and_fetch" || + fv.vname = "__sync_lock_test_and_set" then begin + match !pargs with + ptr :: value :: q -> begin match typeOf ptr with + TPtr (vtype, _) -> + let cast v = snd (castTo (typeOf v) vtype v) in + resType' := vtype; + pargs := ptr :: cast value :: q + | _ -> + ignore (warn "Invalid call to %s" fv.vname) end + | _ -> + ignore (warn "Invalid call to %s" fv.vname) + end else if fv.vname = "__sync_val_compare_and_swap" then begin + match !pargs with + ptr :: oldval :: newval :: q -> begin match typeOf ptr with + TPtr (vtype, _) -> + let cast v = snd (castTo (typeOf v) vtype v) in + resType' := vtype; + pargs := ptr :: cast oldval :: cast newval :: q + | _ -> + ignore (warn "Invalid call to %s" fv.vname) end + | _ -> + ignore (warn "Invalid call to %s" fv.vname) + end else if fv.vname = "__builtin_va_arg" then begin match !pargs with marker :: SizeOf resTyp :: _ -> begin (* Make a variable of the desired type *) @@ -4218,14 +4259,14 @@ and doExp (asconst: bool) (* This expression is used as a constant *) match !pwhat with ADrop -> addCall None zero intType - | AType -> prestype := resType' + | AType -> prestype := !resType' | ASet(lv, vtype) when !pis__builtin_va_arg -> (* Make an exception here for __builtin_va_arg *) addCall None (Lval(lv)) vtype - | ASet(lv, vtype) when !doCollapseCallCast || - (Util.equals (typeSig vtype) (typeSig resType')) + | ASet(lv, vtype) when !doCollapseCallCast || + (Util.equals (typeSig vtype) (typeSig !resType')) -> (* We can assign the result directly to lv *) addCall (Some lv) (Lval(lv)) vtype @@ -4234,7 +4275,7 @@ and doExp (asconst: bool) (* This expression is used as a constant *) let restype'' = match !pwhat with AExp (Some t) when !doCollapseCallCast -> t - | _ -> resType' + | _ -> !resType' in let descr = dprintf "%a(%a)" dd_exp !pf (docList ~sep:(text ", ") (dd_exp ())) !pargs in diff --git a/test/small1/sync-1.c b/test/small1/sync-1.c new file mode 100644 index 0000000..530ce72 --- /dev/null +++ b/test/small1/sync-1.c @@ -0,0 +1,280 @@ +// From c-torture +/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "" { target *-*-* } 0 } */ +/* { dg-message "note: '__sync_nand_and_fetch' changed semantics in GCC 4.4" "" { target *-*-* } 0 } */ + +/* Validate that each of the __sync builtins compiles. This won't + necessarily link, since the target might not support the builtin, + so this may result in external library calls. */ + +signed char sc; +unsigned char uc; +signed short ss; +unsigned short us; +signed int si; +unsigned int ui; +signed long sl; +unsigned long ul; +signed long long sll; +unsigned long long ull; +void *vp; +int *ip; +struct S { struct S *next; int x; } *sp; + +void test_op_ignore (void) +{ + (void) __sync_fetch_and_add (&sc, 1); + (void) __sync_fetch_and_add (&uc, 1); + (void) __sync_fetch_and_add (&ss, 1); + (void) __sync_fetch_and_add (&us, 1); + (void) __sync_fetch_and_add (&si, 1); + (void) __sync_fetch_and_add (&ui, 1); + (void) __sync_fetch_and_add (&sl, 1); + (void) __sync_fetch_and_add (&ul, 1); + (void) __sync_fetch_and_add (&sll, 1); + (void) __sync_fetch_and_add (&ull, 1); + + (void) __sync_fetch_and_sub (&sc, 1); + (void) __sync_fetch_and_sub (&uc, 1); + (void) __sync_fetch_and_sub (&ss, 1); + (void) __sync_fetch_and_sub (&us, 1); + (void) __sync_fetch_and_sub (&si, 1); + (void) __sync_fetch_and_sub (&ui, 1); + (void) __sync_fetch_and_sub (&sl, 1); + (void) __sync_fetch_and_sub (&ul, 1); + (void) __sync_fetch_and_sub (&sll, 1); + (void) __sync_fetch_and_sub (&ull, 1); + + (void) __sync_fetch_and_or (&sc, 1); + (void) __sync_fetch_and_or (&uc, 1); + (void) __sync_fetch_and_or (&ss, 1); + (void) __sync_fetch_and_or (&us, 1); + (void) __sync_fetch_and_or (&si, 1); + (void) __sync_fetch_and_or (&ui, 1); + (void) __sync_fetch_and_or (&sl, 1); + (void) __sync_fetch_and_or (&ul, 1); + (void) __sync_fetch_and_or (&sll, 1); + (void) __sync_fetch_and_or (&ull, 1); + + (void) __sync_fetch_and_xor (&sc, 1); + (void) __sync_fetch_and_xor (&uc, 1); + (void) __sync_fetch_and_xor (&ss, 1); + (void) __sync_fetch_and_xor (&us, 1); + (void) __sync_fetch_and_xor (&si, 1); + (void) __sync_fetch_and_xor (&ui, 1); + (void) __sync_fetch_and_xor (&sl, 1); + (void) __sync_fetch_and_xor (&ul, 1); + (void) __sync_fetch_and_xor (&sll, 1); + (void) __sync_fetch_and_xor (&ull, 1); + + (void) __sync_fetch_and_and (&sc, 1); + (void) __sync_fetch_and_and (&uc, 1); + (void) __sync_fetch_and_and (&ss, 1); + (void) __sync_fetch_and_and (&us, 1); + (void) __sync_fetch_and_and (&si, 1); + (void) __sync_fetch_and_and (&ui, 1); + (void) __sync_fetch_and_and (&sl, 1); + (void) __sync_fetch_and_and (&ul, 1); + (void) __sync_fetch_and_and (&sll, 1); + (void) __sync_fetch_and_and (&ull, 1); + + (void) __sync_fetch_and_nand (&sc, 1); + (void) __sync_fetch_and_nand (&uc, 1); + (void) __sync_fetch_and_nand (&ss, 1); + (void) __sync_fetch_and_nand (&us, 1); + (void) __sync_fetch_and_nand (&si, 1); + (void) __sync_fetch_and_nand (&ui, 1); + (void) __sync_fetch_and_nand (&sl, 1); + (void) __sync_fetch_and_nand (&ul, 1); + (void) __sync_fetch_and_nand (&sll, 1); + (void) __sync_fetch_and_nand (&ull, 1); +} + +void test_fetch_and_op (void) +{ + sc = __sync_fetch_and_add (&sc, 11); + uc = __sync_fetch_and_add (&uc, 11); + ss = __sync_fetch_and_add (&ss, 11); + us = __sync_fetch_and_add (&us, 11); + si = __sync_fetch_and_add (&si, 11); + ui = __sync_fetch_and_add (&ui, 11); + sl = __sync_fetch_and_add (&sl, 11); + ul = __sync_fetch_and_add (&ul, 11); + sll = __sync_fetch_and_add (&sll, 11); + ull = __sync_fetch_and_add (&ull, 11); + + sc = __sync_fetch_and_sub (&sc, 11); + uc = __sync_fetch_and_sub (&uc, 11); + ss = __sync_fetch_and_sub (&ss, 11); + us = __sync_fetch_and_sub (&us, 11); + si = __sync_fetch_and_sub (&si, 11); + ui = __sync_fetch_and_sub (&ui, 11); + sl = __sync_fetch_and_sub (&sl, 11); + ul = __sync_fetch_and_sub (&ul, 11); + sll = __sync_fetch_and_sub (&sll, 11); + ull = __sync_fetch_and_sub (&ull, 11); + + sc = __sync_fetch_and_or (&sc, 11); + uc = __sync_fetch_and_or (&uc, 11); + ss = __sync_fetch_and_or (&ss, 11); + us = __sync_fetch_and_or (&us, 11); + si = __sync_fetch_and_or (&si, 11); + ui = __sync_fetch_and_or (&ui, 11); + sl = __sync_fetch_and_or (&sl, 11); + ul = __sync_fetch_and_or (&ul, 11); + sll = __sync_fetch_and_or (&sll, 11); + ull = __sync_fetch_and_or (&ull, 11); + + sc = __sync_fetch_and_xor (&sc, 11); + uc = __sync_fetch_and_xor (&uc, 11); + ss = __sync_fetch_and_xor (&ss, 11); + us = __sync_fetch_and_xor (&us, 11); + si = __sync_fetch_and_xor (&si, 11); + ui = __sync_fetch_and_xor (&ui, 11); + sl = __sync_fetch_and_xor (&sl, 11); + ul = __sync_fetch_and_xor (&ul, 11); + sll = __sync_fetch_and_xor (&sll, 11); + ull = __sync_fetch_and_xor (&ull, 11); + + sc = __sync_fetch_and_and (&sc, 11); + uc = __sync_fetch_and_and (&uc, 11); + ss = __sync_fetch_and_and (&ss, 11); + us = __sync_fetch_and_and (&us, 11); + si = __sync_fetch_and_and (&si, 11); + ui = __sync_fetch_and_and (&ui, 11); + sl = __sync_fetch_and_and (&sl, 11); + ul = __sync_fetch_and_and (&ul, 11); + sll = __sync_fetch_and_and (&sll, 11); + ull = __sync_fetch_and_and (&ull, 11); + + sc = __sync_fetch_and_nand (&sc, 11); + uc = __sync_fetch_and_nand (&uc, 11); + ss = __sync_fetch_and_nand (&ss, 11); + us = __sync_fetch_and_nand (&us, 11); + si = __sync_fetch_and_nand (&si, 11); + ui = __sync_fetch_and_nand (&ui, 11); + sl = __sync_fetch_and_nand (&sl, 11); + ul = __sync_fetch_and_nand (&ul, 11); + sll = __sync_fetch_and_nand (&sll, 11); + ull = __sync_fetch_and_nand (&ull, 11); +} + +void test_op_and_fetch (void) +{ + sc = __sync_add_and_fetch (&sc, uc); + uc = __sync_add_and_fetch (&uc, uc); + ss = __sync_add_and_fetch (&ss, uc); + us = __sync_add_and_fetch (&us, uc); + si = __sync_add_and_fetch (&si, uc); + ui = __sync_add_and_fetch (&ui, uc); + sl = __sync_add_and_fetch (&sl, uc); + ul = __sync_add_and_fetch (&ul, uc); + sll = __sync_add_and_fetch (&sll, uc); + ull = __sync_add_and_fetch (&ull, uc); + + sc = __sync_sub_and_fetch (&sc, uc); + uc = __sync_sub_and_fetch (&uc, uc); + ss = __sync_sub_and_fetch (&ss, uc); + us = __sync_sub_and_fetch (&us, uc); + si = __sync_sub_and_fetch (&si, uc); + ui = __sync_sub_and_fetch (&ui, uc); + sl = __sync_sub_and_fetch (&sl, uc); + ul = __sync_sub_and_fetch (&ul, uc); + sll = __sync_sub_and_fetch (&sll, uc); + ull = __sync_sub_and_fetch (&ull, uc); + + sc = __sync_or_and_fetch (&sc, uc); + uc = __sync_or_and_fetch (&uc, uc); + ss = __sync_or_and_fetch (&ss, uc); + us = __sync_or_and_fetch (&us, uc); + si = __sync_or_and_fetch (&si, uc); + ui = __sync_or_and_fetch (&ui, uc); + sl = __sync_or_and_fetch (&sl, uc); + ul = __sync_or_and_fetch (&ul, uc); + sll = __sync_or_and_fetch (&sll, uc); + ull = __sync_or_and_fetch (&ull, uc); + + sc = __sync_xor_and_fetch (&sc, uc); + uc = __sync_xor_and_fetch (&uc, uc); + ss = __sync_xor_and_fetch (&ss, uc); + us = __sync_xor_and_fetch (&us, uc); + si = __sync_xor_and_fetch (&si, uc); + ui = __sync_xor_and_fetch (&ui, uc); + sl = __sync_xor_and_fetch (&sl, uc); + ul = __sync_xor_and_fetch (&ul, uc); + sll = __sync_xor_and_fetch (&sll, uc); + ull = __sync_xor_and_fetch (&ull, uc); + + sc = __sync_and_and_fetch (&sc, uc); + uc = __sync_and_and_fetch (&uc, uc); + ss = __sync_and_and_fetch (&ss, uc); + us = __sync_and_and_fetch (&us, uc); + si = __sync_and_and_fetch (&si, uc); + ui = __sync_and_and_fetch (&ui, uc); + sl = __sync_and_and_fetch (&sl, uc); + ul = __sync_and_and_fetch (&ul, uc); + sll = __sync_and_and_fetch (&sll, uc); + ull = __sync_and_and_fetch (&ull, uc); + + sc = __sync_nand_and_fetch (&sc, uc); + uc = __sync_nand_and_fetch (&uc, uc); + ss = __sync_nand_and_fetch (&ss, uc); + us = __sync_nand_and_fetch (&us, uc); + si = __sync_nand_and_fetch (&si, uc); + ui = __sync_nand_and_fetch (&ui, uc); + sl = __sync_nand_and_fetch (&sl, uc); + ul = __sync_nand_and_fetch (&ul, uc); + sll = __sync_nand_and_fetch (&sll, uc); + ull = __sync_nand_and_fetch (&ull, uc); +} + +void test_compare_and_swap (void) +{ + sc = __sync_val_compare_and_swap (&sc, uc, sc); + uc = __sync_val_compare_and_swap (&uc, uc, sc); + ss = __sync_val_compare_and_swap (&ss, uc, sc); + us = __sync_val_compare_and_swap (&us, uc, sc); + si = __sync_val_compare_and_swap (&si, uc, sc); + ui = __sync_val_compare_and_swap (&ui, uc, sc); + sl = __sync_val_compare_and_swap (&sl, uc, sc); + ul = __sync_val_compare_and_swap (&ul, uc, sc); + sll = __sync_val_compare_and_swap (&sll, uc, sc); + ull = __sync_val_compare_and_swap (&ull, uc, sc); + + ui = __sync_bool_compare_and_swap (&sc, uc, sc); + ui = __sync_bool_compare_and_swap (&uc, uc, sc); + ui = __sync_bool_compare_and_swap (&ss, uc, sc); + ui = __sync_bool_compare_and_swap (&us, uc, sc); + ui = __sync_bool_compare_and_swap (&si, uc, sc); + ui = __sync_bool_compare_and_swap (&ui, uc, sc); + ui = __sync_bool_compare_and_swap (&sl, uc, sc); + ui = __sync_bool_compare_and_swap (&ul, uc, sc); + ui = __sync_bool_compare_and_swap (&sll, uc, sc); + ui = __sync_bool_compare_and_swap (&ull, uc, sc); +} + +void test_lock (void) +{ + sc = __sync_lock_test_and_set (&sc, 1); + uc = __sync_lock_test_and_set (&uc, 1); + ss = __sync_lock_test_and_set (&ss, 1); + us = __sync_lock_test_and_set (&us, 1); + si = __sync_lock_test_and_set (&si, 1); + ui = __sync_lock_test_and_set (&ui, 1); + sl = __sync_lock_test_and_set (&sl, 1); + ul = __sync_lock_test_and_set (&ul, 1); + sll = __sync_lock_test_and_set (&sll, 1); + ull = __sync_lock_test_and_set (&ull, 1); + + __sync_synchronize (); + + __sync_lock_release (&sc); + __sync_lock_release (&uc); + __sync_lock_release (&ss); + __sync_lock_release (&us); + __sync_lock_release (&si); + __sync_lock_release (&ui); + __sync_lock_release (&sl); + __sync_lock_release (&ul); + __sync_lock_release (&sll); + __sync_lock_release (&ull); +} diff --git a/test/small1/sync-2.c b/test/small1/sync-2.c new file mode 100644 index 0000000..b4e9bb7 --- /dev/null +++ b/test/small1/sync-2.c @@ -0,0 +1,169 @@ +// From c-torture +/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "" { target *-*-* } 0 } */ + +/* Validate that each of the __sync builtins compiles. This won't + necessarily link, since the target might not support the builtin, + so this may result in external library calls. */ + +signed char sc; +unsigned char uc; +signed short ss; +unsigned short us; +signed int si; +unsigned int ui; +signed long sl; +unsigned long ul; +signed long long sll; +unsigned long long ull; + +void test_op_ignore (void) +{ + (void) __sync_fetch_and_add (&sc, -1); + (void) __sync_fetch_and_add (&uc, -1); + (void) __sync_fetch_and_add (&ss, -1); + (void) __sync_fetch_and_add (&us, -1); + (void) __sync_fetch_and_add (&si, -1); + (void) __sync_fetch_and_add (&ui, -1); + (void) __sync_fetch_and_add (&sl, -1); + (void) __sync_fetch_and_add (&ul, -1); + (void) __sync_fetch_and_add (&sll, -1); + (void) __sync_fetch_and_add (&ull, -1); + + (void) __sync_fetch_and_sub (&sc, -1); + (void) __sync_fetch_and_sub (&uc, -1); + (void) __sync_fetch_and_sub (&ss, -1); + (void) __sync_fetch_and_sub (&us, -1); + (void) __sync_fetch_and_sub (&si, -1); + (void) __sync_fetch_and_sub (&ui, -1); + (void) __sync_fetch_and_sub (&sl, -1); + (void) __sync_fetch_and_sub (&ul, -1); + (void) __sync_fetch_and_sub (&sll, -1); + (void) __sync_fetch_and_sub (&ull, -1); + + (void) __sync_fetch_and_or (&sc, -1); + (void) __sync_fetch_and_or (&uc, -1); + (void) __sync_fetch_and_or (&ss, -1); + (void) __sync_fetch_and_or (&us, -1); + (void) __sync_fetch_and_or (&si, -1); + (void) __sync_fetch_and_or (&ui, -1); + (void) __sync_fetch_and_or (&sl, -1); + (void) __sync_fetch_and_or (&ul, -1); + (void) __sync_fetch_and_or (&sll, -1); + (void) __sync_fetch_and_or (&ull, -1); + + (void) __sync_fetch_and_xor (&sc, -1); + (void) __sync_fetch_and_xor (&uc, -1); + (void) __sync_fetch_and_xor (&ss, -1); + (void) __sync_fetch_and_xor (&us, -1); + (void) __sync_fetch_and_xor (&si, -1); + (void) __sync_fetch_and_xor (&ui, -1); + (void) __sync_fetch_and_xor (&sl, -1); + (void) __sync_fetch_and_xor (&ul, -1); + (void) __sync_fetch_and_xor (&sll, -1); + (void) __sync_fetch_and_xor (&ull, -1); + + (void) __sync_fetch_and_and (&sc, -1); + (void) __sync_fetch_and_and (&uc, -1); + (void) __sync_fetch_and_and (&ss, -1); + (void) __sync_fetch_and_and (&us, -1); + (void) __sync_fetch_and_and (&si, -1); + (void) __sync_fetch_and_and (&ui, -1); + (void) __sync_fetch_and_and (&sl, -1); + (void) __sync_fetch_and_and (&ul, -1); + (void) __sync_fetch_and_and (&sll, -1); + (void) __sync_fetch_and_and (&ull, -1); + + (void) __sync_fetch_and_nand (&sc, -1); + (void) __sync_fetch_and_nand (&uc, -1); + (void) __sync_fetch_and_nand (&ss, -1); + (void) __sync_fetch_and_nand (&us, -1); + (void) __sync_fetch_and_nand (&si, -1); + (void) __sync_fetch_and_nand (&ui, -1); + (void) __sync_fetch_and_nand (&sl, -1); + (void) __sync_fetch_and_nand (&ul, -1); + (void) __sync_fetch_and_nand (&sll, -1); + (void) __sync_fetch_and_nand (&ull, -1); +} + +void test_fetch_and_op (void) +{ + sc = __sync_fetch_and_add (&sc, -11); + uc = __sync_fetch_and_add (&uc, -11); + ss = __sync_fetch_and_add (&ss, -11); + us = __sync_fetch_and_add (&us, -11); + si = __sync_fetch_and_add (&si, -11); + ui = __sync_fetch_and_add (&ui, -11); + sl = __sync_fetch_and_add (&sl, -11); + ul = __sync_fetch_and_add (&ul, -11); + sll = __sync_fetch_and_add (&sll, -11); + ull = __sync_fetch_and_add (&ull, -11); + + sc = __sync_fetch_and_sub (&sc, -11); + uc = __sync_fetch_and_sub (&uc, -11); + ss = __sync_fetch_and_sub (&ss, -11); + us = __sync_fetch_and_sub (&us, -11); + si = __sync_fetch_and_sub (&si, -11); + ui = __sync_fetch_and_sub (&ui, -11); + sl = __sync_fetch_and_sub (&sl, -11); + ul = __sync_fetch_and_sub (&ul, -11); + sll = __sync_fetch_and_sub (&sll, -11); + ull = __sync_fetch_and_sub (&ull, -11); + + sc = __sync_fetch_and_or (&sc, -11); + uc = __sync_fetch_and_or (&uc, -11); + ss = __sync_fetch_and_or (&ss, -11); + us = __sync_fetch_and_or (&us, -11); + si = __sync_fetch_and_or (&si, -11); + ui = __sync_fetch_and_or (&ui, -11); + sl = __sync_fetch_and_or (&sl, -11); + ul = __sync_fetch_and_or (&ul, -11); + sll = __sync_fetch_and_or (&sll, -11); + ull = __sync_fetch_and_or (&ull, -11); + + sc = __sync_fetch_and_xor (&sc, -11); + uc = __sync_fetch_and_xor (&uc, -11); + ss = __sync_fetch_and_xor (&ss, -11); + us = __sync_fetch_and_xor (&us, -11); + si = __sync_fetch_and_xor (&si, -11); + ui = __sync_fetch_and_xor (&ui, -11); + sl = __sync_fetch_and_xor (&sl, -11); + ul = __sync_fetch_and_xor (&ul, -11); + sll = __sync_fetch_and_xor (&sll, -11); + ull = __sync_fetch_and_xor (&ull, -11); + + sc = __sync_fetch_and_and (&sc, -11); + uc = __sync_fetch_and_and (&uc, -11); + ss = __sync_fetch_and_and (&ss, -11); + us = __sync_fetch_and_and (&us, -11); + si = __sync_fetch_and_and (&si, -11); + ui = __sync_fetch_and_and (&ui, -11); + sl = __sync_fetch_and_and (&sl, -11); + ul = __sync_fetch_and_and (&ul, -11); + sll = __sync_fetch_and_and (&sll, -11); + ull = __sync_fetch_and_and (&ull, -11); + + sc = __sync_fetch_and_nand (&sc, -11); + uc = __sync_fetch_and_nand (&uc, -11); + ss = __sync_fetch_and_nand (&ss, -11); + us = __sync_fetch_and_nand (&us, -11); + si = __sync_fetch_and_nand (&si, -11); + ui = __sync_fetch_and_nand (&ui, -11); + sl = __sync_fetch_and_nand (&sl, -11); + ul = __sync_fetch_and_nand (&ul, -11); + sll = __sync_fetch_and_nand (&sll, -11); + ull = __sync_fetch_and_nand (&ull, -11); +} + +void test_lock (void) +{ + sc = __sync_lock_test_and_set (&sc, -1); + uc = __sync_lock_test_and_set (&uc, -1); + ss = __sync_lock_test_and_set (&ss, -1); + us = __sync_lock_test_and_set (&us, -1); + si = __sync_lock_test_and_set (&si, -1); + ui = __sync_lock_test_and_set (&ui, -1); + sl = __sync_lock_test_and_set (&sl, -1); + ul = __sync_lock_test_and_set (&ul, -1); + sll = __sync_lock_test_and_set (&sll, -1); + ull = __sync_lock_test_and_set (&ull, -1); +} diff --git a/test/small1/sync-3.c b/test/small1/sync-3.c new file mode 100644 index 0000000..96ac2b7 --- /dev/null +++ b/test/small1/sync-3.c @@ -0,0 +1,188 @@ +// From c-torture +/* { dg-message "note: '__sync_fetch_and_nand' changed semantics in GCC 4.4" "" { target *-*-* } 0 } */ + +/* Validate that each of the __sync builtins compiles. This won't + necessarily link, since the target might not support the builtin, + so this may result in external library calls. */ + +void test_op_ignore (void) +{ +signed char sc[2]; +unsigned char uc[2]; +signed short ss[2]; +unsigned short us[2]; +signed int si[2]; +unsigned int ui[2]; +signed long sl[2]; +unsigned long ul[2]; +signed long long sll[2]; +unsigned long long ull[2]; + (void) __sync_fetch_and_add (&sc[1], -1); + (void) __sync_fetch_and_add (&uc[1], -1); + (void) __sync_fetch_and_add (&ss[1], -1); + (void) __sync_fetch_and_add (&us[1], -1); + (void) __sync_fetch_and_add (&si[1], -1); + (void) __sync_fetch_and_add (&ui[1], -1); + (void) __sync_fetch_and_add (&sl[1], -1); + (void) __sync_fetch_and_add (&ul[1], -1); + (void) __sync_fetch_and_add (&sll[1], -1); + (void) __sync_fetch_and_add (&ull[1], -1); + + (void) __sync_fetch_and_sub (&sc[1], -1); + (void) __sync_fetch_and_sub (&uc[1], -1); + (void) __sync_fetch_and_sub (&ss[1], -1); + (void) __sync_fetch_and_sub (&us[1], -1); + (void) __sync_fetch_and_sub (&si[1], -1); + (void) __sync_fetch_and_sub (&ui[1], -1); + (void) __sync_fetch_and_sub (&sl[1], -1); + (void) __sync_fetch_and_sub (&ul[1], -1); + (void) __sync_fetch_and_sub (&sll[1], -1); + (void) __sync_fetch_and_sub (&ull[1], -1); + + (void) __sync_fetch_and_or (&sc[1], -1); + (void) __sync_fetch_and_or (&uc[1], -1); + (void) __sync_fetch_and_or (&ss[1], -1); + (void) __sync_fetch_and_or (&us[1], -1); + (void) __sync_fetch_and_or (&si[1], -1); + (void) __sync_fetch_and_or (&ui[1], -1); + (void) __sync_fetch_and_or (&sl[1], -1); + (void) __sync_fetch_and_or (&ul[1], -1); + (void) __sync_fetch_and_or (&sll[1], -1); + (void) __sync_fetch_and_or (&ull[1], -1); + + (void) __sync_fetch_and_xor (&sc[1], -1); + (void) __sync_fetch_and_xor (&uc[1], -1); + (void) __sync_fetch_and_xor (&ss[1], -1); + (void) __sync_fetch_and_xor (&us[1], -1); + (void) __sync_fetch_and_xor (&si[1], -1); + (void) __sync_fetch_and_xor (&ui[1], -1); + (void) __sync_fetch_and_xor (&sl[1], -1); + (void) __sync_fetch_and_xor (&ul[1], -1); + (void) __sync_fetch_and_xor (&sll[1], -1); + (void) __sync_fetch_and_xor (&ull[1], -1); + + (void) __sync_fetch_and_and (&sc[1], -1); + (void) __sync_fetch_and_and (&uc[1], -1); + (void) __sync_fetch_and_and (&ss[1], -1); + (void) __sync_fetch_and_and (&us[1], -1); + (void) __sync_fetch_and_and (&si[1], -1); + (void) __sync_fetch_and_and (&ui[1], -1); + (void) __sync_fetch_and_and (&sl[1], -1); + (void) __sync_fetch_and_and (&ul[1], -1); + (void) __sync_fetch_and_and (&sll[1], -1); + (void) __sync_fetch_and_and (&ull[1], -1); + + (void) __sync_fetch_and_nand (&sc[1], -1); + (void) __sync_fetch_and_nand (&uc[1], -1); + (void) __sync_fetch_and_nand (&ss[1], -1); + (void) __sync_fetch_and_nand (&us[1], -1); + (void) __sync_fetch_and_nand (&si[1], -1); + (void) __sync_fetch_and_nand (&ui[1], -1); + (void) __sync_fetch_and_nand (&sl[1], -1); + (void) __sync_fetch_and_nand (&ul[1], -1); + (void) __sync_fetch_and_nand (&sll[1], -1); + (void) __sync_fetch_and_nand (&ull[1], -1); +} + +void test_fetch_and_op (void) +{ +signed char sc[2]; +unsigned char uc[2]; +signed short ss[2]; +unsigned short us[2]; +signed int si[2]; +unsigned int ui[2]; +signed long sl[2]; +unsigned long ul[2]; +signed long long sll[2]; +unsigned long long ull[2]; + sc[1] = __sync_fetch_and_add (&sc[1], -11); + uc[1] = __sync_fetch_and_add (&uc[1], -11); + ss[1] = __sync_fetch_and_add (&ss[1], -11); + us[1] = __sync_fetch_and_add (&us[1], -11); + si[1] = __sync_fetch_and_add (&si[1], -11); + ui[1] = __sync_fetch_and_add (&ui[1], -11); + sl[1] = __sync_fetch_and_add (&sl[1], -11); + ul[1] = __sync_fetch_and_add (&ul[1], -11); + sll[1] = __sync_fetch_and_add (&sll[1], -11); + ull[1] = __sync_fetch_and_add (&ull[1], -11); + + sc[1] = __sync_fetch_and_sub (&sc[1], -11); + uc[1] = __sync_fetch_and_sub (&uc[1], -11); + ss[1] = __sync_fetch_and_sub (&ss[1], -11); + us[1] = __sync_fetch_and_sub (&us[1], -11); + si[1] = __sync_fetch_and_sub (&si[1], -11); + ui[1] = __sync_fetch_and_sub (&ui[1], -11); + sl[1] = __sync_fetch_and_sub (&sl[1], -11); + ul[1] = __sync_fetch_and_sub (&ul[1], -11); + sll[1] = __sync_fetch_and_sub (&sll[1], -11); + ull[1] = __sync_fetch_and_sub (&ull[1], -11); + + sc[1] = __sync_fetch_and_or (&sc[1], -11); + uc[1] = __sync_fetch_and_or (&uc[1], -11); + ss[1] = __sync_fetch_and_or (&ss[1], -11); + us[1] = __sync_fetch_and_or (&us[1], -11); + si[1] = __sync_fetch_and_or (&si[1], -11); + ui[1] = __sync_fetch_and_or (&ui[1], -11); + sl[1] = __sync_fetch_and_or (&sl[1], -11); + ul[1] = __sync_fetch_and_or (&ul[1], -11); + sll[1] = __sync_fetch_and_or (&sll[1], -11); + ull[1] = __sync_fetch_and_or (&ull[1], -11); + + sc[1] = __sync_fetch_and_xor (&sc[1], -11); + uc[1] = __sync_fetch_and_xor (&uc[1], -11); + ss[1] = __sync_fetch_and_xor (&ss[1], -11); + us[1] = __sync_fetch_and_xor (&us[1], -11); + si[1] = __sync_fetch_and_xor (&si[1], -11); + ui[1] = __sync_fetch_and_xor (&ui[1], -11); + sl[1] = __sync_fetch_and_xor (&sl[1], -11); + ul[1] = __sync_fetch_and_xor (&ul[1], -11); + sll[1] = __sync_fetch_and_xor (&sll[1], -11); + ull[1] = __sync_fetch_and_xor (&ull[1], -11); + + sc[1] = __sync_fetch_and_and (&sc[1], -11); + uc[1] = __sync_fetch_and_and (&uc[1], -11); + ss[1] = __sync_fetch_and_and (&ss[1], -11); + us[1] = __sync_fetch_and_and (&us[1], -11); + si[1] = __sync_fetch_and_and (&si[1], -11); + ui[1] = __sync_fetch_and_and (&ui[1], -11); + sl[1] = __sync_fetch_and_and (&sl[1], -11); + ul[1] = __sync_fetch_and_and (&ul[1], -11); + sll[1] = __sync_fetch_and_and (&sll[1], -11); + ull[1] = __sync_fetch_and_and (&ull[1], -11); + + sc[1] = __sync_fetch_and_nand (&sc[1], -11); + uc[1] = __sync_fetch_and_nand (&uc[1], -11); + ss[1] = __sync_fetch_and_nand (&ss[1], -11); + us[1] = __sync_fetch_and_nand (&us[1], -11); + si[1] = __sync_fetch_and_nand (&si[1], -11); + ui[1] = __sync_fetch_and_nand (&ui[1], -11); + sl[1] = __sync_fetch_and_nand (&sl[1], -11); + ul[1] = __sync_fetch_and_nand (&ul[1], -11); + sll[1] = __sync_fetch_and_nand (&sll[1], -11); + ull[1] = __sync_fetch_and_nand (&ull[1], -11); +} + +void test_lock (void) +{ +signed char sc[2]; +unsigned char uc[2]; +signed short ss[2]; +unsigned short us[2]; +signed int si[2]; +unsigned int ui[2]; +signed long sl[2]; +unsigned long ul[2]; +signed long long sll[2]; +unsigned long long ull[2]; + sc[1] = __sync_lock_test_and_set (&sc[1], -1); + uc[1] = __sync_lock_test_and_set (&uc[1], -1); + ss[1] = __sync_lock_test_and_set (&ss[1], -1); + us[1] = __sync_lock_test_and_set (&us[1], -1); + si[1] = __sync_lock_test_and_set (&si[1], -1); + ui[1] = __sync_lock_test_and_set (&ui[1], -1); + sl[1] = __sync_lock_test_and_set (&sl[1], -1); + ul[1] = __sync_lock_test_and_set (&ul[1], -1); + sll[1] = __sync_lock_test_and_set (&sll[1], -1); + ull[1] = __sync_lock_test_and_set (&ull[1], -1); +} diff --git a/test/testcil.pl b/test/testcil.pl index faf0ff7..adbc679 100644 --- a/test/testcil.pl +++ b/test/testcil.pl @@ -554,6 +554,9 @@ addTest("testrun/builtin3 "); addTest("testrun/builtin_choose_expr"); addTest("testrun/builtin4 "); addTest("test/builtin5 "); +addTest("test/sync-1 _GNUCC=1"); +addTest("test/sync-2 _GNUCC=1"); +addTest("test/sync-3 _GNUCC=1"); addTest("testrun/comparisons"); addTest("testrun/assign"); -- 1.6.5 ------------------------------------------------------------------------------ Throughout its 18-year history, RSA Conference consistently attracts the world's best and brightest in the field, creating opportunities for Conference attendees to learn about information security's most important issues through interactions with peers, luminaries and emerging and established companies. http://p.sf.net/sfu/rsaconf-dev2dev _______________________________________________ CIL-users mailing list CIL-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/cil-users