e88158c14d879018573e88818fa6e270a80d0a5a
[mesa.git] / src / gallium / drivers / swr / rasterizer / jitter / scripts / gen_llvm_types.py
1 # Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved.
2 #
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:
9 #
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
12 # Software.
13 #
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
20 # IN THE SOFTWARE.
21
22 #!deps/python32/python.exe
23
24 import os, sys, re
25 import argparse
26 import json as JSON
27 import operator
28
29 header = r"""
30 /****************************************************************************
31 * Copyright (C) 2014-2016 Intel Corporation. All Rights Reserved.
32 *
33 * Permission is hereby granted, free of charge, to any person obtaining a
34 * copy of this software and associated documentation files (the "Software"),
35 * to deal in the Software without restriction, including without limitation
36 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
37 * and/or sell copies of the Software, and to permit persons to whom the
38 * Software is furnished to do so, subject to the following conditions:
39 *
40 * The above copyright notice and this permission notice (including the next
41 * paragraph) shall be included in all copies or substantial portions of the
42 * Software.
43 *
44 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
47 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
48 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
49 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
50 * IN THE SOFTWARE.
51 *
52 * @file %s
53 *
54 * @brief auto-generated file
55 *
56 * DO NOT EDIT
57 *
58 ******************************************************************************/
59
60 #pragma once
61
62 namespace SwrJit
63 {
64 using namespace llvm;
65
66 """
67
68 """
69 """
70 def gen_file_header(filename):
71 global header
72 headerStr = header % filename
73 return headerStr.splitlines()
74
75 """
76 """
77 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):
78
79 llvm_type = ''
80
81 if is_llvm_struct:
82 if is_pointer or is_pointer_pointer:
83 llvm_type = 'Type::getInt32Ty(ctx)'
84 else:
85 llvm_type = 'ArrayType::get(Type::getInt8Ty(ctx), sizeof(%s))' % type
86 elif is_llvm_enum:
87 llvm_type = 'Type::getInt32Ty(ctx)'
88 elif is_llvm_pfn:
89 llvm_type = 'PointerType::get(Type::getInt8Ty(ctx), 0)'
90 else:
91 if type == "BYTE" or type == "char" or type == "uint8_t" or type == "int8_t" or type == 'bool':
92 llvm_type = 'Type::getInt8Ty(ctx)'
93 elif type == 'UINT64' or type == 'INT64' or type == 'uint64_t' or type == 'int64_t':
94 llvm_type = 'Type::getInt64Ty(ctx)'
95 elif type == 'UINT16' or type == 'int16_t' or type == 'uint16_t':
96 llvm_type = 'Type::getInt16Ty(ctx)'
97 elif type == 'UINT' or type == 'INT' or type == 'int' or type == 'BOOL' or type == 'uint32_t' or type == 'int32_t':
98 llvm_type = 'Type::getInt32Ty(ctx)'
99 elif type == 'float' or type == 'FLOAT':
100 llvm_type = 'Type::getFloatTy(ctx)'
101 elif type == 'double' or type == 'DOUBLE':
102 llvm_type = 'Type::getDoubleTy(ctx)'
103 elif type == 'void' or type == 'VOID':
104 llvm_type = 'Type::getInt32Ty(ctx)'
105 elif type == 'HANDLE':
106 llvm_type = 'PointerType::get(Type::getInt32Ty(ctx), 0)'
107 elif type == 'simdscalar':
108 llvm_type = 'VectorType::get(Type::getFloatTy(ctx), pJitMgr->mVWidth)'
109 elif type == 'simdscalari':
110 llvm_type = 'VectorType::get(Type::getInt32Ty(ctx), pJitMgr->mVWidth)'
111 elif type == 'simdvector':
112 llvm_type = 'ArrayType::get(VectorType::get(Type::getFloatTy(ctx), pJitMgr->mVWidth), 4)'
113 else:
114 llvm_type = 'Gen_%s%s(pJitMgr)' % (type, postfix_name)
115
116 if is_pointer:
117 llvm_type = 'PointerType::get(%s, 0)' % llvm_type
118
119 if is_pointer_pointer:
120 llvm_type = 'PointerType::get(%s, 0)' % llvm_type
121
122 if is_array_array:
123 llvm_type = 'ArrayType::get(ArrayType::get(%s, %s), %s)' % (llvm_type, array_count1, array_count)
124 elif is_array:
125 llvm_type = 'ArrayType::get(%s, %s)' % (llvm_type, array_count)
126
127 return [' members.push_back( %s ); // %s' % (llvm_type, name)]
128
129 """
130 """
131 def gen_llvm_types(input_file, output_file):
132
133 output_lines = gen_file_header(os.path.basename(output_file.name))
134
135 lines = input_file.readlines()
136
137 postfix_name = ""
138
139 for idx in range(len(lines)):
140 line = lines[idx].rstrip()
141
142 if "gen_llvm_types FINI" in line:
143 break
144
145 match = re.match(r"(\s*)struct(\s*)(\w+)", line)
146 if match:
147 llvm_args = []
148
149 # Detect start of structure
150 is_fwd_decl = re.search(r";", line)
151
152 if not is_fwd_decl:
153
154 # Extract the command name
155 struct_name = match.group(3).strip()
156
157 output_lines += [
158 ' //////////////////////////////////////////////////////////////////////////',
159 ' /// Generate LLVM type information for %s' % struct_name,
160 ' INLINE static StructType *Gen_%s%s(JitManager* pJitMgr)' % (struct_name, postfix_name),
161 ' {',
162 ' LLVMContext& ctx = pJitMgr->mContext;',
163 ' std::vector<Type*> members;',
164 '',
165 ]
166
167 end_of_struct = False
168
169 while not end_of_struct and idx < len(lines)-1:
170 idx += 1
171 line = lines[idx].rstrip()
172
173 is_llvm_typedef = re.search(r"@llvm_typedef", line)
174 if is_llvm_typedef is not None:
175 is_llvm_typedef = True
176 else:
177 is_llvm_typedef = False
178
179 ###########################################
180 # Is field a llvm struct? Tells script to treat type as array of bytes that is size of structure.
181 is_llvm_struct = re.search(r"@llvm_struct", line)
182
183 if is_llvm_struct is not None:
184 is_llvm_struct = True
185 else:
186 is_llvm_struct = False
187
188 ###########################################
189 # Is field a llvm enum? Tells script to treat type as an enum and replaced with uint32 type.
190 is_llvm_enum = re.search(r"@llvm_enum", line)
191
192 if is_llvm_enum is not None:
193 is_llvm_enum = True
194 else:
195 is_llvm_enum = False
196
197 ###########################################
198 # Is field a llvm function pointer? Tells script to treat type as an enum and replaced with uint32 type.
199 is_llvm_pfn = re.search(r"@llvm_pfn", line)
200
201 if is_llvm_pfn is not None:
202 is_llvm_pfn = True
203 else:
204 is_llvm_pfn = False
205
206 ###########################################
207 # Is field const?
208 is_const = re.search(r"\s+const\s+", line)
209
210 if is_const is not None:
211 is_const = True
212 else:
213 is_const = False
214
215 ###########################################
216 # Is field a pointer?
217 is_pointer_pointer = re.search("\*\*", line)
218
219 if is_pointer_pointer is not None:
220 is_pointer_pointer = True
221 else:
222 is_pointer_pointer = False
223
224 ###########################################
225 # Is field a pointer?
226 is_pointer = re.search("\*", line)
227
228 if is_pointer is not None:
229 is_pointer = True
230 else:
231 is_pointer = False
232
233 ###########################################
234 # Is field an array of arrays?
235 # TODO: Can add this to a list.
236 is_array_array = re.search("\[(\w*)\]\[(\w*)\]", line)
237 array_count = '0'
238 array_count1 = '0'
239
240 if is_array_array is not None:
241 array_count = is_array_array.group(1)
242 array_count1 = is_array_array.group(2)
243 is_array_array = True
244 else:
245 is_array_array = False
246
247 ###########################################
248 # Is field an array?
249 is_array = re.search("\[(\w*)\]", line)
250
251 if is_array is not None:
252 array_count = is_array.group(1)
253 is_array = True
254 else:
255 is_array = False
256
257 is_scoped = re.search("::", line)
258
259 if is_scoped is not None:
260 is_scoped = True
261 else:
262 is_scoped = False
263
264 type = None
265 name = None
266 if is_const and is_pointer:
267
268 if is_scoped:
269 field_match = re.match(r"(\s*)(\w+\<*\w*\>*)(\s+)(\w+::)(\w+)(\s*\**\s*)(\w+)", line)
270
271 type = "%s%s" % (field_match.group(4), field_match.group(5))
272 name = field_match.group(7)
273 else:
274 field_match = re.match(r"(\s*)(\w+\<*\w*\>*)(\s+)(\w+)(\s*\**\s*)(\w+)", line)
275
276 type = field_match.group(4)
277 name = field_match.group(6)
278
279 elif is_pointer:
280 field_match = re.match(r"(\s*)(\s+)(\w+\<*\w*\>*)(\s*\**\s*)(\w+)", line)
281
282 if field_match:
283 type = field_match.group(3)
284 name = field_match.group(5)
285 elif is_const:
286 field_match = re.match(r"(\s*)(\w+\<*\w*\>*)(\s+)(\w+)(\s*)(\w+)", line)
287
288 if field_match:
289 type = field_match.group(4)
290 name = field_match.group(6)
291 else:
292 if is_scoped:
293 field_match = re.match(r"\s*(\w+\<*\w*\>*)\s*::\s*(\w+\<*\w*\>*)\s+(\w+)", line)
294
295 if field_match:
296 type = field_match.group(1) + '::' + field_match.group(2)
297 name = field_match.group(3)
298 else:
299 field_match = re.match(r"(\s*)(\w+\<*\w*\>*)(\s+)(\w+)", line)
300
301 if field_match:
302 type = field_match.group(2)
303 name = field_match.group(4)
304
305 if is_llvm_typedef is False:
306 if type is not None:
307 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)
308 llvm_args.append(name)
309
310 # Detect end of structure
311 end_of_struct = re.match(r"(\s*)};", line)
312
313 if (end_of_struct):
314 output_lines += [
315 '',
316 ' return StructType::get(ctx, members, false);',
317 ' }',
318 '',
319 ]
320
321 for i in range(len(llvm_args)):
322 output_lines.append(' static const uint32_t %s%s_%s = %s;' % (struct_name, postfix_name, llvm_args[i], i))
323
324 output_lines.append('')
325
326 output_lines.append('}')
327 output_file.write('\n'.join(output_lines) + '\n')
328
329 """
330 Function which is invoked when this script is started from a command line.
331 Will present and consume a set of arguments which will tell this script how
332 to behave
333 """
334 def main():
335
336 # Parse args...
337 parser = argparse.ArgumentParser()
338 parser.add_argument("--input", "-i", type=argparse.FileType('r'),
339 help="Path to input file containing structs", required=True)
340 parser.add_argument("--output", "-o", type=argparse.FileType('w'),
341 help="Path to output file", required=True)
342 parser.add_argument("--scalar", "-scalar", help="Generates scalar files with all enums", action="store_true", default=False)
343 args = parser.parse_args()
344
345 gen_llvm_types(args.input, args.output)
346
347 if __name__ == '__main__':
348 main()
349 # END OF FILE