]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/igen/ld-decode.c
This commit was manufactured by cvs2svn to create branch
[thirdparty/binutils-gdb.git] / sim / igen / ld-decode.c
CommitLineData
feaee4bd
AC
1/* The IGEN simulator generator for GDB, the GNU Debugger.
2
9b254dd1 3 Copyright 2002, 2007, 2008 Free Software Foundation, Inc.
feaee4bd
AC
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
4744ac1b 11 the Free Software Foundation; either version 3 of the License, or
feaee4bd
AC
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
4744ac1b 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
feaee4bd 21
c906108c
SS
22
23/* load the opcode stat structure */
24
25#include "misc.h"
26#include "lf.h"
27#include "table.h"
28#include "filter.h"
29
30#include "igen.h"
31
32#include "ld-decode.h"
33
34#ifndef NULL
35#define NULL 0
36#endif
37
38
39static const name_map decode_type_map[] = {
4e0bf4c4
AC
40 {"normal", normal_decode_rule},
41 {"boolean", boolean_rule},
42 {NULL, normal_decode_rule},
c906108c
SS
43};
44
45static const name_map decode_gen_map[] = {
4e0bf4c4
AC
46 {"array", array_gen},
47 {"switch", switch_gen},
48 {"padded-switch", padded_switch_gen},
49 {"goto-switch", goto_switch_gen},
50 {NULL, -1},
c906108c
SS
51};
52
53static const name_map decode_reserved_map[] = {
4e0bf4c4
AC
54 {"zero-reserved", 1},
55 {NULL, 0},
c906108c
SS
56};
57
58static const name_map decode_duplicates_map[] = {
4e0bf4c4
AC
59 {"duplicate", 1},
60 {NULL, 0},
c906108c
SS
61};
62
63static const name_map decode_combine_map[] = {
4e0bf4c4
AC
64 {"combine", 1},
65 {NULL, 0},
c906108c
SS
66};
67
68static const name_map decode_search_map[] = {
4e0bf4c4
AC
69 {"constants", decode_find_constants},
70 {"mixed", decode_find_mixed},
71 {"strings", decode_find_strings},
72 {NULL, decode_find_mixed},
c906108c
SS
73};
74
75
76static void
4e0bf4c4 77set_bits (int bit[max_insn_bit_size], unsigned64 value)
c906108c
SS
78{
79 int bit_nr;
80 for (bit_nr = 0; bit_nr < max_insn_bit_size; bit_nr++)
81 {
82 if (bit_nr < options.insn_bit_size)
83 bit[bit_nr] = (value >> (options.insn_bit_size - bit_nr - 1)) & 1;
84 else
85 bit[bit_nr] = 0;
86 }
87}
88
89decode_table *
4e0bf4c4 90load_decode_table (char *file_name)
c906108c
SS
91{
92 table *file = table_open (file_name);
93 table_entry *entry;
94 decode_table *table = NULL;
95 decode_table **curr_rule = &table;
96 while ((entry = table_read (file)) != NULL)
97 {
98 char *decode_options = entry->field[decode_options_field];
99 decode_table *new_rule = ZALLOC (decode_table);
100 if (entry->nr_fields < min_nr_decode_fields)
101 error (entry->line, "Missing decode table fields\n");
102 new_rule->line = entry->line;
103
104 /* the options field */
105 new_rule->type = name2i (decode_options, decode_type_map);
106 if (options.decode.overriding_gen != NULL)
4e0bf4c4
AC
107 new_rule->gen =
108 name2i (options.decode.overriding_gen, decode_gen_map);
c906108c
SS
109 else
110 new_rule->gen = name2i (decode_options, decode_gen_map);
4e0bf4c4 111 if (new_rule->gen == padded_switch_gen && options.decode.switch_as_goto)
c906108c
SS
112 new_rule->gen = goto_switch_gen;
113 if (options.decode.zero_reserved)
114 new_rule->with_zero_reserved = 1;
115 else
4e0bf4c4
AC
116 new_rule->with_zero_reserved =
117 name2i (decode_options, decode_reserved_map);
c906108c
SS
118 if (options.decode.duplicate)
119 new_rule->with_duplicates = 1;
120 else
4e0bf4c4
AC
121 new_rule->with_duplicates =
122 name2i (decode_options, decode_duplicates_map);
c906108c
SS
123 if (options.decode.combine)
124 new_rule->with_combine = 1;
125 else
126 new_rule->with_combine = name2i (decode_options, decode_combine_map);
127 if (new_rule->type == boolean_rule)
128 {
129 char *chp = decode_options;
130 while (*chp != '\0')
131 {
132 if (isdigit (*chp))
133 {
134 new_rule->constant = a2i (chp);
135 break;
136 }
137 chp = skip_to_separator (chp, ",");
138 chp = skip_spaces (chp);
139 }
140 }
141
142 /* First and last */
143 if (entry->nr_fields > decode_first_field
144 && strlen (entry->field[decode_first_field]) > 0)
145 {
146 new_rule->first = target_a2i (options.hi_bit_nr,
147 entry->field[decode_first_field]);
148 if (new_rule->first < 0 || new_rule->first >= options.insn_bit_size)
149 error (new_rule->line, "First field out of range\n");
150 }
151 else
152 new_rule->first = 0;
153 if (entry->nr_fields > decode_last_field
154 && strlen (entry->field[decode_last_field]) > 0)
155 {
156 new_rule->last = target_a2i (options.hi_bit_nr,
157 entry->field[decode_last_field]);
158 if (new_rule->last < 0 || new_rule->last >= options.insn_bit_size)
159 error (new_rule->line, "Last field out of range\n");
160 }
161 else
162 new_rule->last = options.insn_bit_size - 1;
163 if (new_rule->first > new_rule->last)
164 error (new_rule->line, "First must preceed last\n");
165
166 /* force first/last, with default values based on first/last */
167 if (entry->nr_fields > decode_force_first_field
168 && strlen (entry->field[decode_force_first_field]) > 0)
169 {
170 new_rule->force_first = target_a2i (options.hi_bit_nr,
4e0bf4c4
AC
171 entry->
172 field
173 [decode_force_first_field]);
c906108c
SS
174 if (new_rule->force_first < new_rule->first
175 || new_rule->force_first > new_rule->last + 1)
176 error (new_rule->line, "Force first out of range\n");
177 }
178 else
179 new_rule->force_first = new_rule->last + 1;
180 if (entry->nr_fields > decode_force_last_field
181 && strlen (entry->field[decode_force_last_field]) > 0)
182 {
183 new_rule->force_last = target_a2i (options.hi_bit_nr,
4e0bf4c4
AC
184 entry->
185 field[decode_force_last_field]);
c906108c
SS
186 if (new_rule->force_last > new_rule->last
187 || new_rule->force_last < new_rule->first - 1)
188 error (new_rule->line, "Force-last out of range\n");
189 }
190 else
191 new_rule->force_last = new_rule->first - 1;
192
193 /* fields to be treated as constant */
194 if (entry->nr_fields > decode_constant_field_names_field)
195 filter_parse (&new_rule->constant_field_names,
196 entry->field[decode_constant_field_names_field]);
197
198 /* applicable word nr */
199 if (entry->nr_fields > decode_word_nr_field)
200 new_rule->word_nr = a2i (entry->field[decode_word_nr_field]);
201
202 /* required instruction format names */
203 if (entry->nr_fields > decode_format_names_field)
204 filter_parse (&new_rule->format_names,
205 entry->field[decode_format_names_field]);
206
207 /* required processor models */
208 if (entry->nr_fields > decode_model_names_field)
209 filter_parse (&new_rule->model_names,
210 entry->field[decode_model_names_field]);
211
212 /* required paths */
213 if (entry->nr_fields > decode_paths_field
214 && strlen (entry->field[decode_paths_field]) > 0)
215 {
216 decode_path_list **last = &new_rule->paths;
217 char *chp = entry->field[decode_paths_field];
218 do
219 {
220 (*last) = ZALLOC (decode_path_list);
221 /* extra root/zero entry */
4e0bf4c4 222 (*last)->path = ZALLOC (decode_path);
c906108c
SS
223 do
224 {
225 decode_path *entry = ZALLOC (decode_path);
226 entry->opcode_nr = a2i (chp);
227 entry->parent = (*last)->path;
228 (*last)->path = entry;
229 chp = skip_digits (chp);
230 chp = skip_spaces (chp);
231 }
232 while (*chp == '.');
233 last = &(*last)->next;
234 }
235 while (*chp == ',');
236 if (*chp != '\0')
237 error (entry->line, "Invalid path field\n");
238 }
239
240 /* collect up the list of optional special conditions applicable
241 to the rule */
242 {
243 int field_nr = nr_decode_fields;
244 while (entry->nr_fields > field_nr)
245 {
246 decode_cond *cond = ZALLOC (decode_cond);
247 decode_cond **last;
248 if (entry->nr_fields > field_nr + decode_cond_mask_field)
4e0bf4c4
AC
249 set_bits (cond->mask,
250 a2i (entry->
251 field[field_nr + decode_cond_mask_field]));
c906108c 252 if (entry->nr_fields > field_nr + decode_cond_value_field)
4e0bf4c4
AC
253 {
254 if (entry->field[field_nr + decode_cond_value_field][0] ==
255 '!')
256 {
257 cond->is_equal = 0;
258 set_bits (cond->value,
259 a2i (entry->
260 field[field_nr + decode_cond_value_field] +
261 1));
262 }
263 else
264 {
265 cond->is_equal = 1;
266 set_bits (cond->value,
267 a2i (entry->
268 field[field_nr +
269 decode_cond_value_field]));
270 }
271 }
c906108c 272 if (entry->nr_fields > field_nr + decode_cond_word_nr_field)
4e0bf4c4
AC
273 cond->word_nr =
274 a2i (entry->field[field_nr + decode_cond_word_nr_field]);
c906108c
SS
275 field_nr += nr_decode_cond_fields;
276 /* insert it */
277 last = &new_rule->conditions;
278 while (*last != NULL)
279 last = &(*last)->next;
280 *last = cond;
281 }
282 }
283 *curr_rule = new_rule;
284 curr_rule = &new_rule->next;
285 }
286 return table;
287}
288
4e0bf4c4 289
c906108c
SS
290int
291decode_table_max_word_nr (decode_table *entry)
292{
293 int max_word_nr = 0;
294 while (entry != NULL)
295 {
296 decode_cond *cond;
297 if (entry->word_nr > max_word_nr)
298 max_word_nr = entry->word_nr;
299 for (cond = entry->conditions; cond != NULL; cond = cond->next)
300 {
301 if (cond->word_nr > max_word_nr)
302 max_word_nr = cond->word_nr;
303 }
304 entry = entry->next;
305 }
306 return max_word_nr;
307}
308
309
310
311static void
4e0bf4c4 312dump_decode_cond (lf *file, char *prefix, decode_cond *cond, char *suffix)
c906108c
SS
313{
314 lf_printf (file, "%s(decode_cond *) 0x%lx", prefix, (long) cond);
315 if (cond != NULL)
316 {
317 lf_indent (file, +1);
318 lf_printf (file, "\n(word_nr %d)", cond->word_nr);
319 lf_printf (file, "\n(mask 0x%lx)", (long) cond->mask);
320 lf_printf (file, "\n(value 0x%lx)", (long) cond->value);
321 lf_printf (file, "\n(is_equal 0x%lx)", (long) cond->is_equal);
322 lf_printf (file, "\n(next (decode_cond *) 0%lx)", (long) cond->next);
323 lf_indent (file, -1);
324 }
325 lf_printf (file, "%s", suffix);
326}
327
328
329static void
4e0bf4c4 330dump_decode_conds (lf *file, char *prefix, decode_cond *cond, char *suffix)
c906108c
SS
331{
332 lf_printf (file, "%s(decode_cond *) 0x%lx", prefix, (long) cond);
333 while (cond != NULL)
334 {
335 dump_decode_cond (file, "\n(", cond, ")");
336 cond = cond->next;
337 }
338 lf_printf (file, "%s", suffix);
339}
340
341
342void
4e0bf4c4 343dump_decode_rule (lf *file, char *prefix, decode_table *rule, char *suffix)
c906108c
SS
344{
345 lf_printf (file, "%s(decode_table *) 0x%lx", prefix, (long) rule);
346 if (rule != NULL)
347 {
348 lf_indent (file, +1);
349 dump_line_ref (file, "\n(line ", rule->line, ")");
4e0bf4c4
AC
350 lf_printf (file, "\n(type %s)", i2name (rule->type, decode_type_map));
351 lf_printf (file, "\n(gen %s)", i2name (rule->gen, decode_gen_map));
c906108c
SS
352 lf_printf (file, "\n(first %d)", rule->first);
353 lf_printf (file, "\n(last %d)", rule->last);
354 lf_printf (file, "\n(force_first %d)", rule->force_first);
355 lf_printf (file, "\n(force_last %d)", rule->force_last);
4e0bf4c4
AC
356 dump_filter (file, "\n(constant_field_names \"",
357 rule->constant_field_names, "\")");
c906108c
SS
358 lf_printf (file, "\n(constant 0x%x)", rule->constant);
359 lf_printf (file, "\n(word_nr %d)", rule->word_nr);
360 lf_printf (file, "\n(with_zero_reserved %d)", rule->with_zero_reserved);
361 lf_printf (file, "\n(with_duplicates %d)", rule->with_duplicates);
362 lf_printf (file, "\n(with_combine %d)", rule->with_combine);
363 dump_filter (file, "\n(format_names \"", rule->format_names, "\")");
364 dump_filter (file, "\n(model_names \"", rule->model_names, "\")");
365 dump_decode_conds (file, "\n(conditions ", rule->conditions, ")");
366 lf_printf (file, "\n(next 0x%lx)", (long) rule->next);
367 lf_indent (file, -1);
368 }
369 lf_printf (file, "%s", suffix);
370}
371
372
373#ifdef MAIN
374
375static void
4e0bf4c4 376dump_decode_rules (lf *file, char *prefix, decode_table *rule, char *suffix)
c906108c
SS
377{
378 lf_printf (file, "%s", prefix);
379 while (rule != NULL)
380 {
381 lf_indent (file, +1);
382 dump_decode_rule (file, "\n(", rule, ")");
383 lf_indent (file, -1);
384 rule = rule->next;
385 }
386 lf_printf (file, "%s", suffix);
387}
388
389igen_options options;
390
391int
4e0bf4c4 392main (int argc, char **argv)
c906108c
SS
393{
394 lf *l;
395 decode_table *rules;
396
397 INIT_OPTIONS (options);
398
399 if (argc != 3)
400 error (NULL, "Usage: decode <decode-file> <hi-bit-nr>\n");
401
402 options.hi_bit_nr = a2i (argv[2]);
403 rules = load_decode_table (argv[1]);
404 l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-ld-insn");
405 dump_decode_rules (l, "(rules ", rules, ")\n");
406
407 return 0;
408}
409#endif