From e01dc7a5887757a5e1d6894cc1fd1305f97a3187 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Wed, 20 Nov 2024 21:57:56 -0400 Subject: [PATCH] asahi/genxml: optimize out masking with shr noticed in the agx asm. Signed-off-by: Alyssa Rosenzweig Part-of: --- src/asahi/genxml/gen_pack.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/asahi/genxml/gen_pack.py b/src/asahi/genxml/gen_pack.py index c2dbf987456..1d711a06e31 100644 --- a/src/asahi/genxml/gen_pack.py +++ b/src/asahi/genxml/gen_pack.py @@ -292,9 +292,22 @@ class Group(object): if field.exact: value = field.default + # These types all use util_bitpack_uint + pack_as_uint = field.type in ["uint", "hex", "address", "bool"] + pack_as_uint |= field.type in self.parser.enums + start_adjusted = start + value_unshifted = None + if field.modifier is not None: if field.modifier[0] == "shr": - value = f"{value} >> {field.modifier[1]}" + if pack_as_uint and start >= field.modifier[1]: + # For uint, we fast path. If we do `(a >> 2) << 2`, + # clang will generate a mask in release builds, even + # though we know we're aligned. So don't generate + # that to avoid the masking. + start_adjusted = start - field.modifier[1] + else: + value = f"{value} >> {field.modifier[1]}" elif field.modifier[0] == "minus": value = f"{value} - {field.modifier[1]}" elif field.modifier[0] == "align": @@ -305,15 +318,15 @@ class Group(object): value = "__gen_to_groups({}, {}, {})".format(value, field.modifier[1], end - start + 1) - if field.type in ["uint", "hex", "address", "bool"] or field.type in self.parser.enums: - bits = (end - start + 1) + if pack_as_uint: + bits = (end - start_adjusted + 1) if bits < 64 and not field.exact: # Add some nicer error checking label = f"{self.label}::{name}" bound = hex(1 << bits) print(f" agx_genxml_validate_bounds(\"{label}\", {value}, {bound}ull);") - s = f"util_bitpack_uint({value}, {start}, {end})" + s = f"util_bitpack_uint({value}, {start_adjusted}, {end})" elif field.type == "int": s = "util_bitpack_sint(%s, %d, %d)" % \ (value, start, end)