Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  gen_header.py   Sprache: Python

 
#!/usr/bin/python3
#
# Copyright © 2019-2024 Google, Inc.
#
# SPDX-License-Identifier: MIT

import xml.parsers.expat
import sys
import os
import collections
import argparse
import time
import datetime
import re

class Error(Exception):
 def __init__(self, message):
  self.message = message

class Enum(object):
 def __init__(self, name):
  self.name = name
  self.values = []

 def has_name(self, name):
  for (n, value) in self.values:
   if n == name:
    return True
  return False

 def names(self):
  return [n for (n, value) in self.values]

 def dump(self):
  use_hex = False
  for (name, value) in self.values:
   if value > 0x1000:
    use_hex = True

  print("enum %s {" % self.name)
  for (name, value) in self.values:
   if use_hex:
    print("\t%s = 0x%08x," % (name, value))
   else:
    print("\t%s = %d," % (name, value))
  print("};\n")

 def dump_pack_struct(self):
  pass

class Field(object):
 def __init__(self, name, low, high, shr, type, parser):
  self.name = name
  self.low = low
  self.high = high
  self.shr = shr
  self.type = type

  builtin_types = [ None"a3xx_regid""boolean""uint""hex""int""fixed""ufixed""float""address""waddress" ]

  maxpos = parser.current_bitsize - 1

  if low < 0 or low > maxpos:
   raise parser.error("low attribute out of range: %d" % low)
  if high < 0 or high > maxpos:
   raise parser.error("high attribute out of range: %d" % high)
  if high < low:
   raise parser.error("low is greater than high: low=%d, high=%d" % (low, high))
  if self.type == "boolean" and not low == high:
   raise parser.error("booleans should be 1 bit fields")
  elif self.type == "float" and not (high - low == 31 or high - low == 15):
   raise parser.error("floats should be 16 or 32 bit fields")
  elif not self.type in builtin_types and not self.type in parser.enums:
   raise parser.error("unknown type '%s'" % self.type)

 def ctype(self, var_name):
  if self.type == None:
   type = "uint32_t"
   val = var_name
  elif self.type == "boolean":
   type = "bool"
   val = var_name
  elif self.type == "uint" or self.type == "hex" or self.type == "a3xx_regid":
   type = "uint32_t"
   val = var_name
  elif self.type == "int":
   type = "int32_t"
   val = var_name
  elif self.type == "fixed":
   type = "float"
   val = "((int32_t)(%s * %d.0))" % (var_name, 1 << self.radix)
  elif self.type == "ufixed":
   type = "float"
   val = "((uint32_t)(%s * %d.0))" % (var_name, 1 << self.radix)
  elif self.type == "float" and self.high - self.low == 31:
   type = "float"
   val = "fui(%s)" % var_name
  elif self.type == "float" and self.high - self.low == 15:
   type = "float"
   val = "_mesa_float_to_half(%s)" % var_name
  elif self.type in [ "address""waddress" ]:
   type = "uint64_t"
   val = var_name
  else:
   type = "enum %s" % self.type
   val = var_name

  if self.shr > 0:
   val = "(%s >> %d)" % (val, self.shr)

  return (type, val)

def tab_to(name, value):
 tab_count = (68 - (len(name) & ~7)) // 8
 if tab_count <= 0:
  tab_count = 1
 print(name + ('\t' * tab_count) + value)

def mask(low, high):
 return ((0xffffffffffffffff >> (64 - (high + 1 - low))) << low)

def field_name(reg, f):
 if f.name:
  name = f.name.lower()
 else:
  # We hit this path when a reg is defined with no bitset fields, ie.
  #  <reg32 offset="0x88db" name="RB_BLIT_DST_ARRAY_PITCH" low="0" high="28" shr="6" type="uint"/>
  name = reg.name.lower()

 if (name in [ "double""float""int" ]) or not (name[0].isalpha()):
   name = "_" + name

 return name

# indices - array of (ctype, stride, __offsets_NAME)
def indices_varlist(indices):
 return ", ".join(["i%d" % i for i in range(len(indices))])

def indices_prototype(indices):
 return ", ".join(["%s i%d" % (ctype, idx)
   for (idx, (ctype, stride, offset)) in  enumerate(indices)])

def indices_strides(indices):
 return " + ".join(["0x%x*i%d" % (stride, idx)
     if stride else
     "%s(i%d)" % (offset, idx)
   for (idx, (ctype, stride, offset)) in  enumerate(indices)])

