sl@0: /* sl@0: * LIBOIL - Library of Optimized Inner Loops sl@0: * Copyright (c) 2003,2004 David A. Schleef sl@0: * All rights reserved. sl@0: * sl@0: * Redistribution and use in source and binary forms, with or without sl@0: * modification, are permitted provided that the following conditions sl@0: * are met: sl@0: * 1. Redistributions of source code must retain the above copyright sl@0: * notice, this list of conditions and the following disclaimer. sl@0: * 2. Redistributions in binary form must reproduce the above copyright sl@0: * notice, this list of conditions and the following disclaimer in the sl@0: * documentation and/or other materials provided with the distribution. sl@0: * sl@0: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR sl@0: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED sl@0: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE sl@0: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, sl@0: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES sl@0: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR sl@0: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) sl@0: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, sl@0: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING sl@0: * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE sl@0: * POSSIBILITY OF SUCH DAMAGE. sl@0: */ sl@0: sl@0: //Portions Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. sl@0: sl@0: #ifndef _LIBOIL_FUNCTION_H_ sl@0: #define _LIBOIL_FUNCTION_H_ sl@0: sl@0: #include "liboil/liboilutils.h" sl@0: #include "liboil/liboiltypes.h" sl@0: sl@0: /** sl@0: * OIL_CHECK_PROTOTYPE: sl@0: * @a: sl@0: * sl@0: * Macro used internally to implement the --enable-prototype-checking sl@0: * configure option. sl@0: */ sl@0: #ifdef LIBOIL_STRICT_PROTOTYPES sl@0: #include sl@0: #define OIL_CHECK_PROTOTYPE(a) a sl@0: #else sl@0: #define OIL_CHECK_PROTOTYPE(a) sl@0: #endif sl@0: sl@0: OIL_BEGIN_DECLS sl@0: sl@0: /** sl@0: * OilImplFlag: sl@0: * sl@0: * Implementation flags. sl@0: * sl@0: * @OIL_IMPL_FLAG_REF: is the reference implementation for the class. sl@0: * sl@0: * @OIL_IMPL_FLAG_OPT: was compiled with alternate CFLAGS as specified sl@0: * by --enable-alternate-optimization. sl@0: * sl@0: * @OIL_IMPL_FLAG_ASM: is written in assembly code. sl@0: * sl@0: * @OIL_IMPL_FLAG_DISABLED: is disabled. This can be set either in the sl@0: * source code or during library initialization. sl@0: * sl@0: * @OIL_IMPL_FLAG_CMOV: uses the i386 instruction cmov or its variants. sl@0: * sl@0: * @OIL_IMPL_FLAG_MMX: uses MMX instructions. sl@0: * sl@0: * @OIL_IMPL_FLAG_SSE: uses SSE instructions. sl@0: * sl@0: * @OIL_IMPL_FLAG_MMXEXT: uses AMD's extended MMX instructions. These sl@0: * are a subset of what Intel calls SSE2. If an implementation uses sl@0: * only AMD's extended MMX instructions, it should set this flag, and sl@0: * not @OIL_IMPL_FLAG_SSE2. sl@0: * sl@0: * @OIL_IMPL_FLAG_SSE2: uses SSE2 instructions. This flag implies sl@0: * @OIL_IMPL_FLAG_SSE and @OIL_IMPL_FLAG_MMXEXT. sl@0: * sl@0: * @OIL_IMPL_FLAG_3DNOW: uses 3DNow! instructions. sl@0: * sl@0: * @OIL_IMPL_FLAG_3DNOWEXT: uses extended 3DNow! instructions. sl@0: * sl@0: * @OIL_IMPL_FLAG_SSE3: uses SSE3 instructions. This flag implies sl@0: * @OIL_IMPL_FLAG_SSE2. sl@0: * sl@0: * @OIL_IMPL_FLAG_SSSE3: uses SSSE3 instructions. This flag implies sl@0: * @OIL_IMPL_FLAG_SSE3. sl@0: * sl@0: * @OIL_IMPL_FLAG_ALTIVEC: uses Altivec instructions. sl@0: * sl@0: */ sl@0: typedef enum { sl@0: OIL_IMPL_FLAG_REF = (1<<0), sl@0: OIL_IMPL_FLAG_OPT = (1<<1), sl@0: OIL_IMPL_FLAG_ASM = (1<<2), sl@0: OIL_IMPL_FLAG_DISABLED = (1<<3), sl@0: OIL_IMPL_FLAG_CMOV = (1<<16), sl@0: OIL_IMPL_FLAG_MMX = (1<<17), sl@0: OIL_IMPL_FLAG_SSE = (1<<18), sl@0: OIL_IMPL_FLAG_MMXEXT = (1<<19), sl@0: OIL_IMPL_FLAG_SSE2 = (1<<20), sl@0: OIL_IMPL_FLAG_3DNOW = (1<<21), sl@0: OIL_IMPL_FLAG_3DNOWEXT = (1<<22), sl@0: OIL_IMPL_FLAG_SSE3 = (1<<23), sl@0: OIL_IMPL_FLAG_ALTIVEC = (1<<24), sl@0: OIL_IMPL_FLAG_EDSP = (1<<25), sl@0: OIL_IMPL_FLAG_ARM6 = (1<<26), sl@0: OIL_IMPL_FLAG_VFP = (1<<27), sl@0: OIL_IMPL_FLAG_SSSE3 = (1<<28) sl@0: } OilImplFlag; sl@0: sl@0: #ifdef OIL_ENABLE_UNSTABLE_API sl@0: sl@0: /** sl@0: * OIL_OPT_MANGLE: sl@0: * sl@0: * Used internally to implement the --enable-alternate-optimizations sl@0: * configure option. sl@0: */ sl@0: /** sl@0: * OIL_OPT_FLAG_MANGLE: sl@0: * sl@0: * Used internally to implement the --enable-alternate-optimizations sl@0: * configure option. sl@0: */ sl@0: /** sl@0: * OIL_NO_CLASSES: sl@0: * sl@0: * Used internally to implement the --enable-alternate-optimizations sl@0: * configure option. sl@0: */ sl@0: /** sl@0: * OIL_OPT_SUFFIX: sl@0: * sl@0: * Used internally to implement the --enable-alternate-optimizations sl@0: * configure option. sl@0: */ sl@0: #ifndef OIL_OPT_MANGLE sl@0: #define OIL_OPT_MANGLE(a) a sl@0: #define OIL_OPT_FLAG_MANGLE(a) a sl@0: #else sl@0: #define OIL_NO_CLASSES sl@0: #define OIL_OPT_FLAG_MANGLE(a) (((a)&(~OIL_IMPL_FLAG_REF)) | OIL_IMPL_FLAG_OPT) sl@0: #endif sl@0: #ifndef OIL_OPT_SUFFIX sl@0: #define OIL_OPT_SUFFIX sl@0: #endif sl@0: sl@0: /** sl@0: * OilFunctionClass: sl@0: * sl@0: * An opaque structure representing a function class. sl@0: * sl@0: */ sl@0: struct _OilFunctionClass { sl@0: /*< private >*/ sl@0: void *func; sl@0: const char *name; sl@0: const char *desc; sl@0: OilTestFunction test_func; sl@0: sl@0: OilFunctionImpl *first_impl; sl@0: OilFunctionImpl *reference_impl; sl@0: sl@0: OilFunctionImpl *chosen_impl; sl@0: sl@0: const char *prototype; sl@0: }; sl@0: sl@0: /** sl@0: * OilFunctionImpl: sl@0: * sl@0: * An opaque structure representing a function implementation. sl@0: * sl@0: */ sl@0: struct _OilFunctionImpl { sl@0: /*< private >*/ sl@0: void *next; sl@0: OilFunctionClass *klass; sl@0: void *func; sl@0: unsigned int flags; sl@0: const char *name; sl@0: double profile_ave; sl@0: double profile_std; sl@0: }; sl@0: sl@0: /** sl@0: * OIL_GET: sl@0: * @ptr: sl@0: * @offset: sl@0: * @type: sl@0: * sl@0: * Offsets @ptr by @offset number of bytes, and dereferences it sl@0: * as type @type. Note that the offset is in bytes, and not in sl@0: * the size of the pointer type. sl@0: */ sl@0: #define OIL_GET(ptr, offset, type) (*(type *)((uint8_t *)(ptr) + (offset)) ) sl@0: /** sl@0: * OIL_OFFSET: sl@0: * @ptr: sl@0: * @offset: sl@0: * sl@0: * Add @offset bytes to the pointer @ptr. sl@0: */ sl@0: #define OIL_OFFSET(ptr, offset) ((void *)((uint8_t *)(ptr) + (offset)) ) sl@0: /** sl@0: * OIL_INCREMENT: sl@0: * @ptr: sl@0: * @offset: sl@0: * sl@0: * Increments the pointer @ptr by @offset number of bytes. sl@0: */ sl@0: #define OIL_INCREMENT(ptr, offset) (ptr = (void *)((uint8_t *)ptr + (offset)) ) sl@0: sl@0: /** sl@0: * OIL_CPU_FLAG_MASK: sl@0: * sl@0: * Mask describing which bits in #OilImplFlag depend on the current sl@0: * CPU. sl@0: */ sl@0: #define OIL_CPU_FLAG_MASK 0xffff0000 sl@0: sl@0: /** sl@0: * OIL_DECLARE_CLASS: sl@0: * @klass: the name of a function class (without the oil_ prefix) sl@0: * sl@0: * Declares the Liboil function class @klass. sl@0: */ sl@0: #define OIL_DECLARE_CLASS(klass) \ sl@0: extern OilFunctionClass _oil_function_class_ ## klass sl@0: sl@0: /** sl@0: * SECTION:liboilmacros sl@0: * @title: Macros sl@0: * @short_description: Macros sl@0: */ sl@0: sl@0: #ifndef OIL_NO_CLASSES sl@0: /** sl@0: * OIL_DEFINE_CLASS_FULL: sl@0: * @klass: name of class to declare (without oil_ prefix) sl@0: * @string: prototype of class sl@0: * @test: test function sl@0: * sl@0: * Defines a #OilFunctionClass structure for @klass. Classes sl@0: * defined this way will be automatically at Liboil initialization sl@0: * time. sl@0: */ sl@0: #define OIL_DEFINE_CLASS_FULL(klass, string, test) \ sl@0: OilFunctionClass _oil_function_class_ ## klass = { \ sl@0: NULL, \ sl@0: #klass , \ sl@0: NULL, \ sl@0: test, \ sl@0: NULL, \ sl@0: NULL, \ sl@0: NULL, \ sl@0: string \ sl@0: }; \ sl@0: OilFunctionClass *oil_function_class_ptr_ ## klass = \ sl@0: &_oil_function_class_ ## klass sl@0: #else sl@0: #define OIL_DEFINE_CLASS_FULL(klass, string, test) \ sl@0: OIL_DECLARE_CLASS(klass) sl@0: #endif sl@0: sl@0: /** sl@0: * OIL_DEFINE_CLASS: sl@0: * @klass: name of class to declare (without oil_ prefix) sl@0: * @string: prototype of class sl@0: * sl@0: * Defines a #OilFunctionClass structure for @klass. Classes sl@0: * defined this way will be automatically at Liboil initialization sl@0: * time. sl@0: */ sl@0: #define OIL_DEFINE_CLASS(klass, string) \ sl@0: OIL_DEFINE_CLASS_FULL (klass, string, NULL) sl@0: sl@0: /** sl@0: * OIL_DEFINE_IMPL_FULL: sl@0: * @function: name of function sl@0: * @klass: name of class to declare (without oil_ prefix) sl@0: * @flags: implementation flags and CPU requirements sl@0: * sl@0: * Defines a #OilFunctionImpl structure for the function @function sl@0: * and class @klass. CPU-dependent flags in @flags will indicate sl@0: * that this implementation requires the given CPU flags. sl@0: */ sl@0: sl@0: #define OIL_DEFINE_IMPL_FULL(function,klass,flags) \ sl@0: OilFunctionImpl OIL_OPT_MANGLE(_oil_function_impl_ ## function) = { \ sl@0: NULL, \ sl@0: &_oil_function_class_ ## klass , \ sl@0: (void *)function, \ sl@0: OIL_OPT_FLAG_MANGLE(flags), \ sl@0: #function OIL_OPT_SUFFIX \ sl@0: } \ sl@0: sl@0: sl@0: sl@0: sl@0: OIL_CHECK_PROTOTYPE(;_oil_type_ ## klass _ignore_me_ ## function = function) sl@0: sl@0: /** sl@0: * OIL_DEFINE_IMPL: sl@0: * @function: name of function sl@0: * @klass: name of class to declare (without oil_ prefix) sl@0: * sl@0: * Shorthand for defining a C implementation. See OIL_DEFINE_IMPL_FULL(). sl@0: */ sl@0: #define OIL_DEFINE_IMPL(function,klass) \ sl@0: OIL_DEFINE_IMPL_FULL(function,klass,0) sl@0: /** sl@0: * OIL_DEFINE_IMPL_REF: sl@0: * @function: name of function sl@0: * @klass: name of class to declare (without oil_ prefix) sl@0: * sl@0: * Shorthand for defining a reference implementation. See OIL_DEFINE_IMPL_FULL(). sl@0: */ sl@0: #define OIL_DEFINE_IMPL_REF(function,klass) \ sl@0: OIL_DEFINE_IMPL_FULL(function,klass,OIL_IMPL_FLAG_REF) sl@0: /** sl@0: * OIL_DEFINE_IMPL_ASM: sl@0: * @function: name of function sl@0: * @klass: name of class to declare (without oil_ prefix) sl@0: * sl@0: * Shorthand for defining an implementation written in inline sl@0: * assembly code. See OIL_DEFINE_IMPL_FULL(). sl@0: */ sl@0: #define OIL_DEFINE_IMPL_ASM(function,klass) \ sl@0: OIL_DEFINE_IMPL_FULL(function,klass,OIL_IMPL_FLAG_ASM) sl@0: /** sl@0: * OIL_DEFINE_IMPL_DEPENDS sl@0: * @function: name of function sl@0: * @klass: name of class to declare (without oil_ prefix) sl@0: * @...: other classes this implementation uses sl@0: * sl@0: * Shorthand for defining an implementation that uses another Liboil sl@0: * function class. This is not currently used. See sl@0: * OIL_DEFINE_IMPL_FULL(). sl@0: */ sl@0: #ifndef __SYMBIAN32__ sl@0: #define OIL_DEFINE_IMPL_DEPENDS(function,klass,...) \ sl@0: OIL_DEFINE_IMPL_FULL(function,klass,0) sl@0: #else sl@0: #define OIL_DEFINE_IMPL_DEPENDS(function,klass,args...) \ sl@0: OIL_DEFINE_IMPL_FULL(function,klass,0) sl@0: #endif sl@0: sl@0: sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: IMPORT_C sl@0: #endif sl@0: void oil_optimize_all (void); sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: IMPORT_C sl@0: #endif sl@0: void oil_optimize (const char *class_name); sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: IMPORT_C sl@0: #endif sl@0: OilFunctionClass * oil_class_get_by_index (int i); sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: IMPORT_C sl@0: #endif sl@0: OilFunctionClass *oil_class_get (const char *class_name); sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: IMPORT_C sl@0: #endif sl@0: void oil_class_optimize (OilFunctionClass *klass); sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: IMPORT_C sl@0: #endif sl@0: int oil_class_get_n_classes (void); sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: IMPORT_C sl@0: #endif sl@0: OilFunctionImpl * oil_impl_get_by_index (int i); sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: IMPORT_C sl@0: #endif sl@0: int oil_impl_is_runnable (OilFunctionImpl *impl); sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: IMPORT_C sl@0: #endif sl@0: int oil_impl_is_usable (OilFunctionImpl *impl); sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: IMPORT_C sl@0: #endif sl@0: void oil_class_choose_by_name (OilFunctionClass * klass, const char *name); sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: IMPORT_C sl@0: #endif sl@0: void oil_class_register_impl_full (OilFunctionClass * klass, sl@0: void (*func)(void), const char *name, unsigned int flags); sl@0: sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: IMPORT_C sl@0: #endif sl@0: void oil_class_register_impl (OilFunctionClass * klass, OilFunctionImpl *impl); sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: IMPORT_C sl@0: #endif sl@0: void oil_class_register_impl_by_name (const char *klass_name, sl@0: OilFunctionImpl *impl); sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: IMPORT_C sl@0: #endif sl@0: void oil_init_no_optimize(void); sl@0: sl@0: #endif sl@0: sl@0: OIL_END_DECLS sl@0: sl@0: #endif sl@0: