swr: [rasterizer jitter] fixes for icc in vs2015 compat mode
[mesa.git] / src / gallium / drivers / swr / rasterizer / jitter / scripts / gen_llvm_ir_macros.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 * Copyright (C) 2014-2016 Intel Corporation. All Rights Reserved.
31 *
32 * Permission is hereby granted, free of charge, to any person obtaining a
33 * copy of this software and associated documentation files (the "Software"),
34 * to deal in the Software without restriction, including without limitation
35 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
36 * and/or sell copies of the Software, and to permit persons to whom the
37 * Software is furnished to do so, subject to the following conditions:
38 *
39 * The above copyright notice and this permission notice (including the next
40 * paragraph) shall be included in all copies or substantial portions of the
41 * Software.
42 *
43 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
44 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
45 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
46 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
47 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
48 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
49 * IN THE SOFTWARE.
50 *
51 * @file %s
52 *
53 * @brief auto-generated file
54 *
55 * DO NOT EDIT
56 *
57 ******************************************************************************/
58
59 """
60
61 """
62 """
63 def gen_file_header(filename):
64 global header
65 headerStr = header % filename
66 return headerStr.splitlines()
67
68
69 inst_aliases = {
70 'SHUFFLE_VECTOR': 'VSHUFFLE',
71 'INSERT_ELEMENT': 'VINSERT',
72 'EXTRACT_ELEMENT': 'VEXTRACT',
73 'MEM_SET': 'MEMSET',
74 'MEM_CPY': 'MEMCOPY',
75 'MEM_MOVE': 'MEMMOVE',
76 'L_SHR': 'LSHR',
77 'A_SHR': 'ASHR',
78 'BIT_CAST': 'BITCAST',
79 'U_DIV': 'UDIV',
80 'S_DIV': 'SDIV',
81 'U_REM': 'UREM',
82 'S_REM': 'SREM',
83 'BIN_OP': 'BINOP',
84 }
85
86 intrinsics = [
87 ["VGATHERPS", "x86_avx2_gather_d_ps_256", ["src", "pBase", "indices", "mask", "scale"]],
88 ["VGATHERDD", "x86_avx2_gather_d_d_256", ["src", "pBase", "indices", "mask", "scale"]],
89 ["VSQRTPS", "x86_avx_sqrt_ps_256", ["a"]],
90 ["VRSQRTPS", "x86_avx_rsqrt_ps_256", ["a"]],
91 ["VRCPPS", "x86_avx_rcp_ps_256", ["a"]],
92 ["VMINPS", "x86_avx_min_ps_256", ["a", "b"]],
93 ["VMAXPS", "x86_avx_max_ps_256", ["a", "b"]],
94 ["VROUND", "x86_avx_round_ps_256", ["a", "rounding"]],
95 ["VCMPPS", "x86_avx_cmp_ps_256", ["a", "b", "cmpop"]],
96 ["VBLENDVPS", "x86_avx_blendv_ps_256", ["a", "b", "mask"]],
97 ["BEXTR_32", "x86_bmi_bextr_32", ["src", "control"]],
98 ["VMASKLOADD", "x86_avx2_maskload_d_256", ["src", "mask"]],
99 ["VMASKMOVPS", "x86_avx_maskload_ps_256", ["src", "mask"]],
100 ["VMASKSTOREPS", "x86_avx_maskstore_ps_256", ["src", "mask", "val"]],
101 ["VPSHUFB", "x86_avx2_pshuf_b", ["a", "b"]],
102 ["VPERMD", "x86_avx2_permd", ["a", "idx"]],
103 ["VPERMPS", "x86_avx2_permps", ["idx", "a"]],
104 ["VCVTPH2PS", "x86_vcvtph2ps_256", ["a"]],
105 ["VCVTPS2PH", "x86_vcvtps2ph_256", ["a", "round"]],
106 ["VHSUBPS", "x86_avx_hsub_ps_256", ["a", "b"]],
107 ["VPTESTC", "x86_avx_ptestc_256", ["a", "b"]],
108 ["VPTESTZ", "x86_avx_ptestz_256", ["a", "b"]],
109 ["VFMADDPS", "x86_fma_vfmadd_ps_256", ["a", "b", "c"]],
110 ["VMOVMSKPS", "x86_avx_movmsk_ps_256", ["a"]],
111 ["INTERRUPT", "x86_int", ["a"]],
112 ]
113
114 def convert_uppercamel(name):
115 s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
116 return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).upper()
117
118 """
119 Given an input file (e.g. IRBuilder.h) generates function dictionary.
120 """
121 def parse_ir_builder(input_file):
122
123 functions = []
124
125 lines = input_file.readlines()
126
127 idx = 0
128 while idx < len(lines) - 1:
129 line = lines[idx].rstrip()
130 idx += 1
131
132 #match = re.search(r"\*Create", line)
133 match = re.search(r"[\*\s]Create(\w*)\(", line)
134 if match is not None:
135 #print("Line: %s" % match.group(1))
136
137 if re.search(r"^\s*Create", line) is not None:
138 func_sig = lines[idx-2].rstrip() + line
139 else:
140 func_sig = line
141
142 end_of_args = False
143 while not end_of_args:
144 end_paren = re.search(r"\)", line)
145 if end_paren is not None:
146 end_of_args = True
147 else:
148 line = lines[idx].rstrip()
149 func_sig += line
150 idx += 1
151
152 delfunc = re.search(r"LLVM_DELETED_FUNCTION|= delete;", func_sig)
153
154 if not delfunc:
155 func = re.search(r"(.*?)\*[\n\s]*(Create\w*)\((.*?)\)", func_sig)
156 if func is not None:
157
158 return_type = func.group(1).lstrip() + '*'
159 func_name = func.group(2)
160 arguments = func.group(3)
161
162 func_args = ''
163 func_args_nodefs = ''
164
165 num_args = arguments.count(',')
166
167 arg_names = []
168 num_args = 0
169 args = arguments.split(',')
170 for arg in args:
171 arg = arg.lstrip()
172 if arg:
173 if num_args > 0:
174 func_args += ', '
175 func_args_nodefs += ', '
176 func_args += arg
177 func_args_nodefs += arg.split(' =')[0]
178
179 split_args = arg.split('=')
180 arg_name = split_args[0].rsplit(None, 1)[-1]
181
182 #print("Before ArgName = %s" % arg_name)
183
184 reg_arg = re.search(r"[\&\*]*(\w*)", arg_name)
185 if reg_arg:
186 #print("Arg Name = %s" % reg_arg.group(1))
187 arg_names += [reg_arg.group(1)]
188
189 num_args += 1
190
191 ignore = False
192
193 # The following functions need to be ignored.
194 if func_name == 'CreateInsertNUWNSWBinOp':
195 ignore = True
196
197 if func_name == 'CreateMaskedIntrinsic':
198 ignore = True
199
200 # Convert CamelCase to CAMEL_CASE
201 func_mod = re.search(r"Create(\w*)", func_name)
202 if func_mod:
203 func_mod = func_mod.group(1)
204 func_mod = convert_uppercamel(func_mod)
205 if func_mod[0:2] == 'F_' or func_mod[0:2] == 'I_':
206 func_mod = func_mod[0] + func_mod[2:]
207
208 # Substitute alias based on CAMEL_CASE name.
209 func_alias = inst_aliases.get(func_mod)
210 if not func_alias:
211 func_alias = func_mod
212
213 if func_name == 'CreateCall' or func_name == 'CreateGEP':
214 arglist = re.search(r'ArrayRef', func_args)
215 if arglist:
216 func_alias = func_alias + 'A'
217
218 if not ignore:
219 functions.append({
220 "name": func_name,
221 "alias": func_alias,
222 "return": return_type,
223 "args": func_args,
224 "args_nodefs": func_args_nodefs,
225 "arg_names": arg_names
226 })
227
228 return functions
229
230 """
231 Auto-generates macros for LLVM IR
232 """
233 def generate_gen_h(functions, output_file):
234 output_lines = gen_file_header(os.path.basename(output_file.name))
235
236 output_lines += [
237 '#pragma once',
238 '',
239 '//////////////////////////////////////////////////////////////////////////',
240 '/// Auto-generated Builder IR declarations',
241 '//////////////////////////////////////////////////////////////////////////',
242 ]
243
244 for func in functions:
245 name = func['name']
246 if func['alias']:
247 name = func['alias']
248 output_lines += [
249 '%s%s(%s);' % (func['return'], name, func['args'])
250 ]
251
252 output_file.write('\n'.join(output_lines) + '\n')
253
254 """
255 Auto-generates macros for LLVM IR
256 """
257 def generate_gen_cpp(functions, output_file):
258 output_lines = gen_file_header(os.path.basename(output_file.name))
259
260 output_lines += [
261 '#include \"builder.h\"',
262 '',
263 'namespace SwrJit',
264 '{',
265 ' using namespace llvm;',
266 '',
267 ]
268
269 for func in functions:
270 name = func['name']
271 if func['alias']:
272 name = func['alias']
273
274 args = func['arg_names']
275 func_args = ''
276 first_arg = True
277 for arg in args:
278 if not first_arg:
279 func_args += ', '
280 func_args += arg
281 first_arg = False
282
283 output_lines += [
284 ' //////////////////////////////////////////////////////////////////////////',
285 ' %sBuilder::%s(%s)' % (func['return'], name, func['args_nodefs']),
286 ' {',
287 ' return IRB()->%s(%s);' % (func['name'], func_args),
288 ' }',
289 '',
290 ]
291 output_lines.append('}')
292 output_file.write('\n'.join(output_lines) + '\n')
293
294 """
295 Auto-generates macros for LLVM IR
296 """
297 def generate_x86_h(output_file):
298 output_lines = gen_file_header(os.path.basename(output_file.name))
299
300 output_lines += [
301 '#pragma once',
302 '',
303 '//////////////////////////////////////////////////////////////////////////',
304 '/// Auto-generated x86 intrinsics',
305 '//////////////////////////////////////////////////////////////////////////',
306 ]
307
308 for inst in intrinsics:
309 #print("Inst: %s, x86: %s numArgs: %d" % (inst[0], inst[1], len(inst[2])))
310
311 args = ''
312 first = True
313 for arg in inst[2]:
314 if not first:
315 args += ', '
316 args += ("Value* %s" % arg)
317 first = False
318
319 output_lines += [
320 'Value *%s(%s);' % (inst[0], args)
321 ]
322
323 output_file.write('\n'.join(output_lines) + '\n')
324
325 """
326 Auto-generates macros for LLVM IR
327 """
328 def generate_x86_cpp(output_file):
329 output_lines = gen_file_header(os.path.basename(output_file.name))
330
331 output_lines += [
332 '#include \"builder.h\"',
333 '',
334 'namespace SwrJit',
335 '{',
336 ' using namespace llvm;',
337 '',
338 ]
339
340 for inst in intrinsics:
341 #print("Inst: %s, x86: %s numArgs: %d" % (inst[0], inst[1], len(inst[2])))
342
343 args = ''
344 pass_args = ''
345 first = True
346 for arg in inst[2]:
347 if not first:
348 args += ', '
349 pass_args += ', '
350 args += ("Value* %s" % arg)
351 pass_args += arg
352 first = False
353
354 output_lines += [
355 ' //////////////////////////////////////////////////////////////////////////',
356 ' Value *Builder::%s(%s)' % (inst[0], args),
357 ' {',
358 ' Function *func = Intrinsic::getDeclaration(JM()->mpCurrentModule, Intrinsic::%s);' % inst[1],
359 ]
360 if inst[0] == "VPERMD":
361 rev_args = ''
362 first = True
363 for arg in reversed(inst[2]):
364 if not first:
365 rev_args += ', '
366 rev_args += arg
367 first = False
368
369 output_lines += [
370 '#if (HAVE_LLVM == 0x306) && (LLVM_VERSION_PATCH == 0)',
371 ' return CALL(func, std::initializer_list<Value*>{%s});' % rev_args,
372 '#else',
373 ]
374 output_lines += [
375 ' return CALL(func, std::initializer_list<Value*>{%s});' % pass_args,
376 ]
377 if inst[0] == "VPERMD":
378 output_lines += [
379 '#endif',
380 ]
381 output_lines += [
382 ' }',
383 '',
384 ]
385
386 output_lines.append('}')
387 output_file.write('\n'.join(output_lines) + '\n')
388
389 """
390 Function which is invoked when this script is started from a command line.
391 Will present and consume a set of arguments which will tell this script how
392 to behave
393 """
394 def main():
395
396 # Parse args...
397 parser = argparse.ArgumentParser()
398 parser.add_argument("--input", "-i", type=argparse.FileType('r'), help="Path to IRBuilder.h", required=False)
399 parser.add_argument("--output", "-o", type=argparse.FileType('w'), help="Path to output file", required=True)
400 parser.add_argument("--gen_h", "-gen_h", help="Generate builder_gen.h", action="store_true", default=False)
401 parser.add_argument("--gen_cpp", "-gen_cpp", help="Generate builder_gen.cpp", action="store_true", default=False)
402 parser.add_argument("--gen_x86_h", "-gen_x86_h", help="Generate x86 intrinsics. No input is needed.", action="store_true", default=False)
403 parser.add_argument("--gen_x86_cpp", "-gen_x86_cpp", help="Generate x86 intrinsics. No input is needed.", action="store_true", default=False)
404 args = parser.parse_args()
405
406 if args.input:
407 functions = parse_ir_builder(args.input)
408
409 if args.gen_h:
410 generate_gen_h(functions, args.output)
411
412 if args.gen_cpp:
413 generate_gen_cpp(functions, args.output)
414 else:
415 if args.gen_x86_h:
416 generate_x86_h(args.output)
417
418 if args.gen_x86_cpp:
419 generate_x86_cpp(args.output)
420
421 if args.gen_h:
422 print("Need to specify --input for --gen_h!")
423
424 if args.gen_cpp:
425 print("Need to specify --input for --gen_cpp!")
426
427 if __name__ == '__main__':
428 main()
429 # END OF FILE