Path: blob/21.2-virgl/src/intel/genxml/gen_bits_header.py
7086 views
#encoding=utf-81# Copyright © 2017 Intel Corporation23# Permission is hereby granted, free of charge, to any person obtaining a copy4# of this software and associated documentation files (the "Software"), to deal5# in the Software without restriction, including without limitation the rights6# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell7# copies of the Software, and to permit persons to whom the Software is8# furnished to do so, subject to the following conditions:910# The above copyright notice and this permission notice shall be included in11# all copies or substantial portions of the Software.1213# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE16# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER17# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,18# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE19# SOFTWARE.2021from __future__ import (22absolute_import, division, print_function, unicode_literals23)2425import argparse26import os27import xml.parsers.expat2829from mako.template import Template30from util import *3132TEMPLATE = Template("""\33<%!34from operator import itemgetter35%>\36/*37* Copyright © 2017 Intel Corporation38*39* Permission is hereby granted, free of charge, to any person obtaining a40* copy of this software and associated documentation files (the "Software"),41* to deal in the Software without restriction, including without limitation42* the rights to use, copy, modify, merge, publish, distribute, sublicense,43* and/or sell copies of the Software, and to permit persons to whom the44* Software is furnished to do so, subject to the following conditions:45*46* The above copyright notice and this permission notice (including the next47* paragraph) shall be included in all copies or substantial portions of the48* Software.49*50* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR51* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,52* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL53* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER54* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING55* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS56* IN THE SOFTWARE.57*/5859/* THIS FILE HAS BEEN GENERATED, DO NOT HAND EDIT.60*61* Sizes of bitfields in genxml instructions, structures, and registers.62*/6364#ifndef ${guard}65#define ${guard}6667#include <stdint.h>6869#include "dev/intel_device_info.h"70#include "util/macros.h"7172<%def name="emit_per_gen_prop_func(item, prop)">73%if item.has_prop(prop):74% for gen, value in sorted(item.iter_prop(prop), reverse=True):75#define ${gen.prefix(item.token_name)}_${prop} ${value}76% endfor7778static inline uint32_t ATTRIBUTE_PURE79${item.token_name}_${prop}(const struct intel_device_info *devinfo)80{81switch (devinfo->verx10) {82case 125: return ${item.get_prop(prop, 12.5)};83case 120: return ${item.get_prop(prop, 12)};84case 110: return ${item.get_prop(prop, 11)};85case 90: return ${item.get_prop(prop, 9)};86case 80: return ${item.get_prop(prop, 8)};87case 75: return ${item.get_prop(prop, 7.5)};88case 70: return ${item.get_prop(prop, 7)};89case 60: return ${item.get_prop(prop, 6)};90case 50: return ${item.get_prop(prop, 5)};91case 45: return ${item.get_prop(prop, 4.5)};92case 40: return ${item.get_prop(prop, 4)};93default:94unreachable("Invalid hardware generation");95}96}97%endif98</%def>99100#ifdef __cplusplus101extern "C" {102#endif103% for _, container in sorted(containers.items(), key=itemgetter(0)):104105/* ${container.name} */106107${emit_per_gen_prop_func(container, 'length')}108109% for _, field in sorted(container.fields.items(), key=itemgetter(0)):110111/* ${container.name}::${field.name} */112113${emit_per_gen_prop_func(field, 'bits')}114115${emit_per_gen_prop_func(field, 'start')}116117% endfor118% endfor119120#ifdef __cplusplus121}122#endif123124#endif /* ${guard} */""", output_encoding='utf-8')125126class Gen(object):127128def __init__(self, z):129# Convert potential "major.minor" string130self.tenx = int(float(z) * 10)131132def __lt__(self, other):133return self.tenx < other.tenx134135def __hash__(self):136return hash(self.tenx)137138def __eq__(self, other):139return self.tenx == other.tenx140141def prefix(self, token):142gen = self.tenx143144if gen % 10 == 0:145gen //= 10146147if token[0] == '_':148token = token[1:]149150return 'GFX{}_{}'.format(gen, token)151152class Container(object):153154def __init__(self, name):155self.name = name156self.token_name = safe_name(name)157self.length_by_gen = {}158self.fields = {}159160def add_gen(self, gen, xml_attrs):161assert isinstance(gen, Gen)162if 'length' in xml_attrs:163self.length_by_gen[gen] = xml_attrs['length']164165def get_field(self, field_name, create=False):166key = to_alphanum(field_name)167if key not in self.fields:168if create:169self.fields[key] = Field(self, field_name)170else:171return None172return self.fields[key]173174def has_prop(self, prop):175if prop == 'length':176return bool(self.length_by_gen)177else:178raise ValueError('Invalid property: "{0}"'.format(prop))179180def iter_prop(self, prop):181if prop == 'length':182return self.length_by_gen.items()183else:184raise ValueError('Invalid property: "{0}"'.format(prop))185186def get_prop(self, prop, gen):187if not isinstance(gen, Gen):188gen = Gen(gen)189190if prop == 'length':191return self.length_by_gen.get(gen, 0)192else:193raise ValueError('Invalid property: "{0}"'.format(prop))194195class Field(object):196197def __init__(self, container, name):198self.name = name199self.token_name = safe_name('_'.join([container.name, self.name]))200self.bits_by_gen = {}201self.start_by_gen = {}202203def add_gen(self, gen, xml_attrs):204assert isinstance(gen, Gen)205start = int(xml_attrs['start'])206end = int(xml_attrs['end'])207self.start_by_gen[gen] = start208self.bits_by_gen[gen] = 1 + end - start209210def has_prop(self, prop):211return True212213def iter_prop(self, prop):214if prop == 'bits':215return self.bits_by_gen.items()216elif prop == 'start':217return self.start_by_gen.items()218else:219raise ValueError('Invalid property: "{0}"'.format(prop))220221def get_prop(self, prop, gen):222if not isinstance(gen, Gen):223gen = Gen(gen)224225if prop == 'bits':226return self.bits_by_gen.get(gen, 0)227elif prop == 'start':228return self.start_by_gen.get(gen, 0)229else:230raise ValueError('Invalid property: "{0}"'.format(prop))231232class XmlParser(object):233234def __init__(self, containers):235self.parser = xml.parsers.expat.ParserCreate()236self.parser.StartElementHandler = self.start_element237self.parser.EndElementHandler = self.end_element238239self.gen = None240self.containers = containers241self.container_stack = []242self.container_stack.append(None)243244def parse(self, filename):245with open(filename, 'rb') as f:246self.parser.ParseFile(f)247248def start_element(self, name, attrs):249if name == 'genxml':250self.gen = Gen(attrs['gen'])251elif name in ('instruction', 'struct', 'register'):252if name == 'instruction' and 'engine' in attrs:253engines = set(attrs['engine'].split('|'))254if not engines & self.engines:255self.container_stack.append(None)256return257self.start_container(attrs)258elif name == 'group':259self.container_stack.append(None)260elif name == 'field':261self.start_field(attrs)262else:263pass264265def end_element(self, name):266if name == 'genxml':267self.gen = None268elif name in ('instruction', 'struct', 'register', 'group'):269self.container_stack.pop()270else:271pass272273def start_container(self, attrs):274assert self.container_stack[-1] is None275name = attrs['name']276if name not in self.containers:277self.containers[name] = Container(name)278self.container_stack.append(self.containers[name])279self.container_stack[-1].add_gen(self.gen, attrs)280281def start_field(self, attrs):282if self.container_stack[-1] is None:283return284285field_name = attrs.get('name', None)286if not field_name:287return288289self.container_stack[-1].get_field(field_name, True).add_gen(self.gen, attrs)290291def parse_args():292p = argparse.ArgumentParser()293p.add_argument('-o', '--output', type=str,294help="If OUTPUT is unset or '-', then it defaults to '/dev/stdout'")295p.add_argument('--cpp-guard', type=str,296help='If unset, then CPP_GUARD is derived from OUTPUT.')297p.add_argument('--engines', nargs='?', type=str, default='render',298help="Comma-separated list of engines whose instructions should be parsed (default: %(default)s)")299p.add_argument('xml_sources', metavar='XML_SOURCE', nargs='+')300301pargs = p.parse_args()302303if pargs.output in (None, '-'):304pargs.output = '/dev/stdout'305306if pargs.cpp_guard is None:307pargs.cpp_guard = os.path.basename(pargs.output).upper().replace('.', '_')308309return pargs310311def main():312pargs = parse_args()313314engines = pargs.engines.split(',')315valid_engines = [ 'render', 'blitter', 'video' ]316if set(engines) - set(valid_engines):317print("Invalid engine specified, valid engines are:\n")318for e in valid_engines:319print("\t%s" % e)320sys.exit(1)321322# Maps name => Container323containers = {}324325for source in pargs.xml_sources:326p = XmlParser(containers)327p.engines = set(engines)328p.parse(source)329330with open(pargs.output, 'wb') as f:331f.write(TEMPLATE.render(containers=containers, guard=pargs.cpp_guard))332333if __name__ == '__main__':334main()335336337