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 3 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, see <http://www.gnu.org/licenses/>.
27 #include "ld-decode.h"
33 #include "gen-semantics.h"
34 #include "gen-icache.h"
35 #include "gen-idecode.h"
39 print_semantic_function_header(lf
*file
,
41 insn_bits
*expanded_bits
,
42 int is_function_definition
)
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
,
51 function_name_prefix_semantics
);
52 if (is_function_definition
)
53 lf_indent(file
, +indent
);
55 lf_printf(file
, "\n");
56 lf_printf(file
, "(%s)", SEMANTIC_FUNCTION_FORMAL
);
57 if (is_function_definition
)
58 lf_indent(file
, -indent
);
61 lf_printf(file
, "\n");
65 print_semantic_declaration(insn_table
*entry
,
71 if (generate_expanded_instructions
) {
72 ASSERT(entry
->nr_insn
== 1);
73 print_semantic_function_header(file
,
74 instruction
->file_entry
->fields
[insn_name
],
76 0/* is not function definition*/);
79 print_semantic_function_header(file
,
80 instruction
->file_entry
->fields
[insn_name
],
82 0/* is not function definition*/);
88 /* generate the semantics.c file */
92 print_idecode_illegal(lf
*file
,
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
);
100 lf_printf(file
, "%s semantic_illegal(%s);\n", result
, SEMANTIC_FUNCTION_ACTUAL
);
105 print_semantic_body(lf
*file
,
107 insn_bits
*expanded_bits
,
108 opcode_field
*opcodes
)
110 print_itrace(file
, instruction
->file_entry
, 0/*put_value_in_cache*/);
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
);
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
],
125 function_name_prefix_itable
);
126 lf_printf(file
, ", processor, cia);\n");
127 lf_printf(file
, "}\n");
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
) {
135 table_entry_print_cpp_line_nr(file
, instruction
->file_entry
);
136 lf_printf(file
, "{\n");
138 lf_print__c_code(file
, instruction
->file_entry
->annex
);
140 lf_printf(file
, "}\n");
141 lf_print__internal_reference(file
);
143 else if (it_is("nop", instruction
->file_entry
->fields
[insn_flags
])) {
144 lf_print__internal_reference(file
);
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
);
156 print_c_semantic(lf
*file
,
158 insn_bits
*expanded_bits
,
159 opcode_field
*opcodes
,
160 cache_table
*cache_rules
)
163 lf_printf(file
, "{\n");
166 print_my_defines(file
, expanded_bits
, instruction
->file_entry
);
167 lf_printf(file
, "\n");
168 print_icache_body(file
,
172 ((code
& generate_with_direct_access
)
174 : declare_variables
),
175 ((code
& generate_with_icache
)
176 ? get_values_from_icache
177 : do_not_use_icache
));
179 lf_printf(file
, "unsigned_word nia;\n");
180 print_semantic_body(file
,
184 lf_printf(file
, "return nia;\n");
186 /* generate something to clean up any #defines created for the cache */
187 if (code
& generate_with_direct_access
)
188 print_icache_body(file
,
193 ((code
& generate_with_icache
)
194 ? get_values_from_icache
195 : do_not_use_icache
));
198 lf_printf(file
, "}\n");
202 print_c_semantic_function(lf
*file
,
204 insn_bits
*expanded_bits
,
205 opcode_field
*opcodes
,
206 cache_table
*cache_rules
)
208 /* build the semantic routine to execute the instruction */
209 print_semantic_function_header(file
,
210 instruction
->file_entry
->fields
[insn_name
],
212 1/*is-function-definition*/);
213 print_c_semantic(file
,
221 print_semantic_definition(insn_table
*entry
,
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
,
240 entry
->expanded_bits
,
241 entry
->parent
->opcode
,
245 print_c_semantic_function(file
, instruction
,