summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Steckelmacher <steckdenis@yahoo.fr>2011-10-26 13:31:24 +0200
committerDenis Steckelmacher <steckdenis@yahoo.fr>2011-10-26 13:31:24 +0200
commitded5c89ad7acc85a8603317bc17806564f08af91 (patch)
tree329fc760e33d284b25cef73ae6b68a78032d2170
parent750754c5e57953b0231cad56a392461b6e92c7ff (diff)
Implement more OpenCL C built-insHEADmaster
exp2, exp10, expm1, fabs, fdim, floor, fma, fmin, trunc, fmod, fract, frexp, sqrt, hypot, ilogb and ldexp.
-rw-r--r--cmake/modules/FindLLVM.cmake2
-rw-r--r--src/runtime/builtins.def139
-rwxr-xr-xsrc/runtime/builtins.py64
3 files changed, 161 insertions, 44 deletions
diff --git a/cmake/modules/FindLLVM.cmake b/cmake/modules/FindLLVM.cmake
index 9808215..2659b45 100644
--- a/cmake/modules/FindLLVM.cmake
+++ b/cmake/modules/FindLLVM.cmake
@@ -20,6 +20,8 @@ else (LLVM_INCLUDE_DIR)
find_program(LLVM_CONFIG_EXECUTABLE
NAMES llvm-config
PATHS
+ /usr/bin
+ /usr/local/bin
/opt/local/bin
)
diff --git a/src/runtime/builtins.def b/src/runtime/builtins.def
index 4f50ed4..24da33d 100644
--- a/src/runtime/builtins.def
+++ b/src/runtime/builtins.def
@@ -136,22 +136,11 @@ native $type ceil $vecf : x:$type
end
// gentype copysign (gentype x, gentype y)
-func float copysign float : x:float y:float
- if ((x < 0.0f && y > 0.0f) ||
- (x > 0.0f && y < 0.0f))
- return -x;
- return x;
-end
-
-native $type copysign $vecf : x:$type y:$type
- REPL($vecdim)
- {
- if ((x[i] < 0.0f && y[i] > 0.0f) ||
- (x[i] > 0.0f && y[i] < 0.0f))
- result[i] = -x[i];
- else
- result[i] = x[i];
- }
+func $type copysign $gentype : x:$type y:$type
+ return (
+ (x < 0.0f & y > 0.0f) |
+ (x > 0.0f & y < 0.0f)
+ ? -x : x);
end
//gentype cos (gentype)
@@ -194,14 +183,126 @@ end
// gentype exp2(gentype x)
native float exp2 float : x:float
- //return std::ldexp(x, 2);
+ return exp2f(x);
end
native $type exp2 $vecf : x:$type
- //REPL($vecdim)
- // result[i] = std::ldexp(x[i], 2);
+ REPL($vecdim)
+ result[i] = exp2f(x[i]);
+end
+
+// gentype exp10(gentype x)
+native float exp10 float : x:float
+ return exp10f(x);
+end
+
+native $type exp10 $vecf : x:$type
+ REPL($vecdim)
+ result[i] = exp10f(x[i]);
+end
+
+// gentype expm1(gentype x)
+func $type expm1 $gentype : x:$type
+ return exp(x) - 1.0f;
end
+// gentype fabs(gentype x)
+func $type fabs $gentype : x:$type
+ return (x < 0.0f ? -x : x);
+end
+
+// gentype fdim(x, y)
+func $type fdim $gentype : x:$type y:$type
+ return (x > y ? x - y : 0.0f);
+end
+
+// gentype floor(gentype x) (TODO: SSE fast path : float->int->float)
+native float floor float : x:float
+ return std::floor(x);
+end
+
+native $type floor $vecf : x:$type
+ REPL($vecdim)
+ result[i] = std::floor(x[i]);
+end
+
+// gentype fma(a, b, c) : a*b + c (TODO)
+func $type fma $gentype : a:$type b:$type c:$type
+ return (a * b) + c;
+end
+
+// gentype fmax(x, y)
+func $type fmax $gentype : x:$type y:$type
+ return (x > y ? x : y);
+end
+
+// gentype fmin(x, y)
func $type fmin $gentype : x:$type y:$type
return (x < y ? x : y);
end
+
+// gentype trunc(x)
+native float trunc float : x:float
+ return boost::math::trunc(x);
+end
+
+native $type trunc $vecf : x:$type
+ REPL($vecdim)
+ result[i] = boost::math::trunc(x[i]);
+end
+
+// gentype fmod(x, y)
+func $type fmod $gentype : x:$type y:$type
+ return x - y * trunc(x / y);
+end
+
+// gentype fract(gentype x, gentype *iptr)
+func $type fract $gentype : x:$type iptr:*$type
+ *iptr = floor(x);
+ return fmin(x - *iptr, 0x1.fffffep-1f);
+end
+
+// gentype frexp(gentype x, intn *exp)
+native float frexp float : x:float exp:*int
+ return std::frexp(x, exp);
+end
+
+native $type frexp $vecf : x:$type exp:*int$vecdim
+ REPL($vecdim)
+ result[i] = std::frexp(x[i], &exp[i]);
+end
+
+// gentype sqrt(gentype x)
+native float sqrt float : x:float
+ return std::sqrt(x);
+end
+
+native $type sqrt $vecf : x:$type
+ REPL($vecdim)
+ result[i] = std::sqrt(x[i]);
+end
+
+// gentype hypot(gentype x, gentype y)
+func $type hypot $gentype : x:$type y:$type
+ return sqrt(x*x + y*y);
+end
+
+// intn ilogb(gentype x)
+native int ilogb float : x:float
+ return ilogb(x);
+end
+
+native int$vecdim ilogb $vecf : x:$type
+ REPL($vecdim)
+ result[i] = ilogb(x[i]);
+end
+
+// gentype ldexp(gentype x, intn n)
+native float ldexp float : x:float n:int
+ return std::ldexp(x, n);
+end
+
+native $type ldexp $vecf : x:$type n:int$vecdim
+ REPL($vecdim)
+ result[i] = std::ldexp(x[i], n[i]);
+end \ No newline at end of file
diff --git a/src/runtime/builtins.py b/src/runtime/builtins.py
index 2031a5c..d7cba5a 100755
--- a/src/runtime/builtins.py
+++ b/src/runtime/builtins.py
@@ -66,9 +66,7 @@ class Function:
self.types.append(ty)
def mangled_name(self, current_type):
- return_type = self.return_type
- if return_type == '$type':
- return_type = current_type
+ return_type = self.process_type_name(current_type, self.return_type)
rs = return_type + '_' + self.name
first = True
@@ -78,13 +76,24 @@ class Function:
rs += '_'
first = False
- arg_type = a.t
- if arg_type == '$type':
- arg_type = current_type
- rs += arg_type
+ arg_type = self.process_type_name(current_type, a.t)
+ rs += arg_type.replace('*', 'p')
return rs
+ def process_type_name(self, current_type, type_name):
+ # Current vector dimension
+ vecdim = '1'
+
+ if current_type[-1].isdigit():
+ if current_type[-2].isdigit():
+ vecdim = current_type[-2:]
+ else:
+ vecdim = current_type[-1]
+
+ # $vecdim expansion
+ return type_name.replace('$vecdim', vecdim).replace('$type', current_type)
+
def arg_list(self, current_type, handle_first_arg):
rs = ''
first = True
@@ -92,25 +101,26 @@ class Function:
# We may need a first "result" arg
if handle_first_arg:
- return_type = self.return_type
- if return_type == '$type':
- return_type = current_type
+ return_type = self.process_type_name(current_type, self.return_type)
if return_type[-1].isdigit():
# Return is a vector
append_arg = self.Arg('result', return_type)
if append_arg:
- args = [append_arg]
- args.extend(self.args)
+ args = [append_arg] + self.args
else:
args = self.args
for arg in args:
# Resolve type
- arg_type = arg.t
- if arg_type == '$type':
- arg_type = current_type
+ arg_type = self.process_type_name(current_type, arg.t)
+
+ if arg_type[0] == '*':
+ arg_ptr = True
+ arg_type = arg_type[1:]
+ else:
+ arg_ptr = False
# We need to pass vector arguments as pointers
arg_vector = False
@@ -125,7 +135,7 @@ class Function:
rs += arg_type + ' '
- if arg_vector:
+ if arg_vector or arg_ptr:
rs += '*'
rs += arg.name
@@ -147,9 +157,7 @@ class Function:
return rs
# Calculate return type
- return_type = self.return_type
- if return_type == '$type':
- return_type = current_type
+ return_type = self.process_type_name(current_type, self.return_type)
if (kind == self.KIND_BUILTINS_IMPL or kind == self.KIND_STDLIB_STUB_DEF) \
and return_type[-1].isdigit():
@@ -204,9 +212,13 @@ class Function:
# Append the args
for arg in self.args:
# Resolve type
- arg_type = arg.t
- if arg_type == '$type':
- arg_type = current_type
+ arg_type = self.process_type_name(current_type, arg.t)
+
+ arg_ptr = False
+ if arg_type[0] == '*':
+ arg_type = arg_type[1:]
+ arg_ptr = True
+
arg_vector = arg_type[-1].isdigit()
if not first:
@@ -215,9 +227,11 @@ class Function:
# We need to pass vector arguments as pointers
if arg_vector:
- rs += '(' + arg_type.rstrip('0123456789') + ' *)&' + arg.name
- else:
- rs += arg.name
+ rs += '(' + arg_type.rstrip('0123456789') + ' *)'
+ if not arg_ptr:
+ rs += '&'
+
+ rs += arg.name
# End the call
rs += ');\n'