OSDN Git Service

Updated copyright notices for most files.
[pf3gnuchains/pf3gnuchains3x.git] / sim / igen / gen-itable.c
1 /* The IGEN simulator generator for GDB, the GNU Debugger.
2
3    Copyright 2002, 2007, 2008 Free Software Foundation, Inc.
4
5    Contributed by Andrew Cagney.
6
7    This file is part of GDB.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
22
23
24 #include "misc.h"
25 #include "lf.h"
26 #include "table.h"
27 #include "filter.h"
28 #include "igen.h"
29
30 #include "ld-insn.h"
31 #include "ld-decode.h"
32
33 #include "gen.h"
34
35 #include "gen-itable.h"
36
37 #ifndef NULL
38 #define NULL 0
39 #endif
40
41
42
43 typedef struct _itable_info
44 {
45   int sizeof_form;
46   int sizeof_name;
47   int sizeof_file;
48 }
49 itable_info;
50
51
52 static void
53 itable_h_insn (lf *file,
54                insn_table *entry, insn_entry * instruction, void *data)
55 {
56   int len;
57   itable_info *info = data;
58   lf_print__line_ref (file, instruction->line);
59   lf_printf (file, "  ");
60   print_function_name (file,
61                        instruction->name,
62                        instruction->format_name,
63                        NULL, NULL, function_name_prefix_itable);
64   lf_printf (file, ",\n");
65   /* update summary info */
66   len = strlen (instruction->format_name);
67   if (info->sizeof_form <= len)
68     info->sizeof_form = len + 1;
69   len = strlen (instruction->name);
70   if (info->sizeof_name <= len)
71     info->sizeof_name = len + 1;
72   len = strlen (filter_filename (instruction->line->file_name));
73   if (info->sizeof_file <= len)
74     info->sizeof_file = len + 1;
75 }
76
77
78 /* print the list of all the different options */
79
80 static void
81 itable_print_enum (lf *file, filter *set, char *name)
82 {
83   char *elem;
84   lf_printf (file, "typedef enum {\n");
85   lf_indent (file, +2);
86   for (elem = filter_next (set, "");
87        elem != NULL; elem = filter_next (set, elem))
88     {
89       lf_printf (file, "%sitable_%s_%s,\n",
90                  options.module.itable.prefix.l, name, elem);
91       if (strlen (options.module.itable.prefix.l) > 0)
92         {
93           lf_indent_suppress (file);
94           lf_printf (file, "#define itable_%s_%s %sitable_%s_%s\n",
95                      name, elem, options.module.itable.prefix.l, name, elem);
96         }
97     }
98   lf_printf (file, "nr_%sitable_%ss,\n", options.module.itable.prefix.l,
99              name);
100
101   lf_indent (file, -2);
102   lf_printf (file, "} %sitable_%ss;\n", options.module.itable.prefix.l, name);
103   if (strlen (options.module.itable.prefix.l) > 0)
104     {
105       lf_indent_suppress (file);
106       lf_printf (file, "#define itable_%ss %sitable_%ss\n",
107                  name, options.module.itable.prefix.l, name);
108       lf_indent_suppress (file);
109       lf_printf (file, "#define nr_itable_%ss nr_%sitable_%ss\n",
110                  name, options.module.itable.prefix.l, name);
111     }
112 }
113
114 /* print an array of the option names as strings */
115
116 static void
117 itable_print_names (lf *file, filter *set, char *name)
118 {
119   char *elem;
120   lf_printf (file, "const char *%sitable_%s_names[nr_%sitable_%ss + 1] = {\n",
121              options.module.itable.prefix.l, name,
122              options.module.itable.prefix.l, name);
123   lf_indent (file, +2);
124   for (elem = filter_next (set, "");
125        elem != NULL; elem = filter_next (set, elem))
126     {
127       lf_printf (file, "\"%s\",\n", elem);
128     }
129   lf_printf (file, "0,\n");
130   lf_indent (file, -2);
131   lf_printf (file, "};\n");
132 }
133
134 extern void
135 gen_itable_h (lf *file, insn_table *isa)
136 {
137   itable_info *info = ZALLOC (itable_info);
138
139   /* output an enumerated type for each instruction */
140   lf_printf (file, "typedef enum {\n");
141   insn_table_traverse_insn (file, isa, itable_h_insn, info);
142   lf_printf (file, "  nr_%sitable_entries,\n",
143              options.module.itable.prefix.l);
144   lf_printf (file, "} %sitable_index;\n", options.module.itable.prefix.l);
145   lf_printf (file, "\n");
146
147   /* output an enumeration type for each flag */
148   itable_print_enum (file, isa->flags, "flag");
149   lf_printf (file, "extern const char *%sitable_flag_names[];\n",
150              options.module.itable.prefix.l);
151   lf_printf (file, "\n");
152
153   /* output an enumeration of all the possible options */
154   itable_print_enum (file, isa->options, "option");
155   lf_printf (file, "extern const char *%sitable_option_names[];\n",
156              options.module.itable.prefix.l);
157   lf_printf (file, "\n");
158
159   /* output an enumeration of all the processor models */
160   itable_print_enum (file, isa->model->processors, "processor");
161   lf_printf (file, "extern const char *%sitable_processor_names[];\n",
162              options.module.itable.prefix.l);
163   lf_printf (file, "\n");
164
165   /* output the table that contains the actual instruction info */
166   lf_printf (file, "typedef struct _%sitable_instruction_info {\n",
167              options.module.itable.prefix.l);
168   lf_printf (file, "  %sitable_index nr;\n", options.module.itable.prefix.l);
169   lf_printf (file, "  char *format;\n");
170   lf_printf (file, "  char *form;\n");
171   lf_printf (file, "  char *flags;\n");
172
173   /* nr_itable_* may be zero, so we add 1 to avoid an
174      illegal zero-sized array. */
175   lf_printf (file, "  char flag[nr_%sitable_flags + 1];\n",
176              options.module.itable.prefix.l);
177   lf_printf (file, "  char *options;\n");
178   lf_printf (file, "  char option[nr_%sitable_options + 1];\n",
179              options.module.itable.prefix.l);
180   lf_printf (file, "  char *processors;\n");
181   lf_printf (file, "  char processor[nr_%sitable_processors + 1];\n",
182              options.module.itable.prefix.l);
183   lf_printf (file, "  char *name;\n");
184   lf_printf (file, "  char *file;\n");
185   lf_printf (file, "  int line_nr;\n");
186   lf_printf (file, "} %sitable_info;\n", options.module.itable.prefix.l);
187   lf_printf (file, "\n");
188   lf_printf (file, "extern %sitable_info %sitable[nr_%sitable_entries];\n",
189              options.module.itable.prefix.l, options.module.itable.prefix.l,
190              options.module.itable.prefix.l);
191   if (strlen (options.module.itable.prefix.l) > 0)
192     {
193       lf_indent_suppress (file);
194       lf_printf (file, "#define itable %sitable\n",
195                  options.module.itable.prefix.l);
196     }
197   lf_printf (file, "\n");
198
199   /* output an enum defining the max size of various itable members */
200   lf_printf (file, "enum {\n");
201   lf_printf (file, "  sizeof_%sitable_form = %d,\n",
202              options.module.itable.prefix.l, info->sizeof_form);
203   lf_printf (file, "  sizeof_%sitable_name = %d,\n",
204              options.module.itable.prefix.l, info->sizeof_name);
205   lf_printf (file, "  sizeof_%sitable_file = %d,\n",
206              options.module.itable.prefix.l, info->sizeof_file);
207   lf_printf (file, "};\n");
208 }
209
210
211 /****************************************************************/
212
213 static void
214 itable_print_set (lf *file, filter *set, filter *members)
215 {
216   char *elem;
217   lf_printf (file, "\"");
218   elem = filter_next (members, "");
219   if (elem != NULL)
220     {
221       while (1)
222         {
223           lf_printf (file, "%s", elem);
224           elem = filter_next (members, elem);
225           if (elem == NULL)
226             break;
227           lf_printf (file, ",");
228         }
229     }
230   lf_printf (file, "\",\n");
231
232   lf_printf (file, "{");
233   for (elem = filter_next (set, "");
234        elem != NULL; elem = filter_next (set, elem))
235     {
236       if (filter_is_member (members, elem))
237         {
238           lf_printf (file, " 1,");
239         }
240       else
241         {
242           lf_printf (file, " 0,");
243         }
244
245     }
246   /* always print a dummy element, to avoid empty initializers. */
247   lf_printf (file, " 99 },\n");
248 }
249
250
251 static void
252 itable_c_insn (lf *file,
253                insn_table *isa, insn_entry * instruction, void *data)
254 {
255   lf_printf (file, "{ ");
256   lf_indent (file, +2);
257   print_function_name (file,
258                        instruction->name,
259                        instruction->format_name,
260                        NULL, NULL, function_name_prefix_itable);
261   lf_printf (file, ",\n");
262   lf_printf (file, "\"");
263   print_insn_words (file, instruction);
264   lf_printf (file, "\",\n");
265   lf_printf (file, "\"%s\",\n", instruction->format_name);
266
267   itable_print_set (file, isa->flags, instruction->flags);
268   itable_print_set (file, isa->options, instruction->options);
269   itable_print_set (file, isa->model->processors, instruction->processors);
270
271   lf_printf (file, "\"%s\",\n", instruction->name);
272   lf_printf (file, "\"%s\",\n",
273              filter_filename (instruction->line->file_name));
274   lf_printf (file, "%d,\n", instruction->line->line_nr);
275   lf_printf (file, "},\n");
276   lf_indent (file, -2);
277 }
278
279
280 extern void
281 gen_itable_c (lf *file, insn_table *isa)
282 {
283   /* leader */
284   lf_printf (file, "#include \"%sitable.h\"\n",
285              options.module.itable.prefix.l);
286   lf_printf (file, "\n");
287
288   /* FIXME - output model data??? */
289   /* FIXME - output assembler data??? */
290
291   /* output the flag, option and processor name tables */
292   itable_print_names (file, isa->flags, "flag");
293   itable_print_names (file, isa->options, "option");
294   itable_print_names (file, isa->model->processors, "processor");
295
296   /* output the table that contains the actual instruction info */
297   lf_printf (file, "%sitable_info %sitable[nr_%sitable_entries] = {\n",
298              options.module.itable.prefix.l,
299              options.module.itable.prefix.l, options.module.itable.prefix.l);
300   insn_table_traverse_insn (file, isa, itable_c_insn, NULL);
301
302   lf_printf (file, "};\n");
303 }