class Bitset(object):
 def __init__(self, name, template):
  self.name = name
  self.inline = False
  self.reg = None
  if template:
   self.fields = template.fields[:]
  else:
   self.fields = []

 # Get address field if there is one in the bitset, else return None:
 def get_address_field(self):
  for f in self.fields:
   if f.type in [ "address""waddress" ]:
    return f
  return None

 def dump_regpair_builder(self, reg):
  print("#ifndef NDEBUG")
  known_mask = 0
  for f in self.fields:
   known_mask |= mask(f.low, f.high)
   if f.type in [ "boolean""address""waddress" ]:
    continue
   type, val = f.ctype("fields.%s" % field_name(reg, f))
   print(" assert((%-40s & 0x%08x) == 0);" % (val, 0xffffffff ^ mask(0 , f.high - f.low)))
  print(" assert((%-40s & 0x%08x) == 0);" % ("fields.unknown", known_mask))
  print("#endif\n")

  print(" return (struct fd_reg_pair) {")
  if reg.array:
   print(" .reg = REG_%s(__i)," % reg.full_name)
  else:
   print(" .reg = REG_%s," % reg.full_name)

  print(" .value =")
  for f in self.fields:
   if f.type in [ "address""waddress" ]:
    continue
   else:
    type, val = f.ctype("fields.%s" % field_name(reg, f))
    print(" (%-40s << %2d) |" % (val, f.low))
  value_name = "dword"
  if reg.bit_size == 64:
   value_name = "qword"
  print(" fields.unknown | fields.%s," % (value_name,))

  address = self.get_address_field()
  if address:
   print(" .bo = fields.bo,")
   print(" .is_address = true,")
   if f.type == "waddress":
    print(" .bo_write = true,")
   print(" .bo_offset = fields.bo_offset,")
   print(" .bo_shift = %d," % address.shr)
   print(" .bo_low = %d," % address.low)

  print(" };")

 def dump_pack_struct(self, reg=None):
  if not reg:
   return

  prefix = reg.full_name

  print("struct %s {" % prefix)
  for f in self.fields:
   if f.type in [ "address""waddress" ]:
    tab_to(" __bo_type""bo;")
    tab_to(" uint32_t""bo_offset;")
    continue
   name = field_name(reg, f)

   type, val = f.ctype("var")

   tab_to(" %s" % type, "%s;" % name)
  if reg.bit_size == 64:
   tab_to(" uint64_t""unknown;")
   tab_to(" uint64_t""qword;")
  else:
   tab_to(" uint32_t""unknown;")
   tab_to(" uint32_t""dword;")
  print("};\n")

  if reg.array:
   print("static inline struct fd_reg_pair\npack_%s(uint32_t __i, struct %s fields)\n{" %
      (prefix, prefix))
  else:
   print("static inline struct fd_reg_pair\npack_%s(struct %s fields)\n{" %
      (prefix, prefix))

  self.dump_regpair_builder(reg)

  print("\n}\n")

  if self.get_address_field():
   skip = ", { .reg = 0 }"
  else:
   skip = ""

  if reg.array:
   print("#define %s(__i, ...) pack_%s(__i, __struct_cast(%s) { __VA_ARGS__ })%s\n" %
      (prefix, prefix, prefix, skip))
  else:
   print("#define %s(...) pack_%s(__struct_cast(%s) { __VA_ARGS__ })%s\n" %
      (prefix, prefix, prefix, skip))


 def dump(self, prefix=None):
  if prefix == None:
   prefix = self.name
  if self.reg and self.reg.bit_size == 64:
   print("static inline uint32_t %s_LO(uint32_t val)\n{" % prefix)
   print("\treturn val;\n}")
   print("static inline uint32_t %s_HI(uint32_t val)\n{" % prefix)
   print("\treturn val;\n}")
  for f in self.fields:
   if f.name:
    name = prefix + "_" + f.name
   else:
    name = prefix

   if not f.name and f.low == 0 and f.shr == 0 and not f.type in ["float""fixed""ufixed"]:
    pass
   elif f.type == "boolean" or (f.type == None and f.low == f.high):
    tab_to("#define %s" % name, "0x%08x" % (1 << f.low))
   else:
    tab_to("#define %s__MASK" % name, "0x%08x" % mask(f.low, f.high))
    tab_to("#define %s__SHIFT" % name, "%d" % f.low)
    type, val = f.ctype("val")

    print("static inline uint32_t %s(%s val)\n{" % (name, type))
    if f.shr > 0:
     print("\tassert(!(val & 0x%x));" % mask(0, f.shr - 1))
    print("\treturn ((%s) << %s__SHIFT) & %s__MASK;\n}" % (val, name, name))
  print()

