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