1bf215546Sopenharmony_ci#encoding=utf-8 2bf215546Sopenharmony_ci 3bf215546Sopenharmony_ciimport argparse 4bf215546Sopenharmony_ciimport ast 5bf215546Sopenharmony_ciimport xml.parsers.expat 6bf215546Sopenharmony_ciimport re 7bf215546Sopenharmony_ciimport sys 8bf215546Sopenharmony_ciimport copy 9bf215546Sopenharmony_ciimport textwrap 10bf215546Sopenharmony_cifrom util import * 11bf215546Sopenharmony_ci 12bf215546Sopenharmony_cilicense = """/* 13bf215546Sopenharmony_ci * Copyright (C) 2016 Intel Corporation 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 16bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 17bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 18bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 19bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 20bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 21bf215546Sopenharmony_ci * 22bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 23bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 24bf215546Sopenharmony_ci * Software. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 27bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 28bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 29bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 30bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 31bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 32bf215546Sopenharmony_ci * IN THE SOFTWARE. 33bf215546Sopenharmony_ci */ 34bf215546Sopenharmony_ci""" 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_cipack_header = """%(license)s 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci/* Instructions, enums and structures for %(platform)s. 39bf215546Sopenharmony_ci * 40bf215546Sopenharmony_ci * This file has been generated, do not hand edit. 41bf215546Sopenharmony_ci */ 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_ci#ifndef %(guard)s 44bf215546Sopenharmony_ci#define %(guard)s 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ci#include <stdio.h> 47bf215546Sopenharmony_ci#include <stdint.h> 48bf215546Sopenharmony_ci#include <stdbool.h> 49bf215546Sopenharmony_ci#include <assert.h> 50bf215546Sopenharmony_ci#include <math.h> 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci#ifndef __gen_validate_value 53bf215546Sopenharmony_ci#define __gen_validate_value(x) 54bf215546Sopenharmony_ci#endif 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci#ifndef __intel_field_functions 57bf215546Sopenharmony_ci#define __intel_field_functions 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci#ifdef NDEBUG 60bf215546Sopenharmony_ci#define NDEBUG_UNUSED __attribute__((unused)) 61bf215546Sopenharmony_ci#else 62bf215546Sopenharmony_ci#define NDEBUG_UNUSED 63bf215546Sopenharmony_ci#endif 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ciunion __intel_value { 66bf215546Sopenharmony_ci float f; 67bf215546Sopenharmony_ci uint32_t dw; 68bf215546Sopenharmony_ci}; 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_cistatic inline __attribute__((always_inline)) uint64_t 71bf215546Sopenharmony_ci__gen_mbo(uint32_t start, uint32_t end) 72bf215546Sopenharmony_ci{ 73bf215546Sopenharmony_ci return (~0ull >> (64 - (end - start + 1))) << start; 74bf215546Sopenharmony_ci} 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_cistatic inline __attribute__((always_inline)) uint64_t 77bf215546Sopenharmony_ci__gen_uint(uint64_t v, uint32_t start, NDEBUG_UNUSED uint32_t end) 78bf215546Sopenharmony_ci{ 79bf215546Sopenharmony_ci __gen_validate_value(v); 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci#ifndef NDEBUG 82bf215546Sopenharmony_ci const int width = end - start + 1; 83bf215546Sopenharmony_ci if (width < 64) { 84bf215546Sopenharmony_ci const uint64_t max = (1ull << width) - 1; 85bf215546Sopenharmony_ci assert(v <= max); 86bf215546Sopenharmony_ci } 87bf215546Sopenharmony_ci#endif 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci return v << start; 90bf215546Sopenharmony_ci} 91bf215546Sopenharmony_ci 92bf215546Sopenharmony_cistatic inline __attribute__((always_inline)) uint64_t 93bf215546Sopenharmony_ci__gen_uint_nonzero(uint64_t v, uint32_t start, uint32_t end) 94bf215546Sopenharmony_ci{ 95bf215546Sopenharmony_ci assert(v != 0ull); 96bf215546Sopenharmony_ci return __gen_uint(v, start, end); 97bf215546Sopenharmony_ci} 98bf215546Sopenharmony_ci 99bf215546Sopenharmony_cistatic inline __attribute__((always_inline)) uint64_t 100bf215546Sopenharmony_ci__gen_sint(int64_t v, uint32_t start, uint32_t end) 101bf215546Sopenharmony_ci{ 102bf215546Sopenharmony_ci const int width = end - start + 1; 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_ci __gen_validate_value(v); 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci#ifndef NDEBUG 107bf215546Sopenharmony_ci if (width < 64) { 108bf215546Sopenharmony_ci const int64_t max = (1ll << (width - 1)) - 1; 109bf215546Sopenharmony_ci const int64_t min = -(1ll << (width - 1)); 110bf215546Sopenharmony_ci assert(min <= v && v <= max); 111bf215546Sopenharmony_ci } 112bf215546Sopenharmony_ci#endif 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci const uint64_t mask = ~0ull >> (64 - width); 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci return (v & mask) << start; 117bf215546Sopenharmony_ci} 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_cistatic inline __attribute__((always_inline)) uint64_t 120bf215546Sopenharmony_ci__gen_sint_nonzero(int64_t v, uint32_t start, uint32_t end) 121bf215546Sopenharmony_ci{ 122bf215546Sopenharmony_ci assert(v != 0ll); 123bf215546Sopenharmony_ci return __gen_sint(v, start, end); 124bf215546Sopenharmony_ci} 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_cistatic inline __attribute__((always_inline)) uint64_t 127bf215546Sopenharmony_ci__gen_offset(uint64_t v, NDEBUG_UNUSED uint32_t start, NDEBUG_UNUSED uint32_t end) 128bf215546Sopenharmony_ci{ 129bf215546Sopenharmony_ci __gen_validate_value(v); 130bf215546Sopenharmony_ci#ifndef NDEBUG 131bf215546Sopenharmony_ci uint64_t mask = (~0ull >> (64 - (end - start + 1))) << start; 132bf215546Sopenharmony_ci 133bf215546Sopenharmony_ci assert((v & ~mask) == 0); 134bf215546Sopenharmony_ci#endif 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_ci return v; 137bf215546Sopenharmony_ci} 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_cistatic inline __attribute__((always_inline)) uint64_t 140bf215546Sopenharmony_ci__gen_offset_nonzero(uint64_t v, uint32_t start, uint32_t end) 141bf215546Sopenharmony_ci{ 142bf215546Sopenharmony_ci assert(v != 0ull); 143bf215546Sopenharmony_ci return __gen_offset(v, start, end); 144bf215546Sopenharmony_ci} 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_cistatic inline __attribute__((always_inline)) uint64_t 147bf215546Sopenharmony_ci__gen_address(__gen_user_data *data, void *location, 148bf215546Sopenharmony_ci __gen_address_type address, uint32_t delta, 149bf215546Sopenharmony_ci __attribute__((unused)) uint32_t start, uint32_t end) 150bf215546Sopenharmony_ci{ 151bf215546Sopenharmony_ci uint64_t addr_u64 = __gen_combine_address(data, location, address, delta); 152bf215546Sopenharmony_ci if (end == 31) { 153bf215546Sopenharmony_ci return addr_u64; 154bf215546Sopenharmony_ci } else if (end < 63) { 155bf215546Sopenharmony_ci const unsigned shift = 63 - end; 156bf215546Sopenharmony_ci return (addr_u64 << shift) >> shift; 157bf215546Sopenharmony_ci } else { 158bf215546Sopenharmony_ci return addr_u64; 159bf215546Sopenharmony_ci } 160bf215546Sopenharmony_ci} 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_cistatic inline __attribute__((always_inline)) uint32_t 163bf215546Sopenharmony_ci__gen_float(float v) 164bf215546Sopenharmony_ci{ 165bf215546Sopenharmony_ci __gen_validate_value(v); 166bf215546Sopenharmony_ci return ((union __intel_value) { .f = (v) }).dw; 167bf215546Sopenharmony_ci} 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_cistatic inline __attribute__((always_inline)) uint32_t 170bf215546Sopenharmony_ci__gen_float_nonzero(float v) 171bf215546Sopenharmony_ci{ 172bf215546Sopenharmony_ci assert(v != 0.0f); 173bf215546Sopenharmony_ci return __gen_float(v); 174bf215546Sopenharmony_ci} 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_cistatic inline __attribute__((always_inline)) uint64_t 177bf215546Sopenharmony_ci__gen_sfixed(float v, uint32_t start, uint32_t end, uint32_t fract_bits) 178bf215546Sopenharmony_ci{ 179bf215546Sopenharmony_ci __gen_validate_value(v); 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci const float factor = (1 << fract_bits); 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci#ifndef NDEBUG 184bf215546Sopenharmony_ci const float max = ((1 << (end - start)) - 1) / factor; 185bf215546Sopenharmony_ci const float min = -(1 << (end - start)) / factor; 186bf215546Sopenharmony_ci assert(min <= v && v <= max); 187bf215546Sopenharmony_ci#endif 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci const int64_t int_val = llroundf(v * factor); 190bf215546Sopenharmony_ci const uint64_t mask = ~0ull >> (64 - (end - start + 1)); 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci return (int_val & mask) << start; 193bf215546Sopenharmony_ci} 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_cistatic inline __attribute__((always_inline)) uint64_t 196bf215546Sopenharmony_ci__gen_sfixed_nonzero(float v, uint32_t start, uint32_t end, uint32_t fract_bits) 197bf215546Sopenharmony_ci{ 198bf215546Sopenharmony_ci assert(v != 0.0f); 199bf215546Sopenharmony_ci return __gen_sfixed(v, start, end, fract_bits); 200bf215546Sopenharmony_ci} 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_cistatic inline __attribute__((always_inline)) uint64_t 203bf215546Sopenharmony_ci__gen_ufixed(float v, uint32_t start, NDEBUG_UNUSED uint32_t end, uint32_t fract_bits) 204bf215546Sopenharmony_ci{ 205bf215546Sopenharmony_ci __gen_validate_value(v); 206bf215546Sopenharmony_ci 207bf215546Sopenharmony_ci const float factor = (1 << fract_bits); 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci#ifndef NDEBUG 210bf215546Sopenharmony_ci const float max = ((1 << (end - start + 1)) - 1) / factor; 211bf215546Sopenharmony_ci const float min = 0.0f; 212bf215546Sopenharmony_ci assert(min <= v && v <= max); 213bf215546Sopenharmony_ci#endif 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_ci const uint64_t uint_val = llroundf(v * factor); 216bf215546Sopenharmony_ci 217bf215546Sopenharmony_ci return uint_val << start; 218bf215546Sopenharmony_ci} 219bf215546Sopenharmony_ci 220bf215546Sopenharmony_cistatic inline __attribute__((always_inline)) uint64_t 221bf215546Sopenharmony_ci__gen_ufixed_nonzero(float v, uint32_t start, uint32_t end, uint32_t fract_bits) 222bf215546Sopenharmony_ci{ 223bf215546Sopenharmony_ci assert(v != 0.0f); 224bf215546Sopenharmony_ci return __gen_ufixed(v, start, end, fract_bits); 225bf215546Sopenharmony_ci} 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci#ifndef __gen_address_type 228bf215546Sopenharmony_ci#error #define __gen_address_type before including this file 229bf215546Sopenharmony_ci#endif 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci#ifndef __gen_user_data 232bf215546Sopenharmony_ci#error #define __gen_combine_address before including this file 233bf215546Sopenharmony_ci#endif 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci#undef NDEBUG_UNUSED 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci#endif 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci""" 240bf215546Sopenharmony_ci 241bf215546Sopenharmony_cidef num_from_str(num_str): 242bf215546Sopenharmony_ci if num_str.lower().startswith('0x'): 243bf215546Sopenharmony_ci return int(num_str, base=16) 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ci assert not num_str.startswith('0'), 'octals numbers not allowed' 246bf215546Sopenharmony_ci return int(num_str) 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_cidef bool_from_str(bool_str): 249bf215546Sopenharmony_ci options = { "true": True, "false": False } 250bf215546Sopenharmony_ci return options[bool_str]; 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ciclass Field(object): 253bf215546Sopenharmony_ci ufixed_pattern = re.compile(r"u(\d+)\.(\d+)") 254bf215546Sopenharmony_ci sfixed_pattern = re.compile(r"s(\d+)\.(\d+)") 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci def __init__(self, parser, attrs): 257bf215546Sopenharmony_ci self.parser = parser 258bf215546Sopenharmony_ci if "name" in attrs: 259bf215546Sopenharmony_ci self.name = safe_name(attrs["name"]) 260bf215546Sopenharmony_ci self.start = int(attrs["start"]) 261bf215546Sopenharmony_ci self.end = int(attrs["end"]) 262bf215546Sopenharmony_ci self.type = attrs["type"] 263bf215546Sopenharmony_ci self.nonzero = bool_from_str(attrs.get("nonzero", "false")) 264bf215546Sopenharmony_ci 265bf215546Sopenharmony_ci assert self.start <= self.end, \ 266bf215546Sopenharmony_ci 'field {} has end ({}) < start ({})'.format(self.name, self.end, 267bf215546Sopenharmony_ci self.start) 268bf215546Sopenharmony_ci if self.type == 'bool': 269bf215546Sopenharmony_ci assert self.end == self.start, \ 270bf215546Sopenharmony_ci 'bool field ({}) is too wide'.format(self.name) 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci if "prefix" in attrs: 273bf215546Sopenharmony_ci self.prefix = attrs["prefix"] 274bf215546Sopenharmony_ci else: 275bf215546Sopenharmony_ci self.prefix = None 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci if "default" in attrs: 278bf215546Sopenharmony_ci # Base 0 recognizes 0x, 0o, 0b prefixes in addition to decimal ints. 279bf215546Sopenharmony_ci self.default = int(attrs["default"], base=0) 280bf215546Sopenharmony_ci else: 281bf215546Sopenharmony_ci self.default = None 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci ufixed_match = Field.ufixed_pattern.match(self.type) 284bf215546Sopenharmony_ci if ufixed_match: 285bf215546Sopenharmony_ci self.type = 'ufixed' 286bf215546Sopenharmony_ci self.fractional_size = int(ufixed_match.group(2)) 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_ci sfixed_match = Field.sfixed_pattern.match(self.type) 289bf215546Sopenharmony_ci if sfixed_match: 290bf215546Sopenharmony_ci self.type = 'sfixed' 291bf215546Sopenharmony_ci self.fractional_size = int(sfixed_match.group(2)) 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci def is_builtin_type(self): 294bf215546Sopenharmony_ci builtins = [ 'address', 'bool', 'float', 'ufixed', 295bf215546Sopenharmony_ci 'offset', 'sfixed', 'offset', 'int', 'uint', 296bf215546Sopenharmony_ci 'mbo', 'mbz' ] 297bf215546Sopenharmony_ci return self.type in builtins 298bf215546Sopenharmony_ci 299bf215546Sopenharmony_ci def is_struct_type(self): 300bf215546Sopenharmony_ci return self.type in self.parser.structs 301bf215546Sopenharmony_ci 302bf215546Sopenharmony_ci def is_enum_type(self): 303bf215546Sopenharmony_ci return self.type in self.parser.enums 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_ci def emit_template_struct(self, dim): 306bf215546Sopenharmony_ci if self.type == 'address': 307bf215546Sopenharmony_ci type = '__gen_address_type' 308bf215546Sopenharmony_ci elif self.type == 'bool': 309bf215546Sopenharmony_ci type = 'bool' 310bf215546Sopenharmony_ci elif self.type == 'float': 311bf215546Sopenharmony_ci type = 'float' 312bf215546Sopenharmony_ci elif self.type == 'ufixed': 313bf215546Sopenharmony_ci type = 'float' 314bf215546Sopenharmony_ci elif self.type == 'sfixed': 315bf215546Sopenharmony_ci type = 'float' 316bf215546Sopenharmony_ci elif self.type == 'uint' and self.end - self.start > 32: 317bf215546Sopenharmony_ci type = 'uint64_t' 318bf215546Sopenharmony_ci elif self.type == 'offset': 319bf215546Sopenharmony_ci type = 'uint64_t' 320bf215546Sopenharmony_ci elif self.type == 'int': 321bf215546Sopenharmony_ci type = 'int32_t' 322bf215546Sopenharmony_ci elif self.type == 'uint': 323bf215546Sopenharmony_ci type = 'uint32_t' 324bf215546Sopenharmony_ci elif self.is_struct_type(): 325bf215546Sopenharmony_ci type = 'struct ' + self.parser.gen_prefix(safe_name(self.type)) 326bf215546Sopenharmony_ci elif self.is_enum_type(): 327bf215546Sopenharmony_ci type = 'enum ' + self.parser.gen_prefix(safe_name(self.type)) 328bf215546Sopenharmony_ci elif self.type == 'mbo' or self.type == 'mbz': 329bf215546Sopenharmony_ci return 330bf215546Sopenharmony_ci else: 331bf215546Sopenharmony_ci print("#error unhandled type: %s" % self.type) 332bf215546Sopenharmony_ci return 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci print(" %-36s %s%s;" % (type, self.name, dim)) 335bf215546Sopenharmony_ci 336bf215546Sopenharmony_ci prefix = self.prefix + '_' if self.prefix else '' 337bf215546Sopenharmony_ci 338bf215546Sopenharmony_ci for value in self.values: 339bf215546Sopenharmony_ci name = value.name 340bf215546Sopenharmony_ci if self.prefix and value.name[0] == '_': 341bf215546Sopenharmony_ci name = name[1:] 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_ci print("#define %-40s %d" % (prefix + name, value.value)) 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ciclass Group(object): 346bf215546Sopenharmony_ci def __init__(self, parser, parent, start, count, size): 347bf215546Sopenharmony_ci self.parser = parser 348bf215546Sopenharmony_ci self.parent = parent 349bf215546Sopenharmony_ci self.start = start 350bf215546Sopenharmony_ci self.count = count 351bf215546Sopenharmony_ci self.size = size 352bf215546Sopenharmony_ci self.fields = [] 353bf215546Sopenharmony_ci 354bf215546Sopenharmony_ci def emit_template_struct(self, dim): 355bf215546Sopenharmony_ci if self.count == 0: 356bf215546Sopenharmony_ci print(" /* variable length fields follow */") 357bf215546Sopenharmony_ci else: 358bf215546Sopenharmony_ci if self.count > 1: 359bf215546Sopenharmony_ci dim = "%s[%d]" % (dim, self.count) 360bf215546Sopenharmony_ci 361bf215546Sopenharmony_ci for field in self.fields: 362bf215546Sopenharmony_ci field.emit_template_struct(dim) 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci class DWord: 365bf215546Sopenharmony_ci def __init__(self): 366bf215546Sopenharmony_ci self.size = 32 367bf215546Sopenharmony_ci self.fields = [] 368bf215546Sopenharmony_ci self.address = None 369bf215546Sopenharmony_ci 370bf215546Sopenharmony_ci def collect_dwords(self, dwords, start, dim): 371bf215546Sopenharmony_ci for field in self.fields: 372bf215546Sopenharmony_ci if isinstance(field, Group): 373bf215546Sopenharmony_ci if field.count == 1: 374bf215546Sopenharmony_ci field.collect_dwords(dwords, start + field.start, dim) 375bf215546Sopenharmony_ci else: 376bf215546Sopenharmony_ci for i in range(field.count): 377bf215546Sopenharmony_ci field.collect_dwords(dwords, 378bf215546Sopenharmony_ci start + field.start + i * field.size, 379bf215546Sopenharmony_ci "%s[%d]" % (dim, i)) 380bf215546Sopenharmony_ci continue 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci index = (start + field.start) // 32 383bf215546Sopenharmony_ci if not index in dwords: 384bf215546Sopenharmony_ci dwords[index] = self.DWord() 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci clone = copy.copy(field) 387bf215546Sopenharmony_ci clone.start = clone.start + start 388bf215546Sopenharmony_ci clone.end = clone.end + start 389bf215546Sopenharmony_ci clone.dim = dim 390bf215546Sopenharmony_ci dwords[index].fields.append(clone) 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci if field.type == "address": 393bf215546Sopenharmony_ci # assert dwords[index].address == None 394bf215546Sopenharmony_ci dwords[index].address = clone 395bf215546Sopenharmony_ci 396bf215546Sopenharmony_ci # Coalesce all the dwords covered by this field. The two cases we 397bf215546Sopenharmony_ci # handle are where multiple fields are in a 64 bit word (typically 398bf215546Sopenharmony_ci # and address and a few bits) or where a single struct field 399bf215546Sopenharmony_ci # completely covers multiple dwords. 400bf215546Sopenharmony_ci while index < (start + field.end) // 32: 401bf215546Sopenharmony_ci if index + 1 in dwords and not dwords[index] == dwords[index + 1]: 402bf215546Sopenharmony_ci dwords[index].fields.extend(dwords[index + 1].fields) 403bf215546Sopenharmony_ci dwords[index].size = 64 404bf215546Sopenharmony_ci dwords[index + 1] = dwords[index] 405bf215546Sopenharmony_ci index = index + 1 406bf215546Sopenharmony_ci 407bf215546Sopenharmony_ci def collect_dwords_and_length(self): 408bf215546Sopenharmony_ci dwords = {} 409bf215546Sopenharmony_ci self.collect_dwords(dwords, 0, "") 410bf215546Sopenharmony_ci 411bf215546Sopenharmony_ci # Determine number of dwords in this group. If we have a size, use 412bf215546Sopenharmony_ci # that, since that'll account for MBZ dwords at the end of a group 413bf215546Sopenharmony_ci # (like dword 8 on BDW+ 3DSTATE_HS). Otherwise, use the largest dword 414bf215546Sopenharmony_ci # index we've seen plus one. 415bf215546Sopenharmony_ci if self.size > 0: 416bf215546Sopenharmony_ci length = self.size // 32 417bf215546Sopenharmony_ci elif dwords: 418bf215546Sopenharmony_ci length = max(dwords.keys()) + 1 419bf215546Sopenharmony_ci else: 420bf215546Sopenharmony_ci length = 0 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ci return (dwords, length) 423bf215546Sopenharmony_ci 424bf215546Sopenharmony_ci def emit_pack_function(self, dwords, length): 425bf215546Sopenharmony_ci for index in range(length): 426bf215546Sopenharmony_ci # Handle MBZ dwords 427bf215546Sopenharmony_ci if not index in dwords: 428bf215546Sopenharmony_ci print("") 429bf215546Sopenharmony_ci print(" dw[%d] = 0;" % index) 430bf215546Sopenharmony_ci continue 431bf215546Sopenharmony_ci 432bf215546Sopenharmony_ci # For 64 bit dwords, we aliased the two dword entries in the dword 433bf215546Sopenharmony_ci # dict it occupies. Now that we're emitting the pack function, 434bf215546Sopenharmony_ci # skip the duplicate entries. 435bf215546Sopenharmony_ci dw = dwords[index] 436bf215546Sopenharmony_ci if index > 0 and index - 1 in dwords and dw == dwords[index - 1]: 437bf215546Sopenharmony_ci continue 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_ci # Special case: only one field and it's a struct at the beginning 440bf215546Sopenharmony_ci # of the dword. In this case we pack directly into the 441bf215546Sopenharmony_ci # destination. This is the only way we handle embedded structs 442bf215546Sopenharmony_ci # larger than 32 bits. 443bf215546Sopenharmony_ci if len(dw.fields) == 1: 444bf215546Sopenharmony_ci field = dw.fields[0] 445bf215546Sopenharmony_ci name = field.name + field.dim 446bf215546Sopenharmony_ci if field.is_struct_type() and field.start % 32 == 0: 447bf215546Sopenharmony_ci print("") 448bf215546Sopenharmony_ci print(" %s_pack(data, &dw[%d], &values->%s);" % 449bf215546Sopenharmony_ci (self.parser.gen_prefix(safe_name(field.type)), index, name)) 450bf215546Sopenharmony_ci continue 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci # Pack any fields of struct type first so we have integer values 453bf215546Sopenharmony_ci # to the dword for those fields. 454bf215546Sopenharmony_ci field_index = 0 455bf215546Sopenharmony_ci for field in dw.fields: 456bf215546Sopenharmony_ci if isinstance(field, Field) and field.is_struct_type(): 457bf215546Sopenharmony_ci name = field.name + field.dim 458bf215546Sopenharmony_ci print("") 459bf215546Sopenharmony_ci print(" uint32_t v%d_%d;" % (index, field_index)) 460bf215546Sopenharmony_ci print(" %s_pack(data, &v%d_%d, &values->%s);" % 461bf215546Sopenharmony_ci (self.parser.gen_prefix(safe_name(field.type)), index, field_index, name)) 462bf215546Sopenharmony_ci field_index = field_index + 1 463bf215546Sopenharmony_ci 464bf215546Sopenharmony_ci print("") 465bf215546Sopenharmony_ci dword_start = index * 32 466bf215546Sopenharmony_ci if dw.address == None: 467bf215546Sopenharmony_ci address_count = 0 468bf215546Sopenharmony_ci else: 469bf215546Sopenharmony_ci address_count = 1 470bf215546Sopenharmony_ci 471bf215546Sopenharmony_ci if dw.size == 32 and dw.address == None: 472bf215546Sopenharmony_ci v = None 473bf215546Sopenharmony_ci print(" dw[%d] =" % index) 474bf215546Sopenharmony_ci elif len(dw.fields) > address_count: 475bf215546Sopenharmony_ci v = "v%d" % index 476bf215546Sopenharmony_ci print(" const uint%d_t %s =" % (dw.size, v)) 477bf215546Sopenharmony_ci else: 478bf215546Sopenharmony_ci v = "0" 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_ci field_index = 0 481bf215546Sopenharmony_ci non_address_fields = [] 482bf215546Sopenharmony_ci for field in dw.fields: 483bf215546Sopenharmony_ci if field.type != "mbo" and field.type != "mbz": 484bf215546Sopenharmony_ci name = field.name + field.dim 485bf215546Sopenharmony_ci 486bf215546Sopenharmony_ci nz = "_nonzero" if field.nonzero else "" 487bf215546Sopenharmony_ci 488bf215546Sopenharmony_ci if field.type == "mbo": 489bf215546Sopenharmony_ci non_address_fields.append("__gen_mbo(%d, %d)" % \ 490bf215546Sopenharmony_ci (field.start - dword_start, field.end - dword_start)) 491bf215546Sopenharmony_ci elif field.type == "mbz": 492bf215546Sopenharmony_ci assert not field.nonzero 493bf215546Sopenharmony_ci elif field.type == "address": 494bf215546Sopenharmony_ci pass 495bf215546Sopenharmony_ci elif field.type == "uint": 496bf215546Sopenharmony_ci non_address_fields.append("__gen_uint%s(values->%s, %d, %d)" % \ 497bf215546Sopenharmony_ci (nz, name, field.start - dword_start, field.end - dword_start)) 498bf215546Sopenharmony_ci elif field.is_enum_type(): 499bf215546Sopenharmony_ci non_address_fields.append("__gen_uint%s(values->%s, %d, %d)" % \ 500bf215546Sopenharmony_ci (nz, name, field.start - dword_start, field.end - dword_start)) 501bf215546Sopenharmony_ci elif field.type == "int": 502bf215546Sopenharmony_ci non_address_fields.append("__gen_sint%s(values->%s, %d, %d)" % \ 503bf215546Sopenharmony_ci (nz, name, field.start - dword_start, field.end - dword_start)) 504bf215546Sopenharmony_ci elif field.type == "bool": 505bf215546Sopenharmony_ci non_address_fields.append("__gen_uint%s(values->%s, %d, %d)" % \ 506bf215546Sopenharmony_ci (nz, name, field.start - dword_start, field.end - dword_start)) 507bf215546Sopenharmony_ci elif field.type == "float": 508bf215546Sopenharmony_ci non_address_fields.append("__gen_float%s(values->%s)" % (nz, name)) 509bf215546Sopenharmony_ci elif field.type == "offset": 510bf215546Sopenharmony_ci non_address_fields.append("__gen_offset%s(values->%s, %d, %d)" % \ 511bf215546Sopenharmony_ci (nz, name, field.start - dword_start, field.end - dword_start)) 512bf215546Sopenharmony_ci elif field.type == 'ufixed': 513bf215546Sopenharmony_ci non_address_fields.append("__gen_ufixed%s(values->%s, %d, %d, %d)" % \ 514bf215546Sopenharmony_ci (nz, name, field.start - dword_start, field.end - dword_start, field.fractional_size)) 515bf215546Sopenharmony_ci elif field.type == 'sfixed': 516bf215546Sopenharmony_ci non_address_fields.append("__gen_sfixed%s(values->%s, %d, %d, %d)" % \ 517bf215546Sopenharmony_ci (nz, name, field.start - dword_start, field.end - dword_start, field.fractional_size)) 518bf215546Sopenharmony_ci elif field.is_struct_type(): 519bf215546Sopenharmony_ci non_address_fields.append("__gen_uint(v%d_%d, %d, %d)" % \ 520bf215546Sopenharmony_ci (index, field_index, field.start - dword_start, field.end - dword_start)) 521bf215546Sopenharmony_ci field_index = field_index + 1 522bf215546Sopenharmony_ci else: 523bf215546Sopenharmony_ci non_address_fields.append("/* unhandled field %s, type %s */\n" % \ 524bf215546Sopenharmony_ci (name, field.type)) 525bf215546Sopenharmony_ci 526bf215546Sopenharmony_ci if non_address_fields: 527bf215546Sopenharmony_ci print(" |\n".join(" " + f for f in non_address_fields) + ";") 528bf215546Sopenharmony_ci 529bf215546Sopenharmony_ci if dw.size == 32: 530bf215546Sopenharmony_ci if dw.address: 531bf215546Sopenharmony_ci print(" dw[%d] = __gen_address(data, &dw[%d], values->%s, %s, %d, %d);" % 532bf215546Sopenharmony_ci (index, index, dw.address.name + field.dim, v, 533bf215546Sopenharmony_ci dw.address.start - dword_start, dw.address.end - dword_start)) 534bf215546Sopenharmony_ci continue 535bf215546Sopenharmony_ci 536bf215546Sopenharmony_ci if dw.address: 537bf215546Sopenharmony_ci v_address = "v%d_address" % index 538bf215546Sopenharmony_ci print(" const uint64_t %s =\n __gen_address(data, &dw[%d], values->%s, %s, %d, %d);" % 539bf215546Sopenharmony_ci (v_address, index, dw.address.name + field.dim, v, 540bf215546Sopenharmony_ci dw.address.start - dword_start, dw.address.end - dword_start)) 541bf215546Sopenharmony_ci if len(dw.fields) > address_count: 542bf215546Sopenharmony_ci print(" dw[%d] = %s;" % (index, v_address)) 543bf215546Sopenharmony_ci print(" dw[%d] = (%s >> 32) | (%s >> 32);" % (index + 1, v_address, v)) 544bf215546Sopenharmony_ci continue 545bf215546Sopenharmony_ci else: 546bf215546Sopenharmony_ci v = v_address 547bf215546Sopenharmony_ci print(" dw[%d] = %s;" % (index, v)) 548bf215546Sopenharmony_ci print(" dw[%d] = %s >> 32;" % (index + 1, v)) 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_ciclass Value(object): 551bf215546Sopenharmony_ci def __init__(self, attrs): 552bf215546Sopenharmony_ci self.name = safe_name(attrs["name"]) 553bf215546Sopenharmony_ci self.value = ast.literal_eval(attrs["value"]) 554bf215546Sopenharmony_ci 555bf215546Sopenharmony_ciclass Parser(object): 556bf215546Sopenharmony_ci def __init__(self): 557bf215546Sopenharmony_ci self.parser = xml.parsers.expat.ParserCreate() 558bf215546Sopenharmony_ci self.parser.StartElementHandler = self.start_element 559bf215546Sopenharmony_ci self.parser.EndElementHandler = self.end_element 560bf215546Sopenharmony_ci 561bf215546Sopenharmony_ci self.instruction = None 562bf215546Sopenharmony_ci self.structs = {} 563bf215546Sopenharmony_ci # Set of enum names we've seen. 564bf215546Sopenharmony_ci self.enums = set() 565bf215546Sopenharmony_ci self.registers = {} 566bf215546Sopenharmony_ci 567bf215546Sopenharmony_ci def gen_prefix(self, name): 568bf215546Sopenharmony_ci if name[0] == "_": 569bf215546Sopenharmony_ci return 'GFX%s%s' % (self.gen, name) 570bf215546Sopenharmony_ci return 'GFX%s_%s' % (self.gen, name) 571bf215546Sopenharmony_ci 572bf215546Sopenharmony_ci def gen_guard(self): 573bf215546Sopenharmony_ci return self.gen_prefix("PACK_H") 574bf215546Sopenharmony_ci 575bf215546Sopenharmony_ci def start_element(self, name, attrs): 576bf215546Sopenharmony_ci if name == "genxml": 577bf215546Sopenharmony_ci self.platform = attrs["name"] 578bf215546Sopenharmony_ci self.gen = attrs["gen"].replace('.', '') 579bf215546Sopenharmony_ci print(pack_header % {'license': license, 'platform': self.platform, 'guard': self.gen_guard()}) 580bf215546Sopenharmony_ci elif name in ("instruction", "struct", "register"): 581bf215546Sopenharmony_ci if name == "instruction": 582bf215546Sopenharmony_ci self.instruction = safe_name(attrs["name"]) 583bf215546Sopenharmony_ci self.length_bias = int(attrs["bias"]) 584bf215546Sopenharmony_ci if "engine" in attrs: 585bf215546Sopenharmony_ci self.instruction_engines = set(attrs["engine"].split('|')) 586bf215546Sopenharmony_ci else: 587bf215546Sopenharmony_ci # When an instruction doesn't have the engine specified, 588bf215546Sopenharmony_ci # it is considered to be for all engines, so 'None' is used 589bf215546Sopenharmony_ci # to signify that the instruction belongs to all engines. 590bf215546Sopenharmony_ci self.instruction_engines = None 591bf215546Sopenharmony_ci elif name == "struct": 592bf215546Sopenharmony_ci self.struct = safe_name(attrs["name"]) 593bf215546Sopenharmony_ci self.structs[attrs["name"]] = 1 594bf215546Sopenharmony_ci elif name == "register": 595bf215546Sopenharmony_ci self.register = safe_name(attrs["name"]) 596bf215546Sopenharmony_ci self.reg_num = num_from_str(attrs["num"]) 597bf215546Sopenharmony_ci self.registers[attrs["name"]] = 1 598bf215546Sopenharmony_ci if "length" in attrs: 599bf215546Sopenharmony_ci self.length = int(attrs["length"]) 600bf215546Sopenharmony_ci size = self.length * 32 601bf215546Sopenharmony_ci else: 602bf215546Sopenharmony_ci self.length = None 603bf215546Sopenharmony_ci size = 0 604bf215546Sopenharmony_ci self.group = Group(self, None, 0, 1, size) 605bf215546Sopenharmony_ci 606bf215546Sopenharmony_ci elif name == "group": 607bf215546Sopenharmony_ci group = Group(self, self.group, 608bf215546Sopenharmony_ci int(attrs["start"]), int(attrs["count"]), int(attrs["size"])) 609bf215546Sopenharmony_ci self.group.fields.append(group) 610bf215546Sopenharmony_ci self.group = group 611bf215546Sopenharmony_ci elif name == "field": 612bf215546Sopenharmony_ci self.group.fields.append(Field(self, attrs)) 613bf215546Sopenharmony_ci self.values = [] 614bf215546Sopenharmony_ci elif name == "enum": 615bf215546Sopenharmony_ci self.values = [] 616bf215546Sopenharmony_ci self.enum = safe_name(attrs["name"]) 617bf215546Sopenharmony_ci self.enums.add(attrs["name"]) 618bf215546Sopenharmony_ci if "prefix" in attrs: 619bf215546Sopenharmony_ci self.prefix = safe_name(attrs["prefix"]) 620bf215546Sopenharmony_ci else: 621bf215546Sopenharmony_ci self.prefix= None 622bf215546Sopenharmony_ci elif name == "value": 623bf215546Sopenharmony_ci self.values.append(Value(attrs)) 624bf215546Sopenharmony_ci 625bf215546Sopenharmony_ci def end_element(self, name): 626bf215546Sopenharmony_ci if name == "instruction": 627bf215546Sopenharmony_ci self.emit_instruction() 628bf215546Sopenharmony_ci self.instruction = None 629bf215546Sopenharmony_ci self.group = None 630bf215546Sopenharmony_ci elif name == "struct": 631bf215546Sopenharmony_ci self.emit_struct() 632bf215546Sopenharmony_ci self.struct = None 633bf215546Sopenharmony_ci self.group = None 634bf215546Sopenharmony_ci elif name == "register": 635bf215546Sopenharmony_ci self.emit_register() 636bf215546Sopenharmony_ci self.register = None 637bf215546Sopenharmony_ci self.reg_num = None 638bf215546Sopenharmony_ci self.group = None 639bf215546Sopenharmony_ci elif name == "group": 640bf215546Sopenharmony_ci self.group = self.group.parent 641bf215546Sopenharmony_ci elif name == "field": 642bf215546Sopenharmony_ci self.group.fields[-1].values = self.values 643bf215546Sopenharmony_ci elif name == "enum": 644bf215546Sopenharmony_ci self.emit_enum() 645bf215546Sopenharmony_ci self.enum = None 646bf215546Sopenharmony_ci elif name == "genxml": 647bf215546Sopenharmony_ci print('#endif /* %s */' % self.gen_guard()) 648bf215546Sopenharmony_ci 649bf215546Sopenharmony_ci def emit_template_struct(self, name, group): 650bf215546Sopenharmony_ci print("struct %s {" % self.gen_prefix(name)) 651bf215546Sopenharmony_ci group.emit_template_struct("") 652bf215546Sopenharmony_ci print("};\n") 653bf215546Sopenharmony_ci 654bf215546Sopenharmony_ci def emit_pack_function(self, name, group): 655bf215546Sopenharmony_ci name = self.gen_prefix(name) 656bf215546Sopenharmony_ci print(textwrap.dedent("""\ 657bf215546Sopenharmony_ci static inline __attribute__((always_inline)) void 658bf215546Sopenharmony_ci %s_pack(__attribute__((unused)) __gen_user_data *data, 659bf215546Sopenharmony_ci %s__attribute__((unused)) void * restrict dst, 660bf215546Sopenharmony_ci %s__attribute__((unused)) const struct %s * restrict values) 661bf215546Sopenharmony_ci {""") % (name, ' ' * len(name), ' ' * len(name), name)) 662bf215546Sopenharmony_ci 663bf215546Sopenharmony_ci (dwords, length) = group.collect_dwords_and_length() 664bf215546Sopenharmony_ci if length: 665bf215546Sopenharmony_ci # Cast dst to make header C++ friendly 666bf215546Sopenharmony_ci print(" uint32_t * restrict dw = (uint32_t * restrict) dst;") 667bf215546Sopenharmony_ci 668bf215546Sopenharmony_ci group.emit_pack_function(dwords, length) 669bf215546Sopenharmony_ci 670bf215546Sopenharmony_ci print("}\n") 671bf215546Sopenharmony_ci 672bf215546Sopenharmony_ci def emit_instruction(self): 673bf215546Sopenharmony_ci name = self.instruction 674bf215546Sopenharmony_ci if self.instruction_engines and not self.instruction_engines & self.engines: 675bf215546Sopenharmony_ci return 676bf215546Sopenharmony_ci 677bf215546Sopenharmony_ci if not self.length is None: 678bf215546Sopenharmony_ci print('#define %-33s %6d' % 679bf215546Sopenharmony_ci (self.gen_prefix(name + "_length"), self.length)) 680bf215546Sopenharmony_ci print('#define %-33s %6d' % 681bf215546Sopenharmony_ci (self.gen_prefix(name + "_length_bias"), self.length_bias)) 682bf215546Sopenharmony_ci 683bf215546Sopenharmony_ci default_fields = [] 684bf215546Sopenharmony_ci for field in self.group.fields: 685bf215546Sopenharmony_ci if not isinstance(field, Field): 686bf215546Sopenharmony_ci continue 687bf215546Sopenharmony_ci if field.default is None: 688bf215546Sopenharmony_ci continue 689bf215546Sopenharmony_ci 690bf215546Sopenharmony_ci if field.is_builtin_type(): 691bf215546Sopenharmony_ci default_fields.append(" .%-35s = %6d" % (field.name, field.default)) 692bf215546Sopenharmony_ci else: 693bf215546Sopenharmony_ci # Default values should not apply to structures 694bf215546Sopenharmony_ci assert field.is_enum_type() 695bf215546Sopenharmony_ci default_fields.append(" .%-35s = (enum %s) %6d" % (field.name, self.gen_prefix(safe_name(field.type)), field.default)) 696bf215546Sopenharmony_ci 697bf215546Sopenharmony_ci if default_fields: 698bf215546Sopenharmony_ci print('#define %-40s\\' % (self.gen_prefix(name + '_header'))) 699bf215546Sopenharmony_ci print(", \\\n".join(default_fields)) 700bf215546Sopenharmony_ci print('') 701bf215546Sopenharmony_ci 702bf215546Sopenharmony_ci self.emit_template_struct(self.instruction, self.group) 703bf215546Sopenharmony_ci 704bf215546Sopenharmony_ci self.emit_pack_function(self.instruction, self.group) 705bf215546Sopenharmony_ci 706bf215546Sopenharmony_ci def emit_register(self): 707bf215546Sopenharmony_ci name = self.register 708bf215546Sopenharmony_ci if not self.reg_num is None: 709bf215546Sopenharmony_ci print('#define %-33s 0x%04x' % 710bf215546Sopenharmony_ci (self.gen_prefix(name + "_num"), self.reg_num)) 711bf215546Sopenharmony_ci 712bf215546Sopenharmony_ci if not self.length is None: 713bf215546Sopenharmony_ci print('#define %-33s %6d' % 714bf215546Sopenharmony_ci (self.gen_prefix(name + "_length"), self.length)) 715bf215546Sopenharmony_ci 716bf215546Sopenharmony_ci self.emit_template_struct(self.register, self.group) 717bf215546Sopenharmony_ci self.emit_pack_function(self.register, self.group) 718bf215546Sopenharmony_ci 719bf215546Sopenharmony_ci def emit_struct(self): 720bf215546Sopenharmony_ci name = self.struct 721bf215546Sopenharmony_ci if not self.length is None: 722bf215546Sopenharmony_ci print('#define %-33s %6d' % 723bf215546Sopenharmony_ci (self.gen_prefix(name + "_length"), self.length)) 724bf215546Sopenharmony_ci 725bf215546Sopenharmony_ci self.emit_template_struct(self.struct, self.group) 726bf215546Sopenharmony_ci self.emit_pack_function(self.struct, self.group) 727bf215546Sopenharmony_ci 728bf215546Sopenharmony_ci def emit_enum(self): 729bf215546Sopenharmony_ci print('enum %s {' % self.gen_prefix(self.enum)) 730bf215546Sopenharmony_ci for value in self.values: 731bf215546Sopenharmony_ci if self.prefix: 732bf215546Sopenharmony_ci name = self.prefix + "_" + value.name 733bf215546Sopenharmony_ci else: 734bf215546Sopenharmony_ci name = value.name 735bf215546Sopenharmony_ci print(' %-36s = %6d,' % (name.upper(), value.value)) 736bf215546Sopenharmony_ci print('};\n') 737bf215546Sopenharmony_ci 738bf215546Sopenharmony_ci def parse(self, filename): 739bf215546Sopenharmony_ci file = open(filename, "rb") 740bf215546Sopenharmony_ci self.parser.ParseFile(file) 741bf215546Sopenharmony_ci file.close() 742bf215546Sopenharmony_ci 743bf215546Sopenharmony_cidef parse_args(): 744bf215546Sopenharmony_ci p = argparse.ArgumentParser() 745bf215546Sopenharmony_ci p.add_argument('xml_source', metavar='XML_SOURCE', 746bf215546Sopenharmony_ci help="Input xml file") 747bf215546Sopenharmony_ci p.add_argument('--engines', nargs='?', type=str, default='render', 748bf215546Sopenharmony_ci help="Comma-separated list of engines whose instructions should be parsed (default: %(default)s)") 749bf215546Sopenharmony_ci 750bf215546Sopenharmony_ci pargs = p.parse_args() 751bf215546Sopenharmony_ci 752bf215546Sopenharmony_ci if pargs.engines is None: 753bf215546Sopenharmony_ci print("No engines specified") 754bf215546Sopenharmony_ci sys.exit(1) 755bf215546Sopenharmony_ci 756bf215546Sopenharmony_ci return pargs 757bf215546Sopenharmony_ci 758bf215546Sopenharmony_cidef main(): 759bf215546Sopenharmony_ci pargs = parse_args() 760bf215546Sopenharmony_ci 761bf215546Sopenharmony_ci input_file = pargs.xml_source 762bf215546Sopenharmony_ci engines = pargs.engines.split(',') 763bf215546Sopenharmony_ci valid_engines = [ 'render', 'blitter', 'video' ] 764bf215546Sopenharmony_ci if set(engines) - set(valid_engines): 765bf215546Sopenharmony_ci print("Invalid engine specified, valid engines are:\n") 766bf215546Sopenharmony_ci for e in valid_engines: 767bf215546Sopenharmony_ci print("\t%s" % e) 768bf215546Sopenharmony_ci sys.exit(1) 769bf215546Sopenharmony_ci 770bf215546Sopenharmony_ci p = Parser() 771bf215546Sopenharmony_ci p.engines = set(engines) 772bf215546Sopenharmony_ci p.parse(input_file) 773bf215546Sopenharmony_ci 774bf215546Sopenharmony_ciif __name__ == '__main__': 775bf215546Sopenharmony_ci main() 776