Signed-off-by: Lionel Landwerlin <lionel.g.landwer...@intel.com>
---
src/intel/common/gen_decoder.c | 208 +++++++++++++++++++++++++++--------------
src/intel/common/gen_decoder.h | 19 ++--
src/intel/tools/aubinator.c | 4 +-
3 files changed, 151 insertions(+), 80 deletions(-)
diff --git a/src/intel/common/gen_decoder.c b/src/intel/common/gen_decoder.c
index 3ea2eaf8dbf..6db02c854ff 100644
--- a/src/intel/common/gen_decoder.c
+++ b/src/intel/common/gen_decoder.c
@@ -38,6 +38,8 @@
#define XML_BUFFER_SIZE 4096
+#define MAX(a, b) ((a) < (b) ? (b) : (a))
+
#define MAKE_GEN(major, minor) ( ((major) << 8) | (minor) )
struct gen_spec {
@@ -67,9 +69,6 @@ struct parser_context {
struct gen_group *group;
struct gen_enum *enoom;
- int nfields;
- struct gen_field *fields[128];
-
int nvalues;
struct gen_value *values[256];
@@ -178,8 +177,32 @@ xzalloc(size_t s)
return fail_on_null(zalloc(s));
}
+static void
+get_group_offset_count(const char **atts, uint32_t *offset, uint32_t *count,
+ uint32_t *size, bool *variable)
+{
+ char *p;
+ int i;
+
+ for (i = 0; atts[i]; i += 2) {
+ if (strcmp(atts[i], "count") == 0) {
+ *count = strtoul(atts[i + 1], &p, 0);
+ if (*count == 0)
+ *variable = true;
+ } else if (strcmp(atts[i], "start") == 0) {
+ *offset = strtoul(atts[i + 1], &p, 0);
+ } else if (strcmp(atts[i], "size") == 0) {
+ *size = strtoul(atts[i + 1], &p, 0);
+ }
+ }
+ return;
+}
+
static struct gen_group *
-create_group(struct parser_context *ctx, const char *name, const char **atts)
+create_group(struct parser_context *ctx,
+ const char *name,
+ const char **atts,
+ struct gen_group *parent)
{
struct gen_group *group;
@@ -190,9 +213,17 @@ create_group(struct parser_context *ctx, const char *name,
const char **atts)
group->spec = ctx->spec;
group->group_offset = 0;
group->group_count = 0;
- group->variable_offset = 0;
group->variable = false;
+ if (parent) {
+ group->parent = parent;
+ get_group_offset_count(atts,
+ &group->group_offset,
+ &group->group_count,
+ &group->group_size,
+ &group->variable);
+ }
+
return group;
}
@@ -211,28 +242,6 @@ create_enum(struct parser_context *ctx, const char *name,
const char **atts)
}
static void
-get_group_offset_count(struct parser_context *ctx, const char *name,
- const char **atts, uint32_t *offset, uint32_t *count,
- uint32_t *elem_size, bool *variable)
-{
- char *p;
- int i;
-
- for (i = 0; atts[i]; i += 2) {
- if (strcmp(atts[i], "count") == 0) {
- *count = strtoul(atts[i + 1], &p, 0);
- if (*count == 0)
- *variable = true;
- } else if (strcmp(atts[i], "start") == 0) {
- *offset = strtoul(atts[i + 1], &p, 0);
- } else if (strcmp(atts[i], "size") == 0) {
- *elem_size = strtoul(atts[i + 1], &p, 0);
- }
- }
- return;
-}
-
-static void
get_register_offset(const char **atts, uint32_t *offset)
{
char *p;
@@ -336,14 +345,9 @@ create_field(struct parser_context *ctx, const char **atts)
if (strcmp(atts[i], "name") == 0)
field->name = xstrdup(atts[i + 1]);
else if (strcmp(atts[i], "start") == 0)
- field->start = ctx->group->group_offset+strtoul(atts[i + 1], &p, 0);
+ field->start = strtoul(atts[i + 1], &p, 0);
else if (strcmp(atts[i], "end") == 0) {
- field->end = ctx->group->group_offset+strtoul(atts[i + 1], &p, 0);
- if (ctx->group->group_offset) {
- ctx->group->group_offset = field->end+1;
- if (ctx->group->variable)
- ctx->group->variable_offset = ctx->group->group_offset;
- }
+ field->end = strtoul(atts[i + 1], &p, 0);
} else if (strcmp(atts[i], "type") == 0)
field->type = string_to_type(ctx, atts[i + 1]);
else if (strcmp(atts[i], "default") == 0 &&
@@ -372,9 +376,31 @@ create_value(struct parser_context *ctx, const char **atts)
}
static void
+create_and_append_field(struct parser_context *ctx,
+ const char **atts)
+{
+ if (ctx->group->nfields == ctx->group->fields_size) {
+ ctx->group->fields_size = MAX(ctx->group->fields_size * 2, 2);
+
+ if (!ctx->group->fields) {
+ ctx->group->fields =
+ (struct gen_field **) calloc(ctx->group->fields_size,
+ sizeof(ctx->group->fields[0]));
+ } else {
+ ctx->group->fields =
+ (struct gen_field **) realloc(ctx->group->fields,
+ sizeof(ctx->group->fields[0]) *
ctx->group->fields_size);
+ }
+ }
+
+ ctx->group->fields[ctx->group->nfields++] = create_field(ctx, atts);
+}
+
+static void
start_element(void *data, const char *element_name, const char **atts)
{
struct parser_context *ctx = data;
+ struct gen_spec *prev_spec = ctx->spec;
int i;
const char *name = NULL;
const char *gen = NULL;
@@ -405,25 +431,30 @@ start_element(void *data, const char *element_name, const
char **atts)
ctx->spec->gen = MAKE_GEN(major, minor);
} else if (strcmp(element_name, "instruction") == 0 ||
strcmp(element_name, "struct") == 0) {
- ctx->group = create_group(ctx, name, atts);
+ ctx->group = create_group(ctx, name, atts, NULL);
} else if (strcmp(element_name, "register") == 0) {
- ctx->group = create_group(ctx, name, atts);
+ ctx->group = create_group(ctx, name, atts, NULL);
get_register_offset(atts, &ctx->group->register_offset);
} else if (strcmp(element_name, "group") == 0) {
- get_group_offset_count(ctx, name, atts, &ctx->group->group_offset,
- &ctx->group->group_count, &ctx->group->elem_size,
- &ctx->group->variable);
+ struct gen_group *previous_group = ctx->group;
+ while (previous_group->next)
+ previous_group = previous_group->next;
+
+ struct gen_group *group = create_group(ctx, "", atts, ctx->group);
+ previous_group->next = group;
+ ctx->group = group;
} else if (strcmp(element_name, "field") == 0) {
- do {
- ctx->fields[ctx->nfields++] = create_field(ctx, atts);
- if (ctx->group->group_count)
- ctx->group->group_count--;
- } while (ctx->group->group_count > 0);
+ create_and_append_field(ctx, atts);
} else if (strcmp(element_name, "enum") == 0) {
ctx->enoom = create_enum(ctx, name, atts);
} else if (strcmp(element_name, "value") == 0) {
ctx->values[ctx->nvalues++] = create_value(ctx, atts);
+ assert(ctx->nvalues < ARRAY_SIZE(ctx->values));
}
+
+ assert(prev_spec == ctx->spec);
+
+
}
static void
@@ -435,14 +466,9 @@ end_element(void *data, const char *name)
if (strcmp(name, "instruction") == 0 ||
strcmp(name, "struct") == 0 ||
strcmp(name, "register") == 0) {
- size_t size = ctx->nfields * sizeof(ctx->fields[0]);
struct gen_group *group = ctx->group;
- group->fields = xzalloc(size);
- group->nfields = ctx->nfields;
- memcpy(group->fields, ctx->fields, size);
- ctx->nfields = 0;
- ctx->group = NULL;
+ ctx->group = ctx->group->parent;
for (int i = 0; i < group->nfields; i++) {
if (group->fields[i]->start >= 16 &&
@@ -461,12 +487,15 @@ end_element(void *data, const char *name)
spec->structs[spec->nstructs++] = group;
else if (strcmp(name, "register") == 0)
spec->registers[spec->nregisters++] = group;
+
+ assert(spec->ncommands < ARRAY_SIZE(spec->commands));
+ assert(spec->nstructs < ARRAY_SIZE(spec->structs));
+ assert(spec->nregisters < ARRAY_SIZE(spec->registers));
} else if (strcmp(name, "group") == 0) {
- ctx->group->group_offset = 0;
- ctx->group->group_count = 0;
+ ctx->group = ctx->group->parent;
} else if (strcmp(name, "field") == 0) {
- assert(ctx->nfields > 0);
- struct gen_field *field = ctx->fields[ctx->nfields - 1];
+ assert(ctx->group->nfields > 0);
+ struct gen_field *field = ctx->group->fields[ctx->group->nfields - 1];
size_t size = ctx->nvalues * sizeof(ctx->values[0]);
field->inline_enum.values = xzalloc(size);
field->inline_enum.nvalues = ctx->nvalues;
@@ -752,12 +781,11 @@ gen_field_iterator_init(struct gen_field_iterator *iter,
const uint32_t *p,
bool print_colors)
{
+ memset(iter, 0, sizeof(*iter));
+
iter->group = group;
iter->p = p;
- iter->i = 0;
iter->print_colors = print_colors;
- iter->repeat = false;
- iter->addr_inc = 0;
}
static const char *
@@ -771,6 +799,56 @@ gen_get_enum_name(struct gen_enum *e, uint64_t value)
return NULL;
}
+static bool iter_more_fields(const struct gen_field_iterator *iter)
+{
+ return iter->field_iter < iter->group->nfields;
+}
+
+static uint32_t iter_group_offset_bits(const struct gen_field_iterator *iter,
+ uint32_t group_iter)
+{
+ return iter->group->group_offset + (group_iter * iter->group->group_size);
+}
+
+static bool iter_more_groups(const struct gen_field_iterator *iter)
+{
+ if (iter->group->variable) {
+ return iter_group_offset_bits(iter, iter->group_iter + 1) <
+ (gen_group_get_length(iter->group, iter->p) * 32);
+ } else {
+ return (iter->group_iter + 1) < iter->group->group_count ||
+ iter->group->next != NULL;
+ }
+}
+
+static void iter_advance_group(struct gen_field_iterator *iter)
+{
+ if (iter->group->variable)
+ iter->group_iter++;
+ else {
+ if ((iter->group_iter + 1) < iter->group->group_count) {
+ iter->group_iter++;
+ } else {
+ iter->group = iter->group->next;
+ iter->group_iter = 0;
+ }
+ }
+
+ iter->field_iter = 0;
+}
+
+static void iter_advance_field(struct gen_field_iterator *iter)
+{
+ if (iter->field_iter == iter->group->nfields)
+ iter_advance_group(iter);
+
+ iter->field = iter->group->fields[iter->field_iter++];
+ iter->name = iter->field->name;
+ iter->dword = iter_group_offset_bits(iter, iter->group_iter) / 32 +
+ iter->field->start / 32;
+ iter->struct_desc = NULL;
+}
+
bool
gen_field_iterator_next(struct gen_field_iterator *iter)
{
@@ -779,22 +857,10 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
float f;
} v;
- if (iter->i == iter->group->nfields) {
- if (iter->group->group_size > 0) {
- int iter_length = iter->group->elem_size;
-
- iter->group->group_size -= iter_length / 32;
- iter->addr_inc += iter_length;
- iter->dword = (iter->field->start + iter->addr_inc) / 32;
- return true;
- }
+ if (!iter_more_fields(iter) && !iter_more_groups(iter))
return false;
- }
- iter->field = iter->group->fields[iter->i++];
- iter->name = iter->field->name;
- iter->dword = iter->field->start / 32;
- iter->struct_desc = NULL;
+ iter_advance_field(iter);
if ((iter->field->end - iter->field->start) > 32)
v.qw = ((uint64_t) iter->p[iter->dword+1] << 32) | iter->p[iter->dword];
diff --git a/src/intel/common/gen_decoder.h b/src/intel/common/gen_decoder.h
index 4f4295ff95a..0a4de6bc8f9 100644
--- a/src/intel/common/gen_decoder.h
+++ b/src/intel/common/gen_decoder.h
@@ -58,23 +58,28 @@ struct gen_field_iterator {
struct gen_group *struct_desc;
const uint32_t *p;
int dword; /**< current field starts at &p[dword] */
- int i;
+
+ int field_iter;
+ int group_iter;
+
struct gen_field *field;
bool print_colors;
- bool repeat;
- uint32_t addr_inc;
};
struct gen_group {
struct gen_spec *spec;
char *name;
- int nfields;
+
struct gen_field **fields;
+ uint32_t nfields;
+ uint32_t fields_size;
+
uint32_t group_offset, group_count;
- uint32_t elem_size;
- uint32_t variable_offset;
- bool variable;
uint32_t group_size;
+ bool variable;
+
+ struct gen_group *parent;
+ struct gen_group *next;
uint32_t opcode_mask;
uint32_t opcode;
diff --git a/src/intel/tools/aubinator.c b/src/intel/tools/aubinator.c
index 53b2a27fa90..5ad884c9e61 100644
--- a/src/intel/tools/aubinator.c
+++ b/src/intel/tools/aubinator.c
@@ -108,8 +108,8 @@ valid_offset(uint32_t offset)
static void
group_set_size(struct gen_group *strct, uint32_t size)
{
- if (strct->variable && strct->elem_size)
- strct->group_size = size - (strct->variable_offset / 32);
+ if (strct->variable && strct->group_size)
+ strct->group_size = size - (strct->group_offset / 32);
}
static void
--
2.11.0
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev