summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLionel Landwerlin <[email protected]>2018-05-01 22:14:12 +0100
committerLionel Landwerlin <[email protected]>2018-05-02 17:10:37 +0100
commit4f128f7850e64829b8b1399ef0bdfd1eec7f4504 (patch)
tree2d2dbda4bcf300bedbe18112fdebbe12c1e26408
parent3c416a50d8d203115012363b13a4083f1c6de069 (diff)
intel: decoder: identify groups with fixed length
<register> & <struct> elements always have fixed length. The get_length() method implies that we're dealing with an instruction in which the length is encoded into the variable data but the field iterator uses it without checking what kind of gen_group it is dealing with. Let's make get_length() report the correct length regardless of the gen_group (register, struct or instruction). Signed-off-by: Lionel Landwerlin <[email protected]> Reviewed-by: Kenneth Graunke <[email protected]>
-rw-r--r--src/intel/common/gen_decoder.c18
-rw-r--r--src/intel/common/gen_decoder.h1
2 files changed, 13 insertions, 6 deletions
diff --git a/src/intel/common/gen_decoder.c b/src/intel/common/gen_decoder.c
index 7c462a0be4e..93fa4864ee3 100644
--- a/src/intel/common/gen_decoder.c
+++ b/src/intel/common/gen_decoder.c
@@ -151,7 +151,8 @@ static struct gen_group *
create_group(struct parser_context *ctx,
const char *name,
const char **atts,
- struct gen_group *parent)
+ struct gen_group *parent,
+ bool fixed_length)
{
struct gen_group *group;
@@ -161,6 +162,7 @@ create_group(struct parser_context *ctx,
group->spec = ctx->spec;
group->variable = false;
+ group->fixed_length = fixed_length;
for (int i = 0; atts[i]; i += 2) {
char *p;
@@ -370,18 +372,19 @@ start_element(void *data, const char *element_name, const char **atts)
minor = 0;
ctx->spec->gen = gen_make_gen(major, minor);
- } else if (strcmp(element_name, "instruction") == 0 ||
- strcmp(element_name, "struct") == 0) {
- ctx->group = create_group(ctx, name, atts, NULL);
+ } else if (strcmp(element_name, "instruction") == 0) {
+ ctx->group = create_group(ctx, name, atts, NULL, false);
+ } else if (strcmp(element_name, "struct") == 0) {
+ ctx->group = create_group(ctx, name, atts, NULL, true);
} else if (strcmp(element_name, "register") == 0) {
- ctx->group = create_group(ctx, name, atts, NULL);
+ ctx->group = create_group(ctx, name, atts, NULL, true);
get_register_offset(atts, &ctx->group->register_offset);
} else if (strcmp(element_name, "group") == 0) {
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);
+ struct gen_group *group = create_group(ctx, "", atts, ctx->group, false);
previous_group->next = group;
ctx->group = group;
} else if (strcmp(element_name, "field") == 0) {
@@ -713,6 +716,9 @@ gen_group_find_field(struct gen_group *group, const char *name)
int
gen_group_get_length(struct gen_group *group, const uint32_t *p)
{
+ if (group && group->fixed_length)
+ return group->dw_length;
+
uint32_t h = p[0];
uint32_t type = field_value(h, 29, 31);
diff --git a/src/intel/common/gen_decoder.h b/src/intel/common/gen_decoder.h
index f28ac7d27af..7d3bedca5b5 100644
--- a/src/intel/common/gen_decoder.h
+++ b/src/intel/common/gen_decoder.h
@@ -104,6 +104,7 @@ struct gen_group {
uint32_t group_offset, group_count;
uint32_t group_size;
bool variable;
+ bool fixed_length; /* True for <struct> & <register> */
struct gen_group *parent;
struct gen_group *next;