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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [sim/] [igen/] [gen-semantics.c] - Blame information for rev 859

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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