gallium/swr: Fix vcvtph2ps llvm intrinsic compile error
[mesa.git] / src / gallium / drivers / swr / rasterizer / codegen / gen_common.py
1 # Copyright (C) 2014-2018 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 # Python source
23 from __future__ import print_function
24 import os
25 import errno
26 import sys
27 import argparse
28 import tempfile
29 import filecmp
30 import shutil
31 from mako.template import Template
32 from mako.exceptions import RichTraceback
33
34 #==============================================================================
35 def ConcatLists(list_of_lists):
36 output = []
37 for l in list_of_lists: output += l
38 return output
39
40 #==============================================================================
41 def MakeTmpDir(suffix=''):
42 '''
43 Create temporary directory for use in codegen scripts.
44 '''
45 return tempfile.mkdtemp(suffix)
46
47 #==============================================================================
48 def MakeDir(dir_path):
49 '''
50 Create a directory if it doesn't exist
51
52 returns 0 on success, non-zero on failure
53 '''
54 dir_path = os.path.abspath(dir_path)
55
56 if not os.path.exists(dir_path):
57 try:
58 os.makedirs(dir_path)
59 except OSError as err:
60 if err.errno != errno.EEXIST:
61 return 1
62 else:
63 if not os.path.isdir(dir_path):
64 return 1
65
66 return 0
67
68 #==============================================================================
69 def DeleteDirTree(dir_path):
70 '''
71 Delete directory tree.
72
73 returns 0 on success, non-zero on failure
74 '''
75 rval = 0
76 try:
77 shutil.rmtree(dir_path, False)
78 except:
79 rval = 1
80 return rval
81
82 #==============================================================================
83 def CopyFileIfDifferent(src, dst, verbose = False):
84 '''
85 Copy <src> file to <dst> file if the <dst>
86 file either doesn't contain the file or the file
87 contents are different.
88
89 returns 0 on success, non-zero on failure
90 '''
91
92 assert os.path.isfile(src)
93 assert (False == os.path.exists(dst) or os.path.isfile(dst))
94
95 need_copy = not os.path.exists(dst)
96 if not need_copy:
97 need_copy = not filecmp.cmp(src, dst)
98
99 if need_copy:
100 try:
101 shutil.copy2(src, dst)
102 except:
103 print('ERROR: Could not copy %s to %s' % (src, dst), file=sys.stderr)
104 return 1
105
106 if verbose:
107 print(src, '-->', dst)
108
109 return 0
110
111 #==============================================================================
112 def CopyDirFilesIfDifferent(src, dst, recurse = True, verbose = False, orig_dst = None):
113 '''
114 Copy files <src> directory to <dst> directory if the <dst>
115 directory either doesn't contain the file or the file
116 contents are different.
117
118 Optionally recurses into subdirectories
119
120 returns 0 on success, non-zero on failure
121 '''
122
123 assert os.path.isdir(src)
124 assert os.path.isdir(dst)
125
126 src = os.path.abspath(src)
127 dst = os.path.abspath(dst)
128
129 if not orig_dst:
130 orig_dst = dst
131
132 for f in os.listdir(src):
133 src_path = os.path.join(src, f)
134 dst_path = os.path.join(dst, f)
135
136 # prevent recursion
137 if src_path == orig_dst:
138 continue
139
140 if os.path.isdir(src_path):
141 if recurse:
142 if MakeDir(dst_path):
143 print('ERROR: Could not create directory:', dst_path, file=sys.stderr)
144 return 1
145
146 if verbose:
147 print('mkdir', dst_path)
148 rval = CopyDirFilesIfDifferent(src_path, dst_path, recurse, verbose, orig_dst)
149 else:
150 rval = CopyFileIfDifferent(src_path, dst_path, verbose)
151
152 if rval:
153 return rval
154
155 return 0
156
157 #==============================================================================
158 class MakoTemplateWriter:
159 '''
160 MakoTemplateWriter - Class (namespace) for functions to generate strings
161 or files using the Mako template module.
162
163 See http://docs.makotemplates.org/en/latest/ for
164 mako documentation.
165 '''
166
167 @staticmethod
168 def to_string(template_filename, **kwargs):
169 '''
170 Write template data to a string object and return the string
171 '''
172 from mako.template import Template
173 from mako.exceptions import RichTraceback
174
175 try:
176 template = Template(filename=template_filename)
177 # Split + Join fixes line-endings for whatever platform you are using
178 return '\n'.join(template.render(**kwargs).splitlines())
179 except:
180 traceback = RichTraceback()
181 for (filename, lineno, function, line) in traceback.traceback:
182 print('File %s, line %s, in %s' % (filename, lineno, function))
183 print(line, '\n')
184 print('%s: %s' % (str(traceback.error.__class__.__name__), traceback.error))
185 raise
186
187 @staticmethod
188 def to_file(template_filename, output_filename, **kwargs):
189 '''
190 Write template data to a file
191 '''
192 if MakeDir(os.path.dirname(output_filename)):
193 return 1
194 with open(output_filename, 'w') as outfile:
195 print(MakoTemplateWriter.to_string(template_filename, **kwargs), file=outfile)
196 return 0
197
198
199 #==============================================================================
200 class ArgumentParser(argparse.ArgumentParser):
201 '''
202 Subclass of argparse.ArgumentParser
203
204 Allow parsing from command files that start with @
205 Example:
206 >bt run @myargs.txt
207
208 Contents of myargs.txt:
209 -m <machine>
210 --target cdv_win7
211
212 The below function allows multiple args to be placed on the same text-file line.
213 The default is one token per line, which is a little cumbersome.
214
215 Also allow all characters after a '#' character to be ignored.
216 '''
217
218 #==============================================================================
219 class _HelpFormatter(argparse.RawTextHelpFormatter):
220 ''' Better help formatter for argument parser '''
221
222 def _split_lines(self, text, width):
223 ''' optimized split lines algorighm, indents split lines '''
224 lines = text.splitlines()
225 out_lines = []
226 if len(lines):
227 out_lines.append(lines[0])
228 for line in lines[1:]:
229 out_lines.append(' ' + line)
230 return out_lines
231
232 #==============================================================================
233 def __init__(self, *args, **kwargs):
234 ''' Constructor. Compatible with argparse.ArgumentParser(),
235 but with some modifications for better usage and help display.
236 '''
237 super(ArgumentParser, self).__init__(
238 *args,
239 fromfile_prefix_chars='@',
240 formatter_class=ArgumentParser._HelpFormatter,
241 **kwargs)
242
243 #==========================================================================
244 def convert_arg_line_to_args(self, arg_line):
245 ''' convert one line of parsed file to arguments '''
246 arg_line = arg_line.split('#', 1)[0]
247 if sys.platform == 'win32':
248 arg_line = arg_line.replace('\\', '\\\\')
249 for arg in shlex.split(arg_line):
250 if not arg.strip():
251 continue
252 yield arg
253
254 #==========================================================================
255 def _read_args_from_files(self, arg_strings):
256 ''' read arguments from files '''
257 # expand arguments referencing files
258 new_arg_strings = []
259 for arg_string in arg_strings:
260
261 # for regular arguments, just add them back into the list
262 if arg_string[0] not in self.fromfile_prefix_chars:
263 new_arg_strings.append(arg_string)
264
265 # replace arguments referencing files with the file content
266 else:
267 filename = arg_string[1:]
268
269 # Search in sys.path
270 if not os.path.exists(filename):
271 for path in sys.path:
272 filename = os.path.join(path, arg_string[1:])
273 if os.path.exists(filename):
274 break
275
276 try:
277 args_file = open(filename)
278 try:
279 arg_strings = []
280 for arg_line in args_file.read().splitlines():
281 for arg in self.convert_arg_line_to_args(arg_line):
282 arg_strings.append(arg)
283 arg_strings = self._read_args_from_files(arg_strings)
284 new_arg_strings.extend(arg_strings)
285 finally:
286 args_file.close()
287 except IOError:
288 err = sys.exc_info()[1]
289 self.error(str(err))
290
291 # return the modified argument list
292 return new_arg_strings