sim/ppc/*: Change immediatly to immediately
[external/binutils.git] / sim / ppc / gen-semantics.c
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
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
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 \f
88 /* generate the semantics.c file */
89
90
91 void
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
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
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
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
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 }