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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [sim/] [igen/] [gen-semantics.c] - Blame information for rev 1775

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

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

powered by: WebSVN 2.1.0

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