diff --git a/configure.ac b/configure.ac index dd327bb2ba..6ca409e086 100644 --- a/configure.ac +++ b/configure.ac @@ -792,6 +792,9 @@ AC_DEFINE_IF([HAVE_DIRENT_H], [test "x${have_dirent}" = "xyes"], ### Checks for structures ### Checks for compiler characteristics +EFL_CHECK_GCC_BUILTIN([bswap16], [HAVE_BSWAP16]) +EFL_CHECK_GCC_BUILTIN([bswap32], [HAVE_BSWAP32]) +EFL_CHECK_GCC_BUILTIN([bswap64], [HAVE_BSWAP64]) ### Checks for linker characteristics diff --git a/m4/gcc_check_builtin.m4 b/m4/gcc_check_builtin.m4 index 1434c5f80a..d5122502a6 100644 --- a/m4/gcc_check_builtin.m4 +++ b/m4/gcc_check_builtin.m4 @@ -1,20 +1,13 @@ AC_DEFUN([EFL_CHECK_GCC_BUILTIN], [efl_check_gcc_builtin_save_libs=$LIBS +EINA_CONFIGURE_$2="" LIBS="-lm $LIBS" AC_LINK_IFELSE( [AC_LANG_PROGRAM( -[[#ifndef __GNUC__ -choke me -#else -#undef $1 -/* Declare this function with same prototype as __builtin_$1. - This removes warning about conflicting type with builtin */ -__typeof__(__builtin_$1) $1; - -__typeof__(__builtin_$1) *f = $1; -#endif -]], [[return f != $1;]] +[[]], [[return __builtin_$1(42);]] )], -[AC_DEFINE([$2], [123], [GCC builtin $1 exists])]) +[EINA_CONFIGURE_$2="#define EINA_$2" +AC_DEFINE([$2], [1], [GCC builtin $1 exists])]) +AC_SUBST(EINA_CONFIGURE_$2) LIBS=$efl_check_gcc_builtin_save_libs]) diff --git a/src/Makefile_Eina.am b/src/Makefile_Eina.am index 7e40749d1f..09264ced9d 100644 --- a/src/Makefile_Eina.am +++ b/src/Makefile_Eina.am @@ -57,6 +57,7 @@ lib/eina/eina_trash.h \ lib/eina/eina_iterator.h \ lib/eina/eina_main.h \ lib/eina/eina_cpu.h \ +lib/eina/eina_inline_cpu.x \ lib/eina/eina_sched.h \ lib/eina/eina_tiler.h \ lib/eina/eina_hamster.h \ diff --git a/src/lib/eina/eina_config.h.in b/src/lib/eina/eina_config.h.in index abcf2f98fc..eb0869cf40 100644 --- a/src/lib/eina/eina_config.h.in +++ b/src/lib/eina/eina_config.h.in @@ -72,4 +72,19 @@ #endif @EINA_CONFIGURE_HAVE_ALLOCA_H@ +#ifdef EINA_HAVE_BSWAP16 +# undef EINA_HAVE_BSWAP16 +#endif +@EINA_CONFIGURE_HAVE_BSWAP16@ + +#ifdef EINA_HAVE_BSWAP32 +# undef EINA_HAVE_BSWAP32 +#endif +@EINA_CONFIGURE_HAVE_BSWAP32@ + +#ifdef EINA_HAVE_BSWAP64 +# undef EINA_HAVE_BSWAP64 +#endif +@EINA_CONFIGURE_HAVE_BSWAP64@ + #endif /* EINA_CONFIG_H_ */ diff --git a/src/lib/eina/eina_cpu.c b/src/lib/eina/eina_cpu.c index eb710027df..670b21c5d0 100644 --- a/src/lib/eina/eina_cpu.c +++ b/src/lib/eina/eina_cpu.c @@ -92,6 +92,9 @@ void _x86_simd(Eina_Cpu_Features *features) * 28 = HTT (Hyper Threading) * ecx * 0 = SSE3 + * 9 = SSSE3 + * 19 = SSE4.1 + * 20 = SSE4.2 */ if ((d >> 23) & 1) *features |= EINA_CPU_MMX; @@ -104,6 +107,15 @@ void _x86_simd(Eina_Cpu_Features *features) if (c & 1) *features |= EINA_CPU_SSE3; + + if ((c >> 9) & 1) + *features |= EINA_CPU_SSSE3; + + if ((c >> 19) & 1) + *features |= EINA_CPU_SSE41; + + if ((c >> 20) & 1) + *features |= EINA_CPU_SSE42; } #endif @@ -118,17 +130,32 @@ void _x86_simd(Eina_Cpu_Features *features) /* FIXME the features checks should be called when this function is called? * or make it static by doing eina_cpu_init() and return a local var */ +EAPI Eina_Cpu_Features eina_cpu_features = 0; + +Eina_Bool +eina_cpu_init(void) +{ +#if defined(__i386__) || defined(__x86_64__) + _x86_simd(&eina_cpu_features); +#endif + // FIXME: Handle NEON and friends + + return EINA_TRUE; +} + +Eina_Bool +eina_cpu_shutdown(void) +{ + return EINA_TRUE; +} + /** * * @return */ EAPI Eina_Cpu_Features eina_cpu_features_get(void) { - Eina_Cpu_Features ecf = 0; -#if defined(__i386__) || defined(__x86_64__) - _x86_simd(&ecf); -#endif - return ecf; + return eina_cpu_features; } static int _cpu_count = -1; diff --git a/src/lib/eina/eina_cpu.h b/src/lib/eina/eina_cpu.h index ac32e1db9b..651d925653 100644 --- a/src/lib/eina/eina_cpu.h +++ b/src/lib/eina/eina_cpu.h @@ -31,9 +31,20 @@ typedef enum _Eina_Cpu_Features EINA_CPU_ALTIVEC = 0x00000010, EINA_CPU_VIS = 0x00000020, EINA_CPU_NEON = 0x00000040, + EINA_CPU_SSSE3 = 0x00000080, + EINA_CPU_SSE41 = 0x00000100, + EINA_CPU_SSE42 = 0x00000200 } Eina_Cpu_Features; +EAPI extern Eina_Cpu_Features eina_cpu_features; + EAPI Eina_Cpu_Features eina_cpu_features_get(void); EAPI int eina_cpu_count(void); +static inline unsigned short eina_swap16(unsigned short x); +static inline unsigned int eina_swap32(unsigned int x); +static inline unsigned long long eina_swap64(unsigned long long x); + +#include "eina_inline_cpu.x" + #endif /* EINA_CPU_H_ */ diff --git a/src/lib/eina/eina_inline_cpu.x b/src/lib/eina/eina_inline_cpu.x new file mode 100644 index 0000000000..bdfb4a4b13 --- /dev/null +++ b/src/lib/eina/eina_inline_cpu.x @@ -0,0 +1,70 @@ +/* EINA - EFL data type library + * Copyright (C) 2013 Cedric Bail + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; + * if not, see . + */ +/* + * This code has been partially inspired by : + * - http://create.stephan-brumme.com/crc32/ + */ + +#ifndef EINA_INLINE_CPU_X_ +#define EINA_INLINE_CPU_X_ + +static inline unsigned short +eina_swap16(unsigned short x) +{ +#ifdef EINA_HAVE_BSWAP16 + return __builtin_bswap16(x); +#else + return (((x & 0xff00) >> 8) | + ((x & 0x00ff) << 8)); +#endif +} + +static inline unsigned int +eina_swap32(unsigned int x) +{ +#ifdef EINA_HAVE_BSWAP32 + return __builtin_bswap32(x); +#else + return (x >> 24) | + ((x >> 8) & 0x0000FF00) | + ((x << 8) & 0x00FF0000) | + (x << 24); +#endif +} + +static inline unsigned long long +eina_swap64(unsigned long long x) +{ +#ifdef EINA_HAVE_BSWAP64 + return __builtin_bswap64(x); +#else + return (((x & 0xff00000000000000ull) >> 56) | + ((x & 0x00ff000000000000ull) >> 40) | + ((x & 0x0000ff0000000000ull) >> 24) | + ((x & 0x000000ff00000000ull) >> 8) | + ((x & 0x00000000ff000000ull) << 8) | + ((x & 0x0000000000ff0000ull) << 24) | + ((x & 0x000000000000ff00ull) << 40) | + ((x & 0x00000000000000ffull) << 56))); +#endif +} + + + +#endif + diff --git a/src/lib/eina/eina_main.c b/src/lib/eina/eina_main.c index fa6ece893c..321946000e 100644 --- a/src/lib/eina/eina_main.c +++ b/src/lib/eina/eina_main.c @@ -159,6 +159,7 @@ EAPI Eina_Inlist *_eina_tracking = NULL; S(tmpstr); S(thread); S(cow); + S(cpu); /* no model for now S(model); */ @@ -201,7 +202,8 @@ static const struct eina_desc_setup _eina_desc_setup[] = { S(value), S(tmpstr), S(thread), - S(cow) + S(cow), + S(cpu) /* no model for now S(model) */