diff options
-rw-r--r-- | src/intel/tools/decoder.c | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/src/intel/tools/decoder.c b/src/intel/tools/decoder.c index b5f557c..be3558b 100644 --- a/src/intel/tools/decoder.c +++ b/src/intel/tools/decoder.c @@ -191,6 +191,26 @@ get_register_offset(const char **atts, uint32_t *offset) return; } +static void +get_start_end_pos(int *start, int *end) +{ + /* start value has to be mod with 32 as we need the relative + * start position in the first DWord. For the end position, add + * the length of the field to the start position to get the + * relative postion in the 64 bit address. + */ + if (*end - *start > 32) { + int len = *end - *start; + *start = *start % 32; + *end = *start + len; + } else { + *start = *start % 32; + *end = *end % 32; + } + + return; +} + static inline uint64_t mask(int start, int end) { @@ -204,18 +224,16 @@ mask(int start, int end) static inline uint64_t field(uint64_t value, int start, int end) { - /* The field values are obtained from the DWord, - * Hence, get the relative start and end positions - * by doing a %32 on the start and end positions - */ - return (value & mask(start % 32, end % 32)) >> (start % 32); + get_start_end_pos(&start, &end); + return (value & mask(start, end)) >> (start); } static inline uint64_t field_address(uint64_t value, int start, int end) { /* no need to right shift for address/offset */ - return (value & mask(start % 32, end % 32)); + get_start_end_pos(&start, &end); + return (value & mask(start, end)); } static struct gen_type @@ -491,7 +509,7 @@ gen_field_iterator_next(struct gen_field_iterator *iter) { struct gen_field *f; union { - uint32_t dw; + uint64_t qw; float f; } v; @@ -500,20 +518,26 @@ gen_field_iterator_next(struct gen_field_iterator *iter) f = iter->group->fields[iter->i++]; iter->name = f->name; - v.dw = iter->p[f->start / 32]; + int index = f->start / 32; + + if ((f->end - f->start) > 32) + v.qw = ((uint64_t) iter->p[index+1] << 32) | iter->p[index]; + else + v.qw = iter->p[index]; + switch (f->type.kind) { case GEN_TYPE_UNKNOWN: case GEN_TYPE_INT: snprintf(iter->value, sizeof(iter->value), - "%ld", field(v.dw, f->start, f->end)); + "%ld", field(v.qw, f->start, f->end)); break; case GEN_TYPE_UINT: snprintf(iter->value, sizeof(iter->value), - "%lu", field(v.dw, f->start, f->end)); + "%lu", field(v.qw, f->start, f->end)); break; case GEN_TYPE_BOOL: snprintf(iter->value, sizeof(iter->value), - "%s", field(v.dw, f->start, f->end) ? "true" : "false"); + "%s", field(v.qw, f->start, f->end) ? "true" : "false"); break; case GEN_TYPE_FLOAT: snprintf(iter->value, sizeof(iter->value), "%f", v.f); @@ -521,7 +545,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%08lx", field_address(v.dw, f->start, f->end)); + "0x%08lx", field_address(v.qw, f->start, f->end)); break; case GEN_TYPE_STRUCT: snprintf(iter->value, sizeof(iter->value), @@ -529,7 +553,7 @@ gen_field_iterator_next(struct gen_field_iterator *iter) break; case GEN_TYPE_UFIXED: snprintf(iter->value, sizeof(iter->value), - "%f", (float) field(v.dw, f->start, f->end) / (1 << f->type.f)); + "%f", (float) field(v.qw, f->start, f->end) / (1 << f->type.f)); break; case GEN_TYPE_SFIXED: /* FIXME: Sign extend extracted field. */ |