summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2017-10-25 20:33:33 -0700
committerMatt Turner <mattst88@gmail.com>2017-10-27 11:45:00 -0700
commit2a10d2e6413d36d103acc588f74d2d02ca3f523c (patch)
treedd3afe459696efdc1e66905dbaaa1499f8e0db76
parentf121a669c7d94d2ff6721e01bec72589fd081ab3 (diff)
genxml: Fix decoding of groups containing fields smaller than a DWord.
Groups containing fields smaller than a DWord were not being decoded correctly. For example: <group count="32" start="32" size="4"> <field name="Vertex Element Enables" start="0" end="3" type="uint"/> </group> gen_field_iterator_next would properly walk over each element of the array, incrementing group_iter, and calling iter_group_offset_bits() to advance to the proper DWord. However, the code to print the actual values only considered iter->field->start/end, which are 0 and 3 in the above example. So it would always fetch bits 3:0 of the current DWord when printing values, instead of advancing to each element of the array, printing bits 0-3, 4-7, 8-11, and so on. To fix this, we add new iter->start/end tracking, which properly advances for each instance of a group's field.
-rw-r--r--src/intel/common/gen_decoder.c24
-rw-r--r--src/intel/common/gen_decoder.h2
2 files changed, 16 insertions, 10 deletions
diff --git a/src/intel/common/gen_decoder.c b/src/intel/common/gen_decoder.c
index 85880143f00..1bf69ac4f94 100644
--- a/src/intel/common/gen_decoder.c
+++ b/src/intel/common/gen_decoder.c
@@ -843,8 +843,12 @@ iter_advance_field(struct gen_field_iterator *iter)
strncpy(iter->name, iter->field->name, sizeof(iter->name));
else
memset(iter->name, 0, sizeof(iter->name));
- iter->dword = iter_group_offset_bits(iter, iter->group_iter) / 32 +
- iter->field->start / 32;
+
+ int group_member_offset = iter_group_offset_bits(iter, iter->group_iter);
+
+ iter->start = group_member_offset + iter->field->start;
+ iter->end = group_member_offset + iter->field->end;
+ iter->dword = iter->start / 32;
iter->struct_desc = NULL;
return true;
@@ -861,7 +865,7 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
if (!iter_advance_field(iter))
return false;
- if ((iter->field->end - iter->field->start) > 32)
+ if ((iter->end - iter->start) > 32)
v.qw = ((uint64_t) iter->p[iter->dword+1] << 32) | iter->p[iter->dword];
else
v.qw = iter->p[iter->dword];
@@ -871,13 +875,13 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
switch (iter->field->type.kind) {
case GEN_TYPE_UNKNOWN:
case GEN_TYPE_INT: {
- uint64_t value = field(v.qw, iter->field->start, iter->field->end);
+ uint64_t value = field(v.qw, iter->start, iter->end);
snprintf(iter->value, sizeof(iter->value), "%"PRId64, value);
enum_name = gen_get_enum_name(&iter->field->inline_enum, value);
break;
}
case GEN_TYPE_UINT: {
- uint64_t value = field(v.qw, iter->field->start, iter->field->end);
+ uint64_t value = field(v.qw, iter->start, iter->end);
snprintf(iter->value, sizeof(iter->value), "%"PRIu64, value);
enum_name = gen_get_enum_name(&iter->field->inline_enum, value);
break;
@@ -886,7 +890,7 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
const char *true_string =
iter->print_colors ? "\e[0;35mtrue\e[0m" : "true";
snprintf(iter->value, sizeof(iter->value), "%s",
- field(v.qw, iter->field->start, iter->field->end) ?
+ field(v.qw, iter->start, iter->end) ?
true_string : "false");
break;
}
@@ -896,7 +900,7 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
case GEN_TYPE_ADDRESS:
case GEN_TYPE_OFFSET:
snprintf(iter->value, sizeof(iter->value), "0x%08"PRIx64,
- field_address(v.qw, iter->field->start, iter->field->end));
+ field_address(v.qw, iter->start, iter->end));
break;
case GEN_TYPE_STRUCT:
snprintf(iter->value, sizeof(iter->value), "<struct %s>",
@@ -907,8 +911,8 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
break;
case GEN_TYPE_UFIXED:
snprintf(iter->value, sizeof(iter->value), "%f",
- (float) field(v.qw, iter->field->start,
- iter->field->end) / (1 << iter->field->type.f));
+ (float) field(v.qw, iter->start,
+ iter->end) / (1 << iter->field->type.f));
break;
case GEN_TYPE_SFIXED:
/* FIXME: Sign extend extracted field. */
@@ -917,7 +921,7 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
case GEN_TYPE_MBO:
break;
case GEN_TYPE_ENUM: {
- uint64_t value = field(v.qw, iter->field->start, iter->field->end);
+ uint64_t value = field(v.qw, iter->start, iter->end);
snprintf(iter->value, sizeof(iter->value),
"%"PRId64, value);
enum_name = gen_get_enum_name(iter->field->type.gen_enum, value);
diff --git a/src/intel/common/gen_decoder.h b/src/intel/common/gen_decoder.h
index cfc9f2e3f15..12d4551a127 100644
--- a/src/intel/common/gen_decoder.h
+++ b/src/intel/common/gen_decoder.h
@@ -58,6 +58,8 @@ struct gen_field_iterator {
struct gen_group *struct_desc;
const uint32_t *p;
int dword; /**< current field starts at &p[dword] */
+ int start; /**< current field starts at this bit number */
+ int end; /**< current field ends at this bit number */
int field_iter;
int group_iter;