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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [sim/] [cris/] [cris-tmpl.c] - Blame information for rev 819

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

Line No. Rev Author Line
1 24 jeremybenn
/* CRIS base simulator support code
2
   Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
3
   Contributed by Axis Communications.
4
 
5
This file is part of the GNU simulators.
6
 
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 3 of the License, or
10
(at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
 
20
/* The infrastructure is based on that of i960.c.  */
21
 
22
#define WANT_CPU
23
 
24
#include "sim-main.h"
25
#include "cgen-mem.h"
26
#include "cgen-ops.h"
27
 
28
#define MY(f) XCONCAT3(crisv,BASENUM,f)
29
 
30
/* Dispatcher for break insn.  */
31
 
32
USI
33
MY (f_break_handler) (SIM_CPU *cpu, USI breaknum, USI pc)
34
{
35
  SIM_DESC sd = CPU_STATE (cpu);
36
  USI ret = pc + 2;
37
 
38
  MY (f_h_pc_set) (cpu, ret);
39
 
40
  /* FIXME: Error out if IBR or ERP set.  */
41
  switch (breaknum)
42
    {
43
    case 13:
44
      MY (f_h_gr_set (cpu, 10,
45
                      cris_break_13_handler (cpu,
46
                                             MY (f_h_gr_get (cpu, 9)),
47
                                             MY (f_h_gr_get (cpu, 10)),
48
                                             MY (f_h_gr_get (cpu, 11)),
49
                                             MY (f_h_gr_get (cpu, 12)),
50
                                             MY (f_h_gr_get (cpu, 13)),
51
                                             MY (f_h_sr_get (cpu, 7)),
52
                                             MY (f_h_sr_get (cpu, 11)),
53
                                             pc)));
54
      break;
55
 
56
    case 14:
57
      sim_io_printf (sd, "%x\n", MY (f_h_gr_get (cpu, 3)));
58
      break;
59
 
60
    case 15:
61
      /* Re-use the Linux exit call.  */
62
      cris_break_13_handler (cpu, /* TARGET_SYS_exit */ 1, 0,
63
                             0, 0, 0, 0, 0, pc);
64
 
65
    default:
66
      abort ();
67
    }
68
 
69
  return MY (f_h_pc_get) (cpu);
70
}
71
 
72
/* Accessor function for simulator internal use.
73
   Note the contents of BUF are in target byte order.  */
74
 
75
int
76
MY (f_fetch_register) (SIM_CPU *current_cpu, int rn,
77
                      unsigned char *buf, int len ATTRIBUTE_UNUSED)
78
{
79
  SETTSI (buf, XCONCAT3(crisv,BASENUM,f_h_gr_get) (current_cpu, rn));
80
  return -1;
81
}
82
 
83
/* Accessor function for simulator internal use.
84
   Note the contents of BUF are in target byte order.  */
85
 
86
int
87
MY (f_store_register) (SIM_CPU *current_cpu, int rn,
88
                      unsigned char *buf, int len ATTRIBUTE_UNUSED)
89
{
90
  XCONCAT3(crisv,BASENUM,f_h_gr_set) (current_cpu, rn, GETTSI (buf));
91
  return -1;
92
}
93
 
94
#if WITH_PROFILE_MODEL_P
95
 
96
/* FIXME: Some of these should be inline or macros.  Later.  */
97
 
98
/* Initialize cycle counting for an insn.
99
   FIRST_P is non-zero if this is the first insn in a set of parallel
100
   insns.  */
101
 
102
void
103
MY (f_model_insn_before) (SIM_CPU *current_cpu, int first_p ATTRIBUTE_UNUSED)
104
{
105
  /* To give the impression that we actually know what PC is, we have to
106
     dump register contents *before* the *next* insn, not after the
107
     *previous* insn.  Uhh...  */
108
 
109
  /* FIXME: Move this to separate, overridable function.  */
110
  if ((CPU_CRIS_MISC_PROFILE (current_cpu)->flags
111
       & FLAG_CRIS_MISC_PROFILE_XSIM_TRACE)
112
#ifdef GET_H_INSN_PREFIXED_P
113
      /* For versions with prefixed insns, trace the combination as
114
         one insn.  */
115
      && !GET_H_INSN_PREFIXED_P ()
116
#endif
117
      && 1)
118
  {
119
    int i;
120
    char flags[7];
121
    unsigned64 cycle_count;
122
 
123
    SIM_DESC sd = CPU_STATE (current_cpu);
124
 
125
    cris_trace_printf (sd, current_cpu, "%lx ",
126
                       0xffffffffUL & (unsigned long) (CPU (h_pc)));
127
 
128
    for (i = 0; i < 15; i++)
129
      cris_trace_printf (sd, current_cpu, "%lx ",
130
                         0xffffffffUL
131
                         & (unsigned long) (XCONCAT3(crisv,BASENUM,
132
                                                     f_h_gr_get) (current_cpu,
133
                                                                  i)));
134
    flags[0] = GET_H_IBIT () != 0 ? 'I' : 'i';
135
    flags[1] = GET_H_XBIT () != 0 ? 'X' : 'x';
136
    flags[2] = GET_H_NBIT () != 0 ? 'N' : 'n';
137
    flags[3] = GET_H_ZBIT () != 0 ? 'Z' : 'z';
138
    flags[4] = GET_H_VBIT () != 0 ? 'V' : 'v';
139
    flags[5] = GET_H_CBIT () != 0 ? 'C' : 'c';
140
    flags[6] = 0;
141
 
142
    /* For anything else than basic tracing we'd add stall cycles for
143
       e.g. unaligned accesses.  FIXME: add --cris-trace=x options to
144
       match --cris-cycles=x.  */
145
    cycle_count
146
      = (CPU_CRIS_MISC_PROFILE (current_cpu)->basic_cycle_count
147
         - CPU_CRIS_PREV_MISC_PROFILE (current_cpu)->basic_cycle_count);
148
 
149
    /* Emit ACR after flags and cycle count for this insn.  */
150
    if (BASENUM == 32)
151
      cris_trace_printf (sd, current_cpu, "%s %d %lx\n", flags,
152
                         (int) cycle_count,
153
                         0xffffffffUL
154
                         & (unsigned long) (XCONCAT3(crisv,BASENUM,
155
                                                     f_h_gr_get) (current_cpu,
156
                                                                  15)));
157
    else
158
      cris_trace_printf (sd, current_cpu, "%s %d\n", flags,
159
                         (int) cycle_count);
160
 
161
    CPU_CRIS_PREV_MISC_PROFILE (current_cpu)[0]
162
      = CPU_CRIS_MISC_PROFILE (current_cpu)[0];
163
  }
164
}
165
 
