-# Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved.
+# Copyright (C) 2014-2017 Intel Corporation. All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
-#!deps/python32/python.exe
-
+from __future__ import print_function
import os, sys, re
import argparse
import json as JSON
import operator
-
-header = r"""
-/****************************************************************************
-* Copyright (C) 2014-2016 Intel Corporation. All Rights Reserved.
-*
-* Permission is hereby granted, free of charge, to any person obtaining a
-* copy of this software and associated documentation files (the "Software"),
-* to deal in the Software without restriction, including without limitation
-* the rights to use, copy, modify, merge, publish, distribute, sublicense,
-* and/or sell copies of the Software, and to permit persons to whom the
-* Software is furnished to do so, subject to the following conditions:
-*
-* The above copyright notice and this permission notice (including the next
-* paragraph) shall be included in all copies or substantial portions of the
-* Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-* IN THE SOFTWARE.
-*
-* @file %s
-*
-* @brief auto-generated file
-*
-* DO NOT EDIT
-*
-******************************************************************************/
-
-#pragma once
-
-namespace SwrJit
-{
- using namespace llvm;
-
-"""
-
-"""
-"""
-def gen_file_header(filename):
- global header
- headerStr = header % filename
- return headerStr.splitlines()
-
-"""
-"""
-def gen_llvm_type(type, name, postfix_name, is_pointer, is_pointer_pointer, is_array, is_array_array, array_count, array_count1, is_llvm_struct, is_llvm_enum, is_llvm_pfn, output_file):
+from mako.template import Template
+from mako.exceptions import RichTraceback
+
+def write_template_to_string(template_filename, **kwargs):
+ try:
+ template = Template(filename=os.path.abspath(template_filename))
+ # Split + Join fixes line-endings for whatever platform you are using
+ return '\n'.join(template.render(**kwargs).splitlines())
+ except:
+ traceback = RichTraceback()
+ for (filename, lineno, function, line) in traceback.traceback:
+ print('File %s, line %s, in %s' % (filename, lineno, function))
+ print(line, '\n')
+ print('%s: %s' % (str(traceback.error.__class__.__name__), traceback.error))
+
+def write_template_to_file(template_filename, output_filename, **kwargs):
+ output_dirname = os.path.dirname(output_filename)
+ if not os.path.exists(output_dirname):
+ os.makedirs(output_dirname)
+ with open(output_filename, 'w') as outfile:
+ print(write_template_to_string(template_filename, **kwargs), file=outfile)
+
+'''
+'''
+def gen_llvm_type(type, name, is_pointer, is_pointer_pointer, is_array, is_array_array, array_count, array_count1, is_llvm_struct, is_llvm_enum, is_llvm_pfn, output_file):
llvm_type = ''
elif is_llvm_pfn:
llvm_type = 'PointerType::get(Type::getInt8Ty(ctx), 0)'
else:
- if type == "BYTE" or type == "char" or type == "uint8_t" or type == "int8_t" or type == 'bool':
+ if type == 'BYTE' or type == 'char' or type == 'uint8_t' or type == 'int8_t' or type == 'bool':
llvm_type = 'Type::getInt8Ty(ctx)'
elif type == 'UINT64' or type == 'INT64' or type == 'uint64_t' or type == 'int64_t':
llvm_type = 'Type::getInt64Ty(ctx)'
llvm_type = 'VectorType::get(Type::getFloatTy(ctx), pJitMgr->mVWidth)'
elif type == 'simdscalari':
llvm_type = 'VectorType::get(Type::getInt32Ty(ctx), pJitMgr->mVWidth)'
+ elif type == 'SIMD8::vector_t':
+ llvm_type = 'VectorType::get(Type::getFloatTy(ctx), 8)'
+ elif type == 'SIMD8::vectori_t':
+ llvm_type = 'VectorType::get(Type::getInt32Ty(ctx), 8)'
+ elif type == 'SIMD16::vector_t':
+ llvm_type = 'VectorType::get(Type::getFloatTy(ctx), 16)'
+ elif type == 'SIMD16::vectori_t':
+ llvm_type = 'VectorType::get(Type::getInt32Ty(ctx), 16)'
elif type == 'simdvector':
llvm_type = 'ArrayType::get(VectorType::get(Type::getFloatTy(ctx), pJitMgr->mVWidth), 4)'
+ elif type == 'SIMD8::attrib_t':
+ llvm_type = 'ArrayType::get(VectorType::get(Type::getFloatTy(ctx), 8), 4)'
+ elif type == 'SIMD16::attrib_t':
+ llvm_type = 'ArrayType::get(VectorType::get(Type::getFloatTy(ctx), 16), 4)'
else:
- llvm_type = 'Gen_%s%s(pJitMgr)' % (type, postfix_name)
+ llvm_type = 'Gen_%s(pJitMgr)' % type
if is_pointer:
llvm_type = 'PointerType::get(%s, 0)' % llvm_type
elif is_array:
llvm_type = 'ArrayType::get(%s, %s)' % (llvm_type, array_count)
- return [' members.push_back( %s ); // %s' % (llvm_type, name)]
+ return {
+ 'name' : name,
+ 'type' : llvm_type,
+ }
-"""
-"""
+'''
+'''
def gen_llvm_types(input_file, output_file):
- output_lines = gen_file_header(os.path.basename(output_file.name))
-
lines = input_file.readlines()
- postfix_name = ""
+ types = []
for idx in range(len(lines)):
line = lines[idx].rstrip()
- if "gen_llvm_types FINI" in line:
+ if 'gen_llvm_types FINI' in line:
break
- match = re.match(r"(\s*)struct(\s*)(\w+)", line)
+ match = re.match(r'(\s*)struct(\s*)(\w+)', line)
if match:
llvm_args = []
# Detect start of structure
- is_fwd_decl = re.search(r";", line)
+ is_fwd_decl = re.search(r';', line)
if not is_fwd_decl:
# Extract the command name
struct_name = match.group(3).strip()
- output_lines += [
- ' //////////////////////////////////////////////////////////////////////////',
- ' /// Generate LLVM type information for %s' % struct_name,
- ' INLINE static StructType *Gen_%s%s(JitManager* pJitMgr)' % (struct_name, postfix_name),
- ' {',
- ' LLVMContext& ctx = pJitMgr->mContext;',
- ' std::vector<Type*> members;',
- '',
- ]
+ type_entry = {
+ 'name' : struct_name,
+ 'members' : [],
+ }
end_of_struct = False
idx += 1
line = lines[idx].rstrip()
- is_llvm_typedef = re.search(r"@llvm_typedef", line)
+ is_llvm_typedef = re.search(r'@llvm_typedef', line)
if is_llvm_typedef is not None:
is_llvm_typedef = True
else:
###########################################
# Is field a llvm struct? Tells script to treat type as array of bytes that is size of structure.
- is_llvm_struct = re.search(r"@llvm_struct", line)
+ is_llvm_struct = re.search(r'@llvm_struct', line)
if is_llvm_struct is not None:
is_llvm_struct = True
###########################################
# Is field a llvm enum? Tells script to treat type as an enum and replaced with uint32 type.
- is_llvm_enum = re.search(r"@llvm_enum", line)
+ is_llvm_enum = re.search(r'@llvm_enum', line)
if is_llvm_enum is not None:
is_llvm_enum = True
###########################################
# Is field a llvm function pointer? Tells script to treat type as an enum and replaced with uint32 type.
- is_llvm_pfn = re.search(r"@llvm_pfn", line)
+ is_llvm_pfn = re.search(r'@llvm_pfn', line)
if is_llvm_pfn is not None:
is_llvm_pfn = True
###########################################
# Is field const?
- is_const = re.search(r"\s+const\s+", line)
+ is_const = re.search(r'\s+const\s+', line)
if is_const is not None:
is_const = True
###########################################
# Is field a pointer?
- is_pointer_pointer = re.search("\*\*", line)
+ is_pointer_pointer = re.search('\*\*', line)
if is_pointer_pointer is not None:
is_pointer_pointer = True
###########################################
# Is field a pointer?
- is_pointer = re.search("\*", line)
+ is_pointer = re.search('\*', line)
if is_pointer is not None:
is_pointer = True
###########################################
# Is field an array of arrays?
# TODO: Can add this to a list.
- is_array_array = re.search("\[(\w*)\]\[(\w*)\]", line)
+ is_array_array = re.search('\[(\w*)\]\[(\w*)\]', line)
array_count = '0'
array_count1 = '0'
###########################################
# Is field an array?
- is_array = re.search("\[(\w*)\]", line)
+ is_array = re.search('\[(\w*)\]', line)
if is_array is not None:
array_count = is_array.group(1)
else:
is_array = False
- is_scoped = re.search("::", line)
+ is_scoped = re.search('::', line)
if is_scoped is not None:
is_scoped = True
if is_const and is_pointer:
if is_scoped:
- field_match = re.match(r"(\s*)(\w+\<*\w*\>*)(\s+)(\w+::)(\w+)(\s*\**\s*)(\w+)", line)
+ field_match = re.match(r'(\s*)(\w+\<*\w*\>*)(\s+)(\w+::)(\w+)(\s*\**\s*)(\w+)', line)
- type = "%s%s" % (field_match.group(4), field_match.group(5))
+ type = '%s%s' % (field_match.group(4), field_match.group(5))
name = field_match.group(7)
else:
- field_match = re.match(r"(\s*)(\w+\<*\w*\>*)(\s+)(\w+)(\s*\**\s*)(\w+)", line)
+ field_match = re.match(r'(\s*)(\w+\<*\w*\>*)(\s+)(\w+)(\s*\**\s*)(\w+)', line)
type = field_match.group(4)
name = field_match.group(6)
elif is_pointer:
- field_match = re.match(r"(\s*)(\s+)(\w+\<*\w*\>*)(\s*\**\s*)(\w+)", line)
+ field_match = re.match(r'(\s*)(\s+)(\w+\<*\w*\>*)(\s*\**\s*)(\w+)', line)
if field_match:
type = field_match.group(3)
name = field_match.group(5)
elif is_const:
- field_match = re.match(r"(\s*)(\w+\<*\w*\>*)(\s+)(\w+)(\s*)(\w+)", line)
+ field_match = re.match(r'(\s*)(\w+\<*\w*\>*)(\s+)(\w+)(\s*)(\w+)', line)
if field_match:
type = field_match.group(4)
name = field_match.group(6)
else:
if is_scoped:
- field_match = re.match(r"\s*(\w+\<*\w*\>*)\s*::\s*(\w+\<*\w*\>*)\s+(\w+)", line)
+ field_match = re.match(r'\s*(\w+\<*\w*\>*)\s*::\s*(\w+\<*\w*\>*)\s+(\w+)', line)
if field_match:
type = field_match.group(1) + '::' + field_match.group(2)
name = field_match.group(3)
else:
- field_match = re.match(r"(\s*)(\w+\<*\w*\>*)(\s+)(\w+)", line)
+ field_match = re.match(r'(\s*)(\w+\<*\w*\>*)(\s+)(\w+)', line)
if field_match:
type = field_match.group(2)
if is_llvm_typedef is False:
if type is not None:
- output_lines += gen_llvm_type(type, name, postfix_name, is_pointer, is_pointer_pointer, is_array, is_array_array, array_count, array_count1, is_llvm_struct, is_llvm_enum, is_llvm_pfn, output_file)
- llvm_args.append(name)
+ type_entry['members'].append(
+ gen_llvm_type(
+ type, name, is_pointer, is_pointer_pointer, is_array, is_array_array,
+ array_count, array_count1, is_llvm_struct, is_llvm_enum, is_llvm_pfn, output_file))
# Detect end of structure
- end_of_struct = re.match(r"(\s*)};", line)
-
- if (end_of_struct):
- output_lines += [
- '',
- ' return StructType::get(ctx, members, false);',
- ' }',
- '',
- ]
+ end_of_struct = re.match(r'(\s*)};', line)
- for i in range(len(llvm_args)):
- output_lines.append(' static const uint32_t %s%s_%s = %s;' % (struct_name, postfix_name, llvm_args[i], i))
+ if end_of_struct:
+ types.append(type_entry)
- output_lines.append('')
+ cur_dir = os.path.dirname(os.path.abspath(__file__))
+ template = os.path.join(cur_dir, 'templates', 'gen_llvm.hpp')
- output_lines.append('}')
- output_file.write('\n'.join(output_lines) + '\n')
+ write_template_to_file(
+ template,
+ output_file,
+ cmdline=sys.argv,
+ filename=os.path.basename(output_file),
+ types=types)
-"""
+'''
Function which is invoked when this script is started from a command line.
Will present and consume a set of arguments which will tell this script how
to behave
-"""
+'''
def main():
# Parse args...
parser = argparse.ArgumentParser()
- parser.add_argument("--input", "-i", type=argparse.FileType('r'),
- help="Path to input file containing structs", required=True)
- parser.add_argument("--output", "-o", type=argparse.FileType('w'),
- help="Path to output file", required=True)
- parser.add_argument("--scalar", "-scalar", help="Generates scalar files with all enums", action="store_true", default=False)
+ parser.add_argument('--input', '-i', type=argparse.FileType('r'),
+ help='Path to input file containing structs', required=True)
+ parser.add_argument('--output', '-o', action='store',
+ help='Path to output file', required=True)
args = parser.parse_args()
gen_llvm_types(args.input, args.output)