1#encoding=utf-8 2 3# Copyright 2016 Intel Corporation 4# Copyright 2016 Broadcom 5# Copyright 2020 Collabora, Ltd. 6# SPDX-License-Identifier: MIT 7 8import xml.parsers.expat 9import sys 10import operator 11import math 12from functools import reduce 13 14global_prefix = "agx" 15 16pack_header = """ 17/* Generated code, see midgard.xml and gen_pack_header.py 18 * 19 * Packets, enums and structures for Panfrost. 20 * 21 * This file has been generated, do not hand edit. 22 */ 23 24#ifndef AGX_PACK_H 25#define AGX_PACK_H 26 27#ifndef __OPENCL_VERSION__ 28#include <stdio.h> 29#include <inttypes.h> 30#include "util/bitpack_helpers.h" 31#include "util/half_float.h" 32#define FILE_TYPE FILE 33#define CONSTANT const 34#else 35 36#include "libagx.h" 37#define assert(x) 38#define FILE_TYPE void 39#define CONSTANT constant 40 41static uint64_t 42util_bitpack_uint(uint64_t v, uint32_t start, uint32_t end) 43{ 44 return v << start; 45} 46 47static uint64_t 48util_bitpack_sint(int64_t v, uint32_t start, uint32_t end) 49{ 50 const int bits = end - start + 1; 51 const uint64_t mask = (bits == 64) ? ~((uint64_t)0) : (1ull << bits) - 1; 52 return (v & mask) << start; 53} 54 55static uint32_t 56util_bitpack_float(float v) 57{ 58 union { float f; uint32_t dw; } x; 59 x.f = v; 60 return x.dw; 61} 62 63static inline float 64uif(uint32_t ui) 65{ 66 union { float f; uint32_t dw; } fi; 67 fi.dw = ui; 68 return fi.f; 69} 70 71#define DIV_ROUND_UP( A, B ) ( ((A) + (B) - 1) / (B) ) 72#define CLAMP( X, MIN, MAX ) ( (X)>(MIN) ? ((X)>(MAX) ? (MAX) : (X)) : (MIN) ) 73#define ALIGN_POT(x, pot_align) (((x) + (pot_align) - 1) & ~((pot_align) - 1)) 74 75static inline unsigned 76util_logbase2(unsigned n) 77{ 78 return ((sizeof(unsigned) * 8 - 1) - __builtin_clz(n | 1)); 79} 80 81static inline int64_t 82util_sign_extend(uint64_t val, unsigned width) 83{ 84 unsigned shift = 64 - width; 85 return (int64_t)(val << shift) >> shift; 86} 87 88static inline uint16_t 89_mesa_float_to_half(float f) 90{ 91 union { half h; uint16_t w; } hi; 92 hi.h = convert_half(f); 93 return hi.w; 94} 95 96static inline float 97_mesa_half_to_float(uint16_t w) 98{ 99 union { half h; uint16_t w; } hi; 100 hi.w = w; 101 return convert_float(hi.h); 102} 103 104#endif 105 106#define __gen_unpack_float(x, y, z) uif(__gen_unpack_uint(x, y, z)) 107#define __gen_unpack_half(x, y, z) _mesa_half_to_float(__gen_unpack_uint(x, y, z)) 108 109static inline uint64_t 110__gen_unpack_uint(CONSTANT uint32_t *restrict cl, uint32_t start, uint32_t end) 111{ 112 uint64_t val = 0; 113 const int width = end - start + 1; 114 const uint64_t mask = (width == 64) ? ~((uint64_t)0) : ((uint64_t)1 << width) - 1; 115 116 for (unsigned word = start / 32; word < (end / 32) + 1; word++) { 117 val |= ((uint64_t) cl[word]) << ((word - start / 32) * 32); 118 } 119 120 return (val >> (start % 32)) & mask; 121} 122 123/* 124 * LODs are 4:6 fixed point. We must clamp before converting to integers to 125 * avoid undefined behaviour for out-of-bounds inputs like +/- infinity. 126 */ 127static inline uint32_t 128__gen_pack_lod(float f, uint32_t start, uint32_t end) 129{ 130 uint32_t fixed = CLAMP(f * (1 << 6), 0 /* 0.0 */, 0x380 /* 14.0 */); 131 return util_bitpack_uint(fixed, start, end); 132} 133 134static inline float 135__gen_unpack_lod(CONSTANT uint32_t *restrict cl, uint32_t start, uint32_t end) 136{ 137 return ((float) __gen_unpack_uint(cl, start, end)) / (1 << 6); 138} 139 140static inline uint64_t 141__gen_unpack_sint(CONSTANT uint32_t *restrict cl, uint32_t start, uint32_t end) 142{ 143 int size = end - start + 1; 144 int64_t val = __gen_unpack_uint(cl, start, end); 145 146 return util_sign_extend(val, size); 147} 148 149static inline uint64_t 150__gen_to_groups(uint32_t value, uint32_t group_size, uint32_t length) 151{ 152 /* Zero is not representable, clamp to minimum */ 153 if (value == 0) 154 return 1; 155 156 /* Round up to the nearest number of groups */ 157 uint32_t groups = DIV_ROUND_UP(value, group_size); 158 159 /* The 0 encoding means "all" */ 160 if (groups == (1ull << length)) 161 return 0; 162 163 /* Otherwise it's encoded as the identity */ 164 assert(groups < (1u << length) && "out of bounds"); 165 assert(groups >= 1 && "exhaustive"); 166 return groups; 167} 168 169static inline uint64_t 170__gen_from_groups(uint32_t value, uint32_t group_size, uint32_t length) 171{ 172 return group_size * (value ? value: (1 << length)); 173} 174 175#define agx_pack(dst, T, name) \\ 176 for (struct AGX_ ## T name = { AGX_ ## T ## _header }, \\ 177 *_loop_count = (void *) ((uintptr_t) 0); \\ 178 (uintptr_t)_loop_count < 1; \\ 179 ({ AGX_ ## T ## _pack((uint32_t *) (dst), &name); \\ 180 _loop_count = (void*)(((uintptr_t)_loop_count) + 1); })) 181 182#define agx_unpack(fp, src, T, name) \\ 183 struct AGX_ ## T name; \\ 184 AGX_ ## T ## _unpack(fp, (CONSTANT uint8_t *)(src), &name) 185 186#define agx_print(fp, T, var, indent) \\ 187 AGX_ ## T ## _print(fp, &(var), indent) 188 189static inline void agx_merge_helper(uint32_t *dst, const uint32_t *src, size_t bytes) 190{ 191 assert((bytes & 3) == 0); 192 193 for (unsigned i = 0; i < (bytes / 4); ++i) 194 dst[i] |= src[i]; 195} 196 197#define agx_merge(packed1, packed2, type) \ 198 agx_merge_helper((packed1).opaque, (packed2).opaque, AGX_##type##_LENGTH) 199""" 200 201def to_alphanum(name): 202 substitutions = { 203 ' ': '_', 204 '/': '_', 205 '[': '', 206 ']': '', 207 '(': '', 208 ')': '', 209 '-': '_', 210 ':': '', 211 '.': '', 212 ',': '', 213 '=': '', 214 '>': '', 215 '#': '', 216 '&': '', 217 '*': '', 218 '"': '', 219 '+': '', 220 '\'': '', 221 '?': '', 222 } 223 224 for i, j in substitutions.items(): 225 name = name.replace(i, j) 226 227 return name 228 229def safe_name(name): 230 name = to_alphanum(name) 231 if not name[0].isalpha(): 232 name = '_' + name 233 234 return name 235 236def prefixed_upper_name(prefix, name): 237 if prefix: 238 name = prefix + "_" + name 239 return safe_name(name).upper() 240 241def enum_name(name): 242 return "{}_{}".format(global_prefix, safe_name(name)).lower() 243 244MODIFIERS = ["shr", "minus", "align", "log2", "groups"] 245 246def parse_modifier(modifier): 247 if modifier is None: 248 return None 249 250 for mod in MODIFIERS: 251 if modifier[0:len(mod)] == mod: 252 if mod == "log2": 253 assert(len(mod) == len(modifier)) 254 return [mod] 255 256 if modifier[len(mod)] == '(' and modifier[-1] == ')': 257 ret = [mod, int(modifier[(len(mod) + 1):-1])] 258 if ret[0] == 'align': 259 align = ret[1] 260 # Make sure the alignment is a power of 2 261 assert(align > 0 and not(align & (align - 1))); 262 263 return ret 264 265 print("Invalid modifier") 266 assert(False) 267 268class Field(object): 269 def __init__(self, parser, attrs): 270 self.parser = parser 271 if "name" in attrs: 272 self.name = safe_name(attrs["name"]).lower() 273 self.human_name = attrs["name"] 274 275 if ":" in str(attrs["start"]): 276 (word, bit) = attrs["start"].split(":") 277 self.start = (int(word) * 32) + int(bit) 278 else: 279 self.start = int(attrs["start"]) 280 281 self.end = self.start + int(attrs["size"]) - 1 282 self.type = attrs["type"] 283 284 if self.type == 'bool' and self.start != self.end: 285 print("#error Field {} has bool type but more than one bit of size".format(self.name)); 286 287 if "prefix" in attrs: 288 self.prefix = safe_name(attrs["prefix"]).upper() 289 else: 290 self.prefix = None 291 292 self.default = attrs.get("default") 293 294 # Map enum values 295 if self.type in self.parser.enums and self.default is not None: 296 self.default = safe_name('{}_{}_{}'.format(global_prefix, self.type, self.default)).upper() 297 298 self.modifier = parse_modifier(attrs.get("modifier")) 299 300 def emit_template_struct(self, dim): 301 if self.type == 'address': 302 type = 'uint64_t' 303 elif self.type == 'bool': 304 type = 'bool' 305 elif self.type in ['float', 'half', 'lod']: 306 type = 'float' 307 elif self.type in ['uint', 'hex'] and self.end - self.start > 32: 308 type = 'uint64_t' 309 elif self.type == 'int': 310 type = 'int32_t' 311 elif self.type in ['uint', 'hex']: 312 type = 'uint32_t' 313 elif self.type in self.parser.structs: 314 type = 'struct ' + self.parser.gen_prefix(safe_name(self.type.upper())) 315 elif self.type in self.parser.enums: 316 type = 'enum ' + enum_name(self.type) 317 else: 318 print("#error unhandled type: %s" % self.type) 319 type = "uint32_t" 320 321 print(" %-36s %s%s;" % (type, self.name, dim)) 322 323 for value in self.values: 324 name = prefixed_upper_name(self.prefix, value.name) 325 print("#define %-40s %d" % (name, value.value)) 326 327 def overlaps(self, field): 328 return self != field and max(self.start, field.start) <= min(self.end, field.end) 329 330class Group(object): 331 def __init__(self, parser, parent, start, count, label): 332 self.parser = parser 333 self.parent = parent 334 self.start = start 335 self.count = count 336 self.label = label 337 self.size = 0 338 self.length = 0 339 self.fields = [] 340 341 def get_length(self): 342 # Determine number of bytes in this group. 343 calculated = max(field.end // 8 for field in self.fields) + 1 if len(self.fields) > 0 else 0 344 if self.length > 0: 345 assert(self.length >= calculated) 346 else: 347 self.length = calculated 348 return self.length 349 350 351 def emit_template_struct(self, dim): 352 if self.count == 0: 353 print(" /* variable length fields follow */") 354 else: 355 if self.count > 1: 356 dim = "%s[%d]" % (dim, self.count) 357 358 if len(self.fields) == 0: 359 print(" int dummy;") 360 361 for field in self.fields: 362 field.emit_template_struct(dim) 363 364 class Word: 365 def __init__(self): 366 self.size = 32 367 self.contributors = [] 368 369 class FieldRef: 370 def __init__(self, field, path, start, end): 371 self.field = field 372 self.path = path 373 self.start = start 374 self.end = end 375 376 def collect_fields(self, fields, offset, path, all_fields): 377 for field in fields: 378 field_path = '{}{}'.format(path, field.name) 379 field_offset = offset + field.start 380 381 if field.type in self.parser.structs: 382 sub_struct = self.parser.structs[field.type] 383 self.collect_fields(sub_struct.fields, field_offset, field_path + '.', all_fields) 384 continue 385 386 start = field_offset 387 end = offset + field.end 388 all_fields.append(self.FieldRef(field, field_path, start, end)) 389 390 def collect_words(self, fields, offset, path, words): 391 for field in fields: 392 field_path = '{}{}'.format(path, field.name) 393 start = offset + field.start 394 395 if field.type in self.parser.structs: 396 sub_fields = self.parser.structs[field.type].fields 397 self.collect_words(sub_fields, start, field_path + '.', words) 398 continue 399 400 end = offset + field.end 401 contributor = self.FieldRef(field, field_path, start, end) 402 first_word = contributor.start // 32 403 last_word = contributor.end // 32 404 for b in range(first_word, last_word + 1): 405 if not b in words: 406 words[b] = self.Word() 407 words[b].contributors.append(contributor) 408 409 def emit_pack_function(self): 410 self.get_length() 411 412 words = {} 413 self.collect_words(self.fields, 0, '', words) 414 415 # Validate the modifier is lossless 416 for field in self.fields: 417 if field.modifier is None: 418 continue 419 420 if field.modifier[0] == "shr": 421 shift = field.modifier[1] 422 mask = hex((1 << shift) - 1) 423 print(" assert((values->{} & {}) == 0);".format(field.name, mask)) 424 elif field.modifier[0] == "minus": 425 print(" assert(values->{} >= {});".format(field.name, field.modifier[1])) 426 elif field.modifier[0] == "log2": 427 print(" assert(IS_POT_NONZERO(values->{}));".format(field.name)) 428 429 for index in range(math.ceil(self.length / 4)): 430 # Handle MBZ words 431 if not index in words: 432 print(" cl[%2d] = 0;" % index) 433 continue 434 435 word = words[index] 436 437 word_start = index * 32 438 439 v = None 440 prefix = " cl[%2d] =" % index 441 442 for contributor in word.contributors: 443 field = contributor.field 444 name = field.name 445 start = contributor.start 446 end = contributor.end 447 contrib_word_start = (start // 32) * 32 448 start -= contrib_word_start 449 end -= contrib_word_start 450 451 value = "values->{}".format(contributor.path) 452 if field.modifier is not None: 453 if field.modifier[0] == "shr": 454 value = "{} >> {}".format(value, field.modifier[1]) 455 elif field.modifier[0] == "minus": 456 value = "{} - {}".format(value, field.modifier[1]) 457 elif field.modifier[0] == "align": 458 value = "ALIGN_POT({}, {})".format(value, field.modifier[1]) 459 elif field.modifier[0] == "log2": 460 value = "util_logbase2({})".format(value) 461 elif field.modifier[0] == "groups": 462 value = "__gen_to_groups({}, {}, {})".format(value, 463 field.modifier[1], end - start + 1) 464 465 if field.type in ["uint", "hex", "address"]: 466 s = "util_bitpack_uint(%s, %d, %d)" % \ 467 (value, start, end) 468 elif field.type in self.parser.enums: 469 s = "util_bitpack_uint(%s, %d, %d)" % \ 470 (value, start, end) 471 elif field.type == "int": 472 s = "util_bitpack_sint(%s, %d, %d)" % \ 473 (value, start, end) 474 elif field.type == "bool": 475 s = "util_bitpack_uint(%s, %d, %d)" % \ 476 (value, start, end) 477 elif field.type == "float": 478 assert(start == 0 and end == 31) 479 s = "util_bitpack_float({})".format(value) 480 elif field.type == "half": 481 assert(start == 0 and end == 15) 482 s = "_mesa_float_to_half({})".format(value) 483 elif field.type == "lod": 484 assert(end - start + 1 == 10) 485 s = "__gen_pack_lod(%s, %d, %d)" % (value, start, end) 486 else: 487 s = "#error unhandled field {}, type {}".format(contributor.path, field.type) 488 489 if not s == None: 490 shift = word_start - contrib_word_start 491 if shift: 492 s = "%s >> %d" % (s, shift) 493 494 if contributor == word.contributors[-1]: 495 print("%s %s;" % (prefix, s)) 496 else: 497 print("%s %s |" % (prefix, s)) 498 prefix = " " 499 500 continue 501 502 # Given a field (start, end) contained in word `index`, generate the 32-bit 503 # mask of present bits relative to the word 504 def mask_for_word(self, index, start, end): 505 field_word_start = index * 32 506 start -= field_word_start 507 end -= field_word_start 508 # Cap multiword at one word 509 start = max(start, 0) 510 end = min(end, 32 - 1) 511 count = (end - start + 1) 512 return (((1 << count) - 1) << start) 513 514 def emit_unpack_function(self): 515 # First, verify there is no garbage in unused bits 516 words = {} 517 self.collect_words(self.fields, 0, '', words) 518 519 print('#ifndef __OPENCL_VERSION__') 520 for index in range(self.length // 4): 521 base = index * 32 522 word = words.get(index, self.Word()) 523 masks = [self.mask_for_word(index, c.start, c.end) for c in word.contributors] 524 mask = reduce(lambda x,y: x | y, masks, 0) 525 526 ALL_ONES = 0xffffffff 527 528 if mask != ALL_ONES: 529 TMPL = ' if (((const uint32_t *) cl)[{}] & {}) fprintf(fp, "XXX: Unknown field of {} unpacked at word {}: got %X, bad mask %X\\n", ((const uint32_t *) cl)[{}], ((const uint32_t *) cl)[{}] & {});' 530 print(TMPL.format(index, hex(mask ^ ALL_ONES), self.label, index, index, index, hex(mask ^ ALL_ONES))) 531 print('#endif') 532 533 fieldrefs = [] 534 self.collect_fields(self.fields, 0, '', fieldrefs) 535 for fieldref in fieldrefs: 536 field = fieldref.field 537 convert = None 538 539 args = [] 540 args.append('(CONSTANT uint32_t *) cl') 541 args.append(str(fieldref.start)) 542 args.append(str(fieldref.end)) 543 544 if field.type in set(["uint", "address", "hex"]) | self.parser.enums: 545 convert = "__gen_unpack_uint" 546 elif field.type == "int": 547 convert = "__gen_unpack_sint" 548 elif field.type == "bool": 549 convert = "__gen_unpack_uint" 550 elif field.type == "float": 551 convert = "__gen_unpack_float" 552 elif field.type == "half": 553 convert = "__gen_unpack_half" 554 elif field.type == "lod": 555 convert = "__gen_unpack_lod" 556 else: 557 s = "/* unhandled field %s, type %s */\n" % (field.name, field.type) 558 559 suffix = "" 560 prefix = "" 561 if field.modifier: 562 if field.modifier[0] == "minus": 563 suffix = " + {}".format(field.modifier[1]) 564 elif field.modifier[0] == "shr": 565 suffix = " << {}".format(field.modifier[1]) 566 if field.modifier[0] == "log2": 567 prefix = "1 << " 568 elif field.modifier[0] == "groups": 569 prefix = "__gen_from_groups(" 570 suffix = ", {}, {})".format(field.modifier[1], 571 fieldref.end - fieldref.start + 1) 572 573 if field.type in self.parser.enums: 574 prefix = f"(enum {enum_name(field.type)}) {prefix}" 575 576 decoded = '{}{}({}){}'.format(prefix, convert, ', '.join(args), suffix) 577 578 print(' values->{} = {};'.format(fieldref.path, decoded)) 579 if field.modifier and field.modifier[0] == "align": 580 mask = hex(field.modifier[1] - 1) 581 print(' assert(!(values->{} & {}));'.format(fieldref.path, mask)) 582 583 def emit_print_function(self): 584 for field in self.fields: 585 convert = None 586 name, val = field.human_name, 'values->{}'.format(field.name) 587 588 if field.type in self.parser.structs: 589 pack_name = self.parser.gen_prefix(safe_name(field.type)).upper() 590 print(' fprintf(fp, "%*s{}:\\n", indent, "");'.format(field.human_name)) 591 print(" {}_print(fp, &values->{}, indent + 2);".format(pack_name, field.name)) 592 elif field.type == "address": 593 # TODO resolve to name 594 print(' fprintf(fp, "%*s{}: 0x%" PRIx64 "\\n", indent, "", {});'.format(name, val)) 595 elif field.type in self.parser.enums: 596 print(' if ({}_as_str({}))'.format(enum_name(field.type), val)) 597 print(' fprintf(fp, "%*s{}: %s\\n", indent, "", {}_as_str({}));'.format(name, enum_name(field.type), val)) 598 print(' else') 599 print(' fprintf(fp, "%*s{}: unknown %X (XXX)\\n", indent, "", {});'.format(name, val)) 600 elif field.type == "int": 601 print(' fprintf(fp, "%*s{}: %d\\n", indent, "", {});'.format(name, val)) 602 elif field.type == "bool": 603 print(' fprintf(fp, "%*s{}: %s\\n", indent, "", {} ? "true" : "false");'.format(name, val)) 604 elif field.type in ["float", "lod", "half"]: 605 print(' fprintf(fp, "%*s{}: %f\\n", indent, "", {});'.format(name, val)) 606 elif field.type in ["uint", "hex"] and (field.end - field.start) >= 32: 607 print(' fprintf(fp, "%*s{}: 0x%" PRIx64 "\\n", indent, "", {});'.format(name, val)) 608 elif field.type == "hex": 609 print(' fprintf(fp, "%*s{}: 0x%" PRIx32 "\\n", indent, "", {});'.format(name, val)) 610 else: 611 print(' fprintf(fp, "%*s{}: %u\\n", indent, "", {});'.format(name, val)) 612 613class Value(object): 614 def __init__(self, attrs): 615 self.name = attrs["name"] 616 self.value = int(attrs["value"], 0) 617 618class Parser(object): 619 def __init__(self): 620 self.parser = xml.parsers.expat.ParserCreate() 621 self.parser.StartElementHandler = self.start_element 622 self.parser.EndElementHandler = self.end_element 623 624 self.struct = None 625 self.structs = {} 626 # Set of enum names we've seen. 627 self.enums = set() 628 629 def gen_prefix(self, name): 630 return '{}_{}'.format(global_prefix.upper(), name) 631 632 def start_element(self, name, attrs): 633 if name == "genxml": 634 print(pack_header) 635 elif name == "struct": 636 name = attrs["name"] 637 object_name = self.gen_prefix(safe_name(name.upper())) 638 self.struct = object_name 639 640 self.group = Group(self, None, 0, 1, name) 641 if "size" in attrs: 642 self.group.length = int(attrs["size"]) 643 self.group.align = int(attrs["align"]) if "align" in attrs else None 644 self.structs[attrs["name"]] = self.group 645 elif name == "field": 646 self.group.fields.append(Field(self, attrs)) 647 self.values = [] 648 elif name == "enum": 649 self.values = [] 650 self.enum = safe_name(attrs["name"]) 651 self.enums.add(attrs["name"]) 652 if "prefix" in attrs: 653 self.prefix = attrs["prefix"] 654 else: 655 self.prefix= None 656 elif name == "value": 657 self.values.append(Value(attrs)) 658 659 def end_element(self, name): 660 if name == "struct": 661 self.emit_struct() 662 self.struct = None 663 self.group = None 664 elif name == "field": 665 self.group.fields[-1].values = self.values 666 elif name == "enum": 667 self.emit_enum() 668 self.enum = None 669 elif name == "genxml": 670 print('#endif') 671 672 def emit_header(self, name): 673 default_fields = [] 674 for field in self.group.fields: 675 if not type(field) is Field: 676 continue 677 if field.default is not None: 678 default_fields.append(" .{} = {}".format(field.name, field.default)) 679 elif field.type in self.structs: 680 default_fields.append(" .{} = {{ {}_header }}".format(field.name, self.gen_prefix(safe_name(field.type.upper())))) 681 682 print('#define %-40s\\' % (name + '_header')) 683 if default_fields: 684 print(", \\\n".join(default_fields)) 685 else: 686 print(' 0') 687 print('') 688 689 def emit_template_struct(self, name, group): 690 print("struct %s {" % name) 691 group.emit_template_struct("") 692 print("};\n") 693 694 def emit_pack_function(self, name, group): 695 print("static inline void\n%s_pack(uint32_t * restrict cl,\n%sconst struct %s * restrict values)\n{" % 696 (name, ' ' * (len(name) + 6), name)) 697 698 group.emit_pack_function() 699 700 print("}\n\n") 701 702 print('#define {} {}'.format (name + "_LENGTH", self.group.length)) 703 if self.group.align != None: 704 print('#define {} {}'.format (name + "_ALIGN", self.group.align)) 705 print('struct {}_packed {{ uint32_t opaque[{}]; }};'.format(name.lower(), self.group.length // 4)) 706 707 def emit_unpack_function(self, name, group): 708 print("static inline void") 709 print("%s_unpack(FILE_TYPE *fp, CONSTANT uint8_t * restrict cl,\n%sstruct %s * restrict values)\n{" % 710 (name.upper(), ' ' * (len(name) + 8), name)) 711 712 group.emit_unpack_function() 713 714 print("}\n") 715 716 def emit_print_function(self, name, group): 717 print("#ifndef __OPENCL_VERSION__") 718 print("static inline void") 719 print("{}_print(FILE *fp, const struct {} * values, unsigned indent)\n{{".format(name.upper(), name)) 720 721 group.emit_print_function() 722 723 print("}\n") 724 print("#endif") 725 726 def emit_struct(self): 727 name = self.struct 728 729 self.emit_template_struct(self.struct, self.group) 730 self.emit_header(name) 731 self.emit_pack_function(self.struct, self.group) 732 self.emit_unpack_function(self.struct, self.group) 733 self.emit_print_function(self.struct, self.group) 734 735 def enum_prefix(self, name): 736 return 737 738 def emit_enum(self): 739 e_name = enum_name(self.enum) 740 prefix = e_name if self.enum != 'Format' else global_prefix 741 print('enum {} {{'.format(e_name)) 742 743 for value in self.values: 744 name = '{}_{}'.format(prefix, value.name) 745 name = safe_name(name).upper() 746 print(' % -36s = %6d,' % (name, value.value)) 747 print('};\n') 748 749 print("#ifndef __OPENCL_VERSION__") 750 print("static inline const char *") 751 print("{}_as_str(enum {} imm)\n{{".format(e_name.lower(), e_name)) 752 print(" switch (imm) {") 753 for value in self.values: 754 name = '{}_{}'.format(prefix, value.name) 755 name = safe_name(name).upper() 756 print(' case {}: return "{}";'.format(name, value.name)) 757 print(' default: break;') 758 print(" }") 759 print(" return NULL;") 760 print("}\n") 761 print("#endif") 762 763 def parse(self, filename): 764 file = open(filename, "rb") 765 self.parser.ParseFile(file) 766 file.close() 767 768if len(sys.argv) < 2: 769 print("No input xml file specified") 770 sys.exit(1) 771 772input_file = sys.argv[1] 773 774p = Parser() 775p.parse(input_file) 776