aubinator: Add support for enum types
Signed-off-by: Kristian H. Kristensen <hoegsberg@gmail.com> Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:
parent
7fc659d8d5
commit
d3d7cab812
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue