struct gen_group *structs[256];
int nregisters;
struct gen_group *registers[256];
+ int nenums;
+ struct gen_enum *enums[256];
};
struct location {
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;
};
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)
{
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)
{
int i, f;
struct gen_group *g;
+ struct gen_enum *e;
if (strcmp(s, "int") == 0)
return (struct gen_type) { .kind = GEN_TYPE_INT };
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
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);
}
}
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 ||
}
}
- struct gen_spec *spec = ctx->spec;
if (strcmp(name, "instruction") == 0)
spec->commands[spec->ncommands++] = group;
else if (strcmp(name, "struct") == 0)
} 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;
}
}
}
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;
}
}
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: {
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;