aubinator: Add support for enum types
authorKristian H. Kristensen <hoegsberg@gmail.com>
Tue, 29 Nov 2016 06:40:23 +0000 (22:40 -0800)
committerKristian H. Kristensen <hoegsberg@gmail.com>
Wed, 30 Nov 2016 06:02:49 +0000 (22:02 -0800)
Signed-off-by: Kristian H. Kristensen <hoegsberg@gmail.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/intel/tools/decoder.c
src/intel/tools/decoder.h

index 633251a44cf382bc2cb572d5f6c54e0ec7f07e38..defb0873da0f7112d1115b09f855037bd855d0b4 100644 (file)
@@ -52,6 +52,8 @@ struct gen_spec {
    struct gen_group *structs[256];
    int nregisters;
    struct gen_group *registers[256];
+   int nenums;
+   struct gen_enum *enums[256];
 };
 
 struct location {
@@ -66,10 +68,14 @@ struct parser_context {
    const char *platform;
 
    struct gen_group *group;
+   struct gen_enum *enoom;
 
    int nfields;
    struct gen_field *fields[128];
 
+   int nvalues;
+   struct gen_value *values[256];
+
    struct gen_spec *spec;
 };
 
@@ -105,6 +111,16 @@ gen_spec_find_register(struct gen_spec *spec, uint32_t offset)
    return NULL;
 }
 
+struct gen_enum *
+gen_spec_find_enum(struct gen_spec *spec, const char *name)
+{
+   for (int i = 0; i < spec->nenums; i++)
+      if (strcmp(spec->enums[i]->name, name) == 0)
+         return spec->enums[i];
+
+   return NULL;
+}
+
 uint32_t
 gen_spec_get_gen(struct gen_spec *spec)
 {
@@ -169,6 +185,20 @@ create_group(struct parser_context *ctx, const char *name, const char **atts)
    return group;
 }
 
+static struct gen_enum *
+create_enum(struct parser_context *ctx, const char *name, const char **atts)
+{
+   struct gen_enum *e;
+
+   e = xzalloc(sizeof(*e));
+   if (name)
+      e->name = xstrdup(name);
+
+   e->nvalues = 0;
+
+   return e;
+}
+
 static void
 get_group_offset_count(struct parser_context *ctx, const char *name,
                        const char **atts, uint32_t *offset, uint32_t *count)
@@ -248,6 +278,7 @@ string_to_type(struct parser_context *ctx, const char *s)
 {
    int i, f;
    struct gen_group *g;
+   struct gen_enum *e;
 
    if (strcmp(s, "int") == 0)
       return (struct gen_type) { .kind = GEN_TYPE_INT };
@@ -267,6 +298,8 @@ string_to_type(struct parser_context *ctx, const char *s)
       return (struct gen_type) { .kind = GEN_TYPE_SFIXED, .i = i, .f = f };
    else if (g = gen_spec_find_struct(ctx->spec, s), g != NULL)
       return (struct gen_type) { .kind = GEN_TYPE_STRUCT, .gen_struct = g };
+   else if (e = gen_spec_find_enum(ctx->spec, s), e != NULL)
+      return (struct gen_type) { .kind = GEN_TYPE_ENUM, .gen_enum = e };
    else if (strcmp(s, "mbo") == 0)
       return (struct gen_type) { .kind = GEN_TYPE_MBO };
    else
@@ -366,23 +399,9 @@ start_element(void *data, const char *element_name, const char **atts)
             ctx->group->group_count--;
       } while (ctx->group->group_count > 0);
    } else if (strcmp(element_name, "enum") == 0) {
+      ctx->enoom = create_enum(ctx, name, atts);
    } else if (strcmp(element_name, "value") == 0) {
-      if (ctx->nfields > 0) {
-         struct gen_field *field = ctx->fields[ctx->nfields - 1];
-         if (field->n_allocated_values <= field->n_values) {
-            if (field->n_allocated_values == 0) {
-               field->n_allocated_values = 2;
-               field->values =
-                  xzalloc(sizeof(field->values[0]) * field->n_allocated_values);
-            } else {
-               field->n_allocated_values *= 2;
-               field->values =
-                  realloc(field->values,
-                          sizeof(field->values[0]) * field->n_allocated_values);
-            }
-         }
-         field->values[field->n_values++] = create_value(ctx, atts);
-      }
+      ctx->values[ctx->nvalues++] = create_value(ctx, atts);
    }
 }
 
@@ -390,6 +409,7 @@ static void
 end_element(void *data, const char *name)
 {
    struct parser_context *ctx = data;
+   struct gen_spec *spec = ctx->spec;
 
    if (strcmp(name, "instruction") == 0 ||
       strcmp(name, "struct") == 0 ||
@@ -414,7 +434,6 @@ end_element(void *data, const char *name)
          }
       }
 
-      struct gen_spec *spec = ctx->spec;
       if (strcmp(name, "instruction") == 0)
          spec->commands[spec->ncommands++] = group;
       else if (strcmp(name, "struct") == 0)
