1 /* The IGEN simulator generator for GDB, the GNU Debugger.
2 
3    Copyright 2002, 2007, 2008, 2009, 2010, 2011 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 #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-idecode.h"
35 #include "gen-icache.h"
36 #include "gen-semantics.h"
37 
38 
39 
40 static void
lf_print_opcodes(lf * file,gen_entry * table)41 lf_print_opcodes (lf *file, gen_entry *table)
42 {
43   if (table !=NULL)
44     {
45       while (1)
46 	{
47 	  ASSERT (table->opcode != NULL);
48 	  lf_printf (file, "_%d_%d",
49 		     table->opcode->first, table->opcode->last);
50 	  if (table->parent == NULL)
51 	    break;
52 	  lf_printf (file, "__%d", table->opcode_nr);
53 	  table = table->parent;
54 	}
55     }
56 }
57 
58 
59 
60 
61 static void
print_idecode_ifetch(lf * file,int previous_nr_prefetched_words,int current_nr_prefetched_words)62 print_idecode_ifetch (lf *file,
63 		      int previous_nr_prefetched_words,
64 		      int current_nr_prefetched_words)
65 {
66   int word_nr;
67   for (word_nr = previous_nr_prefetched_words;
68        word_nr < current_nr_prefetched_words; word_nr++)
69     {
70       lf_printf (file,
71 		 "instruction_word instruction_%d = IMEM%d_IMMED (cia, %d);\n",
72 		 word_nr, options.insn_bit_size, word_nr);
73 
74     }
75 }
76 
77 
78 
79 /****************************************************************/
80 
81 
82 static void
lf_print_table_name(lf * file,gen_entry * table)83 lf_print_table_name (lf *file, gen_entry *table)
84 {
85   lf_printf (file, "idecode_table");
86   lf_print_opcodes (file, table);
87 }
88 
89 
90 
91 static void
print_idecode_table(lf * file,gen_entry * entry,const char * result)92 print_idecode_table (lf *file, gen_entry *entry, const char *result)
93 {
94   lf_printf (file, "/* prime the search */\n");
95   lf_printf (file, "idecode_table_entry *table = ");
96   lf_print_table_name (file, entry);
97   lf_printf (file, ";\n");
98   lf_printf (file, "int opcode = EXTRACTED%d (instruction, %d, %d);\n",
99 	     options.insn_bit_size,
100 	     i2target (options.hi_bit_nr, entry->opcode->first),
101 	     i2target (options.hi_bit_nr, entry->opcode->last));
102   lf_printf (file, "idecode_table_entry *table_entry = table + opcode;\n");
103 
104   lf_printf (file, "\n");
105   lf_printf (file, "/* iterate until a leaf */\n");
106   lf_printf (file, "while (1) {\n");
107   lf_printf (file, "  signed shift = table_entry->shift;\n");
108   lf_printf (file, "if (shift == function_entry) break;\n");
109   lf_printf (file, "  if (shift >= 0) {\n");
110   lf_printf (file, "    table = ((idecode_table_entry*)\n");
111   lf_printf (file, "             table_entry->function_or_table);\n");
112   lf_printf (file, "    opcode = ((instruction & table_entry->mask)\n");
113   lf_printf (file, "              >> shift);\n");
114   lf_printf (file, "    table_entry = table + opcode;\n");
115   lf_printf (file, "  }\n");
116   lf_printf (file, "  else {\n");
117   lf_printf (file, "    /* must be a boolean */\n");
118   lf_printf (file, "    ASSERT(table_entry->shift == boolean_entry);\n");
119   lf_printf (file, "    opcode = ((instruction & table_entry->mask)\n");
120   lf_printf (file, "              != table_entry->value);\n");
121   lf_printf (file, "    table = ((idecode_table_entry*)\n");
122   lf_printf (file, "             table_entry->function_or_table);\n");
123   lf_printf (file, "    table_entry = table + opcode;\n");
124   lf_printf (file, "  }\n");
125   lf_printf (file, "}\n");
126 
127   lf_printf (file, "\n");
128   lf_printf (file, "/* call the leaf code */\n");
129   if (options.gen.code == generate_jumps)
130     {
131       lf_printf (file, "goto *table_entry->function_or_table;\n");
132     }
133   else
134     {
135       lf_printf (file, "%s ", result);
136       if (options.gen.icache)
137 	{
138 	  lf_printf (file,
139 		     "(((idecode_icache*)table_entry->function_or_table)\n");
140 	  lf_printf (file, "  (");
141 	  print_icache_function_actual (file, 1);
142 	  lf_printf (file, "));\n");
143 	}
144       else
145 	{
146 	  lf_printf (file,
147 		     "((idecode_semantic*)table_entry->function_or_table)\n");
148 	  lf_printf (file, "  (");
149 	  print_semantic_function_actual (file, 1);
150 	  lf_printf (file, ");\n");
151 	}
152     }
153 }
154 
155 
156 static void
print_idecode_table_start(lf * file,gen_entry * table,int depth,void * data)157 print_idecode_table_start (lf *file, gen_entry *table, int depth, void *data)
158 {
159   ASSERT (depth == 0);
160   /* start of the table */
161   if (table->opcode_rule->gen == array_gen)
162     {
163       lf_printf (file, "\n");
164       lf_printf (file, "static idecode_table_entry ");
165       lf_print_table_name (file, table);
166       lf_printf (file, "[] = {\n");
167     }
168 }
169 
170 static void
print_idecode_table_leaf(lf * file,gen_entry * entry,int depth,void * data)171 print_idecode_table_leaf (lf *file, gen_entry *entry, int depth, void *data)
172 {
173   gen_entry *master_entry;
174   ASSERT (entry->parent != NULL);
175   ASSERT (depth == 0);
176   if (entry->combined_parent == NULL)
177     master_entry = entry;
178   else
179     master_entry = entry->combined_parent;
180 
181   /* add an entry to the table */
182   if (entry->parent->opcode_rule->gen == array_gen)
183     {
184       lf_printf (file, "  /*%d*/ { ", entry->opcode_nr);
185       if (entry->opcode == NULL)
186 	{
187 	  ASSERT (entry->nr_insns == 1);
188 	  /* table leaf entry */
189 	  lf_printf (file, "function_entry, 0, 0, ");
190 	  if (options.gen.code == generate_jumps)
191 	    {
192 	      lf_printf (file, "&&");
193 	    }
194 	  print_function_name (file,
195 			       entry->insns->insn->name,
196 			       entry->insns->insn->format_name,
197 			       NULL,
198 			       master_entry->expanded_bits,
199 			       (options.gen.icache
200 				? function_name_prefix_icache
201 				: function_name_prefix_semantics));
202 	}
203       else if (entry->opcode_rule->gen == switch_gen
204 	       || entry->opcode_rule->gen == goto_switch_gen
205 	       || entry->opcode_rule->gen == padded_switch_gen)
206 	{
207 	  /* table calling switch statement */
208 	  lf_printf (file, "function_entry, 0, 0, ");
209 	  if (options.gen.code == generate_jumps)
210 	    {
211 	      lf_printf (file, "&&");
212 	    }
213 	  lf_print_table_name (file, entry);
214 	}
215       else if (entry->opcode->is_boolean)
216 	{
217 	  /* table `calling' boolean table */
218 	  lf_printf (file, "boolean_entry, ");
219 	  lf_printf (file, "MASK32(%d, %d), ",
220 		     i2target (options.hi_bit_nr, entry->opcode->first),
221 		     i2target (options.hi_bit_nr, entry->opcode->last));
222 	  lf_printf (file, "INSERTED32(%d, %d, %d), ",
223 		     entry->opcode->boolean_constant,
224 		     i2target (options.hi_bit_nr, entry->opcode->first),
225 		     i2target (options.hi_bit_nr, entry->opcode->last));
226 	  lf_print_table_name (file, entry);
227 	}
228       else
229 	{
230 	  /* table `calling' another table */
231 	  lf_printf (file, "%d, ",
232 		     options.insn_bit_size - entry->opcode->last - 1);
233 	  lf_printf (file, "MASK%d(%d,%d), ", options.insn_bit_size,
234 		     i2target (options.hi_bit_nr, entry->opcode->first),
235 		     i2target (options.hi_bit_nr, entry->opcode->last));
236 	  lf_printf (file, "0, ");
237 	  lf_print_table_name (file, entry);
238 	}
239       lf_printf (file, " },\n");
240     }
241 }
242 
243 static void
print_idecode_table_end(lf * file,gen_entry * table,int depth,void * data)244 print_idecode_table_end (lf *file, gen_entry *table, int depth, void *data)
245 {
246   ASSERT (depth == 0);
247   if (table->opcode_rule->gen == array_gen)
248     {
249       lf_printf (file, "};\n");
250     }
251 }
252 
253 /****************************************************************/
254 
255 
256 static void
print_goto_switch_name(lf * file,gen_entry * entry)257 print_goto_switch_name (lf *file, gen_entry *entry)
258 {
259   lf_printf (file, "case_");
260   if (entry->opcode == NULL)
261     {
262       print_function_name (file,
263 			   entry->insns->insn->name,
264 			   entry->insns->insn->format_name,
265 			   NULL,
266 			   entry->expanded_bits,
267 			   (options.gen.icache
268 			    ? function_name_prefix_icache
269 			    : function_name_prefix_semantics));
270     }
271   else
272     {
273       lf_print_table_name (file, entry);
274     }
275 }
276 
277 static void
print_goto_switch_table_leaf(lf * file,gen_entry * entry,int depth,void * data)278 print_goto_switch_table_leaf (lf *file,
279 			      gen_entry *entry, int depth, void *data)
280 {
281   ASSERT (entry->parent != NULL);
282   ASSERT (depth == 0);
283   ASSERT (entry->parent->opcode_rule->gen == goto_switch_gen);
284   ASSERT (entry->parent->opcode);
285 
286   lf_printf (file, "/* %d */ &&", entry->opcode_nr);
287   if (entry->combined_parent != NULL)
288     print_goto_switch_name (file, entry->combined_parent);
289   else
290     print_goto_switch_name (file, entry);
291   lf_printf (file, ",\n");
292 }
293 
294 static void
print_goto_switch_break(lf * file,gen_entry * entry)295 print_goto_switch_break (lf *file, gen_entry *entry)
296 {
297   lf_printf (file, "goto break_");
298   lf_print_table_name (file, entry->parent);
299   lf_printf (file, ";\n");
300 }
301 
302 
303 static void
print_goto_switch_table(lf * file,gen_entry * table)304 print_goto_switch_table (lf *file, gen_entry *table)
305 {
306   lf_printf (file, "const static void *");
307   lf_print_table_name (file, table);
308   lf_printf (file, "[] = {\n");
309   lf_indent (file, +2);
310   gen_entry_traverse_tree (file, table, 0, NULL /*start */ ,
311 			   print_goto_switch_table_leaf, NULL /*end */ ,
312 			   NULL /*data */ );
313   lf_indent (file, -2);
314   lf_printf (file, "};\n");
315 }
316 
317 
318 void print_idecode_switch (lf *file, gen_entry *table, const char *result);
319 
320 static void
print_idecode_switch_start(lf * file,gen_entry * table,int depth,void * data)321 print_idecode_switch_start (lf *file, gen_entry *table, int depth, void *data)
322 {
323   /* const char *result = data; */
324   ASSERT (depth == 0);
325   ASSERT (table->opcode_rule->gen == switch_gen
326 	  || table->opcode_rule->gen == goto_switch_gen
327 	  || table->opcode_rule->gen == padded_switch_gen);
328 
329   if (table->opcode->is_boolean
330       || table->opcode_rule->gen == switch_gen
331       || table->opcode_rule->gen == padded_switch_gen)
332     {
333       lf_printf (file, "switch (EXTRACTED%d (instruction_%d, %d, %d))\n",
334 		 options.insn_bit_size,
335 		 table->opcode_rule->word_nr,
336 		 i2target (options.hi_bit_nr, table->opcode->first),
337 		 i2target (options.hi_bit_nr, table->opcode->last));
338       lf_indent (file, +2);
339       lf_printf (file, "{\n");
340     }
341   else if (table->opcode_rule->gen == goto_switch_gen)
342     {
343       if (table->parent != NULL
344 	  && (table->parent->opcode_rule->gen == switch_gen
345 	      || table->parent->opcode_rule->gen == goto_switch_gen
346 	      || table->parent->opcode_rule->gen == padded_switch_gen))
347 	{
348 	  lf_printf (file, "{\n");
349 	  lf_indent (file, +2);
350 	}
351       print_goto_switch_table (file, table);
352       lf_printf (file, "ASSERT (EXTRACTED%d (instruction_%d, %d, %d)\n",
353 		 options.insn_bit_size,
354 		 table->opcode->word_nr,
355 		 i2target (options.hi_bit_nr, table->opcode->first),
356 		 i2target (options.hi_bit_nr, table->opcode->last));
357       lf_printf (file, "        < (sizeof (");
358       lf_print_table_name (file, table);
359       lf_printf (file, ") / sizeof(void*)));\n");
360       lf_printf (file, "goto *");
361       lf_print_table_name (file, table);
362       lf_printf (file, "[EXTRACTED%d (instruction_%d, %d, %d)];\n",
363 		 options.insn_bit_size,
364 		 table->opcode->word_nr,
365 		 i2target (options.hi_bit_nr, table->opcode->first),
366 		 i2target (options.hi_bit_nr, table->opcode->last));
367     }
368   else
369     {
370       ASSERT ("bad switch" == NULL);
371     }
372 }
373 
374 
375 static void
print_idecode_switch_leaf(lf * file,gen_entry * entry,int depth,void * data)376 print_idecode_switch_leaf (lf *file, gen_entry *entry, int depth, void *data)
377 {
378   const char *result = data;
379   ASSERT (entry->parent != NULL);
380   ASSERT (depth == 0);
381   ASSERT (entry->parent->opcode_rule->gen == switch_gen
382 	  || entry->parent->opcode_rule->gen == goto_switch_gen
383 	  || entry->parent->opcode_rule->gen == padded_switch_gen);
384   ASSERT (entry->parent->opcode);
385 
386   /* skip over any instructions combined into another entry */
387   if (entry->combined_parent != NULL)
388     return;
389 
390   if (entry->parent->opcode->is_boolean && entry->opcode_nr == 0)
391     {
392       /* case: boolean false target */
393       lf_printf (file, "case %d:\n", entry->parent->opcode->boolean_constant);
394     }
395   else if (entry->parent->opcode->is_boolean && entry->opcode_nr != 0)
396     {
397       /* case: boolean true case */
398       lf_printf (file, "default:\n");
399     }
400   else if (entry->parent->opcode_rule->gen == switch_gen
401 	   || entry->parent->opcode_rule->gen == padded_switch_gen)
402     {
403       /* case: <opcode-nr> - switch */
404       gen_entry *cob;
405       for (cob = entry; cob != NULL; cob = cob->combined_next)
406 	lf_printf (file, "case %d:\n", cob->opcode_nr);
407     }
408   else if (entry->parent->opcode_rule->gen == goto_switch_gen)
409     {
410       /* case: <opcode-nr> - goto-switch */
411       print_goto_switch_name (file, entry);
412       lf_printf (file, ":\n");
413     }
414   else
415     {
416       ERROR ("bad switch");
417     }
418   lf_printf (file, "  {\n");
419   lf_indent (file, +4);
420   {
421     if (entry->opcode == NULL)
422       {
423 	/* switch calling leaf */
424 	ASSERT (entry->nr_insns == 1);
425 	print_idecode_ifetch (file, entry->nr_prefetched_words,
426 			      entry->insns->semantic->nr_prefetched_words);
427 	switch (options.gen.code)
428 	  {
429 	  case generate_jumps:
430 	    lf_printf (file, "goto ");
431 	    break;
432 	  case generate_calls:
433 	    lf_printf (file, "%s", result);
434 	    break;
435 	  }
436 	print_function_name (file,
437 			     entry->insns->insn->name,
438 			     entry->insns->insn->format_name,
439 			     NULL,
440 			     entry->expanded_bits,
441 			     (options.gen.icache
442 			      ? function_name_prefix_icache
443 			      : function_name_prefix_semantics));
444 	if (options.gen.code == generate_calls)
445 	  {
446 	    lf_printf (file, " (");
447 	    print_semantic_function_actual (file,
448 					    entry->insns->semantic->
449 					    nr_prefetched_words);
450 	    lf_printf (file, ")");
451 	  }
452 	lf_printf (file, ";\n");
453       }
454     else if (entry->opcode_rule->gen == switch_gen
455 	     || entry->opcode_rule->gen == goto_switch_gen
456 	     || entry->opcode_rule->gen == padded_switch_gen)
457       {
458 	/* switch calling switch */
459 	lf_printf (file, "{\n");
460 	lf_indent (file, +2);
461 	print_idecode_ifetch (file, entry->parent->nr_prefetched_words,
462 			      entry->nr_prefetched_words);
463 	print_idecode_switch (file, entry, result);
464 	lf_indent (file, -2);
465 	lf_printf (file, "}\n");
466       }
467     else
468       {
469 	/* switch looking up a table */
470 	lf_printf (file, "{\n");
471 	lf_indent (file, +2);
472 	print_idecode_ifetch (file, entry->parent->nr_prefetched_words,
473 			      entry->nr_prefetched_words);
474 	print_idecode_table (file, entry, result);
475 	lf_indent (file, -2);
476 	lf_printf (file, "}\n");
477       }
478     if (entry->parent->opcode->is_boolean
479 	|| entry->parent->opcode_rule->gen == switch_gen
480 	|| entry->parent->opcode_rule->gen == padded_switch_gen)
481       {
482 	lf_printf (file, "break;\n");
483       }
484     else if (entry->parent->opcode_rule->gen == goto_switch_gen)
485       {
486 	print_goto_switch_break (file, entry);
487       }
488     else
489       {
490 	ERROR ("bad switch");
491       }
492   }
493   lf_indent (file, -4);
494   lf_printf (file, "  }\n");
495 }
496 
497 
498 static void
print_idecode_switch_illegal(lf * file,const char * result)499 print_idecode_switch_illegal (lf *file, const char *result)
500 {
501   lf_indent (file, +2);
502   print_idecode_invalid (file, result, invalid_illegal);
503   lf_printf (file, "break;\n");
504   lf_indent (file, -2);
505 }
506 
507 static void
print_idecode_switch_end(lf * file,gen_entry * table,int depth,void * data)508 print_idecode_switch_end (lf *file, gen_entry *table, int depth, void *data)
509 {
510   const char *result = data;
511   ASSERT (depth == 0);
512   ASSERT (table->opcode_rule->gen == switch_gen
513 	  || table->opcode_rule->gen == goto_switch_gen
514 	  || table->opcode_rule->gen == padded_switch_gen);
515   ASSERT (table->opcode);
516 
517   if (table->opcode->is_boolean)
518     {
519       lf_printf (file, "}\n");
520       lf_indent (file, -2);
521     }
522   else if (table->opcode_rule->gen == switch_gen
523 	   || table->opcode_rule->gen == padded_switch_gen)
524     {
525       lf_printf (file, "default:\n");
526       lf_indent (file, +2);
527       if (table->nr_entries == table->opcode->nr_opcodes)
528 	{
529 	  print_sim_engine_abort (file,
530 				  "Internal error - bad switch generated");
531 	  lf_printf (file, "%sNULL_CIA;\n", result);
532 	  lf_printf (file, "break;\n");
533 	}
534       else
535 	{
536 	  print_idecode_switch_illegal (file, result);
537 	}
538       lf_indent (file, -2);
539       lf_printf (file, "}\n");
540       lf_indent (file, -2);
541     }
542   else if (table->opcode_rule->gen == goto_switch_gen)
543     {
544       lf_printf (file, "illegal_");
545       lf_print_table_name (file, table);
546       lf_printf (file, ":\n");
547       print_idecode_invalid (file, result, invalid_illegal);
548       lf_printf (file, "break_");
549       lf_print_table_name (file, table);
550       lf_printf (file, ":;\n");
551       if (table->parent != NULL
552 	  && (table->parent->opcode_rule->gen == switch_gen
553 	      || table->parent->opcode_rule->gen == goto_switch_gen
554 	      || table->parent->opcode_rule->gen == padded_switch_gen))
555 	{
556 	  lf_indent (file, -2);
557 	  lf_printf (file, "}\n");
558 	}
559     }
560   else
561     {
562       ERROR ("bad switch");
563     }
564 }
565 
566 
567 void
print_idecode_switch(lf * file,gen_entry * table,const char * result)568 print_idecode_switch (lf *file, gen_entry *table, const char *result)
569 {
570   gen_entry_traverse_tree (file, table,
571 			   0,
572 			   print_idecode_switch_start,
573 			   print_idecode_switch_leaf,
574 			   print_idecode_switch_end, (void *) result);
575 }
576 
577 
578 static void
print_idecode_switch_function_header(lf * file,gen_entry * table,int is_function_definition,int nr_prefetched_words)579 print_idecode_switch_function_header (lf *file,
580 				      gen_entry *table,
581 				      int is_function_definition,
582 				      int nr_prefetched_words)
583 {
584   lf_printf (file, "\n");
585   if (options.gen.code == generate_calls)
586     {
587       lf_printf (file, "static ");
588       if (options.gen.icache)
589 	{
590 	  lf_printf (file, "idecode_semantic *");
591 	}
592       else
593 	{
594 	  lf_printf (file, "unsigned_word");
595 	}
596       if (is_function_definition)
597 	{
598 	  lf_printf (file, "\n");
599 	}
600       else
601 	{
602 	  lf_printf (file, " ");
603 	}
604       lf_print_table_name (file, table);
605       lf_printf (file, "\n(");
606       print_icache_function_formal (file, nr_prefetched_words);
607       lf_printf (file, ")");
608       if (!is_function_definition)
609 	{
610 	  lf_printf (file, ";");
611 	}
612       lf_printf (file, "\n");
613     }
614   if (options.gen.code == generate_jumps && is_function_definition)
615     {
616       lf_indent (file, -1);
617       lf_print_table_name (file, table);
618       lf_printf (file, ":\n");
619       lf_indent (file, +1);
620     }
621 }
622 
623 
624 static void
idecode_declare_if_switch(lf * file,gen_entry * table,int depth,void * data)625 idecode_declare_if_switch (lf *file, gen_entry *table, int depth, void *data)
626 {
627   if ((table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) &&table->parent != NULL	/* don't declare the top one yet */
628       && table->parent->opcode_rule->gen == array_gen)
629     {
630       print_idecode_switch_function_header (file,
631 					    table,
632 					    0 /*isnt function definition */ ,
633 					    0);
634     }
635 }
636 
637 
638 static void
idecode_expand_if_switch(lf * file,gen_entry * table,int depth,void * data)639 idecode_expand_if_switch (lf *file, gen_entry *table, int depth, void *data)
640 {
641   if ((table->opcode_rule->gen == switch_gen || table->opcode_rule->gen == goto_switch_gen || table->opcode_rule->gen == padded_switch_gen) &&table->parent != NULL	/* don't expand the top one yet */
642       && table->parent->opcode_rule->gen == array_gen)
643     {
644       print_idecode_switch_function_header (file,
645 					    table,
646 					    1 /*is function definition */ ,
647 					    0);
648       if (options.gen.code == generate_calls)
649 	{
650 	  lf_printf (file, "{\n");
651 	  lf_indent (file, +2);
652 	}
653       print_idecode_switch (file, table, "return");
654       if (options.gen.code == generate_calls)
655 	{
656 	  lf_indent (file, -2);
657 	  lf_printf (file, "}\n");
658 	}
659     }
660 }
661 
662 
663 /****************************************************************/
664 
665 
666 void
print_idecode_lookups(lf * file,gen_entry * table,cache_entry * cache_rules)667 print_idecode_lookups (lf *file, gen_entry *table, cache_entry *cache_rules)
668 {
669   int depth;
670 
671   /* output switch function declarations where needed by tables */
672   gen_entry_traverse_tree (file, table, 1, idecode_declare_if_switch,	/* START */
673 			   NULL, NULL, NULL);
674 
675   /* output tables where needed */
676   for (depth = gen_entry_depth (table); depth > 0; depth--)
677     {
678       gen_entry_traverse_tree (file, table,
679 			       1 - depth,
680 			       print_idecode_table_start,
681 			       print_idecode_table_leaf,
682 			       print_idecode_table_end, NULL);
683     }
684 
685   /* output switch functions where needed */
686   gen_entry_traverse_tree (file, table, 1, idecode_expand_if_switch,	/* START */
687 			   NULL, NULL, NULL);
688 }
689 
690 
691 void
print_idecode_body(lf * file,gen_entry * table,const char * result)692 print_idecode_body (lf *file, gen_entry *table, const char *result)
693 {
694   if (table->opcode_rule->gen == switch_gen
695       || table->opcode_rule->gen == goto_switch_gen
696       || table->opcode_rule->gen == padded_switch_gen)
697     {
698       print_idecode_switch (file, table, result);
699     }
700   else
701     {
702       print_idecode_table (file, table, result);
703     }
704 }
705 
706 
707 /****************************************************************/
708 
709 #if 0
710 static void
711 print_jump (lf *file, int is_tail)
712 {
713   if (is_tail)
714     {
715       lf_putstr (file, "if (keep_running != NULL && !*keep_running)\n");
716       lf_putstr (file, "  cpu_halt(cpu, nia, was_continuing, 0/*na*/);\n");
717     }
718 
719   if (!options.generate_smp)
720     {
721       lf_putstr (file, "if (WITH_EVENTS) {\n");
722       lf_putstr (file, "  if (event_queue_tick(events)) {\n");
723       lf_putstr (file, "    cpu_set_program_counter(cpu, nia);\n");
724       lf_putstr (file, "    event_queue_process(events);\n");
725       lf_putstr (file, "    nia = cpu_get_program_counter(cpu);\n");
726       lf_putstr (file, "  }\n");
727       lf_putstr (file, "}\n");
728     }
729 
730   if (options.generate_smp)
731     {
732       if (is_tail)
733 	{
734 	  lf_putstr (file, "cpu_set_program_counter(cpu, nia);\n");
735 	}
736       lf_putstr (file, "if (WITH_EVENTS) {\n");
737       lf_putstr (file, "  current_cpu += 1;\n");
738       lf_putstr (file, "  if (current_cpu >= nr_cpus) {\n");
739       lf_putstr (file, "    if (event_queue_tick(events)) {\n");
740       lf_putstr (file, "      event_queue_process(events);\n");
741       lf_putstr (file, "    }\n");
742       lf_putstr (file, "    current_cpu = 0;\n");
743       lf_putstr (file, "  }\n");
744       lf_putstr (file, "}\n");
745       lf_putstr (file, "else {\n");
746       lf_putstr (file, "  current_cpu = (current_cpu + 1) % nr_cpus;\n");
747       lf_putstr (file, "}\n");
748       lf_putstr (file, "cpu = cpus[current_cpu];\n");
749       lf_putstr (file, "nia = cpu_get_program_counter(cpu);\n");
750     }
751 
752   if (options.gen.icache)
753     {
754       lf_putstr (file, "cache_entry = cpu_icache_entry(cpu, nia);\n");
755       lf_putstr (file, "if (cache_entry->address == nia) {\n");
756       lf_putstr (file, "  /* cache hit */\n");
757       lf_putstr (file, "  goto *cache_entry->semantic;\n");
758       lf_putstr (file, "}\n");
759       if (is_tail)
760 	{
761 	  lf_putstr (file, "goto cache_miss;\n");
762 	}
763     }
764 
765   if (!options.gen.icache && is_tail)
766     {
767       lf_printf (file, "goto idecode;\n");
768     }
769 
770 }
771 #endif
772 
773 
774 
775 #if 0
776 static void
777 print_jump_insn (lf *file,
778 		 insn_entry * instruction,
779 		 insn_bits * expanded_bits,
780 		 opcode_field *opcodes, cache_entry *cache_rules)
781 {
782 
783   /* what we are for the moment */
784   lf_printf (file, "\n");
785   print_my_defines (file, expanded_bits, instruction->name);
786 
787   /* output the icache entry */
788   if (options.gen.icache)
789     {
790       lf_printf (file, "\n");
791       lf_indent (file, -1);
792       print_function_name (file,
793 			   instruction->name,
794 			   expanded_bits, function_name_prefix_icache);
795       lf_printf (file, ":\n");
796       lf_indent (file, +1);
797       lf_printf (file, "{\n");
798       lf_indent (file, +2);
799       lf_putstr (file, "const unsigned_word cia = nia;\n");
800       print_itrace (file, instruction, 1 /*putting-value-in-cache */ );
801       print_idecode_validate (file, instruction, opcodes);
802       lf_printf (file, "\n");
803       lf_printf (file, "{\n");
804       lf_indent (file, +2);
805       print_icache_body (file, instruction, expanded_bits, cache_rules, 0,	/*use_defines */
806 			 put_values_in_icache);
807       lf_printf (file, "cache_entry->address = nia;\n");
808       lf_printf (file, "cache_entry->semantic = &&");
809       print_function_name (file,
810 			   instruction->name,
811 			   expanded_bits, function_name_prefix_semantics);
812       lf_printf (file, ";\n");
813       if (options.gen.semantic_icache)
814 	{
815 	  print_semantic_body (file, instruction, expanded_bits, opcodes);
816 	  print_jump (file, 1 /*is-tail */ );
817 	}
818       else
819 	{
820 	  lf_printf (file, "/* goto ");
821 	  print_function_name (file,
822 			       instruction->name,
823 			       expanded_bits, function_name_prefix_semantics);
824 	  lf_printf (file, "; */\n");
825 	}
826       lf_indent (file, -2);
827       lf_putstr (file, "}\n");
828       lf_indent (file, -2);
829       lf_printf (file, "}\n");
830     }
831 
832   /* print the semantics */
833   lf_printf (file, "\n");
834   lf_indent (file, -1);
835   print_function_name (file,
836 		       instruction->name,
837 		       expanded_bits, function_name_prefix_semantics);
838   lf_printf (file, ":\n");
839   lf_indent (file, +1);
840   lf_printf (file, "{\n");
841   lf_indent (file, +2);
842   lf_putstr (file, "const unsigned_word cia = nia;\n");
843   print_icache_body (file,
844 		     instruction,
845 		     expanded_bits,
846 		     cache_rules,
847 		     (options.gen.direct_access
848 		      ? define_variables
849 		      : declare_variables),
850 		     (options.gen.icache
851 		      ? get_values_from_icache : do_not_use_icache));
852   print_semantic_body (file, instruction, expanded_bits, opcodes);
853   if (options.gen.direct_access)
854     print_icache_body (file,
855 		       instruction,
856 		       expanded_bits,
857 		       cache_rules,
858 		       undef_variables,
859 		       (options.gen.icache
860 			? get_values_from_icache : do_not_use_icache));
861   print_jump (file, 1 /*is tail */ );
862   lf_indent (file, -2);
863   lf_printf (file, "}\n");
864 }
865 #endif
866 
867 
868 #if 0
869 static void
870 print_jump_definition (lf *file,
871 		       gen_entry *entry,
872 		       insn_entry * insn, int depth, void *data)
873 {
874   cache_entry *cache_rules = (cache_entry *) data;
875   if (options.generate_expanded_instructions)
876     {
877       ASSERT (entry->nr_insns == 1
878 	      && entry->opcode == NULL
879 	      && entry->parent != NULL && entry->parent->opcode != NULL);
880       ASSERT (entry->nr_insns == 1
881 	      && entry->opcode == NULL
882 	      && entry->parent != NULL
883 	      && entry->parent->opcode != NULL
884 	      && entry->parent->opcode_rule != NULL);
885       print_jump_insn (file,
886 		       entry->insns->words[0]->insn,
887 		       entry->expanded_bits, entry->opcode, cache_rules);
888     }
889   else
890     {
891       print_jump_insn (file,
892 		       instruction->words[0]->insn, NULL, NULL, cache_rules);
893     }
894 }
895 #endif
896 
897 #if 0
898 static void
899 print_jump_internal_function (lf *file,
900 			      gen_entry *table,
901 			      function_entry * function, void *data)
902 {
903   if (function->is_internal)
904     {
905       lf_printf (file, "\n");
906       lf_print__line_ref (file, function->line);
907       lf_indent (file, -1);
908       print_function_name (file,
909 			   function->name,
910 			   NULL,
911 			   (options.gen.icache
912 			    ? function_name_prefix_icache
913 			    : function_name_prefix_semantics));
914       lf_printf (file, ":\n");
915       lf_indent (file, +1);
916       lf_printf (file, "{\n");
917       lf_indent (file, +2);
918       lf_printf (file, "const unsigned_word cia = nia;\n");
919       table_print_code (file, function->code);
920       lf_print__internal_ref (file);
921       print_sim_engine_abort (file, "Internal function must longjump");
922       lf_indent (file, -2);
923       lf_printf (file, "}\n");
924     }
925 }
926 #endif
927 
928 
929 
930 #if 0
931 static void
932 print_jump_until_stop_body (lf *file,
933 			    insn_table *table, cache_table * cache_rules)
934 {
935   lf_printf (file, "{\n");
936   lf_indent (file, +2);
937   lf_putstr (file, "jmp_buf halt;\n");
938   lf_putstr (file, "jmp_buf restart;\n");
939   lf_putstr (file, "sim_cpu *cpu = NULL;\n");
940   lf_putstr (file, "unsigned_word nia = -1;\n");
941   lf_putstr (file, "instruction_word instruction = 0;\n");
942   if ((code & generate_with_icache))
943     {
944       lf_putstr (file, "idecode_cache *cache_entry = NULL;\n");
945     }
946   if (generate_smp)
947     {
948       lf_putstr (file, "int current_cpu = -1;\n");
949     }
950 
951   /* all the switches and tables - they know about jumping */
952   print_idecode_lookups (file, table, cache_rules);
953 
954   /* start the simulation up */
955   if ((code & generate_with_icache))
956     {
957       lf_putstr (file, "\n");
958       lf_putstr (file, "{\n");
959       lf_putstr (file, "  int cpu_nr;\n");
960       lf_putstr (file, "  for (cpu_nr = 0; cpu_nr < nr_cpus; cpu_nr++)\n");
961       lf_putstr (file, "    cpu_flush_icache(cpus[cpu_nr]);\n");
962       lf_putstr (file, "}\n");
963     }
964 
965   lf_putstr (file, "\n");
966   lf_putstr (file, "psim_set_halt_and_restart(system, &halt, &restart);\n");
967 
968   lf_putstr (file, "\n");
969   lf_putstr (file, "if (setjmp(halt))\n");
970   lf_putstr (file, "  return;\n");
971 
972   lf_putstr (file, "\n");
973   lf_putstr (file, "setjmp(restart);\n");
974 
975   lf_putstr (file, "\n");
976   if (!generate_smp)
977     {
978       lf_putstr (file, "cpu = cpus[0];\n");
979       lf_putstr (file, "nia = cpu_get_program_counter(cpu);\n");
980     }
981   else
982     {
983       lf_putstr (file, "current_cpu = psim_last_cpu(system);\n");
984     }
985 
986   if (!(code & generate_with_icache))
987     {
988       lf_printf (file, "\n");
989       lf_indent (file, -1);
990       lf_printf (file, "idecode:\n");
991       lf_indent (file, +1);
992     }
993 
994   print_jump (file, 0 /*is_tail */ );
995 
996   if ((code & generate_with_icache))
997     {
998       lf_indent (file, -1);
999       lf_printf (file, "cache_miss:\n");
1000       lf_indent (file, +1);
1001     }
1002 
1003   lf_putstr (file, "instruction\n");
1004   lf_putstr (file, "  = vm_instruction_map_read(cpu_instruction_map(cpu),\n");
1005   lf_putstr (file, "                            cpu, nia);\n");
1006   print_idecode_body (file, table, "/*IGORE*/");
1007 
1008   /* print out a table of all the internals functions */
1009   insn_table_traverse_function (table,
1010 				file, NULL, print_jump_internal_function);
1011 
1012   /* print out a table of all the instructions */
1013   if (generate_expanded_instructions)
1014     insn_table_traverse_tree (table, file, cache_rules, 1, NULL,	/* start */
1015 			      print_jump_definition,	/* leaf */
1016 			      NULL,	/* end */
1017 			      NULL);	/* padding */
1018   else
1019     insn_table_traverse_insn (table,
1020 			      file, cache_rules, print_jump_definition);
1021   lf_indent (file, -2);
1022   lf_printf (file, "}\n");
1023 }
1024 #endif
1025 
1026 /****************************************************************/
1027 
1028 
1029 
1030 /* Output code to do any final checks on the decoded instruction.
1031    This includes things like verifying any on decoded fields have the
1032    correct value and checking that (for floating point) floating point
1033    hardware isn't disabled */
1034 
1035 void
print_idecode_validate(lf * file,insn_entry * instruction,insn_opcodes * opcode_paths)1036 print_idecode_validate (lf *file,
1037 			insn_entry * instruction, insn_opcodes *opcode_paths)
1038 {
1039   /* Validate: unchecked instruction fields
1040 
1041      If any constant fields in the instruction were not checked by the
1042      idecode tables, output code to check that they have the correct
1043      value here */
1044   {
1045     int nr_checks = 0;
1046     int word_nr;
1047     lf_printf (file, "\n");
1048     lf_indent_suppress (file);
1049     lf_printf (file, "#if defined (WITH_RESERVED_BITS)\n");
1050     lf_printf (file, "/* validate: ");
1051     print_insn_words (file, instruction);
1052     lf_printf (file, " */\n");
1053     for (word_nr = 0; word_nr < instruction->nr_words; word_nr++)
1054       {
1055 	insn_uint check_mask = 0;
1056 	insn_uint check_val = 0;
1057 	insn_word_entry *word = instruction->word[word_nr];
1058 	int bit_nr;
1059 
1060 	/* form check_mask/check_val containing what needs to be checked
1061 	   in the instruction */
1062 	for (bit_nr = 0; bit_nr < options.insn_bit_size; bit_nr++)
1063 	  {
1064 	    insn_bit_entry *bit = word->bit[bit_nr];
1065 	    insn_field_entry *field = bit->field;
1066 
1067 	    /* Make space for the next bit */
1068 	    check_mask <<= 1;
1069 	    check_val <<= 1;
1070 
1071 	    /* Only need to validate constant (and reserved)
1072 	       bits. Skip any others */
1073 	    if (field->type != insn_field_int
1074 		&& field->type != insn_field_reserved)
1075 	      continue;
1076 
1077 	    /* Look through the list of opcode paths that lead to this
1078 	       instruction.  See if any have failed to check the
1079 	       relevant bit */
1080 	    if (opcode_paths != NULL)
1081 	      {
1082 		insn_opcodes *entry;
1083 		for (entry = opcode_paths; entry != NULL; entry = entry->next)
1084 		  {
1085 		    opcode_field *opcode;
1086 		    for (opcode = entry->opcode;
1087 			 opcode != NULL; opcode = opcode->parent)
1088 		      {
1089 			if (opcode->word_nr == word_nr
1090 			    && opcode->first <= bit_nr
1091 			    && opcode->last >= bit_nr)
1092 			  /* we've decoded on this bit */
1093 			  break;
1094 		      }
1095 		    if (opcode == NULL)
1096 		      /* the bit wasn't decoded on */
1097 		      break;
1098 		  }
1099 		if (entry == NULL)
1100 		  /* all the opcode paths decoded on BIT_NR, no need
1101 		     to check it */
1102 		  continue;
1103 	      }
1104 
1105 	    check_mask |= 1;
1106 	    check_val |= bit->value;
1107 	  }
1108 
1109 	/* if any bits not checked by opcode tables, output code to check them */
1110 	if (check_mask)
1111 	  {
1112 	    if (nr_checks == 0)
1113 	      {
1114 		lf_printf (file, "if (WITH_RESERVED_BITS)\n");
1115 		lf_printf (file, "  {\n");
1116 		lf_indent (file, +4);
1117 	      }
1118 	    nr_checks++;
1119 	    if (options.insn_bit_size > 32)
1120 	      {
1121 		lf_printf (file, "if ((instruction_%d\n", word_nr);
1122 		lf_printf (file, "     & UNSIGNED64 (0x%08lx%08lx))\n",
1123 			   (unsigned long) (check_mask >> 32),
1124 			   (unsigned long) (check_mask));
1125 		lf_printf (file, "    != UNSIGNED64 (0x%08lx%08lx))\n",
1126 			   (unsigned long) (check_val >> 32),
1127 			   (unsigned long) (check_val));
1128 	      }
1129 	    else
1130 	      {
1131 		lf_printf (file,
1132 			   "if ((instruction_%d & 0x%08lx) != 0x%08lx)\n",
1133 			   word_nr, (unsigned long) (check_mask),
1134 			   (unsigned long) (check_val));
1135 	      }
1136 	    lf_indent (file, +2);
1137 	    print_idecode_invalid (file, "return", invalid_illegal);
1138 	    lf_indent (file, -2);
1139 	  }
1140       }
1141     if (nr_checks > 0)
1142       {
1143 	lf_indent (file, -4);
1144 	lf_printf (file, "  }\n");
1145       }
1146     lf_indent_suppress (file);
1147     lf_printf (file, "#endif\n");
1148   }
1149 
1150   /* Validate: Floating Point hardware
1151 
1152      If the simulator is being built with out floating point hardware
1153      (different to it being disabled in the MSR) then floating point
1154      instructions are invalid */
1155   {
1156     if (filter_is_member (instruction->flags, "f"))
1157       {
1158 	lf_printf (file, "\n");
1159 	lf_indent_suppress (file);
1160 	lf_printf (file, "#if defined(CURRENT_FLOATING_POINT)\n");
1161 	lf_printf (file, "/* Validate: FP hardware exists */\n");
1162 	lf_printf (file,
1163 		   "if (CURRENT_FLOATING_POINT != HARD_FLOATING_POINT) {\n");
1164 	lf_indent (file, +2);
1165 	print_idecode_invalid (file, "return", invalid_illegal);
1166 	lf_indent (file, -2);
1167 	lf_printf (file, "}\n");
1168 	lf_indent_suppress (file);
1169 	lf_printf (file, "#endif\n");
1170       }
1171   }
1172 
1173   /* Validate: Floating Point available
1174 
1175      If floating point is not available, we enter a floating point
1176      unavailable interrupt into the cache instead of the instruction
1177      proper.
1178 
1179      The PowerPC spec requires a CSI after MSR[FP] is changed and when
1180      ever a CSI occures we flush the instruction cache. */
1181 
1182   {
1183     if (filter_is_member (instruction->flags, "f"))
1184       {
1185 	lf_printf (file, "\n");
1186 	lf_indent_suppress (file);
1187 	lf_printf (file, "#if defined(IS_FP_AVAILABLE)\n");
1188 	lf_printf (file, "/* Validate: FP available according to cpu */\n");
1189 	lf_printf (file, "if (!IS_FP_AVAILABLE) {\n");
1190 	lf_indent (file, +2);
1191 	print_idecode_invalid (file, "return", invalid_fp_unavailable);
1192 	lf_indent (file, -2);
1193 	lf_printf (file, "}\n");
1194 	lf_indent_suppress (file);
1195 	lf_printf (file, "#endif\n");
1196       }
1197   }
1198 
1199   /* Validate: Validate Instruction in correct slot
1200 
1201      Some architectures place restrictions on the slot that an
1202      instruction can be issued in */
1203 
1204   {
1205     if (filter_is_member (instruction->options, "s")
1206 	|| options.gen.slot_verification)
1207       {
1208 	lf_printf (file, "\n");
1209 	lf_indent_suppress (file);
1210 	lf_printf (file, "#if defined(IS_WRONG_SLOT)\n");
1211 	lf_printf (file,
1212 		   "/* Validate: Instruction issued in correct slot */\n");
1213 	lf_printf (file, "if (IS_WRONG_SLOT) {\n");
1214 	lf_indent (file, +2);
1215 	print_idecode_invalid (file, "return", invalid_wrong_slot);
1216 	lf_indent (file, -2);
1217 	lf_printf (file, "}\n");
1218 	lf_indent_suppress (file);
1219 	lf_printf (file, "#endif\n");
1220       }
1221   }
1222 
1223 }
1224 
1225 
1226 /****************************************************************/
1227 
1228 
1229 void
print_idecode_issue_function_header(lf * file,const char * processor,function_decl_type decl_type,int nr_prefetched_words)1230 print_idecode_issue_function_header (lf *file,
1231 				     const char *processor,
1232 				     function_decl_type decl_type,
1233 				     int nr_prefetched_words)
1234 {
1235   int indent;
1236   lf_printf (file, "\n");
1237   switch (decl_type)
1238     {
1239     case is_function_declaration:
1240       lf_print__function_type_function (file, print_semantic_function_type,
1241 					"INLINE_IDECODE", " ");
1242       break;
1243     case is_function_definition:
1244       lf_print__function_type_function (file, print_semantic_function_type,
1245 					"INLINE_IDECODE", "\n");
1246       break;
1247     case is_function_variable:
1248       print_semantic_function_type (file);
1249       lf_printf (file, " (*");
1250       break;
1251     }
1252   indent = print_function_name (file,
1253 				"issue",
1254 				NULL,
1255 				processor,
1256 				NULL, function_name_prefix_idecode);
1257   switch (decl_type)
1258     {
1259     case is_function_definition:
1260       indent += lf_printf (file, " (");
1261       break;
1262     case is_function_declaration:
1263       lf_putstr (file, "\n(");
1264       indent = 1;
1265       break;
1266     case is_function_variable:
1267       lf_putstr (file, ")\n(");
1268       indent = 1;
1269       break;
1270     }
1271   lf_indent (file, +indent);
1272   print_semantic_function_formal (file, nr_prefetched_words);
1273   lf_putstr (file, ")");
1274   lf_indent (file, -indent);
1275   switch (decl_type)
1276     {
1277     case is_function_definition:
1278       lf_printf (file, "\n");
1279       break;
1280     case is_function_declaration:
1281     case is_function_variable:
1282       lf_putstr (file, ";\n");
1283       break;
1284     }
1285 }
1286 
1287 
1288 
1289 void
print_idecode_globals(lf * file)1290 print_idecode_globals (lf *file)
1291 {
1292   lf_printf (file, "enum {\n");
1293   lf_printf (file, "  /* greater or equal to zero => table */\n");
1294   lf_printf (file, "  function_entry = -1,\n");
1295   lf_printf (file, "  boolean_entry = -2,\n");
1296   lf_printf (file, "};\n");
1297   lf_printf (file, "\n");
1298   lf_printf (file, "typedef struct _idecode_table_entry {\n");
1299   lf_printf (file, "  int shift;\n");
1300   lf_printf (file, "  unsigned%d mask;\n", options.insn_bit_size);
1301   lf_printf (file, "  unsigned%d value;\n", options.insn_bit_size);
1302   lf_printf (file, "  void *function_or_table;\n");
1303   lf_printf (file, "} idecode_table_entry;\n");
1304 }
1305