From 8d8b9d11c97a679c0954a2f2e7ed8ddcd248ccfa Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Sat, 30 Sep 2017 14:43:06 +0100 Subject: [PATCH] intel: decoder: enable decoding a single field Signed-off-by: Lionel Landwerlin Reviewed-by: Scott D Phillips --- src/intel/common/gen_decoder.c | 37 ++++++++++++++++++++++++++++++++++ src/intel/common/gen_decoder.h | 15 ++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/intel/common/gen_decoder.c b/src/intel/common/gen_decoder.c index 2b6a86c0126..d09b6ea32b6 100644 --- a/src/intel/common/gen_decoder.c +++ b/src/intel/common/gen_decoder.c @@ -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) diff --git a/src/intel/common/gen_decoder.h b/src/intel/common/gen_decoder.h index 251582f7121..8b00b6edc2f 100644 --- a/src/intel/common/gen_decoder.h +++ b/src/intel/common/gen_decoder.h @@ -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; -- 2.30.2