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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [fr30/] [fr30.c] - Blame information for rev 1774

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

Line No. Rev Author Line
1 578 markom
/* fr30 simulator support code
2
   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
3
   Contributed by Cygnus Solutions.
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 2, or (at your option)
10
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 along
18
with this program; if not, write to the Free Software Foundation, Inc.,
19
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
 
21
#define WANT_CPU
22
#define WANT_CPU_FR30BF
23
 
24
#include "sim-main.h"
25
#include "cgen-mem.h"
26
#include "cgen-ops.h"
27
 
28
/* Convert gdb dedicated register number to actual dr reg number.  */
29
 
30
static int
31
decode_gdb_dr_regnum (int gdb_regnum)
32
{
33
  switch (gdb_regnum)
34
    {
35
    case TBR_REGNUM : return H_DR_TBR;
36
    case RP_REGNUM : return H_DR_RP;
37
    case SSP_REGNUM : return H_DR_SSP;
38
    case USP_REGNUM : return H_DR_USP;
39
    case MDH_REGNUM : return H_DR_MDH;
40
    case MDL_REGNUM : return H_DR_MDL;
41
    }
42
  abort ();
43
}
44
 
45
/* The contents of BUF are in target byte order.  */
46
 
47
int
48
fr30bf_fetch_register (SIM_CPU *current_cpu, int rn, unsigned char *buf, int len)
49
{
50
  if (rn < 16)
51
    SETTWI (buf, fr30bf_h_gr_get (current_cpu, rn));
52
  else
53
    switch (rn)
54
      {
55
      case PC_REGNUM :
56
        SETTWI (buf, fr30bf_h_pc_get (current_cpu));
57
        break;
58
      case PS_REGNUM :
59
        SETTWI (buf, fr30bf_h_ps_get (current_cpu));
60
        break;
61
      case TBR_REGNUM :
62
      case RP_REGNUM :
63
      case SSP_REGNUM :
64
      case USP_REGNUM :
65
      case MDH_REGNUM :
66
      case MDL_REGNUM :
67
        SETTWI (buf, fr30bf_h_dr_get (current_cpu,
68
                                      decode_gdb_dr_regnum (rn)));
69
        break;
70
      default :
71
        return 0;
72
      }
73
 
74
  return -1; /*FIXME*/
75
}
76
 
77
/* The contents of BUF are in target byte order.  */
78
 
79
int
80
fr30bf_store_register (SIM_CPU *current_cpu, int rn, unsigned char *buf, int len)
81
{
82
  if (rn < 16)
83
    fr30bf_h_gr_set (current_cpu, rn, GETTWI (buf));
84
  else
85
    switch (rn)
86
      {
87
      case PC_REGNUM :
88
        fr30bf_h_pc_set (current_cpu, GETTWI (buf));
89
        break;
90
      case PS_REGNUM :
91
        fr30bf_h_ps_set (current_cpu, GETTWI (buf));
92
        break;
93
      case TBR_REGNUM :
94
      case RP_REGNUM :
95
      case SSP_REGNUM :
96
      case USP_REGNUM :
97
      case MDH_REGNUM :
98
      case MDL_REGNUM :
99
        fr30bf_h_dr_set (current_cpu,
100
                         decode_gdb_dr_regnum (rn),
101
                         GETTWI (buf));
102
        break;
103
      default :
104
        return 0;
105
      }
106
 
107
  return -1; /*FIXME*/
108
}
109
 
110
/* Cover fns to access the ccr bits.  */
111
 
112
BI
113
fr30bf_h_sbit_get_handler (SIM_CPU *current_cpu)
114
{
115
  return CPU (h_sbit);
116
}
117
 
118
void
119
fr30bf_h_sbit_set_handler (SIM_CPU *current_cpu, BI newval)
120
{
121
  int old_sbit = CPU (h_sbit);
122
  int new_sbit = (newval != 0);
123
 
124
  CPU (h_sbit) = new_sbit;
125
 
126
  /* When switching stack modes, update the registers.  */
127
  if (old_sbit != new_sbit)
128
    {
129
      if (old_sbit)
130
        {
131
          /* Switching user -> system.  */
132
          CPU (h_dr[H_DR_USP]) = CPU (h_gr[H_GR_SP]);
133
          CPU (h_gr[H_GR_SP]) = CPU (h_dr[H_DR_SSP]);
134
        }
135
      else
136
        {
137
          /* Switching system -> user.  */
138
          CPU (h_dr[H_DR_SSP]) = CPU (h_gr[H_GR_SP]);
139
          CPU (h_gr[H_GR_SP]) = CPU (h_dr[H_DR_USP]);
140
        }
141
    }
142
 
143
  /* TODO: r15 interlock */
144
}
145
 
146
/* Cover fns to access the ccr bits.  */
147
 
148
UQI
149
fr30bf_h_ccr_get_handler (SIM_CPU *current_cpu)
150
{
151
  int ccr = (  (GET_H_CBIT () << 0)
152
             | (GET_H_VBIT () << 1)
153
             | (GET_H_ZBIT () << 2)
154
             | (GET_H_NBIT () << 3)
155
             | (GET_H_IBIT () << 4)
156
             | (GET_H_SBIT () << 5));
157
 
158
  return ccr;
159
}
160
 
