intel: decoder: enable decoding a single field
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>
Sat, 30 Sep 2017 13:43:06 +0000 (14:43 +0100)
committerLionel Landwerlin <lionel.g.landwerlin@intel.com>
Wed, 1 Nov 2017 17:23:49 +0000 (17:23 +0000)
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Scott D Phillips <scott.d.phillips@intel.com>
src/intel/common/gen_decoder.c
src/intel/common/gen_decoder.h

index 2b6a86c01269e6d1f4fd8355c833405ad9a4c07e..d09b6ea32b66926768543a5bc72503721f07b7c7 100644 (file)
@@ -568,6 +568,9 @@ gen_spec_load(const struct gen_device_info *devinfo)
    ctx.spec->enums =
       _mesa_hash_table_create(ctx.spec, _mesa_hash_string, _mesa_key_string_equal);
 
+   ctx.spec->access_cache =
+      _mesa_hash_table_create(ctx.spec, _mesa_hash_string, _mesa_key_string_equal);
+
    total_length = zlib_inflate(compress_genxmls,
                                sizeof(compress_genxmls),
                                (void **) &text_data);
@@ -680,6 +683,32 @@ gen_spec_find_instruction(struct gen_spec *spec, const uint32_t *p)
    return NULL;
 }
 
+struct gen_field *
+gen_group_find_field(struct gen_group *group, const char *name)
+{
+   char path[256];
+   snprintf(path, sizeof(path), "%s/%s", group->name, name);
+
+   struct gen_spec *spec = group->spec;
+   struct hash_entry *entry = _mesa_hash_table_search(spec->access_cache,
+                                                      path);
+   if (entry)
+      return entry->data;
+
+   struct gen_field *field = group->fields;
+   while (field) {
+      if (strcmp(field->name, name) == 0) {
+         _mesa_hash_table_insert(spec->access_cache,
+                                 ralloc_strdup(spec, path),
+                                 field);
+         return field;
+      }
+      field = field->next;
+   }
+
+   return NULL;
+}
+
 int
 gen_group_get_length(struct gen_group *group, const uint32_t *p)
 {
@@ -981,6 +1010,14 @@ gen_field_is_header(struct gen_field *field)
    return (field->parent->opcode_mask & bits) != 0;
 }
 
+void gen_field_decode(struct gen_field *field,
+                      const uint32_t *p, const uint32_t *end,
+                      union gen_field_value *value)
+{
+   uint32_t dword = field->start / 32;
+   value->u64 = iter_decode_field_raw(field, &p[dword], end);
+}
+
 void
 gen_print_group(FILE *outfile, struct gen_group *group,
                 uint64_t offset, const uint32_t *p, bool color)
index 251582f7121b9a0d2f769fa8fc5a3b4ae601414f..8b00b6edc2f29bd93baecd624d9e324717116bda 100644 (file)
@@ -37,6 +37,7 @@ extern "C" {
 struct gen_spec;
 struct gen_group;
 struct gen_field;
+union gen_field_value;
 
 static inline uint32_t gen_make_gen(uint32_t major, uint32_t minor)
 {
@@ -57,8 +58,13 @@ struct gen_enum *gen_spec_find_enum(struct gen_spec *spec, const char *name);
 int gen_group_get_length(struct gen_group *group, const uint32_t *p);
 const char *gen_group_get_name(struct gen_group *group);
 uint32_t gen_group_get_opcode(struct gen_group *group);
+struct gen_field *gen_group_find_field(struct gen_group *group, const char *name);
 struct gen_enum *gen_spec_find_enum(struct gen_spec *spec, const char *name);
+
 bool gen_field_is_header(struct gen_field *field);
+void gen_field_decode(struct gen_field *field,
+                      const uint32_t *p, const uint32_t *end,
+                      union gen_field_value *value);
 
 struct gen_field_iterator {
    struct gen_group *group;
@@ -85,6 +91,8 @@ struct gen_spec {
    struct hash_table *registers_by_name;
    struct hash_table *registers_by_offset;
    struct hash_table *enums;
+
+   struct hash_table *access_cache;
 };
 
 struct gen_group {
@@ -146,6 +154,13 @@ struct gen_type {
    };
 };
 
+union gen_field_value {
+   bool b32;
+   float f32;
+   uint64_t u64;
+   int64_t i64;
+};
+
 struct gen_field {
    struct gen_group *parent;
    struct gen_field *next;