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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [sim/] [m32r/] [m32r.c] - Blame information for rev 438

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

Line No. Rev Author Line
1 330 jeremybenn
/* m32r simulator support code
2
   Copyright (C) 1996, 1997, 1998, 2003, 2007, 2008, 2009, 2010
3
   Free Software Foundation, Inc.
4
   Contributed by Cygnus Support.
5
 
6
   This file is part of GDB, the GNU debugger.
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
#define WANT_CPU m32rbf
22
#define WANT_CPU_M32RBF
23
 
24
#include "sim-main.h"
25
#include "cgen-mem.h"
26
#include "cgen-ops.h"
27
 
28
/* Decode gdb ctrl register number.  */
29
 
30
int
31
m32r_decode_gdb_ctrl_regnum (int gdb_regnum)
32
{
33
  switch (gdb_regnum)
34
    {
35
      case PSW_REGNUM : return H_CR_PSW;
36
      case CBR_REGNUM : return H_CR_CBR;
37
      case SPI_REGNUM : return H_CR_SPI;
38
      case SPU_REGNUM : return H_CR_SPU;
39
      case BPC_REGNUM : return H_CR_BPC;
40
      case BBPSW_REGNUM : return H_CR_BBPSW;
41
      case BBPC_REGNUM : return H_CR_BBPC;
42
      case EVB_REGNUM : return H_CR_CR5;
43
    }
44
  abort ();
45
}
46
 
47
/* The contents of BUF are in target byte order.  */
48
 
49
int
50
m32rbf_fetch_register (SIM_CPU *current_cpu, int rn, unsigned char *buf, int len)
51
{
52
  if (rn < 16)
53
    SETTWI (buf, m32rbf_h_gr_get (current_cpu, rn));
54
  else
55
    switch (rn)
56
      {
57
      case PSW_REGNUM :
58
      case CBR_REGNUM :
59
      case SPI_REGNUM :
60
      case SPU_REGNUM :
61
      case BPC_REGNUM :
62
      case BBPSW_REGNUM :
63
      case BBPC_REGNUM :
64
        SETTWI (buf, m32rbf_h_cr_get (current_cpu,
65
                                      m32r_decode_gdb_ctrl_regnum (rn)));
66
        break;
67
      case PC_REGNUM :
68
        SETTWI (buf, m32rbf_h_pc_get (current_cpu));
69
        break;
70
      case ACCL_REGNUM :
71
        SETTWI (buf, GETLODI (m32rbf_h_accum_get (current_cpu)));
72
        break;
73
      case ACCH_REGNUM :
74
        SETTWI (buf, GETHIDI (m32rbf_h_accum_get (current_cpu)));
75
        break;
76
      default :
77
        return 0;
78
      }
79
 
80
  return -1; /*FIXME*/
81
}
82
 
83
/* The contents of BUF are in target byte order.  */
84
 
85
int
86
m32rbf_store_register (SIM_CPU *current_cpu, int rn, unsigned char *buf, int len)
87
{
88
  if (rn < 16)
89
    m32rbf_h_gr_set (current_cpu, rn, GETTWI (buf));
90
  else
91
    switch (rn)
92
      {
93
      case PSW_REGNUM :
94
      case CBR_REGNUM :
95
      case SPI_REGNUM :
96
      case SPU_REGNUM :
97
      case BPC_REGNUM :
98
      case BBPSW_REGNUM :
99
      case BBPC_REGNUM :
100
        m32rbf_h_cr_set (current_cpu,
101
                         m32r_decode_gdb_ctrl_regnum (rn),
102
                         GETTWI (buf));
103
        break;
104
      case PC_REGNUM :
105
        m32rbf_h_pc_set (current_cpu, GETTWI (buf));
106
        break;
107
      case ACCL_REGNUM :
108
        {
109
          DI val = m32rbf_h_accum_get (current_cpu);
110
          SETLODI (val, GETTWI (buf));
111
          m32rbf_h_accum_set (current_cpu, val);
112
          break;
113
        }
114
      case ACCH_REGNUM :
115
        {
116
          DI val = m32rbf_h_accum_get (current_cpu);
117
          SETHIDI (val, GETTWI (buf));
118
          m32rbf_h_accum_set (current_cpu, val);
119
          break;
120
        }
121
      default :
122
        return 0;
123
      }
124
 
125
  return -1; /*FIXME*/
126
}
127
 
