2 # Copyright © 2017 Intel Corporation
4 # Permission is hereby granted, free of charge, to any person obtaining a copy
5 # of this software and associated documentation files (the "Software"), to deal
6 # in the Software without restriction, including without limitation the rights
7 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 # copies of the Software, and to permit persons to whom the Software is
9 # furnished to do so, subject to the following conditions:
11 # The above copyright notice and this permission notice shall be included in
12 # all copies or substantial portions of the Software.
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 THE
17 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 from __future__
import (
23 absolute_import
, division
, print_function
, unicode_literals
29 import xml
.parsers
.expat
31 from mako
.template
import Template
33 TEMPLATE
= Template("""\
35 from operator import itemgetter
38 * Copyright © 2017 Intel Corporation
40 * Permission is hereby granted, free of charge, to any person obtaining a
41 * copy of this software and associated documentation files (the "Software"),
42 * to deal in the Software without restriction, including without limitation
43 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
44 * and/or sell copies of the Software, and to permit persons to whom the
45 * Software is furnished to do so, subject to the following conditions:
47 * The above copyright notice and this permission notice (including the next
48 * paragraph) shall be included in all copies or substantial portions of the
51 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
52 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
53 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
54 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
55 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
56 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
60 /* THIS FILE HAS BEEN GENERATED, DO NOT HAND EDIT.
62 * Sizes of bitfields in genxml instructions, structures, and registers.
70 #include "common/gen_device_info.h"
71 #include "util/macros.h"
76 % for _, field in sorted(fields.iteritems(), key=itemgetter(0)):
78 /* ${field.container_name}::${field.name} */
79 % for gen, bits in sorted(field.bits_by_gen.iteritems(), reverse=True):
80 #define ${gen.prefix(field.token_name, padded=True)} ${bits}
83 static inline uint32_t ATTRIBUTE_PURE
84 ${field.token_name}(const struct gen_device_info *devinfo)
86 switch (devinfo->gen) {
87 case 9: return ${field.bits(9)};
88 case 8: return ${field.bits(8)};
90 if (devinfo->is_haswell) {
91 return ${field.bits(7.5)};
93 return ${field.bits(7)};
95 case 6: return ${field.bits(6)};
96 case 5: return ${field.bits(5)};
98 if (devinfo->is_g4x) {
99 return ${field.bits(4.5)};
101 return ${field.bits(4)};
104 unreachable("Invalid hardware generation");
113 #endif /* ${guard} */""", output_encoding
='utf-8')
115 def to_alphanum(name
):
138 for i
, j
in substitutions
.items():
139 name
= name
.replace(i
, j
)
144 name
= to_alphanum(name
)
145 if not name
[0].isalpha():
151 def __init__(self
, z
):
152 # Convert potential "major.minor" string
158 def __lt__(self
, other
):
159 return self
.tenx
< other
.tenx
162 return hash(self
.tenx
)
164 def __eq__(self
, other
):
165 return self
.tenx
== other
.tenx
167 def prefix(self
, token
, padded
=False):
179 return 'GEN{}_{}{}'.format(gen
, token
, pad
)
183 def __init__(self
, container_name
, name
):
184 self
.container_name
= container_name
186 self
.token_name
= safe_name('_'.join([self
.container_name
, self
.name
, 'bits']))
187 self
.bits_by_gen
= {}
189 def add_gen(self
, gen
, xml_attrs
):
190 assert isinstance(gen
, Gen
)
191 start
= int(xml_attrs
['start'])
192 end
= int(xml_attrs
['end'])
193 self
.bits_by_gen
[gen
] = 1 + end
- start
196 if not isinstance(gen
, Gen
):
198 return self
.bits_by_gen
.get(gen
, 0)
200 class XmlParser(object):
202 def __init__(self
, fields
):
203 self
.parser
= xml
.parsers
.expat
.ParserCreate()
204 self
.parser
.StartElementHandler
= self
.start_element
205 self
.parser
.EndElementHandler
= self
.end_element
208 self
.container_name
= None
211 def parse(self
, filename
):
212 with
open(filename
) as f
:
213 self
.parser
.ParseFile(f
)
215 def start_element(self
, name
, attrs
):
217 self
.gen
= Gen(attrs
['gen'])
218 elif name
in ('instruction', 'struct', 'register'):
219 self
.start_container(attrs
)
220 elif name
== 'field':
221 self
.start_field(attrs
)
225 def end_element(self
, name
):
228 elif name
in ('instruction', 'struct', 'register'):
229 self
.container_name
= None
233 def start_container(self
, attrs
):
234 assert self
.container_name
is None
235 self
.container_name
= attrs
['name']
237 def start_field(self
, attrs
):
238 if self
.container_name
is None:
241 field_name
= attrs
.get('name', None)
245 key
= (self
.container_name
, field_name
)
246 if key
not in self
.fields
:
247 self
.fields
[key
] = Field(self
.container_name
, field_name
)
248 self
.fields
[key
].add_gen(self
.gen
, attrs
)
251 p
= argparse
.ArgumentParser()
252 p
.add_argument('-o', '--output', type=str,
253 help="If OUTPUT is unset or '-', then it defaults to '/dev/stdout'")
254 p
.add_argument('--cpp-guard', type=str,
255 help='If unset, then CPP_GUARD is derived from OUTPUT.')
256 p
.add_argument('xml_sources', metavar
='XML_SOURCE', nargs
='+')
258 pargs
= p
.parse_args()
260 if pargs
.output
in (None, '-'):
261 pargs
.output
= '/dev/stdout'
263 if pargs
.cpp_guard
is None:
264 pargs
.cpp_guard
= os
.path
.basename(pargs
.output
).upper().replace('.', '_')
271 # Maps (container_name, field_name) => Field
274 for source
in pargs
.xml_sources
:
275 XmlParser(fields
).parse(source
)
277 with
open(pargs
.output
, 'wb') as f
:
278 f
.write(TEMPLATE
.render(fields
=fields
, guard
=pargs
.cpp_guard
))
280 if __name__
== '__main__':