diff --git a/include/etl/memory.h b/include/etl/memory.h index 93f3c0ec..119c1fce 100644 --- a/include/etl/memory.h +++ b/include/etl/memory.h @@ -2290,9 +2290,15 @@ namespace etl { ETL_STATIC_ASSERT(etl::is_trivially_copyable::value, "Cannot mem_copy a non trivially copyable type"); +#if ETL_USING_BUILTIN_MEMCPY + __builtin_memcpy(reinterpret_cast(db), + reinterpret_cast(sb), + sizeof(T) * static_cast(se - sb)); +#else ::memcpy(reinterpret_cast(db), reinterpret_cast(sb), sizeof(T) * static_cast(se - sb)); +#endif return db; } @@ -2309,9 +2315,15 @@ namespace etl { ETL_STATIC_ASSERT(etl::is_trivially_copyable::value, "Cannot mem_copy a non trivially copyable type"); +#if ETL_USING_BUILTIN_MEMCPY + __builtin_memcpy(reinterpret_cast(db), + reinterpret_cast(sb), + sizeof(T) * n); +#else ::memcpy(reinterpret_cast(db), reinterpret_cast(sb), sizeof(T) * n); +#endif return db; } @@ -2328,9 +2340,15 @@ namespace etl { ETL_STATIC_ASSERT(etl::is_trivially_copyable::value, "Cannot mem_move a non trivially copyable type"); +#if ETL_USING_BUILTIN_MEMMOVE + __builtin_memmove(reinterpret_cast(db), + reinterpret_cast(sb), + sizeof(T) * static_cast(se - sb)); +#else ::memmove(reinterpret_cast(db), reinterpret_cast(sb), sizeof(T) * static_cast(se - sb)); +#endif return db; } @@ -2347,9 +2365,15 @@ namespace etl { ETL_STATIC_ASSERT(etl::is_trivially_copyable::value, "Cannot mem_move a non trivially copyable type"); +#if ETL_USING_BUILTIN_MEMMOVE + __builtin_memmove(reinterpret_cast(db), + reinterpret_cast(sb), + sizeof(T) * n); +#else ::memmove(reinterpret_cast(db), reinterpret_cast(sb), sizeof(T) * n); +#endif return db; } @@ -2369,9 +2393,15 @@ namespace etl { ETL_STATIC_ASSERT(etl::is_trivially_copyable::value, "Cannot mem_compare a non trivially copyable type"); +#if ETL_USING_BUILTIN_MEMCMP + return __builtin_memcmp(reinterpret_cast(db), + reinterpret_cast(sb), + sizeof(T) * static_cast(se - sb)); +#else return ::memcmp(reinterpret_cast(db), reinterpret_cast(sb), sizeof(T) * static_cast(se - sb)); +#endif } //*************************************************************************** @@ -2389,9 +2419,15 @@ namespace etl { ETL_STATIC_ASSERT(etl::is_trivially_copyable::value, "Cannot mem_compare a non trivially copyable type"); +#if ETL_USING_BUILTIN_MEMCMP + return __builtin_memcmp(reinterpret_cast(db), + reinterpret_cast(sb), + sizeof(T) * n); +#else return ::memcmp(reinterpret_cast(db), reinterpret_cast(sb), sizeof(T) * n); +#endif } //*************************************************************************** @@ -2410,9 +2446,15 @@ namespace etl { ETL_STATIC_ASSERT(etl::is_trivially_copyable::value_type>::value, "Cannot mem_set a non trivially copyable type"); +#if ETL_USING_BUILTIN_MEMSET + __builtin_memset(reinterpret_cast(db), + static_cast(value), + sizeof(typename etl::iterator_traits::value_type) * static_cast(de - db)); +#else ::memset(reinterpret_cast(db), static_cast(value), sizeof(typename etl::iterator_traits::value_type) * static_cast(de - db)); +#endif return db; } @@ -2433,9 +2475,15 @@ namespace etl { ETL_STATIC_ASSERT(etl::is_trivially_copyable::value_type>::value, "Cannot mem_set a non trivially copyable type"); +#if ETL_USING_BUILTIN_MEMSET + __builtin_memset(reinterpret_cast(db), + static_cast(value), + sizeof(typename etl::iterator_traits::value_type) * n); +#else ::memset(reinterpret_cast(db), static_cast(value), sizeof(typename etl::iterator_traits::value_type) * n); +#endif return db; } @@ -2455,11 +2503,19 @@ namespace etl sizeof(T) == 1, char*>::type mem_char(TPointer sb, TPointer se, T value) ETL_NOEXCEPT { +#if ETL_USING_BUILTIN_MEMCHR + void* result = __builtin_memchr(reinterpret_cast(sb), + static_cast(value), + sizeof(typename etl::iterator_traits::value_type) * static_cast(se - sb)); + + return (result == 0U) ? reinterpret_cast(se) : reinterpret_cast(result); +#else void* result = ::memchr(reinterpret_cast(sb), static_cast(value), sizeof(typename etl::iterator_traits::value_type) * static_cast(se - sb)); return (result == 0U) ? reinterpret_cast(se) : reinterpret_cast(result); +#endif } //*************************************************************************** @@ -2477,11 +2533,19 @@ namespace etl sizeof(T) == 1, const char*>::type mem_char(TPointer sb, TPointer se, T value) ETL_NOEXCEPT { +#if ETL_USING_BUILTIN_MEMCHR + const void* result = __builtin_memchr(reinterpret_cast(sb), + static_cast(value), + sizeof(typename etl::iterator_traits::value_type) * static_cast(se - sb)); + + return (result == 0U) ? reinterpret_cast(se) : reinterpret_cast(result); +#else const void* result = ::memchr(reinterpret_cast(sb), static_cast(value), sizeof(typename etl::iterator_traits::value_type) * static_cast(se - sb)); return (result == 0U) ? reinterpret_cast(se) : reinterpret_cast(result); +#endif } //*************************************************************************** @@ -2499,11 +2563,19 @@ namespace etl sizeof(T) == 1, char*>::type mem_char(TPointer sb, size_t n, T value) ETL_NOEXCEPT { +#if ETL_USING_BUILTIN_MEMCHR + void* result = __builtin_memchr(reinterpret_cast(sb), + static_cast(value), + sizeof(typename etl::iterator_traits::value_type) * n); + + return (result == 0U) ? reinterpret_cast(sb + n) : reinterpret_cast(result); +#else void* result = ::memchr(reinterpret_cast(sb), static_cast(value), sizeof(typename etl::iterator_traits::value_type) * n); return (result == 0U) ? reinterpret_cast(sb + n) : reinterpret_cast(result); +#endif } //*************************************************************************** @@ -2521,11 +2593,21 @@ namespace etl sizeof(T) == 1, const char*>::type mem_char(TPointer sb, size_t n, T value) ETL_NOEXCEPT { +#if ETL_USING_BUILTIN_MEMCHR + const void* result = __builtin_memchr(reinterpret_cast(sb), + static_cast(value), + sizeof(typename etl::iterator_traits::value_type) * n); + + return (result == 0U) ? reinterpret_cast(sb + n) : reinterpret_cast(result); +#else const void* result = ::memchr(reinterpret_cast(sb), static_cast(value), sizeof(typename etl::iterator_traits::value_type) * n); return (result == 0U) ? reinterpret_cast(sb + n) : reinterpret_cast(result); +#endif + + } #if ETL_USING_CPP11 diff --git a/include/etl/profiles/determine_builtin_support.h b/include/etl/profiles/determine_builtin_support.h index 0d18c315..d9838227 100644 --- a/include/etl/profiles/determine_builtin_support.h +++ b/include/etl/profiles/determine_builtin_support.h @@ -81,6 +81,26 @@ SOFTWARE. #if !defined(ETL_USING_BUILTIN_UNDERLYING_TYPE) #define ETL_USING_BUILTIN_UNDERLYING_TYPE __has_builtin(__underlying_type) #endif + + #if !defined(ETL_USING_BUILTIN_MEMCPY) + #define ETL_USING_BUILTIN_MEMCPY __has_builtin(__builtin_memcpy) + #endif + + #if !defined(ETL_USING_BUILTIN_MEMMOVE) + #define ETL_USING_BUILTIN_MEMMOVE __has_builtin(__builtin_memmove) + #endif + + #if !defined(ETL_USING_BUILTIN_MEMSET) + #define ETL_USING_BUILTIN_MEMSET __has_builtin(__builtin_memset) + #endif + + #if !defined(ETL_USING_BUILTIN_MEMCMP) + #define ETL_USING_BUILTIN_MEMCMP __has_builtin(__builtin_memcmp) + #endif + + #if !defined(ETL_USING_BUILTIN_MEMCHR) + #define ETL_USING_BUILTIN_MEMCHR __has_builtin(__builtin_memchr) + #endif #endif // The default. Set to 0, if not already set. @@ -108,6 +128,26 @@ SOFTWARE. #define ETL_USING_BUILTIN_UNDERLYING_TYPE 0 #endif +#if !defined(ETL_USING_BUILTIN_MEMCPY) + #define ETL_USING_BUILTIN_MEMCPY 0 +#endif + +#if !defined(ETL_USING_BUILTIN_MEMMOVE) + #define ETL_USING_BUILTIN_MEMMOVE 0 +#endif + +#if !defined(ETL_USING_BUILTIN_MEMSET) + #define ETL_USING_BUILTIN_MEMSET 0 +#endif + +#if !defined(ETL_USING_BUILTIN_MEMCMP) + #define ETL_USING_BUILTIN_MEMCMP 0 +#endif + +#if !defined(ETL_USING_BUILTIN_MEMCHR) + #define ETL_USING_BUILTIN_MEMCHR 0 +#endif + namespace etl { namespace traits @@ -120,6 +160,11 @@ namespace etl static ETL_CONSTANT bool using_builtin_is_trivially_destructible = (ETL_USING_BUILTIN_IS_TRIVIALLY_DESTRUCTIBLE == 1); static ETL_CONSTANT bool using_builtin_is_trivially_copyable = (ETL_USING_BUILTIN_IS_TRIVIALLY_COPYABLE == 1); static ETL_CONSTANT bool using_builtin_underlying_type = (ETL_USING_BUILTIN_UNDERLYING_TYPE == 1); + static ETL_CONSTANT bool using_builtin_memcpy = (ETL_USING_BUILTIN_MEMCPY == 1); + static ETL_CONSTANT bool using_builtin_memmove = (ETL_USING_BUILTIN_MEMMOVE == 1); + static ETL_CONSTANT bool using_builtin_memset = (ETL_USING_BUILTIN_MEMSET == 1); + static ETL_CONSTANT bool using_builtin_memcmp = (ETL_USING_BUILTIN_MEMCMP == 1); + static ETL_CONSTANT bool using_builtin_memchr = (ETL_USING_BUILTIN_MEMCHR == 1); } }