swr/rast: SIMD16 Fetch - Fully widen 32-bit float vertex components
[mesa.git] / src / gallium / drivers / swr / rasterizer / codegen / gen_llvm_ir_macros.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 inst_aliases = {
28 'SHUFFLE_VECTOR': 'VSHUFFLE',
29 'INSERT_ELEMENT': 'VINSERT',
30 'EXTRACT_ELEMENT': 'VEXTRACT',
31 'MEM_SET': 'MEMSET',
32 'MEM_CPY': 'MEMCOPY',
33 'MEM_MOVE': 'MEMMOVE',
34 'L_SHR': 'LSHR',
35 'A_SHR': 'ASHR',
36 'BIT_CAST': 'BITCAST',
37 'U_DIV': 'UDIV',
38 'S_DIV': 'SDIV',
39 'U_REM': 'UREM',
40 'S_REM': 'SREM',
41 'BIN_OP': 'BINOP',
42 }
43
44 intrinsics = [
45 ['VGATHERPD', 'x86_avx2_gather_d_pd_256', ['src', 'pBase', 'indices', 'mask', 'scale']],
46 ['VGATHERPS', 'x86_avx2_gather_d_ps_256', ['src', 'pBase', 'indices', 'mask', 'scale']],
47 ['VGATHERPS_16', 'x86_avx512_gather_dps_512', ['src', 'pBase', 'indices', 'mask', 'scale']],
48 ['VGATHERDD', 'x86_avx2_gather_d_d_256', ['src', 'pBase', 'indices', 'mask', 'scale']],
49 ['VPSRLI', 'x86_avx2_psrli_d', ['src', 'imm']],
50 ['VPSRLI_16', 'x86_avx512_psrli_d_512', ['src', 'imm']],
51 ['VSQRTPS', 'x86_avx_sqrt_ps_256', ['a']],
52 ['VRSQRTPS', 'x86_avx_rsqrt_ps_256', ['a']],
53 ['VRCPPS', 'x86_avx_rcp_ps_256', ['a']],
54 ['VMINPS', 'x86_avx_min_ps_256', ['a', 'b']],
55 ['VMAXPS', 'x86_avx_max_ps_256', ['a', 'b']],
56 ['VROUND', 'x86_avx_round_ps_256', ['a', 'rounding']],
57 ['VCMPPS', 'x86_avx_cmp_ps_256', ['a', 'b', 'cmpop']],
58 ['VBLENDVPS', 'x86_avx_blendv_ps_256', ['a', 'b', 'mask']],
59 ['BEXTR_32', 'x86_bmi_bextr_32', ['src', 'control']],
60 ['VMASKLOADD', 'x86_avx2_maskload_d_256', ['src', 'mask']],
61 ['VMASKMOVPS', 'x86_avx_maskload_ps_256', ['src', 'mask']],
62 ['VMASKSTOREPS', 'x86_avx_maskstore_ps_256', ['src', 'mask', 'val']],
63 ['VPSHUFB', 'x86_avx2_pshuf_b', ['a', 'b']],
64 ['VPERMD', 'x86_avx2_permd', ['a', 'idx']],
65 ['VPERMPS', 'x86_avx2_permps', ['idx', 'a']],
66 ['VCVTPD2PS', 'x86_avx_cvt_pd2_ps_256', ['a']],
67 ['VCVTPH2PS', 'x86_vcvtph2ps_256', ['a']],
68 ['VCVTPS2PH', 'x86_vcvtps2ph_256', ['a', 'round']],
69 ['VHSUBPS', 'x86_avx_hsub_ps_256', ['a', 'b']],
70 ['VPTESTC', 'x86_avx_ptestc_256', ['a', 'b']],
71 ['VPTESTZ', 'x86_avx_ptestz_256', ['a', 'b']],
72 ['VFMADDPS', 'x86_fma_vfmadd_ps_256', ['a', 'b', 'c']],
73 ['VMOVMSKPS', 'x86_avx_movmsk_ps_256', ['a']],
74 ['INTERRUPT', 'x86_int', ['a']],
75 ]
76
77 this_dir = os.path.dirname(os.path.abspath(__file__))
78 template = os.path.join(this_dir, 'templates', 'gen_builder.hpp')
79
80 def convert_uppercamel(name):
81 s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
82 return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).upper()
83
84 '''
85 Given an input file (e.g. IRBuilder.h) generates function dictionary.
86 '''
87 def parse_ir_builder(input_file):
88
89 functions = []
90
91 lines = input_file.readlines()
92
93 idx = 0
94 while idx < len(lines) - 1:
95 line = lines[idx].rstrip()
96 idx += 1
97
98 #match = re.search(r'\*Create', line)
99 match = re.search(r'[\*\s]Create(\w*)\(', line)
100 if match is not None:
101 #print('Line: %s' % match.group(1))
102
103 if re.search(r'^\s*Create', line) is not None:
104 func_sig = lines[idx-2].rstrip() + line
105 else:
106 func_sig = line
107
108 end_of_args = False
109 while not end_of_args:
110 end_paren = re.search(r'\)', line)
111 if end_paren is not None:
112 end_of_args = True
113 else:
114 line = lines[idx].rstrip()
115 func_sig += line
116 idx += 1
117
118 delfunc = re.search(r'LLVM_DELETED_FUNCTION|= delete;', func_sig)
119
120 if not delfunc:
121 func = re.search(r'(.*?)\*[\n\s]*(Create\w*)\((.*?)\)', func_sig)
122 if func is not None:
123
124 return_type = func.group(1).strip() + '*'
125 func_name = func.group(2)
126 arguments = func.group(3)
127
128 func_args = []
129 arg_names = []
130 args = arguments.split(',')
131 for arg in args:
132 arg = arg.strip()
133 if arg:
134 func_args.append(arg)
135
136 split_args = arg.split('=')
137 arg_name = split_args[0].rsplit(None, 1)[-1]
138
139 reg_arg = re.search(r'[\&\*]*(\w*)', arg_name)
140 if reg_arg:
141 arg_names += [reg_arg.group(1)]
142
143 ignore = False
144
145 # The following functions need to be ignored in openswr.
146 # API change in llvm-5.0 breaks baked autogen files
147 if (
148 (func_name == 'CreateFence' or
149 func_name == 'CreateAtomicCmpXchg' or
150 func_name == 'CreateAtomicRMW')):
151 ignore = True
152
153 # The following functions need to be ignored.
154 if (func_name == 'CreateInsertNUWNSWBinOp' or
155 func_name == 'CreateMaskedIntrinsic' or
156 func_name == 'CreateAlignmentAssumptionHelper'):
157 ignore = True
158
159 # Convert CamelCase to CAMEL_CASE
160 func_mod = re.search(r'Create(\w*)', func_name)
161 if func_mod:
162 func_mod = func_mod.group(1)
163 func_mod = convert_uppercamel(func_mod)
164 if func_mod[0:2] == 'F_' or func_mod[0:2] == 'I_':
165 func_mod = func_mod[0] + func_mod[2:]
166
167 # Substitute alias based on CAMEL_CASE name.
168 func_alias = inst_aliases.get(func_mod)
169 if not func_alias:
170 func_alias = func_mod
171
172 if func_name == 'CreateCall' or func_name == 'CreateGEP':
173 arglist = re.search(r'ArrayRef', ', '.join(func_args))
174 if arglist:
175 func_alias = func_alias + 'A'
176
177 if not ignore:
178 functions.append({
179 'name' : func_name,
180 'alias' : func_alias,
181 'return' : return_type,
182 'args' : ', '.join(func_args),
183 'arg_names' : arg_names,
184 })
185
186 return functions
187
188 '''
189 Auto-generates macros for LLVM IR
190 '''
191 def generate_gen_h(functions, output_dir):
192 filename = 'gen_builder.hpp'
193 output_filename = os.path.join(output_dir, filename)
194
195 templfuncs = []
196 for func in functions:
197 decl = '%s %s(%s)' % (func['return'], func['alias'], func['args'])
198
199 templfuncs.append({
200 'decl' : decl,
201 'intrin' : func['name'],
202 'args' : ', '.join(func['arg_names']),
203 })
204
205 MakoTemplateWriter.to_file(
206 template,
207 output_filename,
208 cmdline=sys.argv,
209 comment='Builder IR Wrappers',
210 filename=filename,
211 functions=templfuncs,
212 isX86=False)
213
214 '''
215 Auto-generates macros for LLVM IR
216 '''
217 def generate_x86_h(output_dir):
218 filename = 'gen_builder_x86.hpp'
219 output_filename = os.path.join(output_dir, filename)
220
221 functions = []
222 for inst in intrinsics:
223 #print('Inst: %s, x86: %s numArgs: %d' % (inst[0], inst[1], len(inst[2])))
224 declargs = 'Value* ' + ', Value* '.join(inst[2])
225
226 functions.append({
227 'decl' : 'Value* %s(%s)' % (inst[0], declargs),
228 'args' : ', '.join(inst[2]),
229 'intrin' : inst[1],
230 })
231
232 MakoTemplateWriter.to_file(
233 template,
234 output_filename,
235 cmdline=sys.argv,
236 comment='x86 intrinsics',
237 filename=filename,
238 functions=functions,
239 isX86=True)
240
241 '''
242 Function which is invoked when this script is started from a command line.
243 Will present and consume a set of arguments which will tell this script how
244 to behave
245 '''
246 def main():
247
248 # Parse args...
249 parser = ArgumentParser()
250 parser.add_argument('--input', '-i', type=FileType('r'), help='Path to IRBuilder.h', required=False)
251 parser.add_argument('--output-dir', '-o', action='store', dest='output', help='Path to output directory', required=True)
252 parser.add_argument('--gen_h', help='Generate builder_gen.h', action='store_true', default=False)
253 parser.add_argument('--gen_x86_h', help='Generate x86 intrinsics. No input is needed.', action='store_true', default=False)
254 args = parser.parse_args()
255
256 if not os.path.exists(args.output):
257 os.makedirs(args.output)
258
259 if args.input:
260 functions = parse_ir_builder(args.input)
261
262 if args.gen_h:
263 generate_gen_h(functions, args.output)
264
265 elif args.gen_h:
266 print('Need to specify --input for --gen_h!')
267
268 if args.gen_x86_h:
269 generate_x86_h(args.output)
270
271 if __name__ == '__main__':
272 main()
273 # END OF FILE