128
USI
129
m32rbf_h_cr_get_handler (SIM_CPU *current_cpu, UINT cr)
130
{
131
  switch (cr)
132
    {
133
    case H_CR_PSW : /* psw */
134
      return (((CPU (h_bpsw) & 0xc1) << 8)
135
              | ((CPU (h_psw) & 0xc0) << 0)
136
              | GET_H_COND ());
137
    case H_CR_BBPSW : /* backup backup psw */
138
      return CPU (h_bbpsw) & 0xc1;
139
    case H_CR_CBR : /* condition bit */
140
      return GET_H_COND ();
141
    case H_CR_SPI : /* interrupt stack pointer */
142
      if (! GET_H_SM ())
143
        return CPU (h_gr[H_GR_SP]);
144
      else
145
        return CPU (h_cr[H_CR_SPI]);
146
    case H_CR_SPU : /* user stack pointer */
147
      if (GET_H_SM ())
148
        return CPU (h_gr[H_GR_SP]);
149
      else
150
        return CPU (h_cr[H_CR_SPU]);
151
    case H_CR_BPC : /* backup pc */
152
      return CPU (h_cr[H_CR_BPC]) & 0xfffffffe;
153
    case H_CR_BBPC : /* backup backup pc */
154
      return CPU (h_cr[H_CR_BBPC]) & 0xfffffffe;
155
    case 4 : /* ??? unspecified, but apparently available */
156
    case 5 : /* ??? unspecified, but apparently available */
157
      return CPU (h_cr[cr]);
158
    default :
159
      return 0;
160
    }
161
}
162
 
163
void
164
m32rbf_h_cr_set_handler (SIM_CPU *current_cpu, UINT cr, USI newval)
165
{
166
  switch (cr)
167
    {
168
    case H_CR_PSW : /* psw */
169
      {
170
        int old_sm = (CPU (h_psw) & 0x80) != 0;
171
        int new_sm = (newval & 0x80) != 0;
172
        CPU (h_bpsw) = (newval >> 8) & 0xff;
173
        CPU (h_psw) = newval & 0xff;
174
        SET_H_COND (newval & 1);
175
        /* When switching stack modes, update the registers.  */
176
        if (old_sm != new_sm)
177
          {
178
            if (old_sm)
179
              {
180
                /* Switching user -> system.  */
181
                CPU (h_cr[H_CR_SPU]) = CPU (h_gr[H_GR_SP]);
182
                CPU (h_gr[H_GR_SP]) = CPU (h_cr[H_CR_SPI]);
183
              }
184
            else
185
              {
186
                /* Switching system -> user.  */
187
                CPU (h_cr[H_CR_SPI]) = CPU (h_gr[H_GR_SP]);
188
                CPU (h_gr[H_GR_SP]) = CPU (h_cr[H_CR_SPU]);
189
              }
190
          }
191
        break;
192
      }
193
    case H_CR_BBPSW : /* backup backup psw */
194
      CPU (h_bbpsw) = newval & 0xff;
195
      break;
196
    case H_CR_CBR : /* condition bit */
197
      SET_H_COND (newval & 1);
198
      break;
199
    case H_CR_SPI : /* interrupt stack pointer */
200
      if (! GET_H_SM ())
201
        CPU (h_gr[H_GR_SP]) = newval;
202
      else
203
        CPU (h_cr[H_CR_SPI]) = newval;
204
      break;
205
    case H_CR_SPU : /* user stack pointer */
206
      if (GET_H_SM ())
207
        CPU (h_gr[H_GR_SP]) = newval;
208
      else
209
        CPU (h_cr[H_CR_SPU]) = newval;
210
      break;
211
    case H_CR_BPC : /* backup pc */
212
      CPU (h_cr[H_CR_BPC]) = newval;
213
      break;
214
    case H_CR_BBPC : /* backup backup pc */
215
      CPU (h_cr[H_CR_BBPC]) = newval;
216
      break;
217
    case 4 : /* ??? unspecified, but apparently available */
218
    case 5 : /* ??? unspecified, but apparently available */
219
      CPU (h_cr[cr]) = newval;
220
      break;
221
    default :
222
      /* ignore */
223
      break;
224
    }
225
}
226
 
