+\f
+
+/* Indices into option argument vector for options accepting an argument.
+ Use RISCV_OPTION_ARG_NONE for options accepting no argument. */
+
+typedef enum
+{
+ RISCV_OPTION_ARG_NONE = -1,
+ RISCV_OPTION_ARG_PRIV_SPEC,
+
+ RISCV_OPTION_ARG_COUNT
+} riscv_option_arg_t;
+
+/* Valid RISCV disassembler options. */
+
+static struct
+{
+ const char *name;
+ const char *description;
+ riscv_option_arg_t arg;
+} riscv_options[] =
+{
+ { "numeric",
+ N_("Print numeric register names, rather than ABI names."),
+ RISCV_OPTION_ARG_NONE },
+ { "no-aliases",
+ N_("Disassemble only into canonical instructions."),
+ RISCV_OPTION_ARG_NONE },
+ { "priv-spec=",
+ N_("Print the CSR according to the chosen privilege spec."),
+ RISCV_OPTION_ARG_PRIV_SPEC }
+};
+
+/* Build the structure representing valid RISCV disassembler options.
+ This is done dynamically for maintenance ease purpose; a static
+ initializer would be unreadable. */
+
+const disasm_options_and_args_t *
+disassembler_options_riscv (void)
+{
+ static disasm_options_and_args_t *opts_and_args;
+
+ if (opts_and_args == NULL)
+ {
+ size_t num_options = ARRAY_SIZE (riscv_options);
+ size_t num_args = RISCV_OPTION_ARG_COUNT;
+ disasm_option_arg_t *args;
+ disasm_options_t *opts;
+ size_t i, priv_spec_count;
+
+ args = XNEWVEC (disasm_option_arg_t, num_args + 1);
+
+ args[RISCV_OPTION_ARG_PRIV_SPEC].name = "SPEC";
+ priv_spec_count = PRIV_SPEC_CLASS_DRAFT - PRIV_SPEC_CLASS_NONE - 1;
+ args[RISCV_OPTION_ARG_PRIV_SPEC].values
+ = XNEWVEC (const char *, priv_spec_count + 1);
+ for (i = 0; i < priv_spec_count; i++)
+ args[RISCV_OPTION_ARG_PRIV_SPEC].values[i]
+ = riscv_priv_specs[i].name;
+ /* The array we return must be NULL terminated. */
+ args[RISCV_OPTION_ARG_PRIV_SPEC].values[i] = NULL;
+
+ /* The array we return must be NULL terminated. */
+ args[num_args].name = NULL;
+ args[num_args].values = NULL;
+
+ opts_and_args = XNEW (disasm_options_and_args_t);
+ opts_and_args->args = args;
+
+ opts = &opts_and_args->options;
+ opts->name = XNEWVEC (const char *, num_options + 1);
+ opts->description = XNEWVEC (const char *, num_options + 1);
+ opts->arg = XNEWVEC (const disasm_option_arg_t *, num_options + 1);
+ for (i = 0; i < num_options; i++)
+ {
+ opts->name[i] = riscv_options[i].name;
+ opts->description[i] = _(riscv_options[i].description);
+ if (riscv_options[i].arg != RISCV_OPTION_ARG_NONE)
+ opts->arg[i] = &args[riscv_options[i].arg];
+ else
+ opts->arg[i] = NULL;
+ }
+ /* The array we return must be NULL terminated. */
+ opts->name[i] = NULL;
+ opts->description[i] = NULL;
+ opts->arg[i] = NULL;
+ }
+
+ return opts_and_args;
+}