1 /* This file is part of the program psim.
3 Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
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.
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.
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.
30 #include "ld-decode.h"
34 #include "gen-semantics.h"
35 #include "gen-icache.h"
36 #include "gen-idecode.h"
40 print_semantic_function_header (lf
*file
,
42 const char *format_name
,
43 opcode_bits
*expanded_bits
,
44 int is_function_definition
,
45 int nr_prefetched_words
)
48 lf_printf(file
, "\n");
49 lf_print__function_type_function (file
, print_semantic_function_type
,
51 (is_function_definition
? "\n" : " "));
52 indent
= print_function_name (file
,
57 function_name_prefix_semantics
);
58 if (is_function_definition
)
60 indent
+= lf_printf (file
, " ");
61 lf_indent (file
, +indent
);
65 lf_printf (file
, "\n");
67 lf_printf (file
, "(");
69 print_semantic_function_formal (file
, nr_prefetched_words
);
71 lf_printf (file
, ")");
72 if (is_function_definition
)
74 lf_indent (file
, -indent
);
78 lf_printf (file
, ";");
80 lf_printf (file
, "\n");
84 print_semantic_declaration (lf
*file
,
86 opcode_bits
*expanded_bits
,
87 insn_opcodes
*opcodes
,
88 int nr_prefetched_words
)
90 print_semantic_function_header (file
,
94 0/* is not function definition*/,
100 /* generate the semantics.c file */
104 print_idecode_invalid (lf
*file
,
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;
116 if (options
.gen
.code
== generate_jumps
)
118 lf_printf (file
, "goto %s_%s;\n",
119 (options
.gen
.icache
? "icache" : "semantic"),
122 else if (options
.gen
.icache
)
124 lf_printf (file
, "%s %sicache_%s (", result
, options
.prefix
.global
.name
, name
);
125 print_icache_function_actual (file
, 0);
126 lf_printf (file
, ");\n");
130 lf_printf (file
, "%s %ssemantic_%s (", result
, options
.prefix
.global
.name
, name
);
131 print_semantic_function_actual (file
, 0);
132 lf_printf (file
, ");\n");
138 print_semantic_body (lf
*file
,
139 insn_entry
*instruction
,
140 opcode_bits
*expanded_bits
,
141 insn_opcodes
*opcodes
)
143 print_itrace (file
, instruction
, 0/*put_value_in_cache*/);
145 /* validate the instruction, if a cache this has already been done */
146 if (!options
.gen
.icache
)
148 print_idecode_validate (file
, instruction
, opcodes
);
151 /* generate the profiling call - this is delayed until after the
152 instruction has been verified */
154 lf_printf (file
, "\n");
155 lf_indent_suppress (file
);
156 lf_printf (file
, "#if defined (WITH_MON)\n");
157 lf_printf (file
, "/* monitoring: */\n");
158 lf_printf (file
, "if (WITH_MON & MONITOR_INSTRUCTION_ISSUE)\n");
159 lf_printf (file
, " mon_issue (");
160 print_function_name (file
,
162 instruction
->format_name
,
165 function_name_prefix_itable
);
166 lf_printf (file
, ", cpu, cia);\n");
167 lf_indent_suppress (file
);
168 lf_printf (file
, "#endif\n");
169 lf_printf (file
, "\n");
172 /* determine the new instruction address */
174 lf_printf(file
, "/* keep the next instruction address handy */\n");
175 if (options
.gen
.nia
== nia_is_invalid
)
177 lf_printf(file
, "nia = %sINVALID_INSTRUCTION_ADDRESS;\n",
178 options
.prefix
.global
.uname
);
182 int nr_immeds
= instruction
->nr_words
- 1;
183 if (options
.gen
.delayed_branch
)
187 lf_printf (file
, "cia.dp += %d * %d; %s\n",
188 options
.insn_bit_size
/ 8, nr_immeds
,
189 "/* skip dp immeds */");
191 lf_printf (file
, "nia.ip = cia.dp; %s\n",
192 "/* instruction pointer */");
193 lf_printf (file
, "nia.dp = cia.dp + %d; %s\n",
194 options
.insn_bit_size
/ 8,
195 "/* delayed-slot pointer */");
201 lf_printf (file
, "nia = cia + %d * (%d + 1); %s\n",
202 options
.insn_bit_size
/ 8, nr_immeds
,
203 "/* skip immeds as well */");
208 lf_printf (file
, "nia = cia + %d;\n",
209 options
.insn_bit_size
/ 8);
215 /* if conditional, generate code to verify that the instruction
217 if (filter_is_member (instruction
->options
, "c")
218 || options
.gen
.conditional_issue
)
220 lf_printf (file
, "\n");
221 lf_printf (file
, "/* execute only if conditional passes */\n");
222 lf_printf (file
, "if (IS_CONDITION_OK)\n");
223 lf_printf (file
, " {\n");
224 lf_indent (file
, +4);
225 /* FIXME - need to log a conditional failure */
228 /* Architecture expects a REG to be zero. Instead of having to
229 check every read to see if it is refering to that REG just zap it
230 at the start of every instruction */
231 if (options
.gen
.zero_reg
)
233 lf_printf (file
, "\n");
234 lf_printf (file
, "GPR(%d) = 0;\n", options
.gen
.zero_reg_nr
);
237 /* generate the code (or at least something */
238 lf_printf (file
, "\n");
239 lf_printf (file
, "/* semantics: */\n");
240 if (instruction
->code
!= NULL
)
243 lf_printf (file
, "{\n");
244 lf_indent (file
, +2);
245 lf_print__line_ref (file
, instruction
->code
->line
);
246 table_print_code (file
, instruction
->code
);
247 lf_indent (file
, -2);
248 lf_printf (file
, "}\n");
249 lf_print__internal_ref (file
);
251 else if (filter_is_member (instruction
->options
, "nop"))
253 lf_print__internal_ref (file
);
257 /* abort so it is implemented now */
258 lf_print__line_ref (file
, instruction
->line
);
259 lf_printf (file
, "sim_engine_abort (SD, CPU, cia, \"%s:%d:0x%%08lx:%%s unimplemented\\n\",\n",
260 filter_filename (instruction
->line
->file_name
),
261 instruction
->line
->line_nr
);
262 if (options
.gen
.delayed_branch
)
264 lf_printf (file
, " (long)cia.ip,\n");
268 lf_printf (file
, " (long)cia,\n");
270 lf_printf (file
, " %sitable[MY_INDEX].name);\n",
271 options
.prefix
.itable
.name
);
272 lf_print__internal_ref (file
);
275 /* Close off the conditional execution */
276 if (filter_is_member (instruction
->options
, "c")
277 || options
.gen
.conditional_issue
)
279 lf_indent (file
, -4);
280 lf_printf (file
, " }\n");
285 print_c_semantic (lf
*file
,
286 insn_entry
*instruction
,
287 opcode_bits
*expanded_bits
,
288 insn_opcodes
*opcodes
,
289 cache_entry
*cache_rules
,
290 int nr_prefetched_words
)
293 lf_printf (file
, "{\n");
294 lf_indent (file
, +2);
296 print_my_defines (file
,
298 instruction
->format_name
,
300 lf_printf (file
, "\n");
301 print_icache_body (file
,
305 (options
.gen
.direct_access
307 : declare_variables
),
309 ? get_values_from_icache
310 : do_not_use_icache
),
311 nr_prefetched_words
);
313 lf_printf (file
, "%sinstruction_address nia;\n", options
.prefix
.global
.name
);
314 print_semantic_body (file
,
318 lf_printf (file
, "return nia;\n");
320 /* generate something to clean up any #defines created for the cache */
321 if (options
.gen
.direct_access
)
323 print_icache_body (file
,
329 ? get_values_from_icache
330 : do_not_use_icache
),
331 nr_prefetched_words
);
334 lf_indent (file
, -2);
335 lf_printf (file
, "}\n");
339 print_c_semantic_function (lf
*file
,
340 insn_entry
*instruction
,
341 opcode_bits
*expanded_bits
,
342 insn_opcodes
*opcodes
,
343 cache_entry
*cache_rules
,
344 int nr_prefetched_words
)
346 /* build the semantic routine to execute the instruction */
347 print_semantic_function_header (file
,
349 instruction
->format_name
,
351 1/*is-function-definition*/,
352 nr_prefetched_words
);
353 print_c_semantic (file
,
358 nr_prefetched_words
);
362 print_semantic_definition (lf
*file
,
364 opcode_bits
*expanded_bits
,
365 insn_opcodes
*opcodes
,
366 cache_entry
*cache_rules
,
367 int nr_prefetched_words
)
369 print_c_semantic_function (file
,
374 nr_prefetched_words
);