class Array(object):
 def __init__(self, attrs, domain, variant, parent, index_type):
  if "name" in attrs:
   self.local_name = attrs["name"]
  else:
   self.local_name = ""
  self.domain = domain
  self.variant = variant
  self.parent = parent
  if self.parent:
   self.name = self.parent.name + "_" + self.local_name
  else:
   self.name = self.local_name
  if "offsets" in attrs:
   self.offsets = map(lambda i: "0x%08x" % int(i, 0), attrs["offsets"].split(","))
   self.fixed_offsets = True
  elif "doffsets" in attrs:
   self.offsets = map(lambda s: "(%s)" % s , attrs["doffsets"].split(","))
   self.fixed_offsets = True
  else:
   self.offset = int(attrs["offset"], 0)
   self.stride = int(attrs["stride"], 0)
   self.fixed_offsets = False
  if "index" in attrs:
   self.index_type = index_type
  else:
   self.index_type = None
  self.length = int(attrs["length"], 0)
  if "usage" in attrs:
   self.usages = attrs["usage"].split(',')
  else:
   self.usages = None

 def index_ctype(self):
  if not self.index_type:
   return "uint32_t"
  else:
   return "enum %s" % self.index_type.name

 # Generate array of (ctype, stride, __offsets_NAME)
 def indices(self):
  if self.parent:
   indices = self.parent.indices()
  else:
   indices = []
  if self.length != 1:
   if self.fixed_offsets:
    indices.append((self.index_ctype(), None"__offset_%s" % self.local_name))
   else:
    indices.append((self.index_ctype(), self.stride, None))
  return indices

 def total_offset(self):
  offset = 0
  if not self.fixed_offsets:
   offset += self.offset
  if self.parent:
   offset += self.parent.total_offset()
  return offset

 def dump(self):
  proto = indices_varlist(self.indices())
  strides = indices_strides(self.indices())
  array_offset = self.total_offset()
  if self.fixed_offsets:
   print("static inline uint32_t __offset_%s(%s idx)" % (self.local_name, self.index_ctype()))
   print("{\n\tswitch (idx) {")
   if self.index_type:
    for val, offset in zip(self.index_type.names(), self.offsets):
     print("\t\tcase %s: return %s;" % (val, offset))
   else:
    for idx, offset in enumerate(self.offsets):
     print("\t\tcase %d: return %s;" % (idx, offset))
   print("\t\tdefault: return INVALID_IDX(idx);")
   print("\t}\n}")
  if proto == '':
   tab_to("#define REG_%s_%s" % (self.domain, self.name), "0x%08x\n" % array_offset)
  else:
   tab_to("#define REG_%s_%s(%s)" % (self.domain, self.name, proto), "(0x%08x + %s )\n" % (array_offset, strides))

 def dump_pack_struct(self):
  pass

 def dump_regpair_builder(self):
  pass

class Reg(object):
 def __init__(self, attrs, domain, array, bit_size):
  self.name = attrs["name"]
  self.domain = domain
  self.array = array
  self.offset = int(attrs["offset"], 0)
  self.type = None
  self.bit_size = bit_size
  if array:
   self.name = array.name + "_" + self.name
  self.full_name = self.domain + "_" + self.name
  if "stride" in attrs:
   self.stride = int(attrs["stride"], 0)
   self.length = int(attrs["length"], 0)
  else:
   self.stride = None
   self.length = None

 # Generate array of (ctype, stride, __offsets_NAME)
 def indices(self):
  if self.array:
   indices = self.array.indices()
  else:
   indices = []
  if self.stride:
   indices.append(("uint32_t", self.stride, None))
  return indices

 def total_offset(self):
  if self.array:
   return self.array.total_offset() + self.offset
  else:
   return self.offset

 def dump(self):
  proto = indices_prototype(self.indices())
  strides = indices_strides(self.indices())
  offset = self.total_offset()
  if proto == '':
   tab_to("#define REG_%s" % self.full_name, "0x%08x" % offset)
  else:
   print("static inline uint32_t REG_%s(%s) { return 0x%08x + %s; }" % (self.full_name, proto, offset, strides))

  if self.bitset.inline:
   self.bitset.dump(self.full_name)

 def dump_pack_struct(self):
  if self.bitset.inline:
   self.bitset.dump_pack_struct(self)

 def dump_regpair_builder(self):
  if self.bitset.inline:
   self.bitset.dump_regpair_builder(self)

 def dump_py(self):
  print("\tREG_%s = 0x%08x" % (self.full_name, self.offset))