161
void
162
fr30bf_h_ccr_set_handler (SIM_CPU *current_cpu, UQI newval)
163
{
164
  int ccr = newval & 0x3f;
165
 
166
  SET_H_CBIT ((ccr & 1) != 0);
167
  SET_H_VBIT ((ccr & 2) != 0);
168
  SET_H_ZBIT ((ccr & 4) != 0);
169
  SET_H_NBIT ((ccr & 8) != 0);
170
  SET_H_IBIT ((ccr & 0x10) != 0);
171
  SET_H_SBIT ((ccr & 0x20) != 0);
172
}
173
 
174
/* Cover fns to access the scr bits.  */
175
 
176
UQI
177
fr30bf_h_scr_get_handler (SIM_CPU *current_cpu)
178
{
179
  int scr = (  (GET_H_TBIT () << 0)
180
             | (GET_H_D0BIT () << 1)
181
             | (GET_H_D1BIT () << 2));
182
  return scr;
183
}
184
 
185
void
186
fr30bf_h_scr_set_handler (SIM_CPU *current_cpu, UQI newval)
187
{
188
  int scr = newval & 7;
189
 
190
  SET_H_TBIT  ((scr & 1) != 0);
191
  SET_H_D0BIT ((scr & 2) != 0);
192
  SET_H_D1BIT ((scr & 4) != 0);
193
}
194
 
195
/* Cover fns to access the ilm bits.  */
196
 
197
UQI
198
fr30bf_h_ilm_get_handler (SIM_CPU *current_cpu)
199
{
200
  return CPU (h_ilm);
201
}
202
 
203
void
204
fr30bf_h_ilm_set_handler (SIM_CPU *current_cpu, UQI newval)
205
{
206
  int ilm = newval & 0x1f;
207
  int current_ilm = CPU (h_ilm);
208
 
209
  /* We can only set new ilm values < 16 if the current ilm is < 16.  Otherwise
210
     we add 16 to the value we are given.  */
211
  if (current_ilm >= 16 && ilm < 16)
212
    ilm += 16;
213
 
214
  CPU (h_ilm) = ilm;
215
}
216
 
217
/* Cover fns to access the ps register.  */
218
 
219
USI
220
fr30bf_h_ps_get_handler (SIM_CPU *current_cpu)
221
{
222
  int ccr = GET_H_CCR ();
223
  int scr = GET_H_SCR ();
224
  int ilm = GET_H_ILM ();
225
 
226
  return ccr | (scr << 8) | (ilm << 16);
227
}
228
 
229
void
230
fr30bf_h_ps_set_handler (SIM_CPU *current_cpu, USI newval)
231
{
232
  int ccr = newval & 0xff;
233
  int scr = (newval >> 8) & 7;
234
  int ilm = (newval >> 16) & 0x1f;
235
 
236
  SET_H_CCR (ccr);
237
  SET_H_SCR (scr);
238
  SET_H_ILM (ilm);
239
}
240
 
241
/* Cover fns to access the dedicated registers.  */
242
 
243
SI
244
fr30bf_h_dr_get_handler (SIM_CPU *current_cpu, UINT dr)
245
{
246
  switch (dr)
247
    {
248
    case H_DR_SSP :
249
      if (! GET_H_SBIT ())
250
        return GET_H_GR (H_GR_SP);
251
      else
252
        return CPU (h_dr[H_DR_SSP]);
253
    case H_DR_USP :
254
      if (GET_H_SBIT ())
255
        return GET_H_GR (H_GR_SP);
256
      else
257
        return CPU (h_dr[H_DR_USP]);
258
    case H_DR_TBR :
259
    case H_DR_RP :
260
    case H_DR_MDH :
261
    case H_DR_MDL :
262
      return CPU (h_dr[dr]);
263
    }
264
  return 0;
265
}
266
 
267
void
268
fr30bf_h_dr_set_handler (SIM_CPU *current_cpu, UINT dr, SI newval)
269
{
270
  switch (dr)
271
    {
272
    case H_DR_SSP :
273
      if (! GET_H_SBIT ())
274
        SET_H_GR (H_GR_SP, newval);
275
      else
276
        CPU (h_dr[H_DR_SSP]) = newval;
277
      break;
278
    case H_DR_USP :
279
      if (GET_H_SBIT ())
280
        SET_H_GR (H_GR_SP, newval);
281
      else
282
        CPU (h_dr[H_DR_USP]) = newval;
283
      break;
284
    case H_DR_TBR :
285
    case H_DR_RP :
286
    case H_DR_MDH :
287
    case H_DR_MDL :
288
      CPU (h_dr[dr]) = newval;
289
      break;
290
    }
291
}
292
 
293
#if WITH_PROFILE_MODEL_P
294
 
295
/* FIXME: Some of these should be inline or macros.  Later.  */
296
 
297
/* Initialize cycle counting for an insn.
298
   FIRST_P is non-zero if this is the first insn in a set of parallel
299
   insns.  */
300
 