166
/* Record the cycles computed for an insn.
167
   LAST_P is non-zero if this is the last insn in a set of parallel insns,
168
   and we update the total cycle count.
169
   CYCLES is the cycle count of the insn.  */
170
 
171
void
172
MY (f_model_insn_after) (SIM_CPU *current_cpu, int last_p ATTRIBUTE_UNUSED,
173
                         int cycles)
174
{
175
  PROFILE_DATA *p = CPU_PROFILE_DATA (current_cpu);
176
 
177
  PROFILE_MODEL_TOTAL_CYCLES (p) += cycles;
178
  CPU_CRIS_MISC_PROFILE (current_cpu)->basic_cycle_count += cycles;
179
  PROFILE_MODEL_CUR_INSN_CYCLES (p) = cycles;
180
 
181
#if WITH_HW
182
  /* For some reason, we don't get to the sim_events_tick call in
183
     cgen-run.c:engine_run_1.  Besides, more than one cycle has
184
     passed, so we want sim_events_tickn anyway.  The "events we want
185
     to process" is usually to initiate an interrupt, but might also
186
     be other events.  We can't do the former until the main loop is
187
     at point where it accepts changing the PC without internal
188
     inconsistency, so just set a flag and wait.  */
189
  if (sim_events_tickn (CPU_STATE (current_cpu), cycles))
190
    STATE_EVENTS (CPU_STATE (current_cpu))->work_pending = 1;
191
#endif
192
}
193
 
194
/* Initialize cycle counting for an insn.
195
   FIRST_P is non-zero if this is the first insn in a set of parallel
196
   insns.  */
197
 
198
void
199
MY (f_model_init_insn_cycles) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
200
                               int first_p ATTRIBUTE_UNUSED)
201
{
202
  abort ();
203
}
204
 
205
/* Record the cycles computed for an insn.
206
   LAST_P is non-zero if this is the last insn in a set of parallel insns,
207
   and we update the total cycle count.  */
208
 
209
void
210
MY (f_model_update_insn_cycles) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
211
                                 int last_p ATTRIBUTE_UNUSED)
212
{
213
  abort ();
214
}
215
 
216
#if 0
217
void
218
MY (f_model_record_cycles) (SIM_CPU *current_cpu, unsigned long cycles)
219
{
220
  abort ();
221
}
222
 
223
void
224
MY (f_model_mark_get_h_gr) (SIM_CPU *current_cpu, ARGBUF *abuf)
225
{
226
  abort ();
227
}
228
 
229
void
230
MY (f_model_mark_set_h_gr) (SIM_CPU *current_cpu, ARGBUF *abuf)
231
{
232
  abort ();
233
}
234
#endif
235
 
236
/* Create the context for a thread.  */
237
 
238
void *
239
MY (make_thread_cpu_data) (SIM_CPU *current_cpu, void *context)
240
{
241
  void *info = xmalloc (current_cpu->thread_cpu_data_size);
242
 
243
  if (context != NULL)
244
    memcpy (info,
245
            context,
246
            current_cpu->thread_cpu_data_size);
247
  else
248
    memset (info, 0, current_cpu->thread_cpu_data_size),abort();
249
  return info;
250
}
251
 
252
/* Hook function for per-cpu simulator initialization.  */
253
 
254
void
255
MY (f_specific_init) (SIM_CPU *current_cpu)
256
{
257
  current_cpu->make_thread_cpu_data = MY (make_thread_cpu_data);
258
  current_cpu->thread_cpu_data_size = sizeof (current_cpu->cpu_data);
259
#if WITH_HW
260
  current_cpu->deliver_interrupt = MY (deliver_interrupt);
261
#endif
262
}
263
 
264
/* Model function for arbitrary single stall cycles.  */
265
 
266
int
267
MY (XCONCAT3 (f_model_crisv,BASENUM,
268
              _u_stall)) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
269
                          const IDESC *idesc,
270
                          int unit_num,
271
                          int referenced ATTRIBUTE_UNUSED)
272
{
273
  return idesc->timing->units[unit_num].done;
274
}
275
 
276
#ifndef SPECIFIC_U_SKIP4_FN
277
 
278
/* Model function for u-skip4 unit.  */
279
 
280
int
281
MY (XCONCAT3 (f_model_crisv,BASENUM,
282
              _u_skip4)) (SIM_CPU *current_cpu,
283
                          const IDESC *idesc,
284
                          int unit_num,
285
                          int referenced ATTRIBUTE_UNUSED)
286
{
287
  /* Handle PC not being updated with pbb.  FIXME: What if not pbb?  */
288
  CPU (h_pc) += 4;
289
  return idesc->timing->units[unit_num].done;
290
}
291
 
292
#endif
293
 
294
#ifndef SPECIFIC_U_EXEC_FN
295
 
296
/* Model function for u-exec unit.  */
297
 
298
int
299
MY (XCONCAT3 (f_model_crisv,BASENUM,
300
              _u_exec)) (SIM_CPU *current_cpu,
301
                         const IDESC *idesc,
302
                         int unit_num, int referenced ATTRIBUTE_UNUSED)
303
{
304
  /* Handle PC not being updated with pbb.  FIXME: What if not pbb?  */
305
  CPU (h_pc) += 2;
306
  return idesc->timing->units[unit_num].done;
307
}
308
#endif
309
 
310
#ifndef SPECIFIC_U_MEM_FN
311
 
312
/* Model function for u-mem unit.  */
313
 
314
int
315
MY (XCONCAT3 (f_model_crisv,BASENUM,
316
              _u_mem)) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
317
                        const IDESC *idesc,
318
                        int unit_num,
319
                        int referenced ATTRIBUTE_UNUSED)
320
{
321
  return idesc->timing->units[unit_num].done;
322
}
323
#endif
324
 
325
#ifndef SPECIFIC_U_CONST16_FN
326
 
327
/* Model function for u-const16 unit.  */
328
 
329
int
330
MY (XCONCAT3 (f_model_crisv,BASENUM,
331
              _u_const16)) (SIM_CPU *current_cpu,
332
                            const IDESC *idesc,
333
                            int unit_num,
334
                            int referenced ATTRIBUTE_UNUSED)
335
{
336
  CPU (h_pc) += 2;
337
  return idesc->timing->units[unit_num].done;
338
}
339
#endif /* SPECIFIC_U_CONST16_FN */
340
 
341
#ifndef SPECIFIC_U_CONST32_FN
342
 
343
/* This will be incorrect for early models, where a dword always take
344
   two cycles.  */
345
#define CRIS_MODEL_MASK_PC_STALL 2
346
 
347
/* Model function for u-const32 unit.  */
348
 
349
int
350
MY (XCONCAT3 (f_model_crisv,BASENUM,
351
              _u_const32)) (SIM_CPU *current_cpu,
352
                            const IDESC *idesc,
353
                            int unit_num,
354
                            int referenced ATTRIBUTE_UNUSED)
355
{
356
  int unaligned_extra
357
    = (((CPU (h_pc) + 2) & CRIS_MODEL_MASK_PC_STALL)
358
       == CRIS_MODEL_MASK_PC_STALL);
359
 
360
  /* Handle PC not being updated with pbb.  FIXME: What if not pbb?  */
361
  CPU_CRIS_MISC_PROFILE (current_cpu)->unaligned_mem_dword_count
362
    += unaligned_extra;
363
 
364
  CPU (h_pc) += 4;
365
  return idesc->timing->units[unit_num].done;
366
}
367
#endif /* SPECIFIC_U_CONST32_FN */
368
 
369
#ifndef SPECIFIC_U_MOVEM_FN
370
 
371
/* Model function for u-movem unit.  */
372
 
373
int
374
MY (XCONCAT3 (f_model_crisv,BASENUM,
375
              _u_movem)) (SIM_CPU *current_cpu ATTRIBUTE_UNUSED,
376
                          const IDESC *idesc ATTRIBUTE_UNUSED,
377
                          int unit_num ATTRIBUTE_UNUSED,
378
                          int referenced ATTRIBUTE_UNUSED,
379
                          INT limreg)
380
{
381
  /* FIXME: Add cycles for misalignment.  */
382
 
383
  if (limreg == -1)
384
    abort ();
385
 
386
  /* We don't record movem move cycles in movemsrc_stall_count since
387
     those cycles have historically been handled as ordinary cycles.  */
388
  return limreg + 1;
389
}
390
#endif /* SPECIFIC_U_MOVEM_FN */
391
 
392
#endif /* WITH_PROFILE_MODEL_P */

powered by: WebSVN 2.1.0

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