227
/* Cover fns to access h-psw.  */
228
 
229
UQI
230
m32rbf_h_psw_get_handler (SIM_CPU *current_cpu)
231
{
232
  return (CPU (h_psw) & 0xfe) | (CPU (h_cond) & 1);
233
}
234
 
235
void
236
m32rbf_h_psw_set_handler (SIM_CPU *current_cpu, UQI newval)
237
{
238
  CPU (h_psw) = newval;
239
  CPU (h_cond) = newval & 1;
240
}
241
 
242
/* Cover fns to access h-accum.  */
243
 
244
DI
245
m32rbf_h_accum_get_handler (SIM_CPU *current_cpu)
246
{
247
  /* Sign extend the top 8 bits.  */
248
  DI r;
249
#if 1
250
  r = ANDDI (CPU (h_accum), MAKEDI (0xffffff, 0xffffffff));
251
  r = XORDI (r, MAKEDI (0x800000, 0));
252
  r = SUBDI (r, MAKEDI (0x800000, 0));
253
#else
254
  SI hi,lo;
255
  r = CPU (h_accum);
256
  hi = GETHIDI (r);
257
  lo = GETLODI (r);
258
  hi = ((hi & 0xffffff) ^ 0x800000) - 0x800000;
259
  r = MAKEDI (hi, lo);
260
#endif
261
  return r;
262
}
263
 
264
void
265
m32rbf_h_accum_set_handler (SIM_CPU *current_cpu, DI newval)
266
{
267
  CPU (h_accum) = newval;
268
}
269
 
270
#if WITH_PROFILE_MODEL_P
271
 
272
/* FIXME: Some of these should be inline or macros.  Later.  */
273
 
274
/* Initialize cycle counting for an insn.
275
   FIRST_P is non-zero if this is the first insn in a set of parallel
276
   insns.  */
277
 
278
void
279
m32rbf_model_insn_before (SIM_CPU *cpu, int first_p)
280
{
281
  M32R_MISC_PROFILE *mp = CPU_M32R_MISC_PROFILE (cpu);
282
  mp->cti_stall = 0;
283
  mp->load_stall = 0;
284
  if (first_p)
285
    {
286
      mp->load_regs_pending = 0;
287
      mp->biggest_cycles = 0;
288
    }
289
}
290
 
291
/* Record the cycles computed for an insn.
292
   LAST_P is non-zero if this is the last insn in a set of parallel insns,
293
   and we update the total cycle count.
294
   CYCLES is the cycle count of the insn.  */
295
 
296
void
297
m32rbf_model_insn_after (SIM_CPU *cpu, int last_p, int cycles)
298
{
299
  PROFILE_DATA *p = CPU_PROFILE_DATA (cpu);
300
  M32R_MISC_PROFILE *mp = CPU_M32R_MISC_PROFILE (cpu);
301
  unsigned long total = cycles + mp->cti_stall + mp->load_stall;
302
 
303
  if (last_p)
304
    {
305
      unsigned long biggest = total > mp->biggest_cycles ? total : mp->biggest_cycles;
306
      PROFILE_MODEL_TOTAL_CYCLES (p) += biggest;
307
      PROFILE_MODEL_CUR_INSN_CYCLES (p) = total;
308
    }
309
  else
310
    {
311
      /* Here we take advantage of the fact that !last_p -> first_p.  */
312
      mp->biggest_cycles = total;
313
      PROFILE_MODEL_CUR_INSN_CYCLES (p) = total;
314
    }
315
 
316
  /* Branch and load stall counts are recorded independently of the
317
     total cycle count.  */
318
  PROFILE_MODEL_CTI_STALL_CYCLES (p) += mp->cti_stall;
319
  PROFILE_MODEL_LOAD_STALL_CYCLES (p) += mp->load_stall;
320
 
321
  mp->load_regs = mp->load_regs_pending;
322
}
323
 
