[Mesa-dev] [PATCH 17/18] intel/gen_pack_header: Add unpack functions

Kristian H. Kristensen hoegsberg at gmail.com
Tue Nov 29 20:48:17 UTC 2016


Useful for people writing Intel GPU simulators...

Signed-off-by: Kristian H. Kristensen <hoegsberg at gmail.com>
---
 src/intel/genxml/gen_pack_header.py | 108 ++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)

diff --git a/src/intel/genxml/gen_pack_header.py b/src/intel/genxml/gen_pack_header.py
index 1024745..529f572 100644
--- a/src/intel/genxml/gen_pack_header.py
+++ b/src/intel/genxml/gen_pack_header.py
@@ -160,6 +160,46 @@ __gen_ufixed(float v, uint32_t start, uint32_t end, uint32_t fract_bits)
    return uint_val << start;
 }
 
+static inline uint64_t
+__gen_unpack_uint(uint64_t dw, uint32_t start, uint32_t end)
+{
+   uint64_t mask = (~0ul >> (64 - (end - start + 1)));
+
+   return (dw >> start) & mask;
+}
+
+static inline int64_t
+__gen_unpack_sint(uint64_t dw, uint32_t start, uint32_t end)
+{
+   return ((int64_t) dw << (63 - end)) >> (64 - (end - start + 1));
+}
+
+static inline uint64_t
+__gen_unpack_float(uint64_t dw)
+{
+   return ((union __gen_value) { .dw = (dw) }).f;
+}
+
+static inline uint64_t
+__gen_unpack_offset(uint64_t dw, uint32_t start, uint32_t end)
+{
+   uint64_t mask = (~0ul >> (64 - (end - start + 1))) << start;
+
+   return dw & mask;
+}
+
+static inline float
+__gen_unpack_ufixed(uint64_t dw, uint32_t start, uint32_t end, uint32_t fract_bits)
+{
+   return (float) __gen_unpack_uint(dw, start, end) / (1 << fract_bits);
+}
+
+static inline float
+__gen_unpack_sfixed(uint64_t dw, uint32_t start, uint32_t end, uint32_t fract_bits)
+{
+   return (float) __gen_unpack_sint(dw, start, end) / (1 << fract_bits);
+}
+
 #ifndef __gen_address_type
 #error #define __gen_address_type before including this file
 #endif
@@ -476,6 +516,60 @@ class Group(object):
             print("   dw[%d] = %s;" % (index, v))
             print("   dw[%d] = %s >> 32;" % (index + 1, v))
 
+    def emit_unpack_function(self, start):
+        dwords = {}
+        self.collect_dwords(dwords, 0, "")
+
+        for index in dwords.keys():
+            dw = dwords[index]
+            if index > 0 and index - 1 in dwords and dw == dwords[index - 1]:
+                continue
+
+            print("")
+            print("   const uint32_t dw%d __attribute__((unused)) = dw[%d];" % (index, index))
+
+            dword_start = index * 32
+
+            field_index = 0
+            for field in dw.fields:
+                if field.type != "mbo":
+                    name = field.name + field.dim
+
+                if field.type == "address":
+                    print("   const uint64_t qw%d __attribute__((unused)) = *(uint64_t *) &dw[%d];" % (index, index))
+                    print("   values->%s = __gen_unpack_address(qw%d, 0, 63);" % \
+                          (name, index))
+                elif field.type == "uint":
+                    print("   values->%s = __gen_unpack_uint(dw%d, %d, %d);" % \
+                          (name, index, field.start - dword_start, field.end - dword_start))
+                elif field.type in self.parser.enums:
+                    print("   values->%s = __gen_unpack_uint(dw%d, %d, %d);" % \
+                          (name, index, field.start - dword_start, field.end - dword_start))
+                elif field.type == "int":
+                    print("   values->%s = __gen_unpack_sint(dw%d, %d, %d);" % \
+                          (name, index, field.start - dword_start, field.end - dword_start))
+                elif field.type == "bool":
+                    print("   values->%s = __gen_unpack_uint(dw%d, %d, %d);" % \
+                          (name, index, field.start - dword_start, field.end - dword_start))
+                elif field.type == "float":
+                    print("   values->%s = __gen_unpack_float(dw%d);" % (name, index))
+                elif field.type == "offset":
+                    print("   values->%s = __gen_unpack_offset(dw%d, %d, %d);" % \
+                          (name, index, field.start - dword_start, field.end - dword_start))
+                elif field.type == 'ufixed':
+                    print("   values->%s = __gen_unpack_ufixed(dw%d, %d, %d, %d);" % \
+                          (name, index, field.start - dword_start, field.end - dword_start, field.fractional_size))
+                elif field.type == 'sfixed':
+                    print("   values->%s = __gen_unpack_sfixed(dw%d, %d, %d, %d);" % \
+                          (name, index, field.start - dword_start, field.end - dword_start, field.fractional_size))
+                elif field.type in self.parser.structs:
+                    print("/* struct %s */" % \
+                          (field.type))
+                    field_index = field_index + 1
+                else:
+                    print("/* unhandled field %s, type %s */\n" % (name, field.type))
+                    s = None
+
 class Value(object):
     def __init__(self, attrs):
         self.name = safe_name(attrs["name"])
@@ -585,6 +679,17 @@ class Parser(object):
 
         print("}\n")
 
+    def emit_unpack_function(self, name, group):
+        name = self.gen_prefix(name)
+        print("#ifdef __gen_unpack_address")
+        print("static inline void\n%s_unpack(const void * restrict src,\n%sstruct %s * restrict values)\n{" %
+              (name, ' ' * (len(name) + 8), name))
+        print("   const uint32_t *dw = (const uint32_t *) src;")
+
+        group.emit_unpack_function(0)
+
+        print("}\n#endif\n")
+
     def emit_instruction(self):
         name = self.instruction
         if not self.length == None:
@@ -609,6 +714,7 @@ class Parser(object):
         self.emit_template_struct(self.instruction, self.group)
 
         self.emit_pack_function(self.instruction, self.group)
+        self.emit_unpack_function(self.instruction, self.group)
 
     def emit_register(self):
         name = self.register
@@ -622,6 +728,7 @@ class Parser(object):
 
         self.emit_template_struct(self.register, self.group)
         self.emit_pack_function(self.register, self.group)
+        self.emit_unpack_function(self.register, self.group)
 
     def emit_struct(self):
         name = self.struct
@@ -631,6 +738,7 @@ class Parser(object):
 
         self.emit_template_struct(self.struct, self.group)
         self.emit_pack_function(self.struct, self.group)
+        self.emit_unpack_function(self.struct, self.group)
 
     def emit_enum(self):
         print('enum %s {' % self.gen_prefix(self.enum))
-- 
2.9.3



More information about the mesa-dev mailing list