From owner-svn-src-stable-9@FreeBSD.ORG Wed May 30 19:21:55 2012 Return-Path: Delivered-To: svn-src-stable-9@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 2EA27106564A; Wed, 30 May 2012 19:21:55 +0000 (UTC) (envelope-from theraven@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 163738FC14; Wed, 30 May 2012 19:21:55 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q4UJLtdM070039; Wed, 30 May 2012 19:21:55 GMT (envelope-from theraven@svn.freebsd.org) Received: (from theraven@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q4UJLspn070036; Wed, 30 May 2012 19:21:54 GMT (envelope-from theraven@svn.freebsd.org) Message-Id: <201205301921.q4UJLspn070036@svn.freebsd.org> From: David Chisnall Date: Wed, 30 May 2012 19:21:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r236326 - stable/9/include X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 May 2012 19:21:55 -0000 Author: theraven Date: Wed May 30 19:21:54 2012 New Revision: 236326 URL: http://svn.freebsd.org/changeset/base/236326 Log: MFC r228862, 228880, 228882, 228906, 228977, 229332, 229575, 229591, 229704, 229716, 230062, 230225, 230267, 234958 This brings stdatomic.h into -STABLE and includes improvements to tgmath.h that significantly decrease compile times on a C11 compiler (such as the clang in the base system). Added: stable/9/include/stdatomic.h - copied, changed from r228862, head/include/stdatomic.h Modified: stable/9/include/tgmath.h Directory Properties: stable/9/include/ (props changed) Copied and modified: stable/9/include/stdatomic.h (from r228862, head/include/stdatomic.h) ============================================================================== --- head/include/stdatomic.h Sat Dec 24 15:17:01 2011 (r228862, copy source) +++ stable/9/include/stdatomic.h Wed May 30 19:21:54 2012 (r236326) @@ -35,14 +35,14 @@ #if __has_feature(cxx_atomic) #define __CLANG_ATOMICS -#elif defined(__GNUC__) +#elif __GNUC_PREREQ__(4, 7) #define __GNUC_ATOMICS -#else +#elif !defined(__GNUC__) #error "stdatomic.h does not support your compiler" #endif -#ifdef __GNUC_ATOMICS -#define _Atomic(T) struct { volatile T __val; } +#if !defined(__CLANG_ATOMICS) +#define _Atomic(T) struct { volatile T __val; } #endif /* @@ -50,11 +50,13 @@ */ #if defined(__CLANG_ATOMICS) -#define ATOMIC_VAR_INIT(value) (value) -#define atomic_init(obj, value) __atomic_init(obj, value) -#elif defined(__GNUC_ATOMICS) -#define ATOMIC_VAR_INIT(value) { .__val = (value) } -#define atomic_init(obj, value) (obj = ATOMIC_VAR_INIT(value)) +#define ATOMIC_VAR_INIT(value) (value) +#define atomic_init(obj, value) __c11_atomic_init(obj, value) +#else +#define ATOMIC_VAR_INIT(value) { .__val = (value) } +#define atomic_init(obj, value) do { \ + (obj)->__val = (value); \ +} while (0) #endif /* @@ -64,29 +66,29 @@ */ #ifndef __ATOMIC_RELAXED -#define __ATOMIC_RELAXED 0 +#define __ATOMIC_RELAXED 0 #endif #ifndef __ATOMIC_CONSUME -#define __ATOMIC_CONSUME 1 +#define __ATOMIC_CONSUME 1 #endif #ifndef __ATOMIC_ACQUIRE -#define __ATOMIC_ACQUIRE 2 +#define __ATOMIC_ACQUIRE 2 #endif #ifndef __ATOMIC_RELEASE -#define __ATOMIC_RELEASE 3 +#define __ATOMIC_RELEASE 3 #endif #ifndef __ATOMIC_ACQ_REL -#define __ATOMIC_ACQ_REL 4 +#define __ATOMIC_ACQ_REL 4 #endif #ifndef __ATOMIC_SEQ_CST -#define __ATOMIC_SEQ_CST 5 +#define __ATOMIC_SEQ_CST 5 #endif /* * 7.17.3 Order and consistency. * * The memory_order_* constants that denote the barrier behaviour of the - * atomic operations. + * atomic operations. */ enum memory_order { @@ -102,21 +104,30 @@ enum memory_order { * 7.17.4 Fences. */ -#if defined(__CLANG_ATOMICS) -#define atomic_thread_fence(order) __atomic_thread_fence(order) +#ifdef __CLANG_ATOMICS +#define atomic_thread_fence(order) __c11_atomic_thread_fence(order) +#define atomic_signal_fence(order) __c11_atomic_signal_fence(order) #elif defined(__GNUC_ATOMICS) +#define atomic_thread_fence(order) __atomic_thread_fence(order) +#define atomic_signal_fence(order) __atomic_signal_fence(order) +#else #define atomic_thread_fence(order) __sync_synchronize() +#define atomic_signal_fence(order) __asm volatile ("" : : : "memory") #endif -#define atomic_signal_fence(order) __asm volatile ("" : : : "memory"); /* * 7.17.5 Lock-free property. */ #if defined(__CLANG_ATOMICS) -#define atomic_is_lock_free(obj) __atomic_is_lock_free(obj) +#define atomic_is_lock_free(obj) \ + __c11_atomic_is_lock_free(sizeof(obj)) #elif defined(__GNUC_ATOMICS) -#define atomic_is_lock_free(obj) (sizeof((obj->__val)) <= sizeof(void *)) +#define atomic_is_lock_free(obj) \ + __atomic_is_lock_free(sizeof((obj)->__val)) +#else +#define atomic_is_lock_free(obj) \ + (sizeof((obj)->__val) <= sizeof(void *)) #endif /* @@ -174,38 +185,64 @@ typedef _Atomic(__uintmax_t) atomic_uin #if defined(__CLANG_ATOMICS) #define atomic_compare_exchange_strong_explicit(object, expected, \ desired, success, failure) \ - __atomic_compare_exchange_strong(object, expected, desired, \ + __c11_atomic_compare_exchange_strong(object, expected, desired, \ success, failure) #define atomic_compare_exchange_weak_explicit(object, expected, \ desired, success, failure) \ - __atomic_compare_exchange_weak(object, expected, desired, \ + __c11_atomic_compare_exchange_weak(object, expected, desired, \ success, failure) #define atomic_exchange_explicit(object, desired, order) \ - __atomic_exchange(object, desired, order) + __c11_atomic_exchange(object, desired, order) #define atomic_fetch_add_explicit(object, operand, order) \ - __atomic_fetch_add(object, operand, order) + __c11_atomic_fetch_add(object, operand, order) #define atomic_fetch_and_explicit(object, operand, order) \ - __atomic_fetch_and(object, operand, order) + __c11_atomic_fetch_and(object, operand, order) #define atomic_fetch_or_explicit(object, operand, order) \ - __atomic_fetch_or(object, operand, order) + __c11_atomic_fetch_or(object, operand, order) #define atomic_fetch_sub_explicit(object, operand, order) \ - __atomic_fetch_sub(object, operand, order) + __c11_atomic_fetch_sub(object, operand, order) #define atomic_fetch_xor_explicit(object, operand, order) \ - __atomic_fetch_xor(object, operand, order) + __c11_atomic_fetch_xor(object, operand, order) #define atomic_load_explicit(object, order) \ - __atomic_load(object, order) + __c11_atomic_load(object, order) #define atomic_store_explicit(object, desired, order) \ - __atomic_store(object, desired, order) + __c11_atomic_store(object, desired, order) #elif defined(__GNUC_ATOMICS) #define atomic_compare_exchange_strong_explicit(object, expected, \ + desired, success, failure) \ + __atomic_compare_exchange_n(&(object)->__val, expected, \ + desired, 0, success, failure) +#define atomic_compare_exchange_weak_explicit(object, expected, \ + desired, success, failure) \ + __atomic_compare_exchange_n(&(object)->__val, expected, \ + desired, 1, success, failure) +#define atomic_exchange_explicit(object, desired, order) \ + __atomic_exchange_n(&(object)->__val, desired, order) +#define atomic_fetch_add_explicit(object, operand, order) \ + __atomic_fetch_add(&(object)->__val, operand, order) +#define atomic_fetch_and_explicit(object, operand, order) \ + __atomic_fetch_and(&(object)->__val, operand, order) +#define atomic_fetch_or_explicit(object, operand, order) \ + __atomic_fetch_or(&(object)->__val, operand, order) +#define atomic_fetch_sub_explicit(object, operand, order) \ + __atomic_fetch_sub(&(object)->__val, operand, order) +#define atomic_fetch_xor_explicit(object, operand, order) \ + __atomic_fetch_xor(&(object)->__val, operand, order) +#define atomic_load_explicit(object, order) \ + __atomic_load_n(&(object)->__val, order) +#define atomic_store_explicit(object, desired, order) \ + __atomic_store_n(&(object)->__val, desired, order) +#else +#define atomic_compare_exchange_strong_explicit(object, expected, \ desired, success, failure) ({ \ __typeof__((object)->__val) __v; \ - __v = \ - __sync_val_compare_and_swap((__typeof(&((object)->__val)))object,\ - *expected, desired); \ - *expected = __v; \ - (*expected == __v); \ - }) + _Bool __r; \ + __v = __sync_val_compare_and_swap(&(object)->__val, \ + *(expected), desired); \ + __r = *(expected) == __v; \ + *(expected) = __v; \ + __r; \ +}) #define atomic_compare_exchange_weak_explicit(object, expected, \ desired, success, failure) \ @@ -214,7 +251,7 @@ typedef _Atomic(__uintmax_t) atomic_uin #if __has_builtin(__sync_swap) /* Clang provides a full-barrier atomic exchange - use it if available. */ #define atomic_exchange_explicit(object, desired, order) \ - __sync_swap(&(object)->value, desired) + __sync_swap(&(object)->__val, desired) #else /* * __sync_lock_test_and_set() is only an acquire barrier in theory (although in @@ -223,7 +260,7 @@ typedef _Atomic(__uintmax_t) atomic_uin */ #define atomic_exchange_explicit(object, desired, order) ({ \ __typeof__((object)->__val) __v; \ - __v = __sync_lock_test_and_set(object, desired); \ + __v = __sync_lock_test_and_set(&(object)->__val, desired); \ __sync_synchronize(); \ __v; \ }) @@ -278,9 +315,9 @@ typedef _Atomic(__uintmax_t) atomic_uin * 7.17.8 Atomic flag type and operations. */ -typedef atomic_bool atomic_flag; +typedef atomic_bool atomic_flag; -#define ATOMIC_FLAG_INIT ATOMIC_VAR_INIT(0) +#define ATOMIC_FLAG_INIT ATOMIC_VAR_INIT(0) #define atomic_flag_clear_explicit(object, order) \ atomic_store_explicit(object, 0, order) @@ -288,9 +325,8 @@ typedef atomic_bool atomic_flag; atomic_compare_exchange_strong_explicit(object, 0, 1, order, order) #define atomic_flag_clear(object) \ - atomic_flag_clear_explicit(object, 0, memory_order_seq_cst) + atomic_flag_clear_explicit(object, memory_order_seq_cst) #define atomic_flag_test_and_set(object) \ - atomic_flag_test_and_set_explicit(object, 0, 1, \ - memory_order_seq_cst, memory_order_seq_cst) + atomic_flag_test_and_set_explicit(object, memory_order_seq_cst) #endif /* !_STDATOMIC_H_ */ Modified: stable/9/include/tgmath.h ============================================================================== --- stable/9/include/tgmath.h Wed May 30 18:05:48 2012 (r236325) +++ stable/9/include/tgmath.h Wed May 30 19:21:54 2012 (r236326) @@ -2,6 +2,9 @@ * Copyright (c) 2004 Stefan Farfeleder. * All rights reserved. * + * Copyright (c) 2012 Ed Schouten + * All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -33,64 +36,104 @@ #include /* - * This implementation of requires two implementation-dependent - * macros to be defined: - * __tg_impl_simple(x, y, z, fn, fnf, fnl, ...) + * This implementation of uses the two following macros, + * which are based on the macros described in C11 proposal N1404: + * __tg_impl_simple(x, y, z, fnl, fn, fnf, ...) * Invokes fnl() if the corresponding real type of x, y or z is long * double, fn() if it is double or any has an integer type, and fnf() * otherwise. - * __tg_impl_full(x, y, z, fn, fnf, fnl, cfn, cfnf, cfnl, ...) - * Invokes [c]fnl() if the corresponding real type of x, y or z is long + * __tg_impl_full(x, y, cfnl, cfn, cfnf, fnl, fn, fnf, ...) + * Invokes [c]fnl() if the corresponding real type of x or y is long * double, [c]fn() if it is double or any has an integer type, and * [c]fnf() otherwise. The function with the 'c' prefix is called if - * any of x, y or z is a complex number. + * any of x or y is a complex number. * Both macros call the chosen function with all additional arguments passed * to them, as given by __VA_ARGS__. * * Note that these macros cannot be implemented with C's ?: operator, * because the return type of the whole expression would incorrectly be long * double complex regardless of the argument types. + * + * The structure of the C11 implementation of these macros can in + * principle be reused for non-C11 compilers, but due to an integer + * promotion bug for complex types in GCC 4.2, simply let non-C11 + * compilers use an inefficient yet reliable version. */ -#if __GNUC_PREREQ__(3, 1) -#define __tg_type(e, t) __builtin_types_compatible_p(__typeof__(e), t) -#define __tg_type3(e1, e2, e3, t) \ - (__tg_type(e1, t) || __tg_type(e2, t) || __tg_type(e3, t)) -#define __tg_type_corr(e1, e2, e3, t) \ - (__tg_type3(e1, e2, e3, t) || __tg_type3(e1, e2, e3, t _Complex)) -#define __tg_integer(e1, e2, e3) \ - (((__typeof__(e1))1.5 == 1) || ((__typeof__(e2))1.5 == 1) || \ - ((__typeof__(e3))1.5 == 1)) -#define __tg_is_complex(e1, e2, e3) \ - (__tg_type3(e1, e2, e3, float _Complex) || \ - __tg_type3(e1, e2, e3, double _Complex) || \ - __tg_type3(e1, e2, e3, long double _Complex) || \ - __tg_type3(e1, e2, e3, __typeof__(_Complex_I))) - -#define __tg_impl_simple(x, y, z, fn, fnf, fnl, ...) \ - __builtin_choose_expr(__tg_type_corr(x, y, z, long double), \ - fnl(__VA_ARGS__), __builtin_choose_expr( \ - __tg_type_corr(x, y, z, double) || __tg_integer(x, y, z),\ - fn(__VA_ARGS__), fnf(__VA_ARGS__))) - -#define __tg_impl_full(x, y, z, fn, fnf, fnl, cfn, cfnf, cfnl, ...) \ - __builtin_choose_expr(__tg_is_complex(x, y, z), \ - __tg_impl_simple(x, y, z, cfn, cfnf, cfnl, __VA_ARGS__), \ - __tg_impl_simple(x, y, z, fn, fnf, fnl, __VA_ARGS__)) - -#else /* __GNUC__ */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +#define __tg_generic(x, cfnl, cfn, cfnf, fnl, fn, fnf) \ + _Generic(x, \ + long double _Complex: cfnl, \ + double _Complex: cfn, \ + float _Complex: cfnf, \ + long double: fnl, \ + default: fn, \ + float: fnf \ + ) +#define __tg_type(x) \ + __tg_generic(x, (long double _Complex)0, (double _Complex)0, \ + (float _Complex)0, (long double)0, (double)0, (float)0) +#define __tg_impl_simple(x, y, z, fnl, fn, fnf, ...) \ + __tg_generic( \ + __tg_type(x) + __tg_type(y) + __tg_type(z), \ + fnl, fn, fnf, fnl, fn, fnf)(__VA_ARGS__) +#define __tg_impl_full(x, y, cfnl, cfn, cfnf, fnl, fn, fnf, ...) \ + __tg_generic( \ + __tg_type(x) + __tg_type(y), \ + cfnl, cfn, cfnf, fnl, fn, fnf)(__VA_ARGS__) +#elif defined(__generic) +#define __tg_generic_simple(x, fnl, fn, fnf) \ + __generic(x, long double _Complex, fnl, \ + __generic(x, double _Complex, fn, \ + __generic(x, float _Complex, fnf, \ + __generic(x, long double, fnl, \ + __generic(x, float, fnf, fn))))) +#define __tg_impl_simple(x, y, z, fnl, fn, fnf, ...) \ + __tg_generic_simple(x, \ + __tg_generic_simple(y, \ + __tg_generic_simple(z, fnl, fnl, fnl), \ + __tg_generic_simple(z, fnl, fnl, fnl), \ + __tg_generic_simple(z, fnl, fnl, fnl)), \ + __tg_generic_simple(y, \ + __tg_generic_simple(z, fnl, fnl, fnl), \ + __tg_generic_simple(z, fnl, fn , fn ), \ + __tg_generic_simple(z, fnl, fn , fn )), \ + __tg_generic_simple(y, \ + __tg_generic_simple(z, fnl, fnl, fnl), \ + __tg_generic_simple(z, fnl, fn , fn ), \ + __tg_generic_simple(z, fnl, fn , fnf)))(__VA_ARGS__) +#define __tg_generic_full(x, cfnl, cfn, cfnf, fnl, fn, fnf) \ + __generic(x, long double _Complex, cfnl, \ + __generic(x, double _Complex, cfn, \ + __generic(x, float _Complex, cfnf, \ + __generic(x, long double, fnl, \ + __generic(x, float, fnf, fn))))) +#define __tg_impl_full(x, y, cfnl, cfn, cfnf, fnl, fn, fnf, ...) \ + __tg_generic_full(x, \ + __tg_generic_full(y, cfnl, cfnl, cfnl, cfnl, cfnl, cfnl), \ + __tg_generic_full(y, cfnl, cfn , cfn , cfnl, cfn , cfn ), \ + __tg_generic_full(y, cfnl, cfn , cfnf, cfnl, cfn , cfnf), \ + __tg_generic_full(y, cfnl, cfnl, cfnl, fnl , fnl , fnl ), \ + __tg_generic_full(y, cfnl, cfn , cfn , fnl , fn , fn ), \ + __tg_generic_full(y, cfnl, cfn , cfnf, fnl , fn , fnf )) \ + (__VA_ARGS__) +#else #error " not implemented for this compiler" -#endif /* !__GNUC__ */ +#endif /* Macros to save lots of repetition below */ #define __tg_simple(x, fn) \ - __tg_impl_simple(x, x, x, fn, fn##f, fn##l, x) + __tg_impl_simple(x, x, x, fn##l, fn, fn##f, x) #define __tg_simple2(x, y, fn) \ - __tg_impl_simple(x, x, y, fn, fn##f, fn##l, x, y) + __tg_impl_simple(x, x, y, fn##l, fn, fn##f, x, y) +#define __tg_simple3(x, y, z, fn) \ + __tg_impl_simple(x, y, z, fn##l, fn, fn##f, x, y, z) #define __tg_simplev(x, fn, ...) \ - __tg_impl_simple(x, x, x, fn, fn##f, fn##l, __VA_ARGS__) + __tg_impl_simple(x, x, x, fn##l, fn, fn##f, __VA_ARGS__) #define __tg_full(x, fn) \ - __tg_impl_full(x, x, x, fn, fn##f, fn##l, c##fn, c##fn##f, c##fn##l, x) + __tg_impl_full(x, x, c##fn##l, c##fn, c##fn##f, fn##l, fn, fn##f, x) +#define __tg_full2(x, y, fn) \ + __tg_impl_full(x, y, c##fn##l, c##fn, c##fn##f, fn##l, fn, fn##f, x, y) /* 7.22#4 -- These macros expand to real or complex functions, depending on * the type of their arguments. */ @@ -108,13 +151,12 @@ #define tanh(x) __tg_full(x, tanh) #define exp(x) __tg_full(x, exp) #define log(x) __tg_full(x, log) -#define pow(x, y) __tg_impl_full(x, x, y, pow, powf, powl, \ - cpow, cpowf, cpowl, x, y) +#define pow(x, y) __tg_full2(x, y, pow) #define sqrt(x) __tg_full(x, sqrt) /* "The corresponding type-generic macro for fabs and cabs is fabs." */ -#define fabs(x) __tg_impl_full(x, x, x, fabs, fabsf, fabsl, \ - cabs, cabsf, cabsl, x) +#define fabs(x) __tg_impl_full(x, x, cabsl, cabs, cabsf, \ + fabsl, fabs, fabsf, x) /* 7.22#5 -- These macros are only defined for arguments with real type. */ #define atan2(x, y) __tg_simple2(x, y, atan2) @@ -127,7 +169,7 @@ #define expm1(x) __tg_simple(x, expm1) #define fdim(x, y) __tg_simple2(x, y, fdim) #define floor(x) __tg_simple(x, floor) -#define fma(x, y, z) __tg_impl_simple(x, y, z, fma, fmaf, fmal, x, y, z) +#define fma(x, y, z) __tg_simple3(x, y, z, fma) #define fmax(x, y) __tg_simple2(x, y, fmax) #define fmin(x, y) __tg_simple2(x, y, fmin) #define fmod(x, y) __tg_simple2(x, y, fmod) @@ -148,8 +190,8 @@ #define nextafter(x, y) __tg_simple2(x, y, nextafter) #define nexttoward(x, y) __tg_simplev(x, nexttoward, x, y) #define remainder(x, y) __tg_simple2(x, y, remainder) -#define remquo(x, y, z) __tg_impl_simple(x, x, y, remquo, remquof, \ - remquol, x, y, z) +#define remquo(x, y, z) __tg_impl_simple(x, x, y, remquol, remquo, \ + remquof, x, y, z) #define rint(x) __tg_simple(x, rint) #define round(x) __tg_simple(x, round) #define scalbn(x, y) __tg_simplev(x, scalbn, x, y)