324
static INLINE void
325
check_load_stall (SIM_CPU *cpu, int regno)
326
{
327
  UINT h_gr = CPU_M32R_MISC_PROFILE (cpu)->load_regs;
328
 
329
  if (regno != -1
330
      && (h_gr & (1 << regno)) != 0)
331
    {
332
      CPU_M32R_MISC_PROFILE (cpu)->load_stall += 2;
333
      if (TRACE_INSN_P (cpu))
334
        cgen_trace_printf (cpu, " ; Load stall of 2 cycles.");
335
    }
336
}
337
 
338
int
339
m32rbf_model_m32r_d_u_exec (SIM_CPU *cpu, const IDESC *idesc,
340
                            int unit_num, int referenced,
341
                            INT sr, INT sr2, INT dr)
342
{
343
  check_load_stall (cpu, sr);
344
  check_load_stall (cpu, sr2);
345
  return idesc->timing->units[unit_num].done;
346
}
347
 
348
int
349
m32rbf_model_m32r_d_u_cmp (SIM_CPU *cpu, const IDESC *idesc,
350
                           int unit_num, int referenced,
351
                           INT src1, INT src2)
352
{
353
  check_load_stall (cpu, src1);
354
  check_load_stall (cpu, src2);
355
  return idesc->timing->units[unit_num].done;
356
}
357
 
358
int
359
m32rbf_model_m32r_d_u_mac (SIM_CPU *cpu, const IDESC *idesc,
360
                           int unit_num, int referenced,
361
                           INT src1, INT src2)
362
{
363
  check_load_stall (cpu, src1);
364
  check_load_stall (cpu, src2);
365
  return idesc->timing->units[unit_num].done;
366
}
367
 
368
int
369
m32rbf_model_m32r_d_u_cti (SIM_CPU *cpu, const IDESC *idesc,
370
                           int unit_num, int referenced,
371
                           INT sr)
372
{
373
  PROFILE_DATA *profile = CPU_PROFILE_DATA (cpu);
374
  int taken_p = (referenced & (1 << 1)) != 0;
375
 
376
  check_load_stall (cpu, sr);
377
  if (taken_p)
378
    {
379
      CPU_M32R_MISC_PROFILE (cpu)->cti_stall += 2;
380
      PROFILE_MODEL_TAKEN_COUNT (profile) += 1;
381
    }
382
  else
383
    PROFILE_MODEL_UNTAKEN_COUNT (profile) += 1;
384
  return idesc->timing->units[unit_num].done;
385
}
386
 
387
int
388
m32rbf_model_m32r_d_u_load (SIM_CPU *cpu, const IDESC *idesc,
389
                            int unit_num, int referenced,
390
                            INT sr, INT dr)
391
{
392
  CPU_M32R_MISC_PROFILE (cpu)->load_regs_pending |= (1 << dr);
393
  check_load_stall (cpu, sr);
394
  return idesc->timing->units[unit_num].done;
395
}
396
 
397
int
398
m32rbf_model_m32r_d_u_store (SIM_CPU *cpu, const IDESC *idesc,
399
                             int unit_num, int referenced,
400
                             INT src1, INT src2)
401
{
402
  check_load_stall (cpu, src1);
403
  check_load_stall (cpu, src2);
404
  return idesc->timing->units[unit_num].done;
405
}
406
 
407
int
408
m32rbf_model_test_u_exec (SIM_CPU *cpu, const IDESC *idesc,
409
                          int unit_num, int referenced)
410
{
411
  return idesc->timing->units[unit_num].done;
412
}
413
 
414
#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.