1 /* 2 * LIBOIL - Library of Optimized Inner Loops 3 * Copyright (c) 2003,2004 David A. Schleef <ds@schleef.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef _LIBOIL_FUNCTION_H_ 29 #define _LIBOIL_FUNCTION_H_ 30 31 #include <liboil/liboilutils.h> 32 #include <liboil/liboiltypes.h> 33 34 /** 35 * OIL_CHECK_PROTOTYPE: 36 * @a: 37 * 38 * Macro used internally to implement the --enable-prototype-checking 39 * configure option. 40 */ 41 #ifdef LIBOIL_STRICT_PROTOTYPES 42 #include <liboil/liboilfuncs.h> 43 #define OIL_CHECK_PROTOTYPE(a) a 44 #else 45 #define OIL_CHECK_PROTOTYPE(a) 46 #endif 47 48 OIL_BEGIN_DECLS 49 50 /** 51 * OilImplFlag: 52 * 53 * Implementation flags. 54 * 55 * @OIL_IMPL_FLAG_REF: is the reference implementation for the class. 56 * 57 * @OIL_IMPL_FLAG_OPT: was compiled with alternate CFLAGS as specified 58 * by --enable-alternate-optimization. 59 * 60 * @OIL_IMPL_FLAG_ASM: is written in assembly code. 61 * 62 * @OIL_IMPL_FLAG_DISABLED: is disabled. This can be set either in the 63 * source code or during library initialization. 64 * 65 * @OIL_IMPL_FLAG_CMOV: uses the i386 instruction cmov or its variants. 66 * 67 * @OIL_IMPL_FLAG_MMX: uses MMX instructions. 68 * 69 * @OIL_IMPL_FLAG_SSE: uses SSE instructions. 70 * 71 * @OIL_IMPL_FLAG_MMXEXT: uses AMD's extended MMX instructions. These 72 * are a subset of what Intel calls SSE2. If an implementation uses 73 * only AMD's extended MMX instructions, it should set this flag, and 74 * not @OIL_IMPL_FLAG_SSE2. 75 * 76 * @OIL_IMPL_FLAG_SSE2: uses SSE2 instructions. This flag implies 77 * @OIL_IMPL_FLAG_SSE and @OIL_IMPL_FLAG_MMXEXT. 78 * 79 * @OIL_IMPL_FLAG_3DNOW: uses 3DNow! instructions. 80 * 81 * @OIL_IMPL_FLAG_3DNOWEXT: uses extended 3DNow! instructions. 82 * 83 * @OIL_IMPL_FLAG_SSE3: uses SSE3 instructions. This flag implies 84 * @OIL_IMPL_FLAG_SSE2. 85 * 86 * @OIL_IMPL_FLAG_SSSE3: uses SSSE3 instructions. This flag implies 87 * @OIL_IMPL_FLAG_SSE3. 88 * 89 * @OIL_IMPL_FLAG_ALTIVEC: uses Altivec instructions. 90 * 91 */ 92 typedef enum { 93 OIL_IMPL_FLAG_REF = (1<<0), 94 OIL_IMPL_FLAG_OPT = (1<<1), 95 OIL_IMPL_FLAG_ASM = (1<<2), 96 OIL_IMPL_FLAG_DISABLED = (1<<3), 97 OIL_IMPL_FLAG_CMOV = (1<<16), 98 OIL_IMPL_FLAG_MMX = (1<<17), 99 OIL_IMPL_FLAG_SSE = (1<<18), 100 OIL_IMPL_FLAG_MMXEXT = (1<<19), 101 OIL_IMPL_FLAG_SSE2 = (1<<20), 102 OIL_IMPL_FLAG_3DNOW = (1<<21), 103 OIL_IMPL_FLAG_3DNOWEXT = (1<<22), 104 OIL_IMPL_FLAG_SSE3 = (1<<23), 105 OIL_IMPL_FLAG_ALTIVEC = (1<<24), 106 OIL_IMPL_FLAG_EDSP = (1<<25), 107 OIL_IMPL_FLAG_ARM6 = (1<<26), 108 OIL_IMPL_FLAG_VFP = (1<<27), 109 OIL_IMPL_FLAG_SSSE3 = (1<<28) 110 } OilImplFlag; 111 112 #ifdef OIL_ENABLE_UNSTABLE_API 113 114 /** 115 * OIL_OPT_MANGLE: 116 * 117 * Used internally to implement the --enable-alternate-optimizations 118 * configure option. 119 */ 120 /** 121 * OIL_OPT_FLAG_MANGLE: 122 * 123 * Used internally to implement the --enable-alternate-optimizations 124 * configure option. 125 */ 126 /** 127 * OIL_NO_CLASSES: 128 * 129 * Used internally to implement the --enable-alternate-optimizations 130 * configure option. 131 */ 132 /** 133 * OIL_OPT_SUFFIX: 134 * 135 * Used internally to implement the --enable-alternate-optimizations 136 * configure option. 137 */ 138 #ifndef OIL_OPT_MANGLE 139 #define OIL_OPT_MANGLE(a) a 140 #define OIL_OPT_FLAG_MANGLE(a) a 141 #else 142 #define OIL_NO_CLASSES 143 #define OIL_OPT_FLAG_MANGLE(a) (((a)&(~OIL_IMPL_FLAG_REF)) | OIL_IMPL_FLAG_OPT) 144 #endif 145 #ifndef OIL_OPT_SUFFIX 146 #define OIL_OPT_SUFFIX 147 #endif 148 149 /** 150 * OilFunctionClass: 151 * 152 * An opaque structure representing a function class. 153 * 154 */ 155 struct _OilFunctionClass { 156 /*< private >*/ 157 void (*func)(void); 158 const char *name; 159 const char *desc; 160 OilTestFunction test_func; 161 162 OilFunctionImpl *first_impl; 163 OilFunctionImpl *reference_impl; 164 165 OilFunctionImpl *chosen_impl; 166 167 const char *prototype; 168 }; 169 170 /** 171 * OilFunctionImpl: 172 * 173 * An opaque structure representing a function implementation. 174 * 175 */ 176 struct _OilFunctionImpl { 177 /*< private >*/ 178 void *next; 179 OilFunctionClass *klass; 180 void (*func)(void); 181 unsigned int flags; 182 const char *name; 183 double profile_ave; 184 double profile_std; 185 }; 186 187 /** 188 * OIL_GET: 189 * @ptr: 190 * @offset: 191 * @type: 192 * 193 * Offsets @ptr by @offset number of bytes, and dereferences it 194 * as type @type. Note that the offset is in bytes, and not in 195 * the size of the pointer type. 196 */ 197 #define OIL_GET(ptr, offset, type) (*(type *)((uint8_t *)(ptr) + (offset)) ) 198 /** 199 * OIL_OFFSET: 200 * @ptr: 201 * @offset: 202 * 203 * Add @offset bytes to the pointer @ptr. 204 */ 205 #define OIL_OFFSET(ptr, offset) ((void *)((uint8_t *)(ptr) + (offset)) ) 206 /** 207 * OIL_INCREMENT: 208 * @ptr: 209 * @offset: 210 * 211 * Increments the pointer @ptr by @offset number of bytes. 212 */ 213 #define OIL_INCREMENT(ptr, offset) (ptr = (void *)((uint8_t *)ptr + (offset)) ) 214 215 /** 216 * OIL_CPU_FLAG_MASK: 217 * 218 * Mask describing which bits in #OilImplFlag depend on the current 219 * CPU. 220 */ 221 #define OIL_CPU_FLAG_MASK 0xffff0000 222 223 /** 224 * OIL_DECLARE_CLASS: 225 * @klass: the name of a function class (without the oil_ prefix) 226 * 227 * Declares the Liboil function class @klass. 228 */ 229 #define OIL_DECLARE_CLASS(klass) \ 230 extern OilFunctionClass _oil_function_class_ ## klass 231 232 /** 233 * SECTION:liboilmacros 234 * @title: Macros 235 * @short_description: Macros 236 */ 237 238 #ifndef OIL_NO_CLASSES 239 /** 240 * OIL_DEFINE_CLASS_FULL: 241 * @klass: name of class to declare (without oil_ prefix) 242 * @string: prototype of class 243 * @test: test function 244 * 245 * Defines a #OilFunctionClass structure for @klass. Classes 246 * defined this way will be automatically at Liboil initialization 247 * time. 248 */ 249 #define OIL_DEFINE_CLASS_FULL(klass, string, test) \ 250 OilFunctionClass _oil_function_class_ ## klass = { \ 251 NULL, \ 252 #klass , \ 253 NULL, \ 254 test, \ 255 NULL, \ 256 NULL, \ 257 NULL, \ 258 string \ 259 }; \ 260 OilFunctionClass *oil_function_class_ptr_ ## klass = \ 261 &_oil_function_class_ ## klass 262 #else 263 #define OIL_DEFINE_CLASS_FULL(klass, string, test) \ 264 OIL_DECLARE_CLASS(klass) 265 #endif 266 267 /** 268 * OIL_DEFINE_CLASS: 269 * @klass: name of class to declare (without oil_ prefix) 270 * @string: prototype of class 271 * 272 * Defines a #OilFunctionClass structure for @klass. Classes 273 * defined this way will be automatically at Liboil initialization 274 * time. 275 */ 276 #define OIL_DEFINE_CLASS(klass, string) \ 277 OIL_DEFINE_CLASS_FULL (klass, string, NULL) 278 279 /** 280 * OIL_DEFINE_IMPL_FULL: 281 * @function: name of function 282 * @klass: name of class to declare (without oil_ prefix) 283 * @flags: implementation flags and CPU requirements 284 * 285 * Defines a #OilFunctionImpl structure for the function @function 286 * and class @klass. CPU-dependent flags in @flags will indicate 287 * that this implementation requires the given CPU flags. 288 */ 289 #define OIL_DEFINE_IMPL_FULL(function,klass,flags) \ 290 OilFunctionImpl OIL_OPT_MANGLE(_oil_function_impl_ ## function) = { \ 291 NULL, \ 292 &_oil_function_class_ ## klass , \ 293 (void (*)(void)) function, \ 294 OIL_OPT_FLAG_MANGLE(flags), \ 295 #function OIL_OPT_SUFFIX \ 296 } \ 297 OIL_CHECK_PROTOTYPE(;_oil_type_ ## klass _ignore_me_ ## function = function) 298 299 /** 300 * OIL_DEFINE_IMPL: 301 * @function: name of function 302 * @klass: name of class to declare (without oil_ prefix) 303 * 304 * Shorthand for defining a C implementation. See OIL_DEFINE_IMPL_FULL(). 305 */ 306 #define OIL_DEFINE_IMPL(function,klass) \ 307 OIL_DEFINE_IMPL_FULL(function,klass,0) 308 /** 309 * OIL_DEFINE_IMPL_REF: 310 * @function: name of function 311 * @klass: name of class to declare (without oil_ prefix) 312 * 313 * Shorthand for defining a reference implementation. See OIL_DEFINE_IMPL_FULL(). 314 */ 315 #define OIL_DEFINE_IMPL_REF(function,klass) \ 316 OIL_DEFINE_IMPL_FULL(function,klass,OIL_IMPL_FLAG_REF) 317 /** 318 * OIL_DEFINE_IMPL_ASM: 319 * @function: name of function 320 * @klass: name of class to declare (without oil_ prefix) 321 * 322 * Shorthand for defining an implementation written in inline 323 * assembly code. See OIL_DEFINE_IMPL_FULL(). 324 */ 325 #define OIL_DEFINE_IMPL_ASM(function,klass) \ 326 OIL_DEFINE_IMPL_FULL(function,klass,OIL_IMPL_FLAG_ASM) 327 /** 328 * OIL_DEFINE_IMPL_DEPENDS 329 * @function: name of function 330 * @klass: name of class to declare (without oil_ prefix) 331 * @...: other classes this implementation uses 332 * 333 * Shorthand for defining an implementation that uses another Liboil 334 * function class. This is not currently used. See 335 * OIL_DEFINE_IMPL_FULL(). 336 */ 337 #define OIL_DEFINE_IMPL_DEPENDS(function,klass,...) \ 338 OIL_DEFINE_IMPL_FULL(function,klass,0) 339 340 void oil_optimize_all (void); 341 void oil_optimize (const char *class_name); 342 343 OilFunctionClass * oil_class_get_by_index (int i); 344 OilFunctionClass *oil_class_get (const char *class_name); 345 void oil_class_optimize (OilFunctionClass *klass); 346 int oil_class_get_n_classes (void); 347 348 OilFunctionImpl * oil_impl_get_by_index (int i); 349 int oil_impl_is_runnable (OilFunctionImpl *impl); 350 int oil_impl_is_usable (OilFunctionImpl *impl); 351 352 void oil_class_choose_by_name (OilFunctionClass * klass, const char *name); 353 354 void oil_class_register_impl_full (OilFunctionClass * klass, 355 void (*func)(void), const char *name, unsigned int flags); 356 void oil_class_register_impl (OilFunctionClass * klass, OilFunctionImpl *impl); 357 void oil_class_register_impl_by_name (const char *klass_name, 358 OilFunctionImpl *impl); 359 360 void oil_init_no_optimize(void); 361 362 #endif 363 364 OIL_END_DECLS 365 366 #endif 367