xref: /netbsd-src/external/gpl3/gdb.old/dist/sim/ppc/gen-semantics.c (revision bb16d22702ff57c46e117881dd16b08ca16721cc)
1 /*  This file is part of the program psim.
2 
3     Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 3 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, see <http://www.gnu.org/licenses/>.
17 
18     */
19 
20 
21 
22 #include "misc.h"
23 #include "lf.h"
24 #include "table.h"
25 #include "filter.h"
26 
27 #include "ld-decode.h"
28 #include "ld-cache.h"
29 #include "ld-insn.h"
30 
31 #include "igen.h"
32 
33 #include "gen-semantics.h"
34 #include "gen-icache.h"
35 #include "gen-idecode.h"
36 
37 
38 static void
print_semantic_function_header(lf * file,const char * basename,insn_bits * expanded_bits,int is_function_definition)39 print_semantic_function_header(lf *file,
40 			       const char *basename,
41 			       insn_bits *expanded_bits,
42 			       int is_function_definition)
43 {
44   int indent;
45   lf_printf(file, "\n");
46   lf_print_function_type(file, SEMANTIC_FUNCTION_TYPE, "PSIM_EXTERN_SEMANTICS",
47 			 (is_function_definition ? "\n" : " "));
48   indent = print_function_name(file,
49 			       basename,
50 			       expanded_bits,
51 			       function_name_prefix_semantics);
52   if (is_function_definition)
53     lf_indent(file, +indent);
54   else
55     lf_printf(file, "\n");
56   lf_printf(file, "(%s)", SEMANTIC_FUNCTION_FORMAL);
57   if (is_function_definition)
58     lf_indent(file, -indent);
59   else
60     lf_printf(file, ";");
61   lf_printf(file, "\n");
62 }
63 
64 void
print_semantic_declaration(insn_table * entry,lf * file,void * data,insn * instruction,int depth)65 print_semantic_declaration(insn_table *entry,
66 			   lf *file,
67 			   void *data,
68 			   insn *instruction,
69 			   int depth)
70 {
71   if (generate_expanded_instructions) {
72     ASSERT(entry->nr_insn == 1);
73     print_semantic_function_header(file,
74 				   instruction->file_entry->fields[insn_name],
75 				   entry->expanded_bits,
76 				   0/* is not function definition*/);
77   }
78   else {
79     print_semantic_function_header(file,
80 				   instruction->file_entry->fields[insn_name],
81 				   NULL,
82 				   0/* is not function definition*/);
83   }
84 }
85 
86 
87 
88 /* generate the semantics.c file */
89 
90 
91 void
print_idecode_illegal(lf * file,const char * result)92 print_idecode_illegal(lf *file,
93 		      const char *result)
94 {
95   if ((code & generate_jumps))
96     lf_printf(file, "goto %s_illegal;\n", (code & generate_with_icache) ? "icache" : "semantic");
97   else if ((code & generate_with_icache))
98     lf_printf(file, "%s icache_illegal(%s);\n", result, ICACHE_FUNCTION_ACTUAL);
99   else
100     lf_printf(file, "%s semantic_illegal(%s);\n", result, SEMANTIC_FUNCTION_ACTUAL);
101 }
102 
103 
104 void
print_semantic_body(lf * file,insn * instruction,insn_bits * expanded_bits,opcode_field * opcodes)105 print_semantic_body(lf *file,
106 		    insn *instruction,
107 		    insn_bits *expanded_bits,
108 		    opcode_field *opcodes)
109 {
110   print_itrace(file, instruction->file_entry, 0/*put_value_in_cache*/);
111 
112   /* validate the instruction, if a cache this has already been done */
113   if (!(code & generate_with_icache))
114     print_idecode_validate(file, instruction, opcodes);
115 
116   /* generate the profiling call - this is delayed until after the
117      instruction has been verified */
118   lf_printf(file, "\n");
119   lf_printf(file, "/* monitoring: */\n");
120   lf_printf(file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE) {\n");
121   lf_printf(file, "  mon_issue(");
122   print_function_name(file,
123 		      instruction->file_entry->fields[insn_name],
124 		      NULL,
125 		      function_name_prefix_itable);
126   lf_printf(file, ", processor, cia);\n");
127   lf_printf(file, "}\n");
128 
129   /* generate the code (or at least something */
130   lf_printf(file, "\n");
131   lf_printf(file, "/* semantics: */\n");
132   lf_printf(file, "nia = cia + %d;\n", insn_bit_size / 8);
133   if (instruction->file_entry->annex != NULL) {
134     /* true code */
135     table_entry_print_cpp_line_nr(file, instruction->file_entry);
136     lf_printf(file, "{\n");
137     lf_indent(file, +2);
138     lf_print__c_code(file, instruction->file_entry->annex);
139     lf_indent(file, -2);
140     lf_printf(file, "}\n");
141     lf_print__internal_reference(file);
142   }
143   else if (it_is("nop", instruction->file_entry->fields[insn_flags])) {
144     lf_print__internal_reference(file);
145   }
146   else {
147     /* abort so it is implemented now */
148     table_entry_print_cpp_line_nr(file, instruction->file_entry);
149     lf_putstr(file, "error(\"%s:%d:0x%08lx:%s unimplemented\\n\",\n");
150     lf_printf(file, "      itable[MY_INDEX].file, itable[MY_INDEX].line_nr, (long)cia, itable[MY_INDEX].name);\n");
151     lf_print__internal_reference(file);
152   }
153 }
154 
155 static void
print_c_semantic(lf * file,insn * instruction,insn_bits * expanded_bits,opcode_field * opcodes,cache_table * cache_rules)156 print_c_semantic(lf *file,
157 		 insn *instruction,
158 		 insn_bits *expanded_bits,
159 		 opcode_field *opcodes,
160 		 cache_table *cache_rules)
161 {
162 
163   lf_printf(file, "{\n");
164   lf_indent(file, +2);
165 
166   print_my_defines(file, expanded_bits, instruction->file_entry);
167   lf_printf(file, "\n");
168   print_icache_body(file,
169 		    instruction,
170 		    expanded_bits,
171 		    cache_rules,
172 		    ((code & generate_with_direct_access)
173 		     ? define_variables
174 		     : declare_variables),
175 		    ((code & generate_with_icache)
176 		     ? get_values_from_icache
177 		     : do_not_use_icache));
178 
179   lf_printf(file, "unsigned_word nia;\n");
180   print_semantic_body(file,
181 		      instruction,
182 		      expanded_bits,
183 		      opcodes);
184   lf_printf(file, "return nia;\n");
185 
186   /* generate something to clean up any #defines created for the cache */
187   if (code & generate_with_direct_access)
188     print_icache_body(file,
189 		      instruction,
190 		      expanded_bits,
191 		      cache_rules,
192 		      undef_variables,
193 		      ((code & generate_with_icache)
194 		       ? get_values_from_icache
195 		       : do_not_use_icache));
196 
197   lf_indent(file, -2);
198   lf_printf(file, "}\n");
199 }
200 
201 static void
print_c_semantic_function(lf * file,insn * instruction,insn_bits * expanded_bits,opcode_field * opcodes,cache_table * cache_rules)202 print_c_semantic_function(lf *file,
203 			  insn *instruction,
204 			  insn_bits *expanded_bits,
205 			  opcode_field *opcodes,
206 			  cache_table *cache_rules)
207 {
208   /* build the semantic routine to execute the instruction */
209   print_semantic_function_header(file,
210 				 instruction->file_entry->fields[insn_name],
211 				 expanded_bits,
212 				 1/*is-function-definition*/);
213   print_c_semantic(file,
214 		   instruction,
215 		   expanded_bits,
216 		   opcodes,
217 		   cache_rules);
218 }
219 
220 void
print_semantic_definition(insn_table * entry,lf * file,void * data,insn * instruction,int depth)221 print_semantic_definition(insn_table *entry,
222 			  lf *file,
223 			  void *data,
224 			  insn *instruction,
225 			  int depth)
226 {
227   cache_table *cache_rules = (cache_table*)data;
228   if (generate_expanded_instructions) {
229     ASSERT(entry->nr_insn == 1
230 	   && entry->opcode == NULL
231 	   && entry->parent != NULL
232 	   && entry->parent->opcode != NULL);
233     ASSERT(entry->nr_insn == 1
234 	   && entry->opcode == NULL
235 	   && entry->parent != NULL
236 	   && entry->parent->opcode != NULL
237 	   && entry->parent->opcode_rule != NULL);
238     print_c_semantic_function(file,
239 			      entry->insns,
240 			      entry->expanded_bits,
241 			      entry->parent->opcode,
242 			      cache_rules);
243   }
244   else {
245     print_c_semantic_function(file, instruction,
246 			      NULL, NULL,
247 			      cache_rules);
248   }
249 }
250