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
40static void
41lf_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
61static void
62print_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
82static void
83lf_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
91static void
92print_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
156static void
157print_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
170static void
171print_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
243static void
244print_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
256static void
257print_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
277static void
278print_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
294static void
295print_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
303static void
304print_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
318void print_idecode_switch (lf *file, gen_entry *table, const char *result);
319
320static void
321print_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
375static void
376print_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
498static void
499print_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
507static void
508print_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
567void
568print_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
578static void
579print_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
624static void
625idecode_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
638static void
639idecode_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
666void
667print_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
691void
692print_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
710static void
711print_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
776static void
777print_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
869static void
870print_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
898static void
899print_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
931static void
932print_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
1035void
1036print_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
1229void
1230print_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
1289void
1290print_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