swr/rast: Support USE_SIMD16_FRONTEND=0 for EarlyRast
[mesa.git] / src / gallium / drivers / swr / rasterizer / codegen / gen_llvm_types.py
1 # Copyright (C) 2014-2017 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 from __future__ import print_function
23 import os, sys, re
24 from gen_common import MakoTemplateWriter, ArgumentParser
25 from argparse import FileType
26
27 '''
28 '''
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):
30
31 llvm_type = ''
32
33 if is_llvm_struct:
34 if is_pointer or is_pointer_pointer:
35 llvm_type = 'Type::getInt32Ty(ctx)'
36 else:
37 llvm_type = 'ArrayType::get(Type::getInt8Ty(ctx), sizeof(%s))' % type
38 elif is_llvm_enum:
39 llvm_type = 'Type::getInt32Ty(ctx)'
40 elif is_llvm_pfn:
41 llvm_type = 'PointerType::get(Type::getInt8Ty(ctx), 0)'
42 else:
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)'
85 else:
86 llvm_type = 'Gen_%s(pJitMgr)' % type
87
88 if is_pointer:
89 llvm_type = 'PointerType::get(%s, 0)' % llvm_type
90
91 if is_pointer_pointer:
92 llvm_type = 'PointerType::get(%s, 0)' % llvm_type
93
94 if is_array_array:
95 llvm_type = 'ArrayType::get(ArrayType::get(%s, %s), %s)' % (llvm_type, array_count1, array_count)
96 elif is_array:
97 llvm_type = 'ArrayType::get(%s, %s)' % (llvm_type, array_count)
98
99 return {
100 'name' : name,
101 'lineNum' : idx,
102 'type' : llvm_type,
103 }
104
105 '''
106 '''
107 def gen_llvm_types(input_file, output_file):
108
109 lines = input_file.readlines()
110
111 types = []
112
113 for idx in range(len(lines)):
114 line = lines[idx].rstrip()
115
116 if 'gen_llvm_types FINI' in line:
117 break
118
119 match = re.match(r'(\s*)struct(\s*)(\w+)', line)
120 if match:
121 llvm_args = []
122
123 # Detect start of structure
124 is_fwd_decl = re.search(r';', line)
125
126 if not is_fwd_decl:
127
128 # Extract the command name
129 struct_name = match.group(3).strip()
130
131 type_entry = {
132 'name' : struct_name,
133 'lineNum' : idx+1,
134 'members' : [],
135 }
136
137 end_of_struct = False
138
139 while not end_of_struct and idx < len(lines)-1:
140 idx += 1
141 line = lines[idx].rstrip()
142
143 is_llvm_typedef = re.search(r'@llvm_typedef', line)
144 if is_llvm_typedef is not None:
145 is_llvm_typedef = True
146 else:
147 is_llvm_typedef = False
148
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)
152
153 if is_llvm_struct is not None:
154 is_llvm_struct = True
155 else:
156 is_llvm_struct = False
157
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)
161
162 if is_llvm_func_start is not None:
163 while not end_of_struct and idx < len(lines)-1:
164 idx += 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:
168 break;
169 continue
170
171 ###########################################
172 # Is field a function? Tells script to ignore it
173 is_llvm_func = re.search(r'@llvm_func', line)
174
175 if is_llvm_func is not None:
176 continue
177
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)
181
182 if is_llvm_enum is not None:
183 is_llvm_enum = True
184 else:
185 is_llvm_enum = False
186
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)
190
191 if is_llvm_pfn is not None:
192 is_llvm_pfn = True
193 else:
194 is_llvm_pfn = False
195
196 ###########################################
197 # Is field const?
198 is_const = re.search(r'\s+const\s+', line)
199
200 if is_const is not None:
201 is_const = True
202 else:
203 is_const = False
204
205 ###########################################
206 # Is field a pointer?
207 is_pointer_pointer = re.search('\*\*', line)
208
209 if is_pointer_pointer is not None:
210 is_pointer_pointer = True
211 else:
212 is_pointer_pointer = False
213
214 ###########################################
215 # Is field a pointer?
216 is_pointer = re.search('\*', line)
217
218 if is_pointer is not None:
219 is_pointer = True
220 else:
221 is_pointer = False
222
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)
227 array_count = '0'
228 array_count1 = '0'
229
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
234 else:
235 is_array_array = False
236
237 ###########################################
238 # Is field an array?
239 is_array = re.search('\[(\w*)\]', line)
240
241 if is_array is not None:
242 array_count = is_array.group(1)
243 is_array = True
244 else:
245 is_array = False
246
247 is_scoped = re.search('::', line)
248
249 if is_scoped is not None:
250 is_scoped = True
251 else:
252 is_scoped = False
253
254 type = None
255 name = None
256 if is_const and is_pointer:
257
258 if is_scoped:
259 field_match = re.match(r'(\s*)(\w+\<*\w*\>*)(\s+)(\w+::)(\w+)(\s*\**\s*)(\w+)', line)
260
261 type = '%s%s' % (field_match.group(4), field_match.group(5))
262 name = field_match.group(7)
263 else:
264 field_match = re.match(r'(\s*)(\w+\<*\w*\>*)(\s+)(\w+)(\s*\**\s*)(\w+)', line)
265
266 type = field_match.group(4)
267 name = field_match.group(6)
268
269 elif is_pointer:
270 field_match = re.match(r'(\s*)(\s+)(\w+\<*\w*\>*)(\s*\**\s*)(\w+)', line)
271
272 if field_match:
273 type = field_match.group(3)
274 name = field_match.group(5)
275 elif is_const:
276 field_match = re.match(r'(\s*)(\w+\<*\w*\>*)(\s+)(\w+)(\s*)(\w+)', line)
277
278 if field_match:
279 type = field_match.group(4)
280 name = field_match.group(6)
281 else:
282 if is_scoped:
283 field_match = re.match(r'\s*(\w+\<*\w*\>*)\s*::\s*(\w+\<*\w*\>*)\s+(\w+)', line)
284
285 if field_match:
286 type = field_match.group(1) + '::' + field_match.group(2)
287 name = field_match.group(3)
288 else:
289 field_match = re.match(r'(\s*)(\w+\<*\w*\>*)(\s+)(\w+)', line)
290
291 if field_match:
292 type = field_match.group(2)
293 name = field_match.group(4)
294
295 if is_llvm_typedef is False:
296 if type is not None:
297 type_entry['members'].append(
298 gen_llvm_type(
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))
301
302 # Detect end of structure
303 end_of_struct = re.match(r'(\s*)};', line)
304
305 if end_of_struct:
306 types.append(type_entry)
307
308 cur_dir = os.path.dirname(os.path.abspath(__file__))
309 template = os.path.join(cur_dir, 'templates', 'gen_llvm.hpp')
310
311 MakoTemplateWriter.to_file(
312 template,
313 output_file,
314 cmdline=sys.argv,
315 filename=os.path.basename(output_file),
316 types=types,
317 input_dir=os.path.dirname(input_file.name),
318 input_file=os.path.basename(input_file.name))
319
320 '''
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
323 to behave
324 '''
325 def main():
326
327 # Parse args...
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()
334
335 gen_llvm_types(args.input, args.output)
336
337 if __name__ == '__main__':
338 main()
339 # END OF FILE