summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLionel Landwerlin <lionel.g.landwerlin@intel.com>2017-09-30 14:43:06 +0100
committerLionel Landwerlin <lionel.g.landwerlin@intel.com>2017-11-01 17:23:49 +0000
commit8d8b9d11c97a679c0954a2f2e7ed8ddcd248ccfa (patch)
tree344e1bca0338fc5db09ebf02ca6f8d815de9c4fd
parentbb16503542139bdd0acd1b77728f04fbc56d49e8 (diff)
intel: decoder: enable decoding a single field
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Reviewed-by: Scott D Phillips <scott.d.phillips@intel.com>
-rw-r--r--src/intel/common/gen_decoder.c37
-rw-r--r--src/intel/common/gen_decoder.h15
2 files changed, 52 insertions, 0 deletions
diff --git a/src/intel/common/gen_decoder.c b/src/intel/common/gen_decoder.c
index 2b6a86c012..d09b6ea32b 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 251582f712..8b00b6edc2 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;