XML_Parser parser;
int foo;
struct location loc;
- const char *platform;
struct gen_group *group;
struct gen_enum *enoom;
get_group_offset_count(const char **atts, uint32_t *offset, uint32_t *count,
uint32_t *size, bool *variable)
{
- char *p;
- int i;
+ for (int i = 0; atts[i]; i += 2) {
+ char *p;
- for (i = 0; atts[i]; i += 2) {
if (strcmp(atts[i], "count") == 0) {
*count = strtoul(atts[i + 1], &p, 0);
if (*count == 0)
group->spec = ctx->spec;
group->variable = false;
+ for (int i = 0; atts[i]; i += 2) {
+ char *p;
+ if (strcmp(atts[i], "length") == 0) {
+ group->dw_length = strtoul(atts[i + 1], &p, 0);
+ }
+ }
+
if (parent) {
group->parent = parent;
get_group_offset_count(atts,
static void
get_register_offset(const char **atts, uint32_t *offset)
{
- char *p;
- int i;
+ for (int i = 0; atts[i]; i += 2) {
+ char *p;
- for (i = 0; atts[i]; i += 2) {
if (strcmp(atts[i], "num") == 0)
*offset = strtoul(atts[i + 1], &p, 0);
}
}
static inline uint64_t
-field(uint64_t value, int start, int end)
+field_value(uint64_t value, int start, int end)
{
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 */
- get_start_end_pos(&start, &end);
- return (value & mask(start, end));
-}
-
static struct gen_type
string_to_type(struct parser_context *ctx, const char *s)
{
create_field(struct parser_context *ctx, const char **atts)
{
struct gen_field *field;
- char *p;
- int i;
field = rzalloc(ctx->group, struct gen_field);
+ field->parent = ctx->group;
+
+ for (int i = 0; atts[i]; i += 2) {
+ char *p;
- for (i = 0; atts[i]; i += 2) {
if (strcmp(atts[i], "name") == 0)
field->name = ralloc_strdup(field, atts[i + 1]);
else if (strcmp(atts[i], "start") == 0)
start_element(void *data, const char *element_name, const char **atts)
{
struct parser_context *ctx = data;
- int i;
const char *name = NULL;
const char *gen = NULL;
ctx->loc.line_number = XML_GetCurrentLineNumber(ctx->parser);
- for (i = 0; atts[i]; i += 2) {
+ for (int i = 0; atts[i]; i += 2) {
if (strcmp(atts[i], "name") == 0)
name = atts[i + 1];
else if (strcmp(atts[i], "gen") == 0)
if (gen == NULL)
fail(&ctx->loc, "no gen given");
- ctx->platform = strdup(name);
int major, minor;
int n = sscanf(gen, "%d.%d", &major, &minor);
if (n == 0)
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);
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)
{
uint32_t h = p[0];
- uint32_t type = field(h, 29, 31);
+ uint32_t type = field_value(h, 29, 31);
switch (type) {
case 0: /* MI */ {
- uint32_t opcode = field(h, 23, 28);
+ uint32_t opcode = field_value(h, 23, 28);
if (opcode < 16)
return 1;
else
- return field(h, 0, 7) + 2;
+ return field_value(h, 0, 7) + 2;
break;
}
case 2: /* BLT */ {
- return field(h, 0, 7) + 2;
+ return field_value(h, 0, 7) + 2;
}
case 3: /* Render */ {
- uint32_t subtype = field(h, 27, 28);
- uint32_t opcode = field(h, 24, 26);
- uint16_t whole_opcode = field(h, 16, 31);
+ uint32_t subtype = field_value(h, 27, 28);
+ uint32_t opcode = field_value(h, 24, 26);
+ uint16_t whole_opcode = field_value(h, 16, 31);
switch (subtype) {
case 0:
if (whole_opcode == 0x6104 /* PIPELINE_SELECT_965 */)
return 1;
else if (opcode < 2)
- return field(h, 0, 7) + 2;
+ return field_value(h, 0, 7) + 2;
else
return -1;
case 1:
return -1;
case 2: {
if (opcode == 0)
- return field(h, 0, 7) + 2;
+ return field_value(h, 0, 7) + 2;
else if (opcode < 3)
- return field(h, 0, 15) + 2;
+ return field_value(h, 0, 15) + 2;
else
return -1;
}
if (whole_opcode == 0x780b)
return 1;
else if (opcode < 4)
- return field(h, 0, 7) + 2;
+ return field_value(h, 0, 7) + 2;
else
return -1;
}
static bool
iter_advance_field(struct gen_field_iterator *iter)
{
- while (!iter_more_fields(iter)) {
+ if (iter_more_fields(iter)) {
+ iter->field = iter->field->next;
+ } else {
if (!iter_more_groups(iter))
return false;
iter_advance_group(iter);
}
- iter->field = iter->field->next;
if (iter->field->name)
strncpy(iter->name, iter->field->name, sizeof(iter->name));
else
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->bit = group_member_offset + iter->field->start;
iter->struct_desc = NULL;
return true;
}
+static uint64_t
+iter_decode_field_raw(struct gen_field_iterator *iter)
+{
+ uint64_t qw = 0;
+
+ int field_start = iter->p_bit + iter->bit;
+ int field_end = field_start + (iter->field->end - iter->field->start);
+
+ const uint32_t *p = iter->p + (iter->bit / 32);
+ if ((field_end - field_start) > 32) {
+ if ((p + 1) < iter->p_end)
+ qw = ((uint64_t) p[1]) << 32;
+ qw |= p[0];
+ } else
+ qw = p[0];
+
+ qw = field_value(qw, field_start, field_end);
+
+ /* Address & offset types have to be aligned to dwords, their start bit is
+ * a reminder of the alignment requirement.
+ */
+ if (iter->field->type.kind == GEN_TYPE_ADDRESS ||
+ iter->field->type.kind == GEN_TYPE_OFFSET)
+ qw <<= field_start % 32;
+
+ return qw;
+}
+
static void
-gen_field_decode(struct gen_field_iterator *iter)
+iter_decode_field(struct gen_field_iterator *iter)
{
union {
uint64_t qw;
memset(&v, 0, sizeof(v));
- if ((iter->field->end - iter->field->start) > 32) {
- if (&iter->p[iter->dword + 1] < iter->p_end)
- v.qw = ((uint64_t) iter->p[iter->dword+1] << 32);
- v.qw |= iter->p[iter->dword];
- } else
- v.qw = iter->p[iter->dword];
+ iter->raw_value = iter_decode_field_raw(iter);
const char *enum_name = NULL;
+ v.qw = iter->raw_value;
switch (iter->field->type.kind) {
case GEN_TYPE_UNKNOWN:
case GEN_TYPE_INT: {
- 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);
+ snprintf(iter->value, sizeof(iter->value), "%"PRId64, v.qw);
+ enum_name = gen_get_enum_name(&iter->field->inline_enum, v.qw);
break;
}
case GEN_TYPE_UINT: {
- 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);
+ snprintf(iter->value, sizeof(iter->value), "%"PRIu64, v.qw);
+ enum_name = gen_get_enum_name(&iter->field->inline_enum, v.qw);
break;
}
case GEN_TYPE_BOOL: {
const char *true_string =
iter->print_colors ? "\e[0;35mtrue\e[0m" : "true";
snprintf(iter->value, sizeof(iter->value), "%s",
- field(v.qw, iter->start, iter->end) ?
- true_string : "false");
+ v.qw ? true_string : "false");
break;
}
case GEN_TYPE_FLOAT:
break;
case GEN_TYPE_ADDRESS:
case GEN_TYPE_OFFSET:
- snprintf(iter->value, sizeof(iter->value), "0x%08"PRIx64,
- field_address(v.qw, iter->start, iter->end));
+ snprintf(iter->value, sizeof(iter->value), "0x%08"PRIx64, v.qw);
break;
case GEN_TYPE_STRUCT:
snprintf(iter->value, sizeof(iter->value), "<struct %s>",
break;
case GEN_TYPE_UFIXED:
snprintf(iter->value, sizeof(iter->value), "%f",
- (float) field(v.qw, iter->start, iter->end) /
- (1 << iter->field->type.f));
+ (float) v.qw / (1 << iter->field->type.f));
break;
case GEN_TYPE_SFIXED:
/* FIXME: Sign extend extracted field. */
case GEN_TYPE_MBO:
break;
case GEN_TYPE_ENUM: {
- 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);
+ snprintf(iter->value, sizeof(iter->value), "%"PRId64, v.qw);
+ enum_name = gen_get_enum_name(iter->field->type.gen_enum, v.qw);
break;
}
}
void
gen_field_iterator_init(struct gen_field_iterator *iter,
struct gen_group *group,
- const uint32_t *p,
+ const uint32_t *p, int p_bit,
bool print_colors)
{
memset(iter, 0, sizeof(*iter));
else
iter->field = group->next->fields;
iter->p = p;
+ iter->p_bit = p_bit;
iter->p_end = &p[gen_group_get_length(iter->group, iter->p)];
iter->print_colors = print_colors;
- gen_field_decode(iter);
+ iter_decode_field(iter);
}
bool
if (!iter_advance_field(iter))
return false;
- gen_field_decode(iter);
+ iter_decode_field(iter);
return true;
}
}
bool
-gen_group_header_is_header(struct gen_group *group, struct gen_field *field)
+gen_field_is_header(struct gen_field *field)
{
uint32_t bits;
bits = (1U << (field->end - field->start + 1)) - 1;
bits <<= field->start;
- return (group->opcode_mask & bits) != 0;
+ return (field->parent->opcode_mask & bits) != 0;
}
void
-gen_print_group(FILE *outfile, struct gen_group *group,
- uint64_t offset, const uint32_t *p, bool color)
+gen_print_group(FILE *outfile, struct gen_group *group, uint64_t offset,
+ const uint32_t *p, int p_bit, bool color)
{
struct gen_field_iterator iter;
int last_dword = -1;
- gen_field_iterator_init(&iter, group, p, color);
+ gen_field_iterator_init(&iter, group, p, p_bit, color);
do {
- if (last_dword != iter.dword) {
- for (int i = last_dword + 1; i <= iter.dword; i++)
+ int iter_dword = iter.bit / 32;
+ if (last_dword != iter_dword) {
+ for (int i = last_dword + 1; i <= iter_dword; i++)
print_dword_header(outfile, &iter, offset, i);
- last_dword = iter.dword;
+ last_dword = iter_dword;
}
- if (!gen_group_header_is_header(group, iter.field)) {
+ if (!gen_field_is_header(iter.field)) {
fprintf(outfile, " %s: %s\n", iter.name, iter.value);
if (iter.struct_desc) {
- uint64_t struct_offset = offset + 4 * iter.dword;
+ uint64_t struct_offset = offset + 4 * iter_dword;
gen_print_group(outfile, iter.struct_desc, struct_offset,
- &p[iter.dword], color);
+ &p[iter_dword], iter.bit % 32, color);
}
}
} while (gen_field_iterator_next(&iter));