aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorGil Pitney <gil.pitney@linaro.org>2014-10-28 18:00:42 -0700
committerGil Pitney <gil.pitney@linaro.org>2014-10-28 18:00:42 -0700
commit61b2c94d9e64758e55730be6a3fc9006c171db85 (patch)
treef564f09ebf93ba293dfa225bd374df6f1f37aa01 /src/runtime
Initial Commit: Based on TI OpenCL v0.8, originally based on clover.shamrock_v0.8
This is a continuation of the clover OpenCL project: http://people.freedesktop.org/~steckdenis/clover based on the contributions from Texas Instruments for Keystone II DSP device: git.ti.com/opencl and adding contributions from Linaro for ARM CPU-only support. See README.txt for more info, and build instructions. Signed-off-by: Gil Pitney <gil.pitney@linaro.org>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/CMakeLists.txt59
-rw-r--r--src/runtime/builtins.def301
-rwxr-xr-xsrc/runtime/builtins.py380
-rwxr-xr-xsrc/runtime/embed.py76
-rw-r--r--src/runtime/stdlib.c40
5 files changed, 856 insertions, 0 deletions
diff --git a/src/runtime/CMakeLists.txt b/src/runtime/CMakeLists.txt
new file mode 100644
index 0000000..f3d34ab
--- /dev/null
+++ b/src/runtime/CMakeLists.txt
@@ -0,0 +1,59 @@
+# If building for ARM target host then set appropriate clang target
+# Needs to match what's used when using clang to build the kernel
+# See compiler.cpp
+if (HAWKING_BUILD)
+ set(HOST_TARGET -target spir-unknown-unknown-unknown)
+endif()
+
+# If Shamrock build, then we use the builtins.lib built in ../builtins
+if (SHAMROCK_BUILD)
+add_custom_command(
+ OUTPUT stdlib.c.bc.embed.h
+ COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/embed.py
+ ${CMAKE_CURRENT_BINARY_DIR}/stdlib.c.bc.embed.h
+ ${CMAKE_CURRENT_BINARY_DIR}/../builtins/builtins.lib
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/embed.py
+ ${CMAKE_CURRENT_BINARY_DIR}/../builtins/builtins.lib)
+
+add_custom_target(generate_stdlib_c DEPENDS
+ ${CMAKE_CURRENT_BINARY_DIR}/stdlib.c.bc.embed.h)
+# otherwise, this stdlib.c is still being used (but is empty)
+else (SHAMROCK_BUILD)
+ set(CUSTOM_COMMAND
+ ${CLANG_EXECUTABLE} -c -emit-llvm -x cl -O2 ${HOST_TARGET} -nostdinc -fno-builtin)
+
+add_custom_command(
+ OUTPUT stdlib.c.bc
+ COMMAND ${CUSTOM_COMMAND}
+ -I${OCL_BUILTINS_DIR}/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/stdlib.c
+ -I${CMAKE_CURRENT_BINARY_DIR}
+ -o ${CMAKE_CURRENT_BINARY_DIR}/stdlib.c.bc
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/stdlib.c
+ ${CMAKE_CURRENT_BINARY_DIR}/stdlib_impl.h)
+
+add_custom_command(
+ OUTPUT stdlib.c.bc.embed.h
+ COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/embed.py
+ ${CMAKE_CURRENT_BINARY_DIR}/stdlib.c.bc.embed.h
+ ${CMAKE_CURRENT_BINARY_DIR}/stdlib.c.bc
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/embed.py
+ ${CMAKE_CURRENT_BINARY_DIR}/stdlib.c.bc)
+
+add_custom_target(generate_stdlib_c DEPENDS
+ ${CMAKE_CURRENT_BINARY_DIR}/stdlib.c.bc.embed.h)
+
+add_custom_command(
+ OUTPUT builtins_def.h stdlib_def.h builtins_impl.h stdlib_impl.h
+ COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/builtins.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/builtins.def
+ ${CMAKE_CURRENT_BINARY_DIR}
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/builtins.py
+ ${CMAKE_CURRENT_SOURCE_DIR}/builtins.def)
+
+add_custom_target(generate_builtins DEPENDS
+ ${CMAKE_CURRENT_BINARY_DIR}/builtins_def.h
+ ${CMAKE_CURRENT_BINARY_DIR}/builtins_impl.h
+ ${CMAKE_CURRENT_BINARY_DIR}/stdlib_def.h
+ ${CMAKE_CURRENT_BINARY_DIR}/stdlib_impl.h)
+endif(SHAMROCK_BUILD)
diff --git a/src/runtime/builtins.def b/src/runtime/builtins.def
new file mode 100644
index 0000000..b94807b
--- /dev/null
+++ b/src/runtime/builtins.def
@@ -0,0 +1,301 @@
+def vecf : float2 float3 float4 float8 float16
+def veci : int2 int3 int4 int8 int16
+
+def vec : $vecf $veci
+def gentype : float $vecf
+
+// gentype acos(gentype)
+// REPL is defined in src/core/cpu/builtins.cpp
+//native float acos float : x:float
+ //return std::acos(x);
+//end
+
+//native $type acos $vecf : x:$type
+ //REPL($vecdim)
+ //result[i] = std::acos(x[i]);
+//end
+
+// gentype acosh(gentype)
+//native float acosh float : x:float
+ //return boost::math::acosh(x);
+//end
+
+//native $type acosh $vecf : x:$type
+ //REPL($vecdim)
+ //result[i] = boost::math::acosh(x[i]);
+//end
+
+// gentype acospi(gentype)
+//func float acospi float : x:float
+ //return acos(x) / M_PI;
+//end
+
+//native $type acospi $vecf : x:$type
+ //REPL($vecdim)
+ //result[i] = std::acos(x[i]) / M_PI;
+//end
+
+// gentype asin (gentype)
+//native float asin float : x:float
+ //return std::asin(x);
+//end
+
+//native $type asin $vecf : x:$type
+ //REPL($vecdim)
+ //result[i] = std::asin(x[i]);
+//end
+
+// gentype asinh (gentype)
+//native float asinh float : x:float
+ //return boost::math::asinh(x);
+//end
+
+//native $type asinh $vecf : x:$type
+ //REPL($vecdim)
+ //result[i] = boost::math::asinh(x[i]);
+//end
+
+// gentype asinpi (gentype x)
+//func float asinpi float : x:float
+ //return asin(x) / M_PI;
+//end
+
+//native $type asinpi $vecf : x:$type
+ //REPL($vecdim)
+ //result[i] = std::asin(x[i]) / M_PI;
+//end
+
+// gentype atan (gentype y_over_x)
+//native float atan float : y_over_x:float
+ //return std::atan(y_over_x);
+//end
+
+//native $type atan $vecf : y_over_x:$type
+ //REPL($vecdim)
+ //result[i] = std::atan(y_over_x[i]);
+//end
+
+// gentype atan2 (gentype y, gentype x)
+//func float atan2 float : x:float y:float
+ //return atan(y / x);
+//end
+
+//native $type atan2 $vecf : x:$type y:$type
+ //REPL($vecdim)
+ //result[i] = std::atan(y[i] / x[i]);
+//end
+
+// gentype atanh (gentype)
+//native float atanh float : x:float
+ //return boost::math::atanh(x);
+//end
+
+//native $type atanh $vecf : x:$type
+ //REPL($vecdim)
+ //result[i] = boost::math::atanh(x[i]);
+//end
+
+// gentype atanpi (gentype x)
+//func float atanpi float : x:float
+ //return atan(x) / M_PI;
+//end
+
+//native $type atanpi $vecf : x:$type
+ //REPL($vecdim)
+ //result[i] = std::atan(x[i]) / M_PI;
+//end
+
+// gentype atan2pi (gentype y, gentype x)
+//func float atan2pi float : x:float y:float
+ //return atan2(y, x) / M_PI;
+//end
+//
+//native $type atan2pi $vecf : x:$type y:$type
+ //REPL($vecdim)
+ //result[i] = std::atan(y[i] / x[i]) / M_PI;
+//end
+
+// gentype cbrt (gentype)
+//native float cbrt float : x:float
+ //return boost::math::cbrt(x);
+//end
+//
+//native $type cbrt $vecf : x:$type
+ //REPL($vecdim)
+ //result[i] = boost::math::cbrt(x[i]);
+//end
+
+// gentype ceil (gentype)
+//native float ceil float : x:float
+ //return std::ceil(x);
+//end
+//
+//native $type ceil $vecf : x:$type
+ //REPL($vecdim)
+ //result[i] = std::ceil(x[i]);
+//end
+
+// gentype copysign (gentype x, gentype y)
+//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)
+//native float cos float : x:float
+ //return std::cos(x);
+//end
+
+//native $type cos $vecf : x:$type
+ //REPL($vecdim)
+ //result[i] = std::cos(x[i]);
+//end
+
+// gentype cosh (gentype)
+//native float cosh float : x:float
+ //return std::cosh(x);
+//end
+
+//native $type cosh $vecf : x:$type
+ //REPL($vecdim)
+ //result[i] = std::cosh(x[i]);
+//end
+
+// gentype cospi (gentype x)
+//func $type cospi $gentype : x:$type
+ //return cos(x * (float)M_PI);
+//end
+
+// TODO: gentype erfc (gentype)
+// TODO: gentype erf (gentype)
+
+// gentype exp(gentype x)
+//native float exp float : x:float
+ //return std::exp(x);
+//end
+//
+//native $type exp $vecf : x:$type
+ //REPL($vecdim)
+ //result[i] = std::exp(x[i]);
+//end
+//
+// gentype exp2(gentype x)
+//native float exp2 float : x:float
+ //return exp2f(x);
+//end
+//
+//native $type exp2 $vecf : x:$type
+ //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 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 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 double sqrt double : x:double
+ //return std::sqrt(x);
+//end
+//
+//native double log double : x:double
+ //return std::log(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
diff --git a/src/runtime/builtins.py b/src/runtime/builtins.py
new file mode 100755
index 0000000..909fee8
--- /dev/null
+++ b/src/runtime/builtins.py
@@ -0,0 +1,380 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2011, Denis Steckelmacher <steckdenis@yahoo.fr>
+# Copyright (c) 2012-2014, Texas Instruments Incorporated - http://www.ti.com/
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of the copyright holder nor the
+# names of its contributors may be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+# builtins.py <def> <outdir>
+
+import sys
+
+class Function:
+ class Arg:
+ def __init__(self, name, t):
+ self.name = name
+ self.t = t
+
+ KIND_BUILTINS_IMPL = 0 # static function in builtins.cpp
+ KIND_BUILTINS_DEF = 1 # if (name == '__cpu_$name') return (void *)&name;
+ KIND_STDLIB_IMPL = 2 # OpenCL C function in stdlib.c
+ KIND_STDLIB_DEF = 3 # Header in stdlib.h
+ KIND_STDLIB_STUB = 4 # OpenCL C stub in stdlib.c: calls __cpu_$name
+ KIND_STDLIB_STUB_DEF = 5 # __cpu_$name declared in stdlib.c
+
+ def __init__(self, name, native):
+ self.name = name
+ self.native = native
+
+ self.args = [] # Array <Arg>
+ self.types = [] # Array <str>
+ self.return_type = ''
+ self.body = ''
+
+ def set_return_type(self, ty):
+ self.return_type = ty
+
+ def append_body(self, body):
+ self.body += body
+
+ def add_arg(self, name, ty):
+ self.args.append(self.Arg(name, ty))
+
+ def add_type(self, ty):
+ self.types.append(ty)
+
+ def mangled_name(self, current_type):
+ return_type = self.process_type_name(current_type, self.return_type)
+
+ rs = return_type + '_' + self.name
+ first = True
+
+ for a in self.args:
+ if first:
+ rs += '_'
+ first = False
+
+ 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
+ append_arg = None
+
+ # We may need a first "result" arg
+ if handle_first_arg:
+ 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] + self.args
+ else:
+ args = self.args
+
+ for arg in args:
+ # Resolve 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
+ if handle_first_arg:
+ arg_vector = arg_type[-1].isdigit()
+ arg_type = arg_type.rstrip('0123456789')
+
+ # Build the string
+ if not first:
+ rs += ', '
+ first = False
+
+ rs += arg_type + ' '
+
+ if arg_vector or arg_ptr:
+ rs += '*'
+
+ rs += arg.name
+
+ return rs
+
+ def write(self, current_type, kind):
+ # Template:
+ # (static) $ret_type $name($args) {
+ # $body
+ # }
+ rs = ''
+
+ if kind == self.KIND_BUILTINS_IMPL:
+ rs = 'static '
+ elif kind == self.KIND_BUILTINS_DEF:
+ rs += ' else if (name == "__cpu_' + self.mangled_name(current_type) + '")\n'
+ rs += ' return (void *)&' + self.mangled_name(current_type) + ';\n'
+ return rs
+
+ # Calculate return 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():
+ return_type = 'void' # We'll use a 'result' argument
+
+ rs += return_type + ' '
+
+ # Append mangled name if needed
+ if kind == self.KIND_BUILTINS_IMPL:
+ rs += self.mangled_name(current_type)
+ elif kind == self.KIND_STDLIB_STUB_DEF:
+ rs += '__cpu_' + self.mangled_name(current_type)
+ else:
+ # No need to mangle the name, but add OVERLOAD
+ rs += '_CLC_OVERLOAD ' + self.name
+
+ # Print function args
+ rs += '('
+ rs += self.arg_list(current_type, kind == self.KIND_BUILTINS_IMPL or \
+ kind == self.KIND_STDLIB_STUB_DEF)
+ rs += ')'
+
+ # If only a declaration, end it
+ if kind == self.KIND_STDLIB_DEF or kind == self.KIND_STDLIB_STUB_DEF:
+ rs += ';\n'
+ return rs
+
+ # Add the body
+ rs += '\n{\n'
+
+ if kind == self.KIND_STDLIB_STUB:
+ # Special body : call __cpu_$name
+ return_is_vector = return_type[-1].isdigit()
+ if return_is_vector:
+ # Need to create a temporary
+ rs += ' ' + return_type + ' result;\n'
+ rs += '\n'
+
+ # Call the cpu stub
+ rs += ' '
+ if not return_is_vector:
+ rs += 'return '
+
+ rs += '__cpu_' + self.mangled_name(current_type) + '('
+
+ # Pass the result if needed
+ first = True
+ if return_is_vector:
+ rs += '(' + return_type.rstrip('0123456789') + ' *)&result'
+ first = False
+
+ # Append the args
+ for arg in self.args:
+ # Resolve 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:
+ rs += ', '
+ first = False
+
+ # We need to pass vector arguments as pointers
+ if arg_vector:
+ rs += '(' + arg_type.rstrip('0123456789') + ' *)'
+ if not arg_ptr:
+ rs += '&'
+
+ rs += arg.name
+
+ # End the call
+ rs += ');\n'
+
+ if return_is_vector:
+ rs += '\n return result;\n'
+
+ rs += '}\n\n'
+ else:
+ # Simply copy the body
+ vecdim = '1'
+
+ if current_type[-1].isdigit():
+ if current_type[-2].isdigit():
+ vecdim = current_type[-2:]
+ else:
+ vecdim = current_type[-1]
+
+ rs += self.body.replace('$type', current_type) \
+ .replace('$vecdim', vecdim)
+ rs += '\n}\n\n'
+
+ return rs
+
+class Generator:
+ builtins_impl_file = 'builtins_impl.h' # static functions
+ builtins_def_file = 'builtins_def.h' # if () in getBuiltin
+ stdlib_impl_file = 'stdlib_impl.h' # stdlib.c functions
+ stdlib_def_file = 'stdlib_def.h' # stdlib.h definitions
+
+ def __init__(self, out_path):
+ self.out_path = out_path
+
+ # Buffers
+ self.builtins_impl_buffer = ''
+ self.builtins_def_buffer = ''
+ self.stdlib_impl_buffer = ''
+ self.stdlib_def_buffer = ''
+
+ def add_function(self, function):
+ for t in function.types:
+ if function.native:
+ self.stdlib_impl_buffer += function.write(t, function.KIND_STDLIB_STUB_DEF)
+ self.stdlib_impl_buffer += function.write(t, function.KIND_STDLIB_STUB)
+ self.stdlib_def_buffer += function.write(t, function.KIND_STDLIB_DEF)
+ self.builtins_impl_buffer += function.write(t, function.KIND_BUILTINS_IMPL)
+ self.builtins_def_buffer += function.write(t, function.KIND_BUILTINS_DEF)
+ else:
+ self.stdlib_def_buffer += function.write(t, function.KIND_STDLIB_DEF)
+ self.stdlib_impl_buffer += function.write(t, function.KIND_STDLIB_IMPL)
+
+ def write(self):
+ of = open(self.out_path + '/' + self.stdlib_def_file, 'w')
+ of.write(self.stdlib_def_buffer)
+ of.close()
+
+ of = open(self.out_path + '/' + self.stdlib_impl_file, 'w')
+ of.write(self.stdlib_impl_buffer)
+ of.close()
+
+ of = open(self.out_path + '/' + self.builtins_def_file, 'w')
+ of.write(self.builtins_def_buffer)
+ of.close()
+
+ of = open(self.out_path + '/' + self.builtins_impl_file, 'w')
+ of.write(self.builtins_impl_buffer)
+ of.close()
+
+class Parser:
+ def __init__(self, generator, def_file_name):
+ self.generator = generator
+ self.def_file_name = def_file_name
+
+ self.defs = {}
+
+ def replace_variable(self, token):
+ result = []
+
+ if token[0] == '$':
+ for tok in self.defs[token[1:]]:
+ result.extend(self.replace_variable(tok))
+ else:
+ result.append(token)
+
+ return result
+
+ def parse(self):
+ def_file = open(self.def_file_name, 'rb')
+ current_function = None
+
+ for line in def_file:
+ if current_function:
+ # End if we encounter an end
+ if line.startswith('end'):
+ self.generator.add_function(current_function)
+ current_function = None
+ else:
+ # Add a line to the body
+ current_function.append_body(line)
+ else:
+ line = line.strip()
+ tokens = line.split(' ')
+ tok = tokens[0]
+
+ if tok == 'def':
+ # A definition : def <variable> : [values]
+ name = tokens[1]
+ values = []
+
+ for token in tokens[3:]:
+ values.extend(self.replace_variable(token))
+
+ self.defs[name] = values
+ elif tok == 'func' or tok == 'native':
+ # Function : func|native <ret_type> <name> [types] : [args]
+ current_function = Function(tokens[2], \
+ tokens[0] == 'native')
+
+ current_function.set_return_type(tokens[1])
+
+ # Explore the types and args
+ in_types = True
+
+ for token in tokens[3:]:
+ if token == ':':
+ in_types = False
+ elif in_types:
+ for ty in self.replace_variable(token):
+ current_function.add_type(ty)
+ else:
+ # Parameters
+ parts = token.split(':')
+ current_function.add_arg(parts[0], parts[1])
+
+ def_file.close()
+
+if __name__ == '__main__':
+ def_file = sys.argv[1]
+ out_dir = sys.argv[2]
+
+ gen = Generator(out_dir)
+ parser = Parser(gen, def_file)
+
+ parser.parse()
+ gen.write()
diff --git a/src/runtime/embed.py b/src/runtime/embed.py
new file mode 100755
index 0000000..e3aca9d
--- /dev/null
+++ b/src/runtime/embed.py
@@ -0,0 +1,76 @@
+#!/usr/bin/python
+# #!/usr/local/bin/python2.6-2.6.4
+# -*- coding: utf-8 -*-
+#
+# Copyright (c) 2011, Denis Steckelmacher <steckdenis@yahoo.fr>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# * Neither the name of the copyright holder nor the
+# names of its contributors may be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# embed.py <outfile> <filenames..>
+# <filenames> => <outfile>
+
+import sys
+
+outfile = open(sys.argv[1], 'w')
+name = sys.argv[1].split('/')[-1].replace('.embed.h', '').replace('.', '_')
+
+data = ''
+
+for i in xrange(len(sys.argv) - 1):
+ infile = open(sys.argv[i + 1], 'rb')
+ data += infile.read()
+
+# Header
+outfile.write('#ifndef __%s__\n' % name.upper())
+outfile.write('#define __%s__\n' % name.upper())
+outfile.write('\n')
+outfile.write('const char embed_%s[] =\n' % name)
+
+# Write it in chunks of 80 chars :
+# | "\x00..." (4+1+1 + 4*chars ==> chars = 18)
+index = 0
+
+for c in data:
+ if index == 0:
+ outfile.write(' "')
+
+ outfile.write('\\x%s' % ('%x' % ord(c)).rjust(2, '0'))
+ index += 1
+
+ if index == 18:
+ index = 0
+ outfile.write('"\n')
+
+# We may need to terminate a line
+if index != 0:
+ outfile.write('";\n')
+else:
+ outfile.write(';\n') # Alone on its line, poor semicolon
+
+# Footer
+outfile.write('\n')
+outfile.write('#endif\n')
+
+infile.close()
+outfile.close()
diff --git a/src/runtime/stdlib.c b/src/runtime/stdlib.c
new file mode 100644
index 0000000..9b115df
--- /dev/null
+++ b/src/runtime/stdlib.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, Denis Steckelmacher <steckdenis@yahoo.fr>
+ * Copyright (c) 2012-2014, Texas Instruments Incorporated - http://www.ti.com/
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the copyright holder nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+int debug(const char *format, ...);
+
+/* WARNING: Due to some device-specific things in stdlib.h, the bitcode stdlib
+ * must only be used by CPUDevice, as it's targeted to the host CPU at Clover's
+ * compilation! */
+
+/*
+ * Built-in functions generated by src/runtime/builtins.py
+ */
+
+#include <clc.h>
+#include <stdlib_impl.h>