301
void
302
fr30bf_model_insn_before (SIM_CPU *cpu, int first_p)
303
{
304
  MODEL_FR30_1_DATA *d = CPU_MODEL_DATA (cpu);
305
  d->load_regs_pending = 0;
306
}
307
 
308
/* Record the cycles computed for an insn.
309
   LAST_P is non-zero if this is the last insn in a set of parallel insns,
310
   and we update the total cycle count.
311
   CYCLES is the cycle count of the insn.  */
312
 
313
void
314
fr30bf_model_insn_after (SIM_CPU *cpu, int last_p, int cycles)
315
{
316
  PROFILE_DATA *p = CPU_PROFILE_DATA (cpu);
317
  MODEL_FR30_1_DATA *d = CPU_MODEL_DATA (cpu);
318
 
319
  PROFILE_MODEL_TOTAL_CYCLES (p) += cycles;
320
  PROFILE_MODEL_CUR_INSN_CYCLES (p) = cycles;
321
  d->load_regs = d->load_regs_pending;
322
}
323
 
324
static INLINE int
325
check_load_stall (SIM_CPU *cpu, int regno)
326
{
327
  const MODEL_FR30_1_DATA *d = CPU_MODEL_DATA (cpu);
328
  UINT load_regs = d->load_regs;
329
 
330
  if (regno != -1
331
      && (load_regs & (1 << regno)) != 0)
332
    {
333
      PROFILE_DATA *p = CPU_PROFILE_DATA (cpu);
334
      ++ PROFILE_MODEL_LOAD_STALL_CYCLES (p);
335
      if (TRACE_INSN_P (cpu))
336
        cgen_trace_printf (cpu, " ; Load stall.");
337
      return 1;
338
    }
339
  else
340
    return 0;
341
}
342
 
343
int
344
fr30bf_model_fr30_1_u_exec (SIM_CPU *cpu, const IDESC *idesc,
345
                            int unit_num, int referenced,
346
                            INT in_Ri, INT in_Rj, INT out_Ri)
347
{
348
  int cycles = idesc->timing->units[unit_num].done;
349
  cycles += check_load_stall (cpu, in_Ri);
350
  cycles += check_load_stall (cpu, in_Rj);
351
  return cycles;
352
}
353
 
354
int
355
fr30bf_model_fr30_1_u_cti (SIM_CPU *cpu, const IDESC *idesc,
356
                           int unit_num, int referenced,
357
                           INT in_Ri)
358
{
359
  PROFILE_DATA *p = CPU_PROFILE_DATA (cpu);
360
  /* (1 << 1): The pc is the 2nd element in inputs, outputs.
361
     ??? can be cleaned up */
362
  int taken_p = (referenced & (1 << 1)) != 0;
363
  int cycles = idesc->timing->units[unit_num].done;
364
  int delay_slot_p = CGEN_ATTR_VALUE (NULL, idesc->attrs, CGEN_INSN_DELAY_SLOT);
365
 
366
  cycles += check_load_stall (cpu, in_Ri);
367
  if (taken_p)
368
    {
369
      /* ??? Handling cti's without delay slots this way will run afoul of
370
         accurate system simulation.  Later.  */
371
      if (! delay_slot_p)
372
        {
373
          ++cycles;
374
          ++PROFILE_MODEL_CTI_STALL_CYCLES (p);
375
        }
376
      ++PROFILE_MODEL_TAKEN_COUNT (p);
377
    }
378
  else
379
    ++PROFILE_MODEL_UNTAKEN_COUNT (p);
380
 
381
  return cycles;
382
}
383
 
384
int
385
fr30bf_model_fr30_1_u_load (SIM_CPU *cpu, const IDESC *idesc,
386
                            int unit_num, int referenced,
387
                            INT in_Rj, INT out_Ri)
388
{
389
  MODEL_FR30_1_DATA *d = CPU_MODEL_DATA (cpu);
390
  int cycles = idesc->timing->units[unit_num].done;
391
  d->load_regs_pending |= 1 << out_Ri;
392
  cycles += check_load_stall (cpu, in_Rj);
393
  return cycles;
394
}
395
 
396
int
397
fr30bf_model_fr30_1_u_store (SIM_CPU *cpu, const IDESC *idesc,
398
                             int unit_num, int referenced,
399
                             INT in_Ri, INT in_Rj)
400
{
401
  int cycles = idesc->timing->units[unit_num].done;
402
  cycles += check_load_stall (cpu, in_Ri);
403
  cycles += check_load_stall (cpu, in_Rj);
404
  return cycles;
405
}
406
 
407
int
408
fr30bf_model_fr30_1_u_ldm (SIM_CPU *cpu, const IDESC *idesc,
409
                           int unit_num, int referenced,
410
                           INT reglist)
411
{
412
  return idesc->timing->units[unit_num].done;
413
}
414
 
415
int
416
fr30bf_model_fr30_1_u_stm (SIM_CPU *cpu, const IDESC *idesc,
417
                           int unit_num, int referenced,
418
                           INT reglist)
419
{
420
  return idesc->timing->units[unit_num].done;
421
}
422
 
423
#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.