1bf215546Sopenharmony_ci#encoding=utf-8 2bf215546Sopenharmony_ci# Copyright © 2017 Intel Corporation 3bf215546Sopenharmony_ci 4bf215546Sopenharmony_ci# Permission is hereby granted, free of charge, to any person obtaining a copy 5bf215546Sopenharmony_ci# of this software and associated documentation files (the "Software"), to deal 6bf215546Sopenharmony_ci# in the Software without restriction, including without limitation the rights 7bf215546Sopenharmony_ci# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8bf215546Sopenharmony_ci# copies of the Software, and to permit persons to whom the Software is 9bf215546Sopenharmony_ci# furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci 11bf215546Sopenharmony_ci# The above copyright notice and this permission notice shall be included in 12bf215546Sopenharmony_ci# all copies or substantial portions of the Software. 13bf215546Sopenharmony_ci 14bf215546Sopenharmony_ci# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15bf215546Sopenharmony_ci# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16bf215546Sopenharmony_ci# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17bf215546Sopenharmony_ci# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18bf215546Sopenharmony_ci# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19bf215546Sopenharmony_ci# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20bf215546Sopenharmony_ci# SOFTWARE. 21bf215546Sopenharmony_ci 22bf215546Sopenharmony_ciimport argparse 23bf215546Sopenharmony_ciimport os 24bf215546Sopenharmony_ciimport xml.parsers.expat 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_cifrom mako.template import Template 27bf215546Sopenharmony_cifrom util import * 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ciTEMPLATE = Template("""\ 30bf215546Sopenharmony_ci<%! 31bf215546Sopenharmony_cifrom operator import itemgetter 32bf215546Sopenharmony_ci%>\ 33bf215546Sopenharmony_ci/* 34bf215546Sopenharmony_ci * Copyright © 2017 Intel Corporation 35bf215546Sopenharmony_ci * 36bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 37bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 38bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 39bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 40bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 41bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 42bf215546Sopenharmony_ci * 43bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 44bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 45bf215546Sopenharmony_ci * Software. 46bf215546Sopenharmony_ci * 47bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 48bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 49bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 50bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 51bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 52bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 53bf215546Sopenharmony_ci * IN THE SOFTWARE. 54bf215546Sopenharmony_ci */ 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci/* THIS FILE HAS BEEN GENERATED, DO NOT HAND EDIT. 57bf215546Sopenharmony_ci * 58bf215546Sopenharmony_ci * Sizes of bitfields in genxml instructions, structures, and registers. 59bf215546Sopenharmony_ci */ 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci#ifndef ${guard} 62bf215546Sopenharmony_ci#define ${guard} 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci#include <stdint.h> 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_ci#include "dev/intel_device_info.h" 67bf215546Sopenharmony_ci#include "util/macros.h" 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci<%def name="emit_per_gen_prop_func(item, prop, protect_defines)"> 70bf215546Sopenharmony_ci%if item.has_prop(prop): 71bf215546Sopenharmony_ci% for gen, value in sorted(item.iter_prop(prop), reverse=True): 72bf215546Sopenharmony_ci% if protect_defines: 73bf215546Sopenharmony_ci#ifndef ${gen.prefix(item.token_name)}_${prop} 74bf215546Sopenharmony_ci#define ${gen.prefix(item.token_name)}_${prop} ${value} 75bf215546Sopenharmony_ci#endif 76bf215546Sopenharmony_ci% else: 77bf215546Sopenharmony_ci#define ${gen.prefix(item.token_name)}_${prop} ${value} 78bf215546Sopenharmony_ci% endif 79bf215546Sopenharmony_ci% endfor 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_cistatic inline uint32_t ATTRIBUTE_PURE 82bf215546Sopenharmony_ci${item.token_name}_${prop}(const struct intel_device_info *devinfo) 83bf215546Sopenharmony_ci{ 84bf215546Sopenharmony_ci switch (devinfo->verx10) { 85bf215546Sopenharmony_ci case 125: return ${item.get_prop(prop, 12.5)}; 86bf215546Sopenharmony_ci case 120: return ${item.get_prop(prop, 12)}; 87bf215546Sopenharmony_ci case 110: return ${item.get_prop(prop, 11)}; 88bf215546Sopenharmony_ci case 90: return ${item.get_prop(prop, 9)}; 89bf215546Sopenharmony_ci case 80: return ${item.get_prop(prop, 8)}; 90bf215546Sopenharmony_ci case 75: return ${item.get_prop(prop, 7.5)}; 91bf215546Sopenharmony_ci case 70: return ${item.get_prop(prop, 7)}; 92bf215546Sopenharmony_ci case 60: return ${item.get_prop(prop, 6)}; 93bf215546Sopenharmony_ci case 50: return ${item.get_prop(prop, 5)}; 94bf215546Sopenharmony_ci case 45: return ${item.get_prop(prop, 4.5)}; 95bf215546Sopenharmony_ci case 40: return ${item.get_prop(prop, 4)}; 96bf215546Sopenharmony_ci default: 97bf215546Sopenharmony_ci unreachable("Invalid hardware generation"); 98bf215546Sopenharmony_ci } 99bf215546Sopenharmony_ci} 100bf215546Sopenharmony_ci%endif 101bf215546Sopenharmony_ci</%def> 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_ci#ifdef __cplusplus 104bf215546Sopenharmony_ciextern "C" { 105bf215546Sopenharmony_ci#endif 106bf215546Sopenharmony_ci% for _, container in sorted(containers.items(), key=itemgetter(0)): 107bf215546Sopenharmony_ci% if container.allowed: 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci/* ${container.name} */ 110bf215546Sopenharmony_ci 111bf215546Sopenharmony_ci${emit_per_gen_prop_func(container, 'length', True)} 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci% for _, field in sorted(container.fields.items(), key=itemgetter(0)): 114bf215546Sopenharmony_ci% if field.allowed: 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci/* ${container.name}::${field.name} */ 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ci${emit_per_gen_prop_func(field, 'bits', False)} 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci${emit_per_gen_prop_func(field, 'start', False)} 121bf215546Sopenharmony_ci% endif 122bf215546Sopenharmony_ci% endfor 123bf215546Sopenharmony_ci% endif 124bf215546Sopenharmony_ci% endfor 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci#ifdef __cplusplus 127bf215546Sopenharmony_ci} 128bf215546Sopenharmony_ci#endif 129bf215546Sopenharmony_ci 130bf215546Sopenharmony_ci#endif /* ${guard} */""") 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ciclass Gen(object): 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci def __init__(self, z): 135bf215546Sopenharmony_ci # Convert potential "major.minor" string 136bf215546Sopenharmony_ci self.tenx = int(float(z) * 10) 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci def __lt__(self, other): 139bf215546Sopenharmony_ci return self.tenx < other.tenx 140bf215546Sopenharmony_ci 141bf215546Sopenharmony_ci def __hash__(self): 142bf215546Sopenharmony_ci return hash(self.tenx) 143bf215546Sopenharmony_ci 144bf215546Sopenharmony_ci def __eq__(self, other): 145bf215546Sopenharmony_ci return self.tenx == other.tenx 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci def prefix(self, token): 148bf215546Sopenharmony_ci gen = self.tenx 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_ci if gen % 10 == 0: 151bf215546Sopenharmony_ci gen //= 10 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci if token[0] == '_': 154bf215546Sopenharmony_ci token = token[1:] 155bf215546Sopenharmony_ci 156bf215546Sopenharmony_ci return 'GFX{}_{}'.format(gen, token) 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ciclass Container(object): 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci def __init__(self, name): 161bf215546Sopenharmony_ci self.name = name 162bf215546Sopenharmony_ci self.token_name = safe_name(name) 163bf215546Sopenharmony_ci self.length_by_gen = {} 164bf215546Sopenharmony_ci self.fields = {} 165bf215546Sopenharmony_ci self.allowed = False 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci def add_gen(self, gen, xml_attrs): 168bf215546Sopenharmony_ci assert isinstance(gen, Gen) 169bf215546Sopenharmony_ci if 'length' in xml_attrs: 170bf215546Sopenharmony_ci self.length_by_gen[gen] = xml_attrs['length'] 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci def get_field(self, field_name, create=False): 173bf215546Sopenharmony_ci key = to_alphanum(field_name) 174bf215546Sopenharmony_ci if key not in self.fields: 175bf215546Sopenharmony_ci if create: 176bf215546Sopenharmony_ci self.fields[key] = Field(self, field_name) 177bf215546Sopenharmony_ci else: 178bf215546Sopenharmony_ci return None 179bf215546Sopenharmony_ci return self.fields[key] 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci def has_prop(self, prop): 182bf215546Sopenharmony_ci if prop == 'length': 183bf215546Sopenharmony_ci return bool(self.length_by_gen) 184bf215546Sopenharmony_ci else: 185bf215546Sopenharmony_ci raise ValueError('Invalid property: "{0}"'.format(prop)) 186bf215546Sopenharmony_ci 187bf215546Sopenharmony_ci def iter_prop(self, prop): 188bf215546Sopenharmony_ci if prop == 'length': 189bf215546Sopenharmony_ci return self.length_by_gen.items() 190bf215546Sopenharmony_ci else: 191bf215546Sopenharmony_ci raise ValueError('Invalid property: "{0}"'.format(prop)) 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci def get_prop(self, prop, gen): 194bf215546Sopenharmony_ci if not isinstance(gen, Gen): 195bf215546Sopenharmony_ci gen = Gen(gen) 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci if prop == 'length': 198bf215546Sopenharmony_ci return self.length_by_gen.get(gen, 0) 199bf215546Sopenharmony_ci else: 200bf215546Sopenharmony_ci raise ValueError('Invalid property: "{0}"'.format(prop)) 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_ciclass Field(object): 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci def __init__(self, container, name): 205bf215546Sopenharmony_ci self.name = name 206bf215546Sopenharmony_ci self.token_name = safe_name('_'.join([container.name, self.name])) 207bf215546Sopenharmony_ci self.bits_by_gen = {} 208bf215546Sopenharmony_ci self.start_by_gen = {} 209bf215546Sopenharmony_ci self.allowed = False 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci def add_gen(self, gen, xml_attrs): 212bf215546Sopenharmony_ci assert isinstance(gen, Gen) 213bf215546Sopenharmony_ci start = int(xml_attrs['start']) 214bf215546Sopenharmony_ci end = int(xml_attrs['end']) 215bf215546Sopenharmony_ci self.start_by_gen[gen] = start 216bf215546Sopenharmony_ci self.bits_by_gen[gen] = 1 + end - start 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci def has_prop(self, prop): 219bf215546Sopenharmony_ci return True 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci def iter_prop(self, prop): 222bf215546Sopenharmony_ci if prop == 'bits': 223bf215546Sopenharmony_ci return self.bits_by_gen.items() 224bf215546Sopenharmony_ci elif prop == 'start': 225bf215546Sopenharmony_ci return self.start_by_gen.items() 226bf215546Sopenharmony_ci else: 227bf215546Sopenharmony_ci raise ValueError('Invalid property: "{0}"'.format(prop)) 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ci def get_prop(self, prop, gen): 230bf215546Sopenharmony_ci if not isinstance(gen, Gen): 231bf215546Sopenharmony_ci gen = Gen(gen) 232bf215546Sopenharmony_ci 233bf215546Sopenharmony_ci if prop == 'bits': 234bf215546Sopenharmony_ci return self.bits_by_gen.get(gen, 0) 235bf215546Sopenharmony_ci elif prop == 'start': 236bf215546Sopenharmony_ci return self.start_by_gen.get(gen, 0) 237bf215546Sopenharmony_ci else: 238bf215546Sopenharmony_ci raise ValueError('Invalid property: "{0}"'.format(prop)) 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_ciclass XmlParser(object): 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_ci def __init__(self, containers): 243bf215546Sopenharmony_ci self.parser = xml.parsers.expat.ParserCreate() 244bf215546Sopenharmony_ci self.parser.StartElementHandler = self.start_element 245bf215546Sopenharmony_ci self.parser.EndElementHandler = self.end_element 246bf215546Sopenharmony_ci 247bf215546Sopenharmony_ci self.gen = None 248bf215546Sopenharmony_ci self.containers = containers 249bf215546Sopenharmony_ci self.container_stack = [] 250bf215546Sopenharmony_ci self.container_stack.append(None) 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci def parse(self, filename): 253bf215546Sopenharmony_ci with open(filename, 'rb') as f: 254bf215546Sopenharmony_ci self.parser.ParseFile(f) 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci def start_element(self, name, attrs): 257bf215546Sopenharmony_ci if name == 'genxml': 258bf215546Sopenharmony_ci self.gen = Gen(attrs['gen']) 259bf215546Sopenharmony_ci elif name in ('instruction', 'struct', 'register'): 260bf215546Sopenharmony_ci if name == 'instruction' and 'engine' in attrs: 261bf215546Sopenharmony_ci engines = set(attrs['engine'].split('|')) 262bf215546Sopenharmony_ci if not engines & self.engines: 263bf215546Sopenharmony_ci self.container_stack.append(None) 264bf215546Sopenharmony_ci return 265bf215546Sopenharmony_ci self.start_container(attrs) 266bf215546Sopenharmony_ci elif name == 'group': 267bf215546Sopenharmony_ci self.container_stack.append(None) 268bf215546Sopenharmony_ci elif name == 'field': 269bf215546Sopenharmony_ci self.start_field(attrs) 270bf215546Sopenharmony_ci else: 271bf215546Sopenharmony_ci pass 272bf215546Sopenharmony_ci 273bf215546Sopenharmony_ci def end_element(self, name): 274bf215546Sopenharmony_ci if name == 'genxml': 275bf215546Sopenharmony_ci self.gen = None 276bf215546Sopenharmony_ci elif name in ('instruction', 'struct', 'register', 'group'): 277bf215546Sopenharmony_ci self.container_stack.pop() 278bf215546Sopenharmony_ci else: 279bf215546Sopenharmony_ci pass 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ci def start_container(self, attrs): 282bf215546Sopenharmony_ci assert self.container_stack[-1] is None 283bf215546Sopenharmony_ci name = attrs['name'] 284bf215546Sopenharmony_ci if name not in self.containers: 285bf215546Sopenharmony_ci self.containers[name] = Container(name) 286bf215546Sopenharmony_ci self.container_stack.append(self.containers[name]) 287bf215546Sopenharmony_ci self.container_stack[-1].add_gen(self.gen, attrs) 288bf215546Sopenharmony_ci 289bf215546Sopenharmony_ci def start_field(self, attrs): 290bf215546Sopenharmony_ci if self.container_stack[-1] is None: 291bf215546Sopenharmony_ci return 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci field_name = attrs.get('name', None) 294bf215546Sopenharmony_ci if not field_name: 295bf215546Sopenharmony_ci return 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci self.container_stack[-1].get_field(field_name, True).add_gen(self.gen, attrs) 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_cidef parse_args(): 300bf215546Sopenharmony_ci p = argparse.ArgumentParser() 301bf215546Sopenharmony_ci p.add_argument('-o', '--output', type=str, 302bf215546Sopenharmony_ci help="If OUTPUT is unset or '-', then it defaults to '/dev/stdout'") 303bf215546Sopenharmony_ci p.add_argument('--cpp-guard', type=str, 304bf215546Sopenharmony_ci help='If unset, then CPP_GUARD is derived from OUTPUT.') 305bf215546Sopenharmony_ci p.add_argument('--engines', nargs='?', type=str, default='render', 306bf215546Sopenharmony_ci help="Comma-separated list of engines whose instructions should be parsed (default: %(default)s)") 307bf215546Sopenharmony_ci p.add_argument('--include-symbols', type=str, action='store', 308bf215546Sopenharmony_ci help='List of instruction/structures to generate', 309bf215546Sopenharmony_ci required=True) 310bf215546Sopenharmony_ci p.add_argument('xml_sources', metavar='XML_SOURCE', nargs='+') 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_ci pargs = p.parse_args() 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_ci if pargs.output in (None, '-'): 315bf215546Sopenharmony_ci pargs.output = '/dev/stdout' 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci if pargs.cpp_guard is None: 318bf215546Sopenharmony_ci pargs.cpp_guard = os.path.basename(pargs.output).upper().replace('.', '_') 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci return pargs 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_cidef main(): 323bf215546Sopenharmony_ci pargs = parse_args() 324bf215546Sopenharmony_ci 325bf215546Sopenharmony_ci engines = pargs.engines.split(',') 326bf215546Sopenharmony_ci valid_engines = [ 'render', 'blitter', 'video' ] 327bf215546Sopenharmony_ci if set(engines) - set(valid_engines): 328bf215546Sopenharmony_ci print("Invalid engine specified, valid engines are:\n") 329bf215546Sopenharmony_ci for e in valid_engines: 330bf215546Sopenharmony_ci print("\t%s" % e) 331bf215546Sopenharmony_ci sys.exit(1) 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ci # Maps name => Container 334bf215546Sopenharmony_ci containers = {} 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci for source in pargs.xml_sources: 337bf215546Sopenharmony_ci p = XmlParser(containers) 338bf215546Sopenharmony_ci p.engines = set(engines) 339bf215546Sopenharmony_ci p.parse(source) 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci included_symbols_list = pargs.include_symbols.split(',') 342bf215546Sopenharmony_ci for _name_field in included_symbols_list: 343bf215546Sopenharmony_ci name_field = _name_field.split('::') 344bf215546Sopenharmony_ci container = containers[name_field[0]] 345bf215546Sopenharmony_ci container.allowed = True 346bf215546Sopenharmony_ci if len(name_field) > 1: 347bf215546Sopenharmony_ci field = container.get_field(name_field[1]) 348bf215546Sopenharmony_ci assert field 349bf215546Sopenharmony_ci field.allowed = True 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci with open(pargs.output, 'w') as f: 352bf215546Sopenharmony_ci f.write(TEMPLATE.render(containers=containers, guard=pargs.cpp_guard)) 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ciif __name__ == '__main__': 355bf215546Sopenharmony_ci main() 356