OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [sim/] [igen/] [gen-semantics.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*  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
 
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_CLEAR(%d);\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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.