summaryrefslogtreecommitdiff
path: root/packages/gdb/10.2/0013-arc-Construct-disassembler-options-dynamically.patch
blob: d656f743e33632fd54cd7c54006e5ade6f3bdb9e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
From 8b8464d228b46a2abd677a0a440e0d08da75df0b Mon Sep 17 00:00:00 2001
From: Shahab Vahedi <shahab@synopsys.com>
Date: Wed, 2 Jun 2021 15:30:16 +0300
Subject: [PATCH 16/20] arc: Construct disassembler options dynamically

The idea of this change is simple: Populate a data structure, namely
"disasm_option_and_arg_t" from "include/dis-asm.h", to encompass the
disassembly options and their possible arguments.

This will make it easier to manage or extend those options by adapting
entries in a data structure, "arc_options".  There will be lesser need
to hard-code the options in the code itself.  Moreover, ARC GDB will
use this population function, "disassembler_options_arc ()", to enable
the "set disassembler-option" for ARC targets.  The gdb change will be
in a separate patch though.

The changes in this patch can be divided into:

1) Introduction of "disassembler_options_arc ()" that will return a
"disasm_option_and_arg_t" structure representing the disassembly
options and their likely arguments.

2) New data type "arc_options_arg_t" and new data "arc_options".
These are the internals for keeping track of options and arguments
entries that can easily be extended.

3) To print the options, the "print_arc_disassembler_options ()" has
been adjusted to use this dynamically built structure instead of having
them hard-coded inside.

To see this in effect, one can look into the output of:
$ ./binutils/objdump --help
  ...
  The following ARC specific disassembler options are...
  ...

include/ChangeLog:

	* dis-asm.h (disassembler_options_arc): New prototype.

opcodes/ChangeLog:

	* arc-dis.c (arc_option_arg_t): New enumeration.
	(arc_options): New variable.
	(disassembler_options_arc): New function.
	(print_arc_disassembler_options): Reimplement in terms of
	"disassembler_options_arc".

Will be a part of GDB 11:
https://sourceware.org/git?p=binutils-gdb.git;a=commit;h=8f467114435286e4f78b16fc1f5864acf6488fc0
---
 include/ChangeLog |    4 +
 include/dis-asm.h |    1 
 opcodes/ChangeLog |    8 ++
 opcodes/arc-dis.c |  180 +++++++++++++++++++++++++++++++++++++++++++++---------
 4 files changed, 166 insertions(+), 27 deletions(-)

--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,7 @@
+2021-06-02  Shahab Vahedi  <shahab@synopsys.com>
+
+	* dis-asm.h (disassembler_options_arc): New prototype.
+
 2020-09-12  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR ld/26391
--- a/include/dis-asm.h
+++ b/include/dis-asm.h
@@ -311,6 +311,7 @@
 extern void disassemble_init_s390 (struct disassemble_info *);
 extern void disassemble_init_wasm32 (struct disassemble_info *);
 extern void disassemble_init_nds32 (struct disassemble_info *);
+extern const disasm_options_and_args_t *disassembler_options_arc (void);
 extern const disasm_options_and_args_t *disassembler_options_arm (void);
 extern const disasm_options_and_args_t *disassembler_options_mips (void);
 extern const disasm_options_and_args_t *disassembler_options_powerpc (void);
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,11 @@
+2021-06-02  Shahab Vahedi  <shahab@synopsys.com>
+
+	* arc-dis.c (arc_option_arg_t): New enumeration.
+	(arc_options): New variable.
+	(disassembler_options_arc): New function.
+	(print_arc_disassembler_options): Reimplement in terms of
+	"disassembler_options_arc".
+
 2020-10-22  Andrew Burgess <andrew.burgess@embecosm.com>
 
 	* csky-dis.c (csky_get_disassembler): Don't return NULL when there
--- a/opcodes/arc-dis.c
+++ b/opcodes/arc-dis.c
@@ -1412,41 +1412,167 @@
   return print_insn_arc;
 }
 
