* ld-insn.c (load_insn_table): Terminate error with NL.
[platform/upstream/binutils.git] / sim / igen / gen-itable.c
1 /*  This file is part of the program psim.
2
3     Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au>
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14  
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  
19     */
20
21
22
23 #include "misc.h"
24 #include "lf.h"
25 #include "table.h"
26 #include "filter.h"
27 #include "igen.h"
28
29 #include "ld-insn.h"
30 #include "ld-decode.h"
31
32 #include "gen.h"
33
34 #include "gen-itable.h"
35
36 #ifndef NULL
37 #define NULL 0
38 #endif
39
40
41
42 static void
43 itable_h_insn (lf *file,
44                insn_table *entry,
45                insn_entry *instruction,
46                void *data)
47 {
48   lf_print__line_ref (file, instruction->line);
49   lf_printf (file, "  ");
50   print_function_name (file,
51                        instruction->name,
52                        instruction->format_name,
53                        NULL,
54                        NULL,
55                        function_name_prefix_itable);
56   lf_printf (file, ",\n");
57 }
58
59
60 /* print the list of all the different options */
61
62 static void
63 itable_print_enum (lf *file,
64                    filter *set,
65                    char *name)
66 {
67   char *elem;
68   lf_printf (file, "typedef enum {\n");
69   lf_indent (file, +2);
70   for (elem = filter_next (set, "");
71        elem != NULL;
72        elem = filter_next (set, elem))
73     {
74       lf_printf (file, "%sitable_%s_%s,\n",
75                  options.prefix.itable.name, name, elem);
76       if (strlen (options.prefix.itable.name) > 0)
77         {
78           lf_indent_suppress (file);
79           lf_printf (file, "#define itable_%s_%s %sitable_%s_%s\n",
80                      name, elem, options.prefix.itable.name, name, elem);
81         }
82     }
83   lf_printf (file, "nr_%sitable_%ss,", options.prefix.itable.name, name);
84   
85   lf_indent (file, -2);
86   lf_printf (file, "\n} %sitable_%ss;\n", options.prefix.itable.name, name);
87   if (strlen (options.prefix.itable.name) > 0)
88     {
89       lf_indent_suppress (file);
90       lf_printf (file, "#define itable_%ss %sitable_%ss\n",
91                  name, options.prefix.itable.name, name);
92       lf_indent_suppress (file);
93       lf_printf (file, "#define nr_itable_%ss nr_%sitable_%ss\n",
94                  name, options.prefix.itable.name, name);
95     }
96   lf_printf (file, "\n");
97 }
98
99 extern void 
100 gen_itable_h (lf *file,
101               insn_table *isa)
102 {
103
104   /* output an enumerated type for each instruction */
105   lf_printf (file, "typedef enum {\n");
106   insn_table_traverse_insn (file, isa, itable_h_insn, NULL);
107   lf_printf (file, "  nr_%sitable_entries,\n", options.prefix.itable.name);
108   lf_printf (file, "} %sitable_index;\n", options.prefix.itable.name);
109   lf_printf (file, "\n");
110
111   /* output an enumeration type for each flag */
112   itable_print_enum (file, isa->flags, "flag");
113     
114   /* output an enumeration of all the possible options */
115   itable_print_enum (file, isa->options, "option");
116
117   /* output an enumeration of all the processor models */
118   itable_print_enum (file, isa->model->processors, "processor");
119
120   /* output the table that contains the actual instruction info */
121   lf_printf (file, "typedef struct _%sitable_instruction_info {\n",
122              options.prefix.itable.name);
123   lf_printf (file, "  %sitable_index nr;\n", options.prefix.itable.name);
124   lf_printf (file, "  char *format;\n");
125   lf_printf (file, "  char *form;\n");
126   lf_printf (file, "  char *flags;\n");
127   lf_printf (file, "  char flag[nr_%sitable_flags];\n",
128              options.prefix.itable.name);
129   lf_printf (file, "  char *options;\n");
130   lf_printf (file, "  char option[nr_%sitable_options];\n",
131              options.prefix.itable.name);
132   lf_printf (file, "  char *processors;\n");
133   lf_printf (file, "  char processor[nr_%sitable_processors];\n",
134              options.prefix.itable.name);
135   lf_printf (file, "  char *name;\n");
136   lf_printf (file, "  char *file;\n");
137   lf_printf (file, "  int line_nr;\n");
138   lf_printf (file, "} %sitable_info;\n", options.prefix.itable.name);
139   lf_printf (file, "\n");
140   lf_printf (file, "extern %sitable_info %sitable[nr_%sitable_entries];\n",
141              options.prefix.itable.name, options.prefix.itable.name,
142              options.prefix.itable.name);
143   if (strlen (options.prefix.itable.name) > 0)
144     {
145       lf_indent_suppress (file);
146       lf_printf (file, "#define itable %sitable\n",
147                  options.prefix.itable.name);
148     }
149 }
150
151
152 /****************************************************************/
153
154 static void
155 itable_print_set (lf *file,
156                   filter *set,
157                   filter *members)
158 {
159   char *elem;
160   lf_printf (file, "\"");
161   elem = filter_next (members, "");
162   if (elem != NULL)
163     {
164       while (1)
165         {
166           lf_printf (file, "%s", elem);
167           elem = filter_next (members, elem);
168           if (elem == NULL)
169             break;
170           lf_printf (file, ",");
171         }
172     }
173   lf_printf (file, "\",\n");
174
175   lf_printf(file, "{");
176   for (elem = filter_next (set, "");
177        elem != NULL;
178        elem = filter_next (set, elem))
179     {
180       if (filter_is_member (members, elem))
181         {
182           lf_printf (file, " 1,");
183         }
184       else
185         {
186           lf_printf (file, " 0,");
187         }
188       
189     }
190   lf_printf(file, " },\n");
191 }
192
193
194 static void
195 itable_c_insn (lf *file,
196                insn_table *isa,
197                insn_entry *instruction,
198                void *data)
199 {
200   lf_printf (file, "{ ");
201   lf_indent (file, +2);
202   print_function_name (file,
203                        instruction->name,
204                        instruction->format_name,
205                        NULL,
206                        NULL,
207                        function_name_prefix_itable);
208   lf_printf (file, ",\n");
209   lf_printf (file, "\"");
210   print_insn_words (file, instruction);
211   lf_printf (file, "\",\n");
212   lf_printf (file, "\"%s\",\n", instruction->format_name);
213
214   itable_print_set (file, isa->flags, instruction->flags);
215   itable_print_set (file, isa->options, instruction->options);
216   itable_print_set (file, isa->model->processors, instruction->processors);
217
218   lf_printf(file, "\"%s\",\n", instruction->name);
219   lf_printf(file, "\"%s\",\n",
220             filter_filename (instruction->line->file_name));
221   lf_printf(file, "%d,\n", instruction->line->line_nr);
222   lf_printf(file, "},\n");
223   lf_indent (file, -2);
224 }
225
226
227 extern void 
228 gen_itable_c (lf *file,
229               insn_table *isa)
230 {
231   /* leader */
232   lf_printf(file, "#include \"%sitable.h\"\n", options.prefix.itable.name);
233   lf_printf(file, "\n");
234
235   /* FIXME - output model data??? */
236   /* FIXME - output assembler data??? */
237
238   /* output the table that contains the actual instruction info */
239   lf_printf(file, "%sitable_info %sitable[nr_%sitable_entries] = {\n",
240             options.prefix.itable.name,
241             options.prefix.itable.name,
242             options.prefix.itable.name);
243   insn_table_traverse_insn (file, isa, itable_c_insn, NULL);
244
245   lf_printf(file, "};\n");
246 }