diff options
author | Gil Pitney <gil.pitney@linaro.org> | 2014-10-28 18:00:42 -0700 |
---|---|---|
committer | Gil Pitney <gil.pitney@linaro.org> | 2014-10-28 18:00:42 -0700 |
commit | 61b2c94d9e64758e55730be6a3fc9006c171db85 (patch) | |
tree | f564f09ebf93ba293dfa225bd374df6f1f37aa01 /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.txt | 59 | ||||
-rw-r--r-- | src/runtime/builtins.def | 301 | ||||
-rwxr-xr-x | src/runtime/builtins.py | 380 | ||||
-rwxr-xr-x | src/runtime/embed.py | 76 | ||||
-rw-r--r-- | src/runtime/stdlib.c | 40 |
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> |