]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/igen/gen-semantics.c
Initial creation of sourceware repository
[thirdparty/binutils-gdb.git] / sim / igen / gen-semantics.c
1 /* This file is part of the program psim.
2
3 Copyright (C) 1994-1998, 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 2 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, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
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-semantics.h"
35 #include "gen-icache.h"
36 #include "gen-idecode.h"
37
38
39 static void
40 print_semantic_function_header (lf *file,
41 const char *basename,
42 const char *format_name,
43 opcode_bits *expanded_bits,
44 int is_function_definition,
45 int nr_prefetched_words)
46 {
47 int indent;
48 lf_printf(file, "\n");
49 lf_print__function_type_function (file, print_semantic_function_type,
50 "EXTERN_SEMANTICS",
51 (is_function_definition ? "\n" : " "));
52 indent = print_function_name (file,
53 basename,
54 format_name,
55 NULL,
56 expanded_bits,
57 function_name_prefix_semantics);
58 if (is_function_definition)
59 {
60 indent += lf_printf (file, " ");
61 lf_indent (file, +indent);
62 }
63 else
64 {
65 lf_printf (file, "\n");
66 }
67 lf_printf (file, "(");
68 lf_indent (file, +1);
69 print_semantic_function_formal (file, nr_prefetched_words);
70 lf_indent (file, -1);
71 lf_printf (file, ")");
72 if (is_function_definition)
73 {
74 lf_indent (file, -indent);
75 }
76 else
77 {
78 lf_printf (file, ";");
79 }
80 lf_printf (file, "\n");
81 }
82
83 void
84 print_semantic_declaration (lf *file,
85 insn_entry *insn,
86 opcode_bits *expanded_bits,
87 insn_opcodes *opcodes,
88 int nr_prefetched_words)
89 {
90 print_semantic_function_header (file,
91 insn->name,
92 insn->format_name,
93 expanded_bits,
94 0/* is not function definition*/,
95 nr_prefetched_words);
96 }
97
98
99 \f
100 /* generate the semantics.c file */
101
102
103 void
104 print_idecode_invalid (lf *file,
105 const char *result,
106 invalid_type type)
107 {
108 const char *name;
109 switch (type)
110 {
111 default: name = "unknown"; break;
112 case invalid_illegal: name = "illegal"; break;
113 case invalid_fp_unavailable: name = "fp_unavailable"; break;
114 case invalid_wrong_slot: name = "wrong_slot"; break;
115 }
116 if (options.gen.code == generate_jumps)
117 {
118 lf_printf (file, "goto %s_%s;\n",
119 (options.gen.icache ? "icache" : "semantic"),
120 name);
121 }
122 else if (options.gen.icache)
123 {
124 lf_printf (file, "%s %sicache_%s (", result, options.module.global.prefix.l, name);
125 print_icache_function_actual (file, 0);
126 lf_printf (file, ");\n");
127 }
128 else
129 {
130 lf_printf (file, "%s %ssemantic_%s (", result, options.module.global.prefix.l, name);
131 print_semantic_function_actual (file, 0);
132 lf_printf (file, ");\n");
133 }
134 }
135
136
137 void
138 print_semantic_body (lf *file,
139 insn_entry *instruction,
140 opcode_bits *expanded_bits,
141 insn_opcodes *opcodes)
142 {
143 /* validate the instruction, if a cache this has already been done */
144 if (!options.gen.icache)
145 {
146 print_idecode_validate (file, instruction, opcodes);
147 }
148
149 print_itrace (file, instruction, 0/*put_value_in_cache*/);
150
151 /* generate the instruction profile call - this is delayed until
152 after the instruction has been verified. The count macro
153 generated is prefixed by ITABLE_PREFIX */
154 {
155 lf_printf (file, "\n");
156 lf_indent_suppress (file);
157 lf_printf (file, "#if defined (%sPROFILE_COUNT_INSN)\n",
158 options.module.itable.prefix.u);
159 lf_printf (file, "%sPROFILE_COUNT_INSN (CPU, CIA, MY_INDEX);\n",
160 options.module.itable.prefix.u);
161 lf_indent_suppress (file);
162 lf_printf (file, "#endif\n");
163 }
164
165 /* generate the model call - this is delayed until after the
166 instruction has been verified */
167 {
168 lf_printf (file, "\n");
169 lf_indent_suppress (file);
170 lf_printf (file, "#if defined (WITH_MON)\n");
171 lf_printf (file, "/* monitoring: */\n");
172 lf_printf (file, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n");
173 lf_printf (file, " mon_issue (");
174 print_function_name (file,
175 instruction->name,
176 instruction->format_name,
177 NULL,
178 NULL,
179 function_name_prefix_itable);
180 lf_printf (file, ", cpu, cia);\n");
181 lf_indent_suppress (file);
182 lf_printf (file, "#endif\n");
183 lf_printf (file, "\n");
184 }
185
186 /* determine the new instruction address */
187 {
188 lf_printf(file, "/* keep the next instruction address handy */\n");
189 if (options.gen.nia == nia_is_invalid)
190 {
191 lf_printf(file, "nia = %sINVALID_INSTRUCTION_ADDRESS;\n",
192 options.module.global.prefix.u);
193 }
194 else
195 {
196 int nr_immeds = instruction->nr_words - 1;
197 if (options.gen.delayed_branch)
198 {
199 if (nr_immeds > 0)
200 {
201 lf_printf (file, "cia.dp += %d * %d; %s\n",
202 options.insn_bit_size / 8, nr_immeds,
203 "/* skip dp immeds */");
204 }
205 lf_printf (file, "nia.ip = cia.dp; %s\n",
206 "/* instruction pointer */");
207 lf_printf (file, "nia.dp = cia.dp + %d; %s\n",
208 options.insn_bit_size / 8,
209 "/* delayed-slot pointer */");
210 }
211 else
212 {
213 if (nr_immeds > 0)
214 {
215 lf_printf (file, "nia = cia + %d * (%d + 1); %s\n",
216 options.insn_bit_size / 8, nr_immeds,
217 "/* skip immeds as well */");
218
219 }
220 else
221 {
222 lf_printf (file, "nia = cia + %d;\n",
223 options.insn_bit_size / 8);
224 }
225 }
226 }
227 }
228
229 /* if conditional, generate code to verify that the instruction
230 should be issued */
231 if (filter_is_member (instruction->options, "c")
232 || options.gen.conditional_issue)
233 {
234 lf_printf (file, "\n");
235 lf_printf (file, "/* execute only if conditional passes */\n");
236 lf_printf (file, "if (IS_CONDITION_OK)\n");
237 lf_printf (file, " {\n");
238 lf_indent (file, +4);
239 /* FIXME - need to log a conditional failure */
240 }
241
242 /* Architecture expects a REG to be zero. Instead of having to
243 check every read to see if it is refering to that REG just zap it
244 at the start of every instruction */
245 if (options.gen.zero_reg)
246 {
247 lf_printf (file, "\n");
248 lf_printf (file, "/* Architecture expects REG to be zero */\n");
249 lf_printf (file, "GPR_SET(%d, 0);\n", options.gen.zero_reg_nr);
250 }
251
252 /* generate the code (or at least something */
253 lf_printf (file, "\n");
254 lf_printf (file, "/* semantics: */\n");
255 if (instruction->code != NULL)
256 {
257 /* true code */
258 lf_printf (file, "{\n");
259 lf_indent (file, +2);
260 lf_print__line_ref (file, instruction->code->line);
261 table_print_code (file, instruction->code);
262 lf_indent (file, -2);
263 lf_printf (file, "}\n");
264 lf_print__internal_ref (file);
265 }
266 else if (filter_is_member (instruction->options, "nop"))
267 {
268 lf_print__internal_ref (file);
269 }
270 else
271 {
272 const char *prefix = "sim_engine_abort (";
273 int indent = strlen (prefix);
274 /* abort so it is implemented now */
275 lf_print__line_ref (file, instruction->line);
276 lf_printf (file, "%sSD, CPU, cia, \\\n", prefix);
277 lf_indent (file, +indent);
278 lf_printf (file, "\"%s:%d:0x%%08lx:%%s unimplemented\\n\", \\\n",
279 filter_filename (instruction->line->file_name),
280 instruction->line->line_nr);
281 lf_printf (file, "(long) CIA, \\\n");
282 lf_printf (file, "%sitable[MY_INDEX].name);\n",
283 options.module.itable.prefix.l);
284 lf_indent (file, -indent);
285 lf_print__internal_ref (file);
286 }
287
288 /* Close off the conditional execution */
289 if (filter_is_member (instruction->options, "c")
290 || options.gen.conditional_issue)
291 {
292 lf_indent (file, -4);
293 lf_printf (file, " }\n");
294 }
295 }
296
297 static void
298 print_c_semantic (lf *file,
299 insn_entry *instruction,
300 opcode_bits *expanded_bits,
301 insn_opcodes *opcodes,
302 cache_entry *cache_rules,
303 int nr_prefetched_words)
304 {
305
306 lf_printf (file, "{\n");
307 lf_indent (file, +2);
308
309 print_my_defines (file,
310 instruction->name,
311 instruction->format_name,
312 expanded_bits);
313 lf_printf (file, "\n");
314 print_icache_body (file,
315 instruction,
316 expanded_bits,
317 cache_rules,
318 (options.gen.direct_access
319 ? define_variables
320 : declare_variables),
321 (options.gen.icache
322 ? get_values_from_icache
323 : do_not_use_icache),
324 nr_prefetched_words);
325
326 lf_printf (file, "%sinstruction_address nia;\n", options.module.global.prefix.l);
327 print_semantic_body (file,
328 instruction,
329 expanded_bits,
330 opcodes);
331 lf_printf (file, "return nia;\n");
332
333 /* generate something to clean up any #defines created for the cache */
334 if (options.gen.direct_access)
335 {
336 print_icache_body (file,
337 instruction,
338 expanded_bits,
339 cache_rules,
340 undef_variables,
341 (options.gen.icache
342 ? get_values_from_icache
343 : do_not_use_icache),
344 nr_prefetched_words);
345 }
346
347 lf_indent (file, -2);
348 lf_printf (file, "}\n");
349 }
350
351 static void
352 print_c_semantic_function (lf *file,
353 insn_entry *instruction,
354 opcode_bits *expanded_bits,
355 insn_opcodes *opcodes,
356 cache_entry *cache_rules,
357 int nr_prefetched_words)
358 {
359 /* build the semantic routine to execute the instruction */
360 print_semantic_function_header (file,
361 instruction->name,
362 instruction->format_name,
363 expanded_bits,
364 1/*is-function-definition*/,
365 nr_prefetched_words);
366 print_c_semantic (file,
367 instruction,
368 expanded_bits,
369 opcodes,
370 cache_rules,
371 nr_prefetched_words);
372 }
373
374 void
375 print_semantic_definition (lf *file,
376 insn_entry *insn,
377 opcode_bits *expanded_bits,
378 insn_opcodes *opcodes,
379 cache_entry *cache_rules,
380 int nr_prefetched_words)
381 {
382 print_c_semantic_function (file,
383 insn,
384 expanded_bits,
385 opcodes,
386 cache_rules,
387 nr_prefetched_words);
388 }
389
390