#include"liboil.h"
//Arun's changes
typedef struct _OilFunctionImpl OilFunctionImpl;
typedef struct _OilFunctionClass OilFunctionClass;
typedef void (*OilTestFunction) (OilFunctionClass *klass,OilFunctionImpl *impl);
#define OIL_CHECK_PROTOTYPE(a)
/**
* OilFunctionClass:
*
* An opaque structure representing a function class.
*
*/
struct _OilFunctionClass {
/*< private >*/
void *func;
const char *name;
const char *desc;
OilTestFunction test_func;
OilFunctionImpl *first_impl;
OilFunctionImpl *reference_impl;
OilFunctionImpl *chosen_impl;
const char *prototype;
};
/**
* OilFunctionImpl:
*
* An opaque structure representing a function implementation.
*
*/
struct _OilFunctionImpl {
/*< private >*/
void *next;
OilFunctionClass *klass;
void *func;
unsigned int flags;
const char *name;
double profile_ave;
double profile_std;
};
#ifndef OIL_NO_CLASSES
/**
* OIL_DEFINE_CLASS_FULL:
* @klass: name of class to declare (without oil_ prefix)
* @string: prototype of class
* @test: test function
*
* Defines a #OilFunctionClass structure for @klass. Classes
* defined this way will be automatically at Liboil initialization
* time.
*/
#define OIL_DEFINE_CLASS_FULL(klass, string, test) \
OilFunctionClass _oil_function_class_ ## klass = { \
NULL, \
#klass , \
NULL, \
test, \
NULL, \
NULL, \
NULL, \
string \
}; \
OilFunctionClass *oil_function_class_ptr_ ## klass = \
&_oil_function_class_ ## klass
#else
#define OIL_DEFINE_CLASS_FULL(klass, string, test) \
OIL_DECLARE_CLASS(klass)
#endif
/**
* OIL_DEFINE_CLASS:
* @klass: name of class to declare (without oil_ prefix)
* @string: prototype of class
*
* Defines a #OilFunctionClass structure for @klass. Classes
* defined this way will be automatically at Liboil initialization
* time.
*/
#define OIL_DEFINE_CLASS(klass, string) \
OIL_DEFINE_CLASS_FULL (klass, string, NULL)
OIL_DEFINE_CLASS (scalarmultiply_f32_ns, "float *d, float *s1, float *s2_1, int n");
OIL_DEFINE_CLASS_FULL (resample_linear_argb,
"uint32_t *d_n, uint32_t *s_2xn, int n, uint32_t *i_2",
NULL);
OIL_DEFINE_CLASS_FULL (resample_linear_u8,
"uint8_t *d_n, uint8_t *s_2xn, int n, uint32_t *i_2",
NULL);
OIL_DEFINE_CLASS_FULL (merge_linear_argb,
"uint32_t *d_n, uint32_t *s_n, uint32_t *s2_n, uint32_t *s3_1, int n",
NULL);
OIL_DEFINE_CLASS_FULL (merge_linear_u8,
"uint8_t *d_n, uint8_t *s_n, uint8_t *s2_n, uint32_t *s3_1, int n",
NULL);
OIL_DEFINE_CLASS(splat_u8_ns,"uint8_t *dest, uint8_t *s1_1, int n");
OIL_DEFINE_CLASS(splat_u8,"uint8_t *dest, int dstr, uint8_t *s1_1, int n");
typedef enum {
OIL_IMPL_FLAG_REF = (1<<0),
OIL_IMPL_FLAG_OPT = (1<<1),
OIL_IMPL_FLAG_ASM = (1<<2),
OIL_IMPL_FLAG_DISABLED = (1<<3),
OIL_IMPL_FLAG_CMOV = (1<<16),
OIL_IMPL_FLAG_MMX = (1<<17),
OIL_IMPL_FLAG_SSE = (1<<18),
OIL_IMPL_FLAG_MMXEXT = (1<<19),
OIL_IMPL_FLAG_SSE2 = (1<<20),
OIL_IMPL_FLAG_3DNOW = (1<<21),
OIL_IMPL_FLAG_3DNOWEXT = (1<<22),
OIL_IMPL_FLAG_SSE3 = (1<<23),
OIL_IMPL_FLAG_ALTIVEC = (1<<24),
OIL_IMPL_FLAG_EDSP = (1<<25),
OIL_IMPL_FLAG_ARM6 = (1<<26),
OIL_IMPL_FLAG_VFP = (1<<27),
OIL_IMPL_FLAG_SSSE3 = (1<<28)
} OilImplFlag;
#ifndef OIL_OPT_MANGLE
#define OIL_OPT_MANGLE(a) a
#define OIL_OPT_FLAG_MANGLE(a) a
#else
#define OIL_NO_CLASSES
#define OIL_OPT_FLAG_MANGLE(a) (((a)&(~OIL_IMPL_FLAG_REF)) | OIL_IMPL_FLAG_OPT)
#endif
#ifndef OIL_OPT_SUFFIX
#define OIL_OPT_SUFFIX
#endif
/**
* OIL_DEFINE_IMPL_FULL:
* @function: name of function
* @klass: name of class to declare (without oil_ prefix)
* @flags: implementation flags and CPU requirements
*
* Defines a #OilFunctionImpl structure for the function @function
* and class @klass. CPU-dependent flags in @flags will indicate
* that this implementation requires the given CPU flags.
*/
#define OIL_DEFINE_IMPL_FULL(function,klass,flags) \
OilFunctionImpl OIL_OPT_MANGLE(_oil_function_impl_ ## function) = { \
NULL, \
&_oil_function_class_ ## klass , \
(void *)function, \
OIL_OPT_FLAG_MANGLE(flags), \
#function OIL_OPT_SUFFIX \
} \
OIL_CHECK_PROTOTYPE(;_oil_type_ ## klass _ignore_me_ ## function = function)
/**
* OIL_DEFINE_IMPL:
* @function: name of function
* @klass: name of class to declare (without oil_ prefix)
*
* Shorthand for defining a C implementation. See OIL_DEFINE_IMPL_FULL().
*/
#define OIL_DEFINE_IMPL(function,klass) \
OIL_DEFINE_IMPL_FULL(function,klass,0)
/**
* OIL_DEFINE_IMPL_REF:
* @function: name of function
* @klass: name of class to declare (without oil_ prefix)
*
* Shorthand for defining a reference implementation. See OIL_DEFINE_IMPL_FULL().
*/
#define OIL_DEFINE_IMPL_REF(function,klass) \
OIL_DEFINE_IMPL_FULL(function,klass,OIL_IMPL_FLAG_REF)
typedef void (*_oil_type_scalarmultiply_f32_ns)(float * d, const float * s1, const float * s2_1, int n);
//#define oil_scalarmultiply_f32_ns ((_oil_type_scalarmultiply_f32_ns)(*(void **)oil_function_class_ptr_scalarmultiply_f32_ns))
#define OIL_GET(ptr, offset, type) (*(type *)((uint8_t *)(ptr) + (offset)) )
/**************'_oil_resample_linear_u8'****************************/
#ifdef __SYMBIAN32__
EXPORT_C
#endif
static void
resample_linear_u8_ref (uint8_t *dest, uint8_t *src, int n,
uint32_t *in)
{
int acc = in[0];
int increment = in[1];
int i;
int j;
int x;
for(i=0;i<n;i++){
j = acc>>16;
x = (acc&0xffff)>>8;
dest[i] = (src[j]*(256-x) + src[j+1]*x) >> 8;
acc += increment;
}
in[0] = acc;
}
/************************'_oil_resample_linear_argb'***************************/
static void
resample_linear_argb_ref (uint32_t *d, uint32_t *s, int n, uint32_t *in)
{
uint8_t *src = (uint8_t *)s;
uint8_t *dest = (uint8_t *)d;
int acc = in[0];
int increment = in[1];
int i;
int j;
int x;
for(i=0;i<n;i++){
j = acc>>16;
x = (acc&0xffff)>>8;
dest[4*i+0] = (src[4*j+0]*(256-x) + src[4*j+4]*x) >> 8;
dest[4*i+1] = (src[4*j+1]*(256-x) + src[4*j+5]*x) >> 8;
dest[4*i+2] = (src[4*j+2]*(256-x) + src[4*j+6]*x) >> 8;
dest[4*i+3] = (src[4*j+3]*(256-x) + src[4*j+7]*x) >> 8;
acc += increment;
}
in[0] = acc;
}
/****************** '_oil_merge_linear_argb'**************************/
static void
merge_linear_argb_ref (uint32_t *d, uint32_t *s1, uint32_t *s2,
uint32_t *src3, int n)
{
uint8_t *src1 = (uint8_t *)s1;
uint8_t *src2 = (uint8_t *)s2;
uint8_t *dest = (uint8_t *)d;
int i;
int x = src3[0];
for(i=0;i<n;i++){
dest[4*i+0] = (src1[4*i+0]*(256-x) + src2[4*i+0]*x) >> 8;
dest[4*i+1] = (src1[4*i+1]*(256-x) + src2[4*i+1]*x) >> 8;
dest[4*i+2] = (src1[4*i+2]*(256-x) + src2[4*i+2]*x) >> 8;
dest[4*i+3] = (src1[4*i+3]*(256-x) + src2[4*i+3]*x) >> 8;
}
}
static void
merge_linear_u8_ref (uint8_t *dest, uint8_t *src1, uint8_t *src2,
uint32_t *src3, int n)
{
int i;
int x = src3[0];
for(i=0;i<n;i++){
dest[i] = (src1[i]*(256-x) + src2[i]*x) >> 8;
}
}
static void splat_u8_ref (uint8_t *dest, int dstr, uint8_t *param, int n)
{
int i;
for(i=0;i<n;i++){
OIL_GET(dest,i*dstr, uint8_t) = *param;
}
}
static void splat_u8_ns_ref (uint8_t *dest, uint8_t *param, int n)
{
int i;
for(i=0;i<n;i++){
dest[i] = *param;
}
}
static void
scalarmultiply_f32_ns_ref (float *dest, float *src1, float *src2, int n)
{
int i;
for(i=0;i<n;i++){
dest[i] = src1[i] * src2[0];
}
}
/********oil_splat_u8*******/
/*
EXPORT_C void splat_u8_ref (uint8_t *dest, int dstr, uint8_t *param, int n)
{
int i;
for(i=0;i<n;i++){
OIL_GET(dest,i*dstr, uint8_t) = *param;
}
}
*/
unsigned long oil_cpu_flags;
/**
* oil_cpu_get_flags:
*
* Returns a bitmask containing the available CPU features.
*
* Returns: the CPU features.
*/
#ifdef __SYMBIAN32__
EXPORT_C
#endif
unsigned int
oil_cpu_get_flags (void)
{
return oil_cpu_flags;
}
/**
* OIL_CPU_FLAG_MASK:
*
* Mask describing which bits in #OilImplFlag depend on the current
* CPU.
*/
#define OIL_CPU_FLAG_MASK 0xffff0000
/**
* oil_impl_is_runnable:
* @impl: an @OilFunctionImpl
*
* Determines whether the function implementation given by @impl
* can be executed by the current CPU.
*
* Returns: 1 if the implementation can be executed, otherwise 0
*/
#ifdef __SYMBIAN32__
EXPORT_C
#endif
int
oil_impl_is_runnable (OilFunctionImpl *impl)
{
unsigned int oil_cpu_flags = oil_cpu_get_flags();
if ((impl->flags & OIL_CPU_FLAG_MASK) & (~oil_cpu_flags))
return 0;
return 1;
}
/**
* oil_class_optimize:
* @klass: a function class
*
* Tests and profiles each implementation for the given function
* class. Testing compares the output of running each implementation
* on random input against the reference implementation for the
* same input.
*/
#ifdef __SYMBIAN32__
EXPORT_C
#endif
void
oil_class_optimize (OilFunctionClass * klass)
{
OilFunctionImpl *impl;
OilFunctionImpl *min_impl;
int ret;
if (klass->reference_impl == NULL) {
return;
}
if (klass->first_impl == NULL) {
return;
}
min_impl = NULL;
for (impl = klass->first_impl; impl; impl = impl->next) {
if (!oil_impl_is_runnable (impl))
continue;
}
if (min_impl == NULL) {
return;
}
klass->chosen_impl = min_impl;
klass->func = min_impl->func;
}
#ifdef __SYMBIAN32__
EXPORT_C
#endif
void oil_scalarmultiply_f32_ns (float * d, const float * s1, const float * s2_1, int n)
{
/*
if (_oil_function_class_scalarmultiply_f32_ns.func == NULL) {
oil_class_optimize (&_oil_function_class_scalarmultiply_f32_ns);
}
*/
scalarmultiply_f32_ns_ref(d,(float*) s1,(float*) s2_1, n);
//((void (*)(float * d, const float * s1, const float * s2_1, int n))(_oil_function_class_scalarmultiply_f32_ns.func))(d, s1, s2_1, n);
}
#ifdef __SYMBIAN32__
EXPORT_C
#endif
void
oil_merge_linear_argb (uint32_t * d_n, const uint32_t * s_n, const uint32_t * s2_n, const uint32_t * s3_1, int n)
{
if (_oil_function_class_merge_linear_argb.func == NULL) {
oil_class_optimize (&_oil_function_class_merge_linear_argb);
}
((void (*)(uint32_t * d_n, const uint32_t * s_n, const uint32_t * s2_n, const uint32_t * s3_1, int n))(_oil_function_class_merge_linear_argb.func))(d_n, s_n, s2_n, s3_1, n);
}
#ifdef __SYMBIAN32__
EXPORT_C
#endif
void
oil_merge_linear_u8 (uint8_t * d_n, const uint8_t * s_n, const uint8_t * s2_n, const uint32_t * s3_1, int n)
{
if (_oil_function_class_merge_linear_u8.func == NULL) {
oil_class_optimize (&_oil_function_class_merge_linear_u8);
}
((void (*)(uint8_t * d_n, const uint8_t * s_n, const uint8_t * s2_n, const uint32_t * s3_1, int n))(_oil_function_class_merge_linear_u8.func))(d_n, s_n, s2_n, s3_1, n);
}
#ifdef __SYMBIAN32__
EXPORT_C
#endif
void
oil_resample_linear_argb (uint32_t * d_n, const uint32_t * s_2xn, int n, uint32_t * i_2)
{
if (_oil_function_class_resample_linear_argb.func == NULL) {
oil_class_optimize (&_oil_function_class_resample_linear_argb);
}
((void (*)(uint32_t * d_n, const uint32_t * s_2xn, int n, uint32_t * i_2))(_oil_function_class_resample_linear_argb.func))(d_n, s_2xn, n, i_2);
}
#ifdef __SYMBIAN32__
EXPORT_C
#endif
void
oil_resample_linear_u8 (uint8_t * d_n, const uint8_t * s_2xn, int n, uint32_t * i_2)
{
if (_oil_function_class_resample_linear_u8.func == NULL) {
oil_class_optimize (&_oil_function_class_resample_linear_u8);
}
((void (*)(uint8_t * d_n, const uint8_t * s_2xn, int n, uint32_t * i_2))(_oil_function_class_resample_linear_u8.func))(d_n, s_2xn, n, i_2);
}
#ifdef __SYMBIAN32__
EXPORT_C
#endif
void
oil_splat_u8 (uint8_t * dest, int dstr, const uint8_t * s1_1, int n)
{
if (_oil_function_class_splat_u8.func == NULL) {
oil_class_optimize (&_oil_function_class_splat_u8);
}
((void (*)(uint8_t * dest, int dstr, const uint8_t * s1_1, int n))(_oil_function_class_splat_u8.func))(dest, dstr, s1_1, n);
}
#ifdef __SYMBIAN32__
EXPORT_C
#endif
void
oil_splat_u8_ns (uint8_t * dest, const uint8_t * s1_1, int n)
{
if (_oil_function_class_splat_u8_ns.func == NULL) {
oil_class_optimize (&_oil_function_class_splat_u8_ns);
}
((void (*)(uint8_t * dest, const uint8_t * s1_1, int n))(_oil_function_class_splat_u8_ns.func))(dest, s1_1, n);
}
OIL_DEFINE_IMPL_REF (scalarmultiply_f32_ns_ref, scalarmultiply_f32_ns);
OIL_DEFINE_IMPL_REF (resample_linear_u8_ref, resample_linear_u8);
OIL_DEFINE_IMPL_REF (resample_linear_argb_ref, resample_linear_argb);
OIL_DEFINE_IMPL_REF (merge_linear_argb_ref, merge_linear_argb);
OIL_DEFINE_IMPL_REF (merge_linear_u8_ref, merge_linear_u8);
OIL_DEFINE_IMPL_REF(splat_u8_ref, splat_u8);
OIL_DEFINE_IMPL_REF(splat_u8_ns_ref, splat_u8_ns);