diff --git a/src/asahi/genxml/agx_pack_header.h b/src/asahi/genxml/agx_pack_header.h index 5abbed82c4b..77464d56df4 100644 --- a/src/asahi/genxml/agx_pack_header.h +++ b/src/asahi/genxml/agx_pack_header.h @@ -199,4 +199,38 @@ agx_merge_helper(uint32_t *dst, const uint32_t *src, size_t bytes) #define agx_merge(packed1, packed2, type) \ agx_merge_helper((packed1).opaque, (packed2).opaque, AGX_##type##_LENGTH) +#if defined(NDEBUG) || defined(__OPENCL_VERSION__) +#define agx_genxml_validate_bounds(a, b, c) +#define agx_genxml_validate_mask(a, b, c, d, e) true +#else +static inline void +agx_genxml_validate_bounds(const char *name, uint64_t value, uint64_t bound) +{ + if (unlikely(value >= bound)) { + fprintf(stderr, "%s out-of-bounds, got 0x%" PRIx64 ", max %" PRIx64 "\n", + name, value, bound); + + unreachable("Out-of-bounds pack"); + } +} + +static inline bool +agx_genxml_validate_mask(FILE *fp, const char *name, const void *cl_, + uint32_t index, uint32_t bad_mask) +{ + const uint32_t *cl = (const uint32_t *)cl_; + uint32_t bad = cl[index] & bad_mask; + + if (bad && fp != NULL) { + fprintf( + fp, + "XXX: Unknown field of %s unpacked at word %u got %X, bad mask %X\n", + name, index, cl[index], bad); + } + + return bad == 0; +} + +#endif + /* Everything after this is autogenerated from XML. Do not hand edit. */ diff --git a/src/asahi/genxml/gen_pack.py b/src/asahi/genxml/gen_pack.py index fe055b70532..24cd39903d8 100644 --- a/src/asahi/genxml/gen_pack.py +++ b/src/asahi/genxml/gen_pack.py @@ -283,17 +283,9 @@ class Group(object): bits = (end - start + 1) if bits < 64: # Add some nicer error checking - error = f"{self.label}::{name} out-of-bounds" + label = f"{self.label}::{name}" bound = hex(1 << bits) - - print("#ifndef NDEBUG") - print("#ifndef __OPENCL_VERSION__") - print(f"if (unlikely((uint64_t){value} >= {bound})) {{") - print(f" fprintf(stderr, \"{error}, got 0x%\" PRIx64 \", max {bound}\\n\", (uint64_t) {value});") - print(f" unreachable(\"{error}\");") - print(f"}}") - print("#endif") - print("#endif") + print(f" agx_genxml_validate_bounds(\"{label}\", {value}, {bound}ull);") s = f"util_bitpack_uint({value}, {start}, {end})" elif field.type == "int": @@ -343,9 +335,8 @@ class Group(object): # First, verify there is no garbage in unused bits words = {} self.collect_words(self.fields, 0, '', words) - print(' bool valid = true;') + print(' bool valid = true;') - print('#ifndef __OPENCL_VERSION__') for index in range(self.length // 4): base = index * 32 word = words.get(index, self.Word()) @@ -355,18 +346,8 @@ class Group(object): ALL_ONES = 0xffffffff if mask != ALL_ONES: - TMPL = ''' - if (((const uint32_t *) cl)[{}] & {}) {{ - valid = false; - - if (fp != NULL) {{ - fprintf(fp, "XXX: Unknown field of {} unpacked at word {}: got %X, bad mask %X\\n", - ((const uint32_t *) cl)[{}], ((const uint32_t *) cl)[{}] & {}); - }} - }} - ''' - print(TMPL.format(index, hex(mask ^ ALL_ONES), self.label, index, index, index, hex(mask ^ ALL_ONES))) - print('#endif') + bad_mask = hex(mask ^ ALL_ONES) + print(f' valid &= agx_genxml_validate_mask(fp, \"{self.label}\", cl, {index}, {bad_mask});') fieldrefs = [] self.collect_fields(self.fields, 0, '', fieldrefs)