1
# Copyright (C) 2014-2017 Intel Corporation. All Rights Reserved.
3 # Permission is hereby granted, free of charge, to any person obtaining a
4 # copy of this software and associated documentation files (the "Software"),
5 # to deal in the Software without restriction, including without limitation
6 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 # and/or sell copies of the Software, and to permit persons to whom the
8 # Software is furnished to do so, subject to the following conditions:
10 # The above copyright notice and this permission notice (including the next
11 # paragraph) shall be included in all copies or substantial portions of the
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 from __future__
import print_function
24 from gen_common
import MakoTemplateWriter
, ArgumentParser
25 from argparse
import FileType
29 def gen_llvm_type(type, name
, idx
, 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
):
34 if is_pointer
or is_pointer_pointer
:
35 llvm_type
= 'Type::getInt32Ty(ctx)'
37 llvm_type
= 'ArrayType::get(Type::getInt8Ty(ctx), sizeof(%s))' % type
39 llvm_type
= 'Type::getInt32Ty(ctx)'
41 llvm_type
= 'PointerType::get(Type::getInt8Ty(ctx), 0)'
43 if type == 'BYTE' or type == 'char' or type == 'uint8_t' or type == 'int8_t' or type == 'bool':
44 llvm_type
= 'Type::getInt8Ty(ctx)'
45 elif type == 'UINT64' or type == 'INT64' or type == 'uint64_t' or type == 'int64_t' or type == 'gfxptr_t':
46 llvm_type
= 'Type::getInt64Ty(ctx)'
47 elif type == 'UINT16' or type == 'int16_t' or type == 'uint16_t':
48 llvm_type
= 'Type::getInt16Ty(ctx)'
49 elif type == 'UINT' or type == 'INT' or type == 'int' or type == 'BOOL' or type == 'uint32_t' or type == 'int32_t':
50 llvm_type
= 'Type::getInt32Ty(ctx)'
51 elif type == 'float' or type == 'FLOAT':
52 llvm_type
= 'Type::getFloatTy(ctx)'
53 elif type == 'double' or type == 'DOUBLE':
54 llvm_type
= 'Type::getDoubleTy(ctx)'
55 elif type == 'void' or type == 'VOID':
56 llvm_type
= 'Type::getInt32Ty(ctx)'
57 elif type == 'HANDLE':
58 llvm_type
= 'PointerType::get(Type::getInt32Ty(ctx), 0)'
59 elif type == 'simdscalar':
60 llvm_type
= 'VectorType::get(Type::getFloatTy(ctx), pJitMgr->mVWidth)'
61 elif type == 'simdscalari':
62 llvm_type
= 'VectorType::get(Type::getInt32Ty(ctx), pJitMgr->mVWidth)'
63 elif type == 'simd16scalar':
64 llvm_type
= 'VectorType::get(Type::getFloatTy(ctx), 16)'
65 elif type == 'simd16scalari':
66 llvm_type
= 'VectorType::get(Type::getInt32Ty(ctx), 16)'
67 elif type == '__m128i':
68 llvm_type
= 'VectorType::get(Type::getInt32Ty(ctx), 4)'
69 elif type == 'SIMD256::Float':
70 llvm_type
= 'VectorType::get(Type::getFloatTy(ctx), 8)'
71 elif type == 'SIMD256::Integer':
72 llvm_type
= 'VectorType::get(Type::getInt32Ty(ctx), 8)'
73 elif type == 'SIMD512::Float':
74 llvm_type
= 'VectorType::get(Type::getFloatTy(ctx), 16)'
75 elif type == 'SIMD512::Integer':
76 llvm_type
= 'VectorType::get(Type::getInt32Ty(ctx), 16)'
77 elif type == 'simdvector':
78 llvm_type
= 'ArrayType::get(VectorType::get(Type::getFloatTy(ctx), 8), 4)'
79 elif type == 'simd16vector':
80 llvm_type
= 'ArrayType::get(VectorType::get(Type::getFloatTy(ctx), 16), 4)'
81 elif type == 'SIMD256::Vec4':
82 llvm_type
= 'ArrayType::get(VectorType::get(Type::getFloatTy(ctx), 8), 4)'
83 elif type == 'SIMD512::Vec4':
84 llvm_type
= 'ArrayType::get(VectorType::get(Type::getFloatTy(ctx), 16), 4)'
86 llvm_type
= 'Gen_%s(pJitMgr)' % type
89 llvm_type
= 'PointerType::get(%s, 0)' % llvm_type
91 if is_pointer_pointer
:
92 llvm_type
= 'PointerType::get(%s, 0)' % llvm_type
95 llvm_type
= 'ArrayType::get(ArrayType::get(%s, %s), %s)' % (llvm_type
, array_count1
, array_count
)
97 llvm_type
= 'ArrayType::get(%s, %s)' % (llvm_type
, array_count
)
107 def gen_llvm_types(input_file
, output_file
):
109 lines
= input_file
.readlines()
113 for idx
in range(len(lines
)):
114 line
= lines
[idx
].rstrip()
116 if 'gen_llvm_types FINI' in line
:
119 match
= re
.match(r
'(\s*)struct(\s*)(\w+)', line
)
123 # Detect start of structure
124 is_fwd_decl
= re
.search(r
';', line
)
128 # Extract the command name
129 struct_name
= match
.group(3).strip()
132 'name' : struct_name
,
137 end_of_struct
= False
139 while not end_of_struct
and idx
< len(lines
)-1:
141 line
= lines
[idx
].rstrip()
143 is_llvm_typedef
= re
.search(r
'@llvm_typedef', line
)
144 if is_llvm_typedef
is not None:
145 is_llvm_typedef
= True
147 is_llvm_typedef
= False
149 ###########################################
150 # Is field a llvm struct? Tells script to treat type as array of bytes that is size of structure.
151 is_llvm_struct
= re
.search(r
'@llvm_struct', line
)
153 if is_llvm_struct
is not None:
154 is_llvm_struct
= True
156 is_llvm_struct
= False
158 ###########################################
159 # Is field the start of a function? Tells script to ignore it
160 is_llvm_func_start
= re
.search(r
'@llvm_func_start', line
)
162 if is_llvm_func_start
is not None:
163 while not end_of_struct
and idx
< len(lines
)-1:
165 line
= lines
[idx
].rstrip()
166 is_llvm_func_end
= re
.search(r
'@llvm_func_end', line
)
167 if is_llvm_func_end
is not None:
171 ###########################################
172 # Is field a function? Tells script to ignore it
173 is_llvm_func
= re
.search(r
'@llvm_func', line
)
175 if is_llvm_func
is not None:
178 ###########################################
179 # Is field a llvm enum? Tells script to treat type as an enum and replaced with uint32 type.
180 is_llvm_enum
= re
.search(r
'@llvm_enum', line
)
182 if is_llvm_enum
is not None:
187 ###########################################
188 # Is field a llvm function pointer? Tells script to treat type as an enum and replaced with uint32 type.
189 is_llvm_pfn
= re
.search(r
'@llvm_pfn', line
)
191 if is_llvm_pfn
is not None:
196 ###########################################
198 is_const
= re
.search(r
'\s+const\s+', line
)
200 if is_const
is not None:
205 ###########################################
206 # Is field a pointer?
207 is_pointer_pointer
= re
.search('\*\*', line
)
209 if is_pointer_pointer
is not None:
210 is_pointer_pointer
= True
212 is_pointer_pointer
= False
214 ###########################################
215 # Is field a pointer?
216 is_pointer
= re
.search('\*', line
)
218 if is_pointer
is not None:
223 ###########################################
224 # Is field an array of arrays?
225 # TODO: Can add this to a list.
226 is_array_array
= re
.search('\[(\w*)\]\[(\w*)\]', line
)
230 if is_array_array
is not None:
231 array_count
= is_array_array
.group(1)
232 array_count1
= is_array_array
.group(2)
233 is_array_array
= True
235 is_array_array
= False
237 ###########################################
239 is_array
= re
.search('\[(\w*)\]', line
)
241 if is_array
is not None:
242 array_count
= is_array
.group(1)
247 is_scoped
= re
.search('::', line
)
249 if is_scoped
is not None:
256 if is_const
and is_pointer
:
259 field_match
= re
.match(r
'(\s*)(\w+\<*\w*\>*)(\s+)(\w+::)(\w+)(\s*\**\s*)(\w+)', line
)
261 type = '%s%s' % (field_match
.group(4), field_match
.group(5))
262 name
= field_match
.group(7)
264 field_match
= re
.match(r
'(\s*)(\w+\<*\w*\>*)(\s+)(\w+)(\s*\**\s*)(\w+)', line
)
266 type = field_match
.group(4)
267 name
= field_match
.group(6)
270 field_match
= re
.match(r
'(\s*)(\s+)(\w+\<*\w*\>*)(\s*\**\s*)(\w+)', line
)
273 type = field_match
.group(3)
274 name
= field_match
.group(5)
276 field_match
= re
.match(r
'(\s*)(\w+\<*\w*\>*)(\s+)(\w+)(\s*)(\w+)', line
)
279 type = field_match
.group(4)
280 name
= field_match
.group(6)
283 field_match
= re
.match(r
'\s*(\w+\<*\w*\>*)\s*::\s*(\w+\<*\w*\>*)\s+(\w+)', line
)
286 type = field_match
.group(1) + '::' + field_match
.group(2)
287 name
= field_match
.group(3)
289 field_match
= re
.match(r
'(\s*)(\w+\<*\w*\>*)(\s+)(\w+)', line
)
292 type = field_match
.group(2)
293 name
= field_match
.group(4)
295 if is_llvm_typedef
is False:
297 type_entry
['members'].append(
299 type, name
, idx
+1, is_pointer
, is_pointer_pointer
, is_array
, is_array_array
,
300 array_count
, array_count1
, is_llvm_struct
, is_llvm_enum
, is_llvm_pfn
, output_file
))
302 # Detect end of structure
303 end_of_struct
= re
.match(r
'(\s*)};', line
)
306 types
.append(type_entry
)
308 cur_dir
= os
.path
.dirname(os
.path
.abspath(__file__
))
309 template
= os
.path
.join(cur_dir
, 'templates', 'gen_llvm.hpp')
311 MakoTemplateWriter
.to_file(
315 filename
=os
.path
.basename(output_file
),
317 input_dir
=os
.path
.dirname(input_file
.name
),
318 input_file
=os
.path
.basename(input_file
.name
))
321 Function which is invoked when this script is started from a command line.
322 Will present and consume a set of arguments which will tell this script how
328 parser
= ArgumentParser()
329 parser
.add_argument('--input', '-i', type=FileType('r'),
330 help='Path to input file containing structs', required
=True)
331 parser
.add_argument('--output', '-o', action
='store',
332 help='Path to output file', required
=True)
333 args
= parser
.parse_args()
335 gen_llvm_types(args
.input, args
.output
)
337 if __name__
== '__main__':