+/* Indices into option argument vector for options that do require
+   an argument.  Use ARC_OPTION_ARG_NONE for options that don't
+   expect an argument.  */
+typedef enum
+{
+  ARC_OPTION_ARG_NONE = -1,
+  ARC_OPTION_ARG_ARCH,
+  ARC_OPTION_ARG_SIZE
+} arc_option_arg_t;
+
+/* Valid ARC disassembler options.  */
+static struct
+{
+  const char *name;
+  const char *description;
+  arc_option_arg_t arg;
+} arc_options[] =
+{
+  { "cpu=",       N_("Enforce the designated architecture while decoding."),
+		  ARC_OPTION_ARG_ARCH },
+  { "dsp",	  N_("Recognize DSP instructions."),
+		  ARC_OPTION_ARG_NONE },
+  { "spfp",	  N_("Recognize FPX SP instructions."),
+		  ARC_OPTION_ARG_NONE },
+  { "dpfp",	  N_("Recognize FPX DP instructions."),
+		  ARC_OPTION_ARG_NONE },
+  { "quarkse_em", N_("Recognize FPU QuarkSE-EM instructions."),
+		  ARC_OPTION_ARG_NONE },
+  { "fpuda",	  N_("Recognize double assist FPU instructions."),
+		  ARC_OPTION_ARG_NONE },
+  { "fpus",	  N_("Recognize single precision FPU instructions."),
+		  ARC_OPTION_ARG_NONE },
+  { "fpud",	  N_("Recognize double precision FPU instructions."),
+		  ARC_OPTION_ARG_NONE },
+  { "nps400",	  N_("Recognize NPS400 instructions."),
+		  ARC_OPTION_ARG_NONE },
+  { "hex",	  N_("Use only hexadecimal number to print immediates."),
+		  ARC_OPTION_ARG_NONE }
+};
+
+/* Populate the structure for representing ARC's disassembly options.
+   Such a dynamic initialization is desired, because it makes the maintenance
+   easier and also gdb uses this to enable the "disassembler-option".  */
+
+const disasm_options_and_args_t *
+disassembler_options_arc (void)
+{
+  static disasm_options_and_args_t *opts_and_args;
+
+  if (opts_and_args == NULL)
+    {
+      disasm_option_arg_t *args;
+      disasm_options_t *opts;
+      size_t i;
+      const size_t nr_of_options = ARRAY_SIZE (arc_options);
+      /* There is a null element at the end of CPU_TYPES, therefore
+	 NR_OF_CPUS is actually 1 more and that is desired here too.  */
+      const size_t nr_of_cpus = ARRAY_SIZE (cpu_types);
+
+      opts_and_args = XNEW (disasm_options_and_args_t);
+      opts_and_args->args
+	= XNEWVEC (disasm_option_arg_t, ARC_OPTION_ARG_SIZE + 1);
+      opts_and_args->options.name
+	= XNEWVEC (const char *, nr_of_options + 1);
+      opts_and_args->options.description
+	= XNEWVEC (const char *, nr_of_options + 1);
+      opts_and_args->options.arg
+	= XNEWVEC (const disasm_option_arg_t *, nr_of_options + 1);
+
+      /* Populate the arguments for "cpu=" option.  */
+      args = opts_and_args->args;
+      args[ARC_OPTION_ARG_ARCH].name = "ARCH";
+      args[ARC_OPTION_ARG_ARCH].values = XNEWVEC (const char *, nr_of_cpus);
+      for (i = 0; i < nr_of_cpus; ++i)
+	args[ARC_OPTION_ARG_ARCH].values[i] = cpu_types[i].name;
+      args[ARC_OPTION_ARG_SIZE].name = NULL;
+      args[ARC_OPTION_ARG_SIZE].values = NULL;
+
+      /* Populate the options.  */
+      opts = &opts_and_args->options;
+      for (i = 0; i < nr_of_options; ++i)
+	{
+	  opts->name[i] = arc_options[i].name;
+	  opts->description[i] = arc_options[i].description;
+	  if (arc_options[i].arg != ARC_OPTION_ARG_NONE)
+	    opts->arg[i] = &args[arc_options[i].arg];
+	  else
+	    opts->arg[i] = NULL;
+	}
+      opts->name[nr_of_options] = NULL;
+      opts->description[nr_of_options] = NULL;
+      opts->arg[nr_of_options] = NULL;
+    }
+
+  return opts_and_args;
+}
+
+
 void
 print_arc_disassembler_options (FILE *stream)
 {
-  int i;
+  const disasm_options_and_args_t *opts_and_args;
+  const disasm_option_arg_t *args;
+  const disasm_options_t *opts;
+  size_t i, j;
+  size_t max_len = 0;
+
+  opts_and_args = disassembler_options_arc ();
+  opts = &opts_and_args->options;
+  args = opts_and_args->args;
 
-  fprintf (stream, _("\n\
-The following ARC specific disassembler options are supported for use \n\
-with -M switch (multiple options should be separated by commas):\n"));
+  fprintf (stream, _("\nThe following ARC specific disassembler options are"
+		     " supported for use \nwith the -M switch (multiple"
+		     " options should be separated by commas):\n"));
+
+  /* Find the maximum length for printing options (and their arg name).  */
+  for (i = 0; opts->name[i] != NULL; ++i)
+    {
+      size_t len = strlen (opts->name[i]);
+      len += (opts->arg[i]) ? strlen (opts->arg[i]->name) : 0;
+      max_len = (len > max_len) ? len : max_len;
+    }
+
+  /* Print the options, their arg and description, if any.  */
+  for (i = 0, ++max_len; opts->name[i] != NULL; ++i)
+    {
+      fprintf (stream, "  %s", opts->name[i]);
+      if (opts->arg[i] != NULL)
+	fprintf (stream, "%s", opts->arg[i]->name);
+      if (opts->description[i] != NULL)
+	{
+	  size_t len = strlen (opts->name[i]);
+	  len += (opts->arg[i]) ? strlen (opts->arg[i]->name) : 0;
+	  fprintf (stream,
+		   "%*c %s", (int) (max_len - len), ' ', opts->description[i]);
+	}
+      fprintf (stream, _("\n"));
+    }
 
-  /* cpu=... options.  */
-  for (i = 0; cpu_types[i].name; ++i)
+  /* Print the possible values of an argument.  */
+  for (i = 0; args[i].name != NULL; ++i)
     {
-      /* As of now all value CPU values are less than 16 characters.  */
-      fprintf (stream, "  cpu=%-16s\tEnforce %s ISA.\n",
-	       cpu_types[i].name, cpu_types[i].isa);
+      size_t len = 3;
+      fprintf (stream, _("\n\
+  For the options above, the following values are supported for \"%s\":\n   "),
+	       args[i].name);
+      for (j = 0; args[i].values[j] != NULL; ++j)
+	{
+	  fprintf (stream, " %s", args[i].values[j]);
+	  len += strlen (args[i].values[j]) + 1;
+	  /* reset line if printed too long.  */
+	  if (len >= 78)
+	    {
+	      fprintf (stream, _("\n   "));
+	      len = 3;
+	    }
+	}
+      fprintf (stream, _("\n"));
     }
 
-  fprintf (stream, _("\
-  dsp             Recognize DSP instructions.\n"));
-  fprintf (stream, _("\
-  spfp            Recognize FPX SP instructions.\n"));
-  fprintf (stream, _("\
-  dpfp            Recognize FPX DP instructions.\n"));
-  fprintf (stream, _("\
-  quarkse_em      Recognize FPU QuarkSE-EM instructions.\n"));
-  fprintf (stream, _("\
-  fpuda           Recognize double assist FPU instructions.\n"));
-  fprintf (stream, _("\
-  fpus            Recognize single precision FPU instructions.\n"));
-  fprintf (stream, _("\
-  fpud            Recognize double precision FPU instructions.\n"));
-  fprintf (stream, _("\
-  nps400          Recognize NPS400 instructions.\n"));
-  fprintf (stream, _("\
-  hex             Use only hexadecimal number to print immediates.\n"));
+  fprintf (stream, _("\n"));
 }
 
 void arc_insn_decode (bfd_vma addr,