@@ -424,6 +443,23 @@ end_element(void *data, const char *name)
    } else if (strcmp(name, "group") == 0) {
       ctx->group->group_offset = 0;
       ctx->group->group_count = 0;
+   } else if (strcmp(name, "field") == 0) {
+      assert(ctx->nfields > 0);
+      struct gen_field *field = ctx->fields[ctx->nfields - 1];
+      size_t size = ctx->nvalues * sizeof(ctx->values[0]);
+      field->inline_enum.values = xzalloc(size);
+      field->inline_enum.nvalues = ctx->nvalues;
+      memcpy(field->inline_enum.values, ctx->values, size);
+      ctx->nvalues = 0;
+   } else if (strcmp(name, "enum") == 0) {
+      struct gen_enum *e = ctx->enoom;
+      size_t size = ctx->nvalues * sizeof(ctx->values[0]);
+      e->values = xzalloc(size);
+      e->nvalues = ctx->nvalues;
+      memcpy(e->values, ctx->values, size);
+      ctx->nvalues = 0;
+      ctx->enoom = NULL;
+      spec->enums[spec->nenums++] = e;
    }
 }
 
@@ -637,13 +673,12 @@ gen_field_iterator_init(struct gen_field_iterator *iter,
 }
 
 static void
-gen_field_write_value(char *str, size_t max_length,
-                      struct gen_field *field,
-                      uint64_t value)
+gen_enum_write_value(char *str, size_t max_length,
+                      struct gen_enum *e, uint64_t value)
 {
-   for (int i = 0; i < field->n_values; i++) {
-      if (field->values[i]->value == value) {
-         strncpy(str, field->values[i]->name, max_length);
+   for (int i = 0; i < e->nvalues; i++) {
+      if (e->values[i]->value == value) {
+         strncpy(str, e->values[i]->name, max_length);
          return;
       }
    }
@@ -678,16 +713,16 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
       uint64_t value = field(v.qw, f->start, f->end);
       snprintf(iter->value, sizeof(iter->value),
                "%"PRId64, value);
-      gen_field_write_value(iter->description, sizeof(iter->description),
-                            f, value);
+      gen_enum_write_value(iter->description, sizeof(iter->description),
+                           &f->inline_enum, value);
       break;
    }
    case GEN_TYPE_UINT: {
       uint64_t value = field(v.qw, f->start, f->end);
       snprintf(iter->value, sizeof(iter->value),
                "%"PRIu64, value);
-      gen_field_write_value(iter->description, sizeof(iter->description),
-                            f, value);
+      gen_enum_write_value(iter->description, sizeof(iter->description),
+                            &f->inline_enum, value);
       break;
    }
    case GEN_TYPE_BOOL: {
@@ -719,6 +754,14 @@ gen_field_iterator_next(struct gen_field_iterator *iter)
       break;
    case GEN_TYPE_MBO:
        break;
+   case GEN_TYPE_ENUM: {
+      uint64_t value = field(v.qw, f->start, f->end);
+      snprintf(iter->value, sizeof(iter->value),
+               "%"PRId64, value);
+      gen_enum_write_value(iter->description, sizeof(iter->description),
+                           f->type.gen_enum, value);
+      break;
+   }
    }
 
    return true;
index b28e603124954ceda1ac03e218bc0b41bda3f25a..9f0aa4f35f19e9b5fe573e2d59df6aa7b9a5c961 100644 (file)
@@ -48,6 +48,7 @@ struct gen_group *gen_spec_find_register(struct gen_spec *spec, uint32_t offset)
 int gen_group_get_length(struct gen_group *group, const uint32_t *p);
 const char *gen_group_get_name(struct gen_group *group);
 uint32_t gen_group_get_opcode(struct gen_group *group);
+struct gen_enum *gen_spec_find_enum(struct gen_spec *spec, const char *name);
 
 struct gen_field_iterator {
    struct gen_group *group;
@@ -72,6 +73,17 @@ struct gen_group {
    uint32_t register_offset;
 };
 
+struct gen_value {
+   char *name;
+   uint64_t value;
+};
+
+struct gen_enum {
+   char *name;
+   int nvalues;
+   struct gen_value **values;
+};
+
 struct gen_type {
    enum {
       GEN_TYPE_UNKNOWN,
@@ -84,14 +96,19 @@ struct gen_type {
       GEN_TYPE_STRUCT,
       GEN_TYPE_UFIXED,
       GEN_TYPE_SFIXED,
-      GEN_TYPE_MBO
+      GEN_TYPE_MBO,
+      GEN_TYPE_ENUM
    } 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;
+   union {
+      struct gen_group *gen_struct;
+      struct gen_enum *gen_enum;
+      struct {
+         /* Integer and fractional sizes for GEN_TYPE_UFIXED and GEN_TYPE_SFIXED */
+         int i, f;
+      };
+   };
 };
 
 struct gen_field {
@@ -101,14 +118,7 @@ struct gen_field {
    bool has_default;
    uint32_t default_value;
 
-   struct gen_value **values;
-   uint32_t n_values;
-   uint32_t n_allocated_values;
-};
-
-struct gen_value {
-   char *name;
-   uint64_t value;
+   struct gen_enum inline_enum;
 };
 
 void gen_field_iterator_init(struct gen_field_iterator *iter,