class Parser(object):
 def __init__(self):
  self.current_array = None
  self.current_domain = None
  self.current_prefix = None
  self.current_prefix_type = None
  self.current_stripe = None
  self.current_bitset = None
  self.current_bitsize = 32
  # The varset attribute on the domain specifies the enum which
  # specifies all possible hw variants:
  self.current_varset = None
  # Regs that have multiple variants.. we only generated the C++
  # template based struct-packers for these
  self.variant_regs = {}
  # Information in which contexts regs are used, to be used in
  # debug options
  self.usage_regs = collections.defaultdict(list)
  self.bitsets = {}
  self.enums = {}
  self.variants = set()
  self.file = []
  self.xml_files = []
  self.copyright_year = None
  self.authors = []
  self.license = None

 def error(self, message):
  parser, filename = self.stack[-1]
  return Error("%s:%d:%d: %s" % (filename, parser.CurrentLineNumber, parser.CurrentColumnNumber, message))

 def prefix(self, variant=None):
  if self.current_prefix_type == "variant" and variant:
   return variant
  elif self.current_stripe:
   return self.current_stripe + "_" + self.current_domain
  elif self.current_prefix:
   return self.current_prefix + "_" + self.current_domain
  else:
   return self.current_domain

 def parse_field(self, name, attrs):
  try:
   if "pos" in attrs:
    high = low = int(attrs["pos"], 0)
   elif "high" in attrs and "low" in attrs:
    high = int(attrs["high"], 0)
    low = int(attrs["low"], 0)
   else:
    low = 0
    high = self.current_bitsize - 1

   if "type" in attrs:
    type = attrs["type"]
   else:
    type = None

   if "shr" in attrs:
    shr = int(attrs["shr"], 0)
   else:
    shr = 0

   b = Field(name, low, high, shr, type, self)

   if type == "fixed" or type == "ufixed":
    b.radix = int(attrs["radix"], 0)

   self.current_bitset.fields.append(b)
  except ValueError as e:
   raise self.error(e)

 def parse_varset(self, attrs):
  # Inherit the varset from the enclosing domain if not overriden:
  varset = self.current_varset
  if "varset" in attrs:
   varset = self.enums[attrs["varset"]]
  return varset

 def parse_variants(self, attrs):
  if not "variants" in attrs:
    return None
  variant = attrs["variants"].split(",")[0]
  if "-" in variant:
   variant = variant[:variant.index("-")]

  varset = self.parse_varset(attrs)

  assert varset.has_name(variant)

  return variant

 def add_all_variants(self, reg, attrs, parent_variant):
  # TODO this should really handle *all* variants, including dealing
  # with open ended ranges (ie. "A2XX,A4XX-") (we have the varset
  # enum now to make that possible)
  variant = self.parse_variants(attrs)
  if not variant:
   variant = parent_variant

  if reg.name not in self.variant_regs:
   self.variant_regs[reg.name] = {}
  else:
   # All variants must be same size:
   v = next(iter(self.variant_regs[reg.name]))
   assert self.variant_regs[reg.name][v].bit_size == reg.bit_size

  self.variant_regs[reg.name][variant] = reg

 def add_all_usages(self, reg, usages):
  if not usages:
   return

  for usage in usages:
   self.usage_regs[usage].append(reg)

  self.variants.add(reg.domain)

 def do_validate(self, schemafile):
  if not self.validate:
   return

  try:
   from lxml import etree

   parser, filename = self.stack[-1]
   dirname = os.path.dirname(filename)

   # we expect this to look like <namespace url> schema.xsd.. I think
   # technically it is supposed to be just a URL, but that doesn't
   # quite match up to what we do.. Just skip over everything up to
   # and including the first whitespace character:
   schemafile = schemafile[schemafile.rindex(" ")+1:]

   # this is a bit cheezy, but the xml file to validate could be
   # in a child director, ie. we don't really know where the schema
   # file is, the way the rnn C code does.  So if it doesn't exist
   # just look one level up
   if not os.path.exists(dirname + "/" + schemafile):
    schemafile = "../" + schemafile

   if not os.path.exists(dirname + "/" + schemafile):
    raise self.error("Cannot find schema for: " + filename)

   xmlschema_doc = etree.parse(dirname + "/" + schemafile)
   xmlschema = etree.XMLSchema(xmlschema_doc)

   xml_doc = etree.parse(filename)
   if not xmlschema.validate(xml_doc):
    error_str = str(xmlschema.error_log.filter_from_errors()[0])
    raise self.error("Schema validation failed for: " + filename + "\n" + error_str)
  except ImportError as e:
   if self.validate:
    raise e

   print("lxml not found, skipping validation", file=sys.stderr)

 def do_parse(self, filename):
  filepath = os.path.abspath(filename)
  if filepath in self.xml_files:
   return
  self.xml_files.append(filepath)
  file = open(filename, "rb")
  parser = xml.parsers.expat.ParserCreate()
  self.stack.append((parser, filename))
  parser.StartElementHandler = self.start_element
  parser.EndElementHandler = self.end_element
  parser.CharacterDataHandler = self.character_data
  parser.buffer_text = True
  parser.ParseFile(file)
  self.stack.pop()
  file.close()

 def parse(self, rnn_path, filename, validate):
  self.path = rnn_path
  self.stack = []
  self.validate = validate
  self.do_parse(filename)

 def parse_reg(self, attrs, bit_size):
  self.current_bitsize = bit_size
  if "type" in attrs and attrs["type"in self.bitsets:
   bitset = self.bitsets[attrs["type"]]
   if bitset.inline:
    self.current_bitset = Bitset(attrs["name"], bitset)
    self.current_bitset.inline = True
   else:
    self.current_bitset = bitset
  else:
   self.current_bitset = Bitset(attrs["name"], None)
   self.current_bitset.inline = True
   if "type" in attrs:
    self.parse_field(None, attrs)

  variant = self.parse_variants(attrs)
  if not variant and self.current_array:
   variant = self.current_array.variant

  self.current_reg = Reg(attrs, self.prefix(variant), self.current_array, bit_size)
  self.current_reg.bitset = self.current_bitset
  self.current_bitset.reg = self.current_reg

  if len(self.stack) == 1:
   self.file.append(self.current_reg)

  if variant is not None:
   self.add_all_variants(self.current_reg, attrs, variant)

  usages = None
  if "usage" in attrs:
   usages = attrs["usage"].split(',')
  elif self.current_array:
   usages = self.current_array.usages

  self.add_all_usages(self.current_reg, usages)

 def start_element(self, name, attrs):
  self.cdata = ""
  if name == "import":
   filename = attrs["file"]
   self.do_parse(os.path.join(self.path, filename))
  elif name == "domain":
   self.current_domain = attrs["name"]
   if "prefix" in attrs:
    self.current_prefix = self.parse_variants(attrs)
    self.current_prefix_type = attrs["prefix"]
   else:
    self.current_prefix = None
    self.current_prefix_type = None
   if "varset" in attrs:
    self.current_varset = self.enums[attrs["varset"]]
  elif name == "stripe":
   self.current_stripe = self.parse_variants(attrs)
  elif name == "enum":
   self.current_enum_value = 0
   self.current_enum = Enum(attrs["name"])
   self.enums[attrs["name"]] = self.current_enum
   if len(self.stack) == 1:
    self.file.append(self.current_enum)
  elif name == "value":
   if "value" in attrs:
    value = int(attrs["value"], 0)
   else:
    value = self.current_enum_value
   self.current_enum.values.append((attrs["name"], value))
  elif name == "reg32":
   self.parse_reg(attrs, 32)
  elif name == "reg64":
   self.parse_reg(attrs, 64)
  elif name == "array":
   self.current_bitsize = 32
   variant = self.parse_variants(attrs)
   index_type = self.enums[attrs["index"]] if "index" in attrs else None
   self.current_array = Array(attrs, self.prefix(variant), variant, self.current_array, index_type)
   if len(self.stack) == 1:
    self.file.append(self.current_array)
  elif name == "bitset":
   self.current_bitset = Bitset(attrs["name"], None)
   if "inline" in attrs and attrs["inline"] == "yes":
    self.current_bitset.inline = True
   self.bitsets[self.current_bitset.name] = self.current_bitset
   if len(self.stack) == 1 and not self.current_bitset.inline:
    self.file.append(self.current_bitset)
  elif name == "bitfield" and self.current_bitset:
   self.parse_field(attrs["name"], attrs)
  elif name == "database":
   self.do_validate(attrs["xsi:schemaLocation"])
  elif name == "copyright":
   self.copyright_year = attrs["year"]
  elif name == "author":
   self.authors.append(attrs["name"] + " <" + attrs["email"] + "> " + attrs["name"])

 def end_element(self, name):
  if name == "domain":
   self.current_domain = None
   self.current_prefix = None
   self.current_prefix_type = None
  elif name == "stripe":
   self.current_stripe = None
  elif name == "bitset":
   self.current_bitset = None
  elif name == "reg32":
   self.current_reg = None
  elif name == "array":
   self.current_array = self.current_array.parent
  elif name == "enum":
   self.current_enum = None
  elif name == "license":
   self.license = self.cdata

 def character_data(self, data):
  self.cdata += data

 def dump_reg_usages(self):
  d = collections.defaultdict(list)
  for usage, regs in self.usage_regs.items():
   for reg in regs:
    variants = self.variant_regs.get(reg.name)
    if variants:
     for variant, vreg in variants.items():
      if reg == vreg:
       d[(usage, variant)].append(reg)
    else:
     for variant in self.variants:
      d[(usage, variant)].append(reg)

  print("#ifdef __cplusplus")

  for usage, regs in self.usage_regs.items():
   print("template constexpr inline uint16_t %s_REGS[] = {};" % (usage.upper()))

  for (usage, variant), regs in d.items():
   offsets = []

   for reg in regs:
    if reg.array:
     for i in range(reg.array.length):
      offsets.append(reg.array.offset + reg.offset + i * reg.array.stride)
      if reg.bit_size == 64:
       offsets.append(offsets[-1] + 1)
    else:
     offsets.append(reg.offset)
     if reg.bit_size == 64:
      offsets.append(offsets[-1] + 1)

   offsets.sort()

   print("template<> constexpr inline uint16_t %s_REGS<%s>[] = {" % (usage.upper(), variant))
   for offset in offsets:
    print("\t%s," % hex(offset))
   print("};")

  print("#endif")

 def dump(self):
  enums = []
  bitsets = []
  regs = []
  for e in self.file:
   if isinstance(e, Enum):
    enums.append(e)
   elif isinstance(e, Bitset):
    bitsets.append(e)
   else:
    regs.append(e)

  for e in enums + bitsets + regs:
   e.dump()

  self.dump_reg_usages()


 def dump_regs_py(self):
  regs = []
  for e in self.file:
   if isinstance(e, Reg):
    regs.append(e)

  for e in regs:
   e.dump_py()


 def dump_reg_variants(self, regname, variants):
  # Don't bother for things that only have a single variant:
  if len(variants) == 1:
   return
  print("#ifdef __cplusplus")
  print("struct __%s {" % regname)
  # TODO be more clever.. we should probably figure out which
  # fields have the same type in all variants (in which they
  # appear) and stuff everything else in a variant specific
  # sub-structure.
  seen_fields = []
  bit_size = 32
  array = False
  address = None
  for variant in variants.keys():
   print(" /* %s fields: */" % variant)
   reg = variants[variant]
   bit_size = reg.bit_size
   array = reg.array
   for f in reg.bitset.fields:
    fld_name = field_name(reg, f)
    if fld_name in seen_fields:
     continue
    seen_fields.append(fld_name)
    name = fld_name.lower()
    if f.type in [ "address""waddress" ]:
     if address:
      continue
     address = f
     tab_to(" __bo_type""bo;")
     tab_to(" uint32_t""bo_offset;")
     continue
    type, val = f.ctype("var")
    tab_to(" %s" %type, "%s;" %name)
  print(" /* fallback fields: */")
  if bit_size == 64:
   tab_to(" uint64_t""unknown;")
   tab_to(" uint64_t""qword;")
  else:
   tab_to(" uint32_t""unknown;")
   tab_to(" uint32_t""dword;")
  print("};")
  # TODO don't hardcode the varset enum name
  varenum = "chip"
  print("template <%s %s>" % (varenum, varenum.upper()))
  print("static inline struct fd_reg_pair")
  xtra = ""
  xtravar = ""
  if array:
   xtra = "int __i, "
   xtravar = "__i, "
  print("__%s(%sstruct __%s fields) {" % (regname, xtra, regname))
  for variant in variants.keys():
   print(" if (%s == %s) {" % (varenum.upper(), variant))
   reg = variants[variant]
   reg.dump_regpair_builder()
   print(" } else")
  print(" assert(!\"invalid variant\");")
  print("}")

  if bit_size == 64:
   skip = ", { .reg = 0 }"
  else:
   skip = ""

  print("#define %s(VARIANT, %s...) __%s(%s{__VA_ARGS__})%s" % (regname, xtravar, regname, xtravar, skip))
  print("#endif /* __cplusplus */")

 def dump_structs(self):
  for e in self.file:
   e.dump_pack_struct()

  for regname in self.variant_regs:
   self.dump_reg_variants(regname, self.variant_regs[regname])


def dump_c(args, guard, func):
 p = Parser()

 try:
  p.parse(args.rnn, args.xml, args.validate)
 except Error as e:
  print(e, file=sys.stderr)
  exit(1)

 print("#ifndef %s\n#define %s\n" % (guard, guard))

 print("""/* Autogenerated file, DO NOT EDIT manually!

This file was generated by the rules-ng-ng gen_header.py tool in this git repository:
http://gitlab.freedesktop.org/mesa/mesa/
git clone https://gitlab.freedesktop.org/mesa/mesa.git

The rules-ng-ng source files this header was generated from are:
""")
 maxlen = 0
 for filepath in p.xml_files:
  new_filepath = re.sub("^.+drivers","drivers",filepath)
  maxlen = max(maxlen, len(new_filepath))
 for filepath in p.xml_files:
  pad = " " * (maxlen - len(new_filepath))
  filesize = str(os.path.getsize(filepath))
  filesize = " " * (7 - len(filesize)) + filesize
  filetime = time.ctime(os.path.getmtime(filepath))
  print("- " + new_filepath + pad + " (" + filesize + " bytes, from )")
 if p.copyright_year:
  current_year = str(datetime.date.today().year)
  print()
  print("Copyright (C) %s-%s by the following authors:" % (p.copyright_year, current_year))
  for author in p.authors:
   print("- " + author)
 if p.license:
  print(p.license)
 print("*/")

 print()
 print("#ifdef __KERNEL__")
 print("#include ")
 print("#define assert(x) BUG_ON(!(x))")
 print("#else")
 print("#include ")
 print("#endif")
 print()

 print("#ifdef __cplusplus")
 print("#define __struct_cast(X)")
 print("#else")
 print("#define __struct_cast(X) (struct X)")
 print("#endif")
 print()

 func(p)

 print("\n#endif /* %s */" % guard)


def dump_c_defines(args):
 guard = str.replace(os.path.basename(args.xml), '.''_').upper()
 dump_c(args, guard, lambda p: p.dump())


def dump_c_pack_structs(args):
 guard = str.replace(os.path.basename(args.xml), '.''_').upper() + '_STRUCTS'
 dump_c(args, guard, lambda p: p.dump_structs())


def dump_py_defines(args):
 p = Parser()

 try:
  p.parse(args.rnn, args.xml)
 except Error as e:
  print(e, file=sys.stderr)
  exit(1)

 file_name = os.path.splitext(os.path.basename(args.xml))[0]

 print("from enum import IntEnum")
 print("class %sRegs(IntEnum):" % file_name.upper())

 os.path.basename(args.xml)

 p.dump_regs_py()


def main():
 parser = argparse.ArgumentParser()
 parser.add_argument('--rnn', type=str, required=True)
 parser.add_argument('--xml', type=str, required=True)
 parser.add_argument('--validate', default=False, action='store_true')
 parser.add_argument('--no-validate', dest='validate', action='store_false')

 subparsers = parser.add_subparsers()
 subparsers.required = True

 parser_c_defines = subparsers.add_parser('c-defines')
 parser_c_defines.set_defaults(func=dump_c_defines)

 parser_c_pack_structs = subparsers.add_parser('c-pack-structs')
 parser_c_pack_structs.set_defaults(func=dump_c_pack_structs)

 parser_py_defines = subparsers.add_parser('py-defines')
 parser_py_defines.set_defaults(func=dump_py_defines)

 args = parser.parse_args()
 args.func(args)


if __name__ == '__main__':
 main()

Messung V0.5
C=89 H=91 G=89

¤ Dauer der Verarbeitung: 0.23 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge