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

Subversion Repositories openrisc

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