return offset < gtt_end;
}
+static void
+print_dword_val(struct gen_field_iterator *iter, uint64_t offset, int *dword_num)
+{
+ struct gen_field *f;
+ union {
+ uint32_t dw;
+ float f;
+ } v;
+
+ f = iter->group->fields[iter->i - 1];
+ v.dw = iter->p[f->start / 32];
+
+ if (*dword_num != (f->start / 32)) {
+ printf("0x%08lx: 0x%08x : Dword %d\n",(offset + 4 * (f->start / 32)), v.dw, f->start / 32);
+ *dword_num = (f->start / 32);
+ }
+}
+
+static char*
+print_iterator_values(struct gen_field_iterator *iter, int *idx)
+{
+ char *token = NULL;
+ if (strstr(iter->value,"struct") == NULL) {
+ printf(" %s: %s\n", iter->name, iter->value);
+ } else {
+ token = strtok(iter->value, " ");
+ if (token != NULL) {
+ token = strtok(NULL, " ");
+ *idx = atoi(strtok(NULL, ">"));
+ } else {
+ token = NULL;
+ }
+ printf(" %s:<struct %s>\n", iter->name, token);
+ }
+ return token;
+}
+
static void
decode_structure(struct gen_spec *spec, struct gen_group *strct, const uint32_t *p)
{
struct gen_field_iterator iter;
+ char *token = NULL;
+ int idx = 0, dword_num = 0;
+ uint64_t offset = 0;
+
+ if (option_print_offsets)
+ offset = (void *) p - gtt;
+ else
+ offset = 0;
gen_field_iterator_init(&iter, strct, p);
while (gen_field_iterator_next(&iter)) {
- printf(" %s: %s\n", iter.name, iter.value);
+ idx = 0;
+ print_dword_val(&iter, offset, &dword_num);
+ token = print_iterator_values(&iter, &idx);
+ if (token != NULL) {
+ struct gen_group *struct_val = gen_spec_find_struct(spec, token);
+ decode_structure(spec, struct_val, &p[idx]);
+ token = NULL;
+ }
}
}
+static void
+handle_struct_decode(struct gen_spec *spec, char *struct_name, uint32_t *p)
+{
+ if (struct_name == NULL)
+ return;
+ struct gen_group *struct_val = gen_spec_find_struct(spec, struct_name);
+ decode_structure(spec, struct_val, p);
+}
+
static void
dump_binding_table(struct gen_spec *spec, uint32_t offset)
{
}
}
+static void
+handle_3dstate_hs(struct gen_spec *spec, uint32_t *p)
+{
+ uint64_t start;
+ struct brw_instruction *insns;
+ int hs_enable;
+
+ if (gen_spec_get_gen(spec) >= gen_make_gen(8, 0)) {
+ start = get_qword(&p[4]);
+ } else {
+ start = p[4];
+ }
+
+ hs_enable = p[2] & 0x80000000;
+
+ if (hs_enable) {
+ printf("instruction_base %08lx, start %08lx\n",
+ instruction_base, start);
+
+ insns = (struct brw_instruction *) (gtt + instruction_base + start);
+ gen_disasm_disassemble(disasm, insns, 0, 8192, stdout);
+ }
+}
+
static void
handle_3dstate_constant(struct gen_spec *spec, uint32_t *p)
{
#define _3DSTATE_VS 0x78100000
#define _3DSTATE_GS 0x78110000
+#define _3DSTATE_HS 0x781b0000
+#define _3DSTATE_DS 0x781d0000
#define _3DSTATE_CONSTANT_VS 0x78150000
#define _3DSTATE_CONSTANT_GS 0x78160000
{ _3DSTATE_INDEX_BUFFER, handle_3dstate_index_buffer },
{ _3DSTATE_VS, handle_3dstate_vs },
{ _3DSTATE_GS, handle_3dstate_vs },
- /* FIXME: Handle disassmbing for 3DSTATE_HS and 3DSTATE_DS. */
+ { _3DSTATE_DS, handle_3dstate_vs },
+ { _3DSTATE_HS, handle_3dstate_hs },
{ _3DSTATE_CONSTANT_VS, handle_3dstate_constant },
{ _3DSTATE_CONSTANT_GS, handle_3dstate_constant },
{ _3DSTATE_CONSTANT_PS, handle_3dstate_constant },
if (option_full_decode) {
struct gen_field_iterator iter;
+ char* token = NULL;
+ int idx = 0, dword_num = 0;
gen_field_iterator_init(&iter, inst, p);
while (gen_field_iterator_next(&iter)) {
- printf(" %s: %s\n", iter.name, iter.value);
+ idx = 0;
+ print_dword_val(&iter, offset, &dword_num);
+ if (dword_num > 0)
+ token = print_iterator_values(&iter, &idx);
+ if (token != NULL) {
+ printf("0x%08lx: 0x%08x : Dword %d\n",(offset+4*idx), p[idx], idx);
+ handle_struct_decode(spec,token, &p[idx]);
+ token = NULL;
+ }
}
for (i = 0; i < ARRAY_LENGTH(custom_handlers); i++) {
struct gen_group *registers[256];
};
-struct gen_group {
- char *name;
- int nfields;
- struct gen_field **fields;
-
- uint32_t opcode_mask;
- uint32_t opcode;
-};
-
-struct gen_type {
- enum {
- GEN_TYPE_UNKNOWN,
- GEN_TYPE_INT,
- GEN_TYPE_UINT,
- GEN_TYPE_BOOL,
- GEN_TYPE_FLOAT,
- GEN_TYPE_ADDRESS,
- GEN_TYPE_OFFSET,
- GEN_TYPE_STRUCT,
- GEN_TYPE_UFIXED,
- GEN_TYPE_SFIXED,
- GEN_TYPE_MBO
- } kind;
-
- /* Struct definition for GEN_TYPE_STRUCT */
- struct gen_group *gen_struct;
-
- /* Integer and fractional sizes for GEN_TYPE_UFIXED and GEN_TYPE_SFIXED */
- int i, f;
-};
-
-struct gen_field {
- char *name;
- int start, end;
- struct gen_type type;
- bool has_default;
- uint32_t default_value;
-};
-
struct location {
const char *filename;
int line_number;
if (name)
group->name = xstrdup(name);
+ group->group_offset = 0;
+ group->group_count = 0;
+
return group;
}
+static void
+get_group_offset_count(struct parser_context *ctx, const char *name, const char **atts, uint32_t *offset, uint32_t *count)
+{
+ char *p;
+ int i;
+
+ for (i = 0; atts[i]; i += 2) {
+ if (strcmp(atts[i], "count") == 0)
+ *count = strtoul(atts[i + 1], &p, 0);
+ else if (strcmp(atts[i], "start") == 0)
+ *offset = strtoul(atts[i + 1], &p, 0);
+ }
+ return;
+}
+
static inline uint64_t
mask(int start, int end)
{
static inline uint64_t
field(uint64_t value, int start, int end)
{
- return (value & mask(start, end)) >> start;
+ /* 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);
+}
+
+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));
}
static struct gen_type
if (strcmp(atts[i], "name") == 0)
field->name = xstrdup(atts[i + 1]);
else if (strcmp(atts[i], "start") == 0)
- field->start = strtoul(atts[i + 1], &p, 0);
- else if (strcmp(atts[i], "end") == 0)
- field->end = strtoul(atts[i + 1], &p, 0);
- else if (strcmp(atts[i], "type") == 0)
+ field->start = ctx->group->group_offset+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;
+ } else if (strcmp(atts[i], "type") == 0)
field->type = string_to_type(ctx, atts[i + 1]);
else if (strcmp(atts[i], "default") == 0 &&
field->start >= 16 && field->end <= 31) {
strcmp(element_name, "register") == 0) {
ctx->group = create_group(ctx, name, atts);
} else if (strcmp(element_name, "group") == 0) {
+ get_group_offset_count(ctx, name, atts,&ctx->group->group_offset,&ctx->group->group_count);
} else if (strcmp(element_name, "field") == 0) {
- ctx->fields[ctx->nfields++] = create_field(ctx, atts);
+ do {
+ ctx->fields[ctx->nfields++] = create_field(ctx, atts);
+ if(ctx->group->group_count)
+ ctx->group->group_count--;
+ } while (ctx->group->group_count > 0);
} else if (strcmp(element_name, "enum") == 0) {
} else if (strcmp(element_name, "value") == 0) {
}
group->fields[i]->end <= 31 &&
group->fields[i]->has_default) {
group->opcode_mask |=
- mask(group->fields[i]->start, group->fields[i]->end);
+ mask(group->fields[i]->start % 32, group->fields[i]->end % 32);
group->opcode |=
group->fields[i]->default_value << group->fields[i]->start;
}
spec->structs[spec->nstructs++] = group;
else if (strcmp(name, "register") == 0)
spec->registers[spec->nregisters++] = group;
+ } else if (strcmp(name, "group") == 0) {
+ ctx->group->group_offset = 0;
+ ctx->group->group_count = 0;
}
}
struct gen_group *
gen_spec_find_instruction(struct gen_spec *spec, const uint32_t *p)
{
- /* FIXME: Make sure the opcodes put out are correct */
for (int i = 0; i < spec->ncommands; i++) {
uint32_t opcode = *p & spec->commands[i]->opcode_mask;
if (opcode == spec->commands[i]->opcode)
case GEN_TYPE_ADDRESS:
case GEN_TYPE_OFFSET:
snprintf(iter->value, sizeof(iter->value),
- "0x%08lx", field(v.dw, f->start, f->end));
+ "0x%08lx", field_address(v.dw, f->start, f->end));
break;
case GEN_TYPE_STRUCT:
- /* FIXME: Make iterator decode the struct recursively */
snprintf(iter->value, sizeof(iter->value),
- "<struct %s>", f->type.gen_struct->name);
+ "<struct %s %d>", f->type.gen_struct->name, (f->start / 32));
break;
case GEN_TYPE_UFIXED:
snprintf(iter->value, sizeof(iter->value),