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

Subversion Repositories or1k

[/] [or1k/] [tags/] [rel-0-3-0-rc1/] [or1ksim/] [cpu/] [or32/] [execute.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 cvs
/* execute.c -- OR1K architecture dependent simulation
2 1744 jeremybenn
 
3 2 cvs
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
4 1346 nogj
   Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
5 1744 jeremybenn
   Copyright (C) 2008 Embecosm Limited
6
 
7
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
8
 
9
   This file is part of OpenRISC 1000 Architectural Simulator.
10
 
11
   This program is free software; you can redistribute it and/or modify it
12
   under the terms of the GNU General Public License as published by the Free
13
   Software Foundation; either version 3 of the License, or (at your option)
14
   any later version.
15
 
16
   This program is distributed in the hope that it will be useful, but WITHOUT
17
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
19
   more details.
20
 
21
   You should have received a copy of the GNU General Public License along
22
   with this program.  If not, see <http://www.gnu.org/licenses/>. */
23 2 cvs
 
24 1748 jeremybenn
/* This program is commented throughout in a fashion suitable for processing
25
   with Doxygen. */
26 2 cvs
 
27 1748 jeremybenn
 
28 706 markom
/* Most of the OR1K simulation is done in here.
29 2 cvs
 
30 706 markom
   When SIMPLE_EXECUTION is defined below a file insnset.c is included!
31
*/
32
 
33 1748 jeremybenn
/* Autoconf and/or portability configuration */
34 123 markom
#include "config.h"
35 1748 jeremybenn
#include "port.h"
36 1350 nogj
 
37 1748 jeremybenn
/* System includes */
38
#include <stdlib.h>
39 1350 nogj
 
40 1748 jeremybenn
/* Package includes */
41
#include "execute.h"
42
#include "toplevel-support.h"
43
#include "except.h"
44 261 markom
#include "labels.h"
45 1748 jeremybenn
#include "gdbcomm.h"
46
#include "sched.h"
47
#include "stats.h"
48 1308 phoenix
#include "opcode/or32.h"
49 1748 jeremybenn
#include "dmmu.h"
50 1308 phoenix
#include "immu.h"
51 1748 jeremybenn
#include "sim-cmd.h"
52 1690 nogj
#include "vapi.h"
53 1748 jeremybenn
#include "debug-unit.h"
54
#include "branch-predict.h"
55
#include "support/simprintf.h"
56
#include "sprs.h"
57 2 cvs
 
58
 
59 1748 jeremybenn
/* Sets a new SPR_SR_OV value, based on next register value */
60
#if SET_OV_FLAG
61
#define SET_OV_FLAG_FN(value) \
62
  if((value) & 0x80000000) \
63
    cpu_state.sprs[SPR_SR] |= SPR_SR_OV; \
64
  else \
65
    cpu_state.sprs[SPR_SR] &= ~SPR_SR_OV
66
#else
67
#define SET_OV_FLAG_FN(value)
68
#endif
69 2 cvs
 
70 1748 jeremybenn
/* Macros for simple execution */
71
#if SIMPLE_EXECUTION
72
#define SET_PARAM0(val) set_operand(0, val, current->insn_index, current->insn)
73 2 cvs
 
74 1748 jeremybenn
#define PARAM0 eval_operand(0, current->insn_index, current->insn)
75
#define PARAM1 eval_operand(1, current->insn_index, current->insn)
76
#define PARAM2 eval_operand(2, current->insn_index, current->insn)
77
#endif
78 626 markom
 
79 1748 jeremybenn
/*! Current cpu state. Globally available. */
80
struct cpu_state  cpu_state;
81 626 markom
 
82 1748 jeremybenn
/*! Temporary program counter. Globally available */
83
oraddr_t  pcnext;
84 626 markom
 
85 1748 jeremybenn
/*! Num cycles waiting for stores to complete. Globally available */
86
int  sbuf_wait_cyc = 0;
87 714 markom
 
88 1748 jeremybenn
/*! Number of total store cycles. Globally available */
89
int  sbuf_total_cyc = 0;
90
 
91
/*! Whether we are doing statistical analysis. Globally available */
92
int  do_stats = 0;
93
 
94
/*! History of execution. Globally available */
95
struct hist_exec *hist_exec_tail = NULL;
96
 
97
/* Benchmark multi issue execution. This file only */
98
static int  multissue[20];
99
static int  issued_per_cycle = 4;
100
 
101
/* Store buffer analysis - stores are accumulated and commited when IO is
102
   idle. This file only */
103
static int  sbuf_head              = 0;
104
static int  sbuf_tail              = 0;
105
static int  sbuf_count             = 0;
106
static int  sbuf_buf[MAX_SBUF_LEN] = { 0 };
107
 
108
static int sbuf_prev_cycles = 0;
109
 
110 138 markom
/* Local data needed for execution.  */
111
static int next_delay_insn;
112
static int breakpoint;
113
 
114 1748 jeremybenn
/* Forward declaration of static functions */
115
static void decode_execute (struct iqueue_entry *current);
116 1346 nogj
 
117 1748 jeremybenn
/*---------------------------------------------------------------------------*/
118
/*!Get an actual value of a specific register
119 1352 nogj
 
120 1748 jeremybenn
   Implementation specific. Abort if we are given a duff register. Only used
121
   externally to support simprintf().
122 2 cvs
 
123 1748 jeremybenn
   @param[in] regno  The register of interest
124
 
125
   @return  The value of the register                                        */
126
/*---------------------------------------------------------------------------*/
127
uorreg_t
128
evalsim_reg (unsigned int  regno)
129 2 cvs
{
130 1748 jeremybenn
  if (regno < MAX_GPRS)
131
    {
132
#if RAW_RANGE_STATS
133
      int delta = (runtime.sim.cycles - raw_stats.reg[regno]);
134 560 markom
 
135 1748 jeremybenn
      if ((unsigned long) delta < (unsigned long) MAX_RAW_RANGE)
136
        {
137
          raw_stats.range[delta]++;
138
        }
139
#endif /* RAW_RANGE */
140 560 markom
 
141 1748 jeremybenn
      return cpu_state.reg[regno];
142
    }
143
  else
144
    {
145
      PRINTF ("\nABORT: read out of registers\n");
146
      sim_done ();
147
      return 0;
148
    }
149
}       /* evalsim_reg() */
150 560 markom
 
151 2 cvs
 
152 1748 jeremybenn
/*---------------------------------------------------------------------------*/
153
/*!Set a specific register with value
154
 
155
   Implementation specific. Abort if we are given a duff register.
156
 
157
   @param[in] regno  The register of interest
158
   @param[in] value  The value to be set                                     */
159
/*---------------------------------------------------------------------------*/
160
void
161
setsim_reg (unsigned int  regno,
162
            uorreg_t      value)
163 2 cvs
{
164 1748 jeremybenn
  if (regno == 0)                /* gpr0 is always zero */
165
    {
166
      value = 0;
167
    }
168 560 markom
 
169 1748 jeremybenn
  if (regno < MAX_GPRS)
170
    {
171
      cpu_state.reg[regno] = value;
172
    }
173
  else
174
    {
175
      PRINTF ("\nABORT: write out of registers\n");
176
      sim_done ();
177
    }
178
 
179 713 markom
#if RAW_RANGE_STATS
180 1748 jeremybenn
  raw_stats.reg[regno] = runtime.sim.cycles;
181 713 markom
#endif /* RAW_RANGE */
182 2 cvs
 
183 1748 jeremybenn
}       /* setsim_reg() */
184 1346 nogj
 
185 1748 jeremybenn
 
186
/*---------------------------------------------------------------------------*/
187
/*!Evaluates source operand operand
188
 
189
   Implementation specific. Declared global, although this is only actually
190
   required for DYNAMIC_EXECUTION,
191
 
192
   @param[in] insn  The instruction
193
   @param[in] opd   The operand
194
 
195
   @return  The value of the source operand                                  */
196
/*---------------------------------------------------------------------------*/
197
uorreg_t
198
eval_operand_val (uint32_t               insn,
199
                  struct insn_op_struct *opd)
200 1346 nogj
{
201 1748 jeremybenn
  unsigned long  operand = 0;
202
  unsigned long  sbit;
203
  unsigned int   nbits = 0;
204 1346 nogj
 
205 1748 jeremybenn
  while (1)
206
    {
207
      operand |=
208
        ((insn >> (opd->type & OPTYPE_SHR)) & ((1 << opd->data) - 1)) <<
209
        nbits;
210
      nbits += opd->data;
211 1346 nogj
 
212 1748 jeremybenn
      if (opd->type & OPTYPE_OP)
213
        {
214
          break;
215
        }
216 1346 nogj
 
217 1748 jeremybenn
      opd++;
218
    }
219 1346 nogj
 
220 1748 jeremybenn
  if (opd->type & OPTYPE_SIG)
221
    {
222
      sbit = (opd->type & OPTYPE_SBIT) >> OPTYPE_SBIT_SHR;
223
 
224
      if (operand & (1 << sbit))
225
        {
226
          operand |= ~REG_C (0) << sbit;
227
        }
228
    }
229
 
230 1346 nogj
  return operand;
231
 
232 1748 jeremybenn
}       /* eval_operand_val() */
233 2 cvs
 
234
 
235 1748 jeremybenn
/*---------------------------------------------------------------------------*/
236
/*!Does source operand depend on computation of dest operand?
237
 
238
      Cycle t                 Cycle t+1
239
  dst: irrelevant         src: immediate                  always 0
240
  dst: reg1 direct        src: reg2 direct                0 if reg1 != reg2
241
  dst: reg1 disp          src: reg2 direct                always 0
242
  dst: reg1 direct        src: reg2 disp                  0 if reg1 != reg2
243
  dst: reg1 disp          src: reg2 disp                  always 1 (store must
244
                                                          finish before load)
245
  dst: flag               src: flag                       always 1
246
 
247
  @param[in] prev  Previous instruction
248
  @param[in] next  Next instruction
249
 
250
  @return  Non-zero if yes.                                                  */
251
/*---------------------------------------------------------------------------*/
252
static int
253
check_depend (struct iqueue_entry *prev,
254
              struct iqueue_entry *next)
255 2 cvs
{
256 138 markom
  /* Find destination type. */
257 1748 jeremybenn
  unsigned long          type = 0;
258
  int                    prev_dis;
259
  int                    next_dis;
260
  orreg_t                prev_reg_val = 0;
261 1346 nogj
  struct insn_op_struct *opd;
262
 
263 138 markom
  if (or32_opcodes[prev->insn_index].flags & OR32_W_FLAG
264
      && or32_opcodes[next->insn_index].flags & OR32_R_FLAG)
265 1748 jeremybenn
    {
266
      return  1;
267
    }
268 2 cvs
 
269 1748 jeremybenn
  opd      = op_start[prev->insn_index];
270 1346 nogj
  prev_dis = 0;
271 560 markom
 
272 1748 jeremybenn
  while (1)
273
    {
274
      if (opd->type & OPTYPE_DIS)
275
        {
276
          prev_dis = 1;
277
        }
278 1346 nogj
 
279 1748 jeremybenn
      if (opd->type & OPTYPE_DST)
280
        {
281
          type = opd->type;
282
 
283
          if (prev_dis)
284
            {
285
              type |= OPTYPE_DIS;
286
            }
287
 
288
          /* Destination is always a register */
289
          prev_reg_val = eval_operand_val (prev->insn, opd);
290
          break;
291
        }
292
 
293
      if (opd->type & OPTYPE_LAST)
294
        {
295
          return 0;              /* Doesn't have a destination operand */
296
        }
297
 
298
      if (opd->type & OPTYPE_OP)
299
        {
300
          prev_dis = 0;
301
        }
302
 
303
      opd++;
304 1346 nogj
    }
305
 
306 138 markom
  /* We search all source operands - if we find confict => return 1 */
307 1748 jeremybenn
  opd      = op_start[next->insn_index];
308 1346 nogj
  next_dis = 0;
309
 
310 1748 jeremybenn
  while (1)
311
    {
312
      if (opd->type & OPTYPE_DIS)
313
        {
314
          next_dis = 1;
315
        }
316
 
317
      /* This instruction sequence also depends on order of execution:
318
           l.lw r1, k(r1)
319
           l.sw k(r1), r4
320
         Here r1 is a destination in l.sw */
321
 
322
      /* FIXME: This situation is not handeld here when r1 == r2:
323
           l.sw k(r1), r4
324
           l.lw r3, k(r2) */
325
      if (!(opd->type & OPTYPE_DST) || (next_dis && (opd->type & OPTYPE_DST)))
326
        {
327
          if (opd->type & OPTYPE_REG)
328
            {
329
              if (eval_operand_val (next->insn, opd) == prev_reg_val)
330
                {
331
                  return 1;
332
                }
333
            }
334
        }
335
 
336
      if (opd->type & OPTYPE_LAST)
337
        {
338
          break;
339
        }
340
 
341
      opd++;
342 1346 nogj
    }
343
 
344 1748 jeremybenn
  return  0;
345 2 cvs
 
346 1748 jeremybenn
}       /* check_depend() */
347 2 cvs
 
348 605 markom
 
349 1748 jeremybenn
/*---------------------------------------------------------------------------*/
350
/*!Should instruction NOT be executed?
351
 
352
   Modified by CZ 26/05/01 for new mode execution.
353
 
354
   @return  Nonzero if instruction should NOT be executed                    */
355
/*---------------------------------------------------------------------------*/
356
static int
357
fetch ()
358 557 markom
{
359 1386 nogj
  static int break_just_hit = 0;
360 574 markom
 
361 1748 jeremybenn
  if (NULL != breakpoints)
362
    {
363
      /* MM: Check for breakpoint.  This has to be done in fetch cycle,
364
         because of peripheria.
365
         MM1709: if we cannot access the memory entry, we could not set the
366
         breakpoint earlier, so just check the breakpoint list.  */
367
      if (has_breakpoint (peek_into_itlb (cpu_state.pc)) && !break_just_hit)
368
        {
369
          break_just_hit = 1;
370
          return 1;             /* Breakpoint set. */
371
        }
372
      break_just_hit = 0;
373 557 markom
    }
374 1244 hpanther
 
375 1748 jeremybenn
  breakpoint                 = 0;
376 1482 nogj
  cpu_state.iqueue.insn_addr = cpu_state.pc;
377 1748 jeremybenn
  cpu_state.iqueue.insn      = eval_insn (cpu_state.pc, &breakpoint);
378 1482 nogj
 
379 378 markom
  /* Fetch instruction. */
380 1386 nogj
  if (!except_pending)
381 1748 jeremybenn
    {
382
      runtime.cpu.instructions++;
383
    }
384 1386 nogj
 
385 378 markom
  /* update_pc will be called after execution */
386
  return 0;
387 2 cvs
 
388 1748 jeremybenn
}       /* fetch() */
389
 
390
 
391
/*---------------------------------------------------------------------------*/
392
/*!This code actually updates the PC value                                   */
393
/*---------------------------------------------------------------------------*/
394
static void
395
update_pc ()
396 142 chris
{
397 1748 jeremybenn
  cpu_state.delay_insn    = next_delay_insn;
398
  cpu_state.sprs[SPR_PPC] = cpu_state.pc;       /* Store value for later */
399
  cpu_state.pc            = pcnext;
400
  pcnext                  = cpu_state.delay_insn ? cpu_state.pc_delay :
401
                                                   pcnext + 4;
402
}       /* update_pc() */
403 2 cvs
 
404 1748 jeremybenn
 
405
/*---------------------------------------------------------------------------*/
406
/*!Perform analysis of the instruction being executed
407
 
408
   This could be static for SIMPLE_EXECUTION, but made global for general use.
409
 
410
   @param[in] current  The instruction being executed                        */
411
/*---------------------------------------------------------------------------*/
412
void
413
analysis (struct iqueue_entry *current)
414 2 cvs
{
415 1748 jeremybenn
  if (config.cpu.dependstats)
416
    {
417
      /* Dynamic, dependency stats. */
418
      adddstats (cpu_state.icomplet.insn_index, current->insn_index, 1,
419
                 check_depend (&cpu_state.icomplet, current));
420 713 markom
 
421 1748 jeremybenn
      /* Dynamic, functional units stats. */
422
      addfstats (or32_opcodes[cpu_state.icomplet.insn_index].func_unit,
423
                 or32_opcodes[current->insn_index].func_unit, 1,
424
                 check_depend (&cpu_state.icomplet, current));
425 713 markom
 
426 1748 jeremybenn
      /* Dynamic, single stats. */
427
      addsstats (current->insn_index, 1);
428
    }
429 713 markom
 
430 1748 jeremybenn
  if (config.cpu.superscalar)
431
    {
432
      if ((or32_opcodes[current->insn_index].func_unit == it_branch) ||
433
          (or32_opcodes[current->insn_index].func_unit == it_jump))
434
        runtime.sim.storecycles += 0;
435
 
436
      if (or32_opcodes[current->insn_index].func_unit == it_store)
437
        runtime.sim.storecycles += 1;
438
 
439
      if (or32_opcodes[current->insn_index].func_unit == it_load)
440
        runtime.sim.loadcycles += 1;
441
 
442
      /* Pseudo multiple issue benchmark */
443
      if ((multissue[or32_opcodes[current->insn_index].func_unit] < 1) ||
444
          (check_depend (&cpu_state.icomplet, current))
445
          || (issued_per_cycle < 1))
446
        {
447
          int i;
448
          for (i = 0; i < 20; i++)
449
            multissue[i] = 2;
450
          issued_per_cycle = 2;
451
          runtime.cpu.supercycles++;
452
          if (check_depend (&cpu_state.icomplet, current))
453
            runtime.cpu.hazardwait++;
454
          multissue[it_unknown] = 2;
455
          multissue[it_shift] = 2;
456
          multissue[it_compare] = 1;
457
          multissue[it_branch] = 1;
458
          multissue[it_jump] = 1;
459
          multissue[it_extend] = 2;
460
          multissue[it_nop] = 2;
461
          multissue[it_move] = 2;
462
          multissue[it_movimm] = 2;
463
          multissue[it_arith] = 2;
464
          multissue[it_store] = 2;
465
          multissue[it_load] = 2;
466
        }
467
      multissue[or32_opcodes[current->insn_index].func_unit]--;
468
      issued_per_cycle--;
469 713 markom
    }
470 1748 jeremybenn
 
471 394 markom
  if (config.cpu.dependstats)
472 123 markom
    /* Instruction waits in completition buffer until retired. */
473 1432 nogj
    memcpy (&cpu_state.icomplet, current, sizeof (struct iqueue_entry));
474 138 markom
 
475 1748 jeremybenn
  if (config.sim.history)
476
    {
477
      /* History of execution */
478
      hist_exec_tail = hist_exec_tail->next;
479
      hist_exec_tail->addr = cpu_state.icomplet.insn_addr;
480
    }
481 714 markom
 
482 1748 jeremybenn
  if (config.sim.exe_log)
483
    dump_exe_log ();
484 2 cvs
 
485 1748 jeremybenn
}       /* analysis() */
486
 
487
/*---------------------------------------------------------------------------*/
488
/*!Store buffer analysis for store instructions
489
 
490
   Stores are accumulated and commited when IO is idle
491
 
492
   @param[in] cyc  Number of cycles being analysed                           */
493
/*---------------------------------------------------------------------------*/
494
static void
495
sbuf_store (int cyc)
496
{
497 884 markom
  int delta = runtime.sim.cycles - sbuf_prev_cycles;
498 1748 jeremybenn
 
499
  sbuf_total_cyc   += cyc;
500
  sbuf_prev_cycles  = runtime.sim.cycles;
501
 
502 626 markom
  /* Take stores from buffer, that occured meanwhile */
503 1748 jeremybenn
  while (sbuf_count && delta >= sbuf_buf[sbuf_tail])
504
    {
505
      delta     -= sbuf_buf[sbuf_tail];
506
      sbuf_tail  = (sbuf_tail + 1) % MAX_SBUF_LEN;
507
      sbuf_count--;
508
    }
509
 
510 626 markom
  if (sbuf_count)
511 1748 jeremybenn
    {
512
      sbuf_buf[sbuf_tail] -= delta;
513
    }
514 630 markom
 
515 626 markom
  /* Store buffer is full, take one out */
516 1748 jeremybenn
  if (sbuf_count >= config.cpu.sbuf_len)
517
    {
518
      sbuf_wait_cyc          += sbuf_buf[sbuf_tail];
519
      runtime.sim.mem_cycles += sbuf_buf[sbuf_tail];
520
      sbuf_prev_cycles       += sbuf_buf[sbuf_tail];
521
      sbuf_tail               = (sbuf_tail + 1) % MAX_SBUF_LEN;
522
      sbuf_count--;
523
    }
524
 
525 626 markom
  /* Put newest store in the buffer */
526
  sbuf_buf[sbuf_head] = cyc;
527 1748 jeremybenn
  sbuf_head           = (sbuf_head + 1) % MAX_SBUF_LEN;
528 626 markom
  sbuf_count++;
529 294 markom
 
530 1748 jeremybenn
}       /* sbuf_store() */
531
 
532
 
533
/*---------------------------------------------------------------------------*/
534
/*!Store buffer analysis for load instructions
535
 
536
   Previous stores should commit, before any load                            */
537
/*---------------------------------------------------------------------------*/
538
static void
539
sbuf_load ()
540
{
541 884 markom
  int delta = runtime.sim.cycles - sbuf_prev_cycles;
542
  sbuf_prev_cycles = runtime.sim.cycles;
543 1748 jeremybenn
 
544 629 markom
  /* Take stores from buffer, that occured meanwhile */
545 1748 jeremybenn
  while (sbuf_count && delta >= sbuf_buf[sbuf_tail])
546
    {
547
      delta     -= sbuf_buf[sbuf_tail];
548
      sbuf_tail  = (sbuf_tail + 1) % MAX_SBUF_LEN;
549
      sbuf_count--;
550
    }
551
 
552 629 markom
  if (sbuf_count)
553 1748 jeremybenn
    {
554
      sbuf_buf[sbuf_tail] -= delta;
555
    }
556 629 markom
 
557 626 markom
  /* Wait for all stores to complete */
558 1748 jeremybenn
  while (sbuf_count > 0)
559
    {
560
      sbuf_wait_cyc          += sbuf_buf[sbuf_tail];
561
      runtime.sim.mem_cycles += sbuf_buf[sbuf_tail];
562
      sbuf_prev_cycles       += sbuf_buf[sbuf_tail];
563
      sbuf_tail               = (sbuf_tail + 1) % MAX_SBUF_LEN;
564
      sbuf_count--;
565
    }
566
}       /* sbuf_load() */
567 626 markom
 
568 1748 jeremybenn
 
569
/*---------------------------------------------------------------------------*/
570
/*!Outputs dissasembled instruction                                          */
571
/*---------------------------------------------------------------------------*/
572
void
573
dump_exe_log ()
574 294 markom
{
575 1748 jeremybenn
  oraddr_t      insn_addr = cpu_state.iqueue.insn_addr;
576
  unsigned int  i;
577
  unsigned int  j;
578
  uorreg_t      operand;
579 294 markom
 
580 1748 jeremybenn
  if (insn_addr == 0xffffffff)
581
    {
582
      return;
583
    }
584
 
585 1346 nogj
  if ((config.sim.exe_log_start <= runtime.cpu.instructions) &&
586
      ((config.sim.exe_log_end <= 0) ||
587 1748 jeremybenn
       (runtime.cpu.instructions <= config.sim.exe_log_end)))
588
    {
589
      struct label_entry *entry;
590 714 markom
 
591 1748 jeremybenn
      if (config.sim.exe_log_marker &&
592
          !(runtime.cpu.instructions % config.sim.exe_log_marker))
593
        {
594
          fprintf (runtime.sim.fexe_log,
595
                   "--------------------- %8lli instruction "
596
                   "---------------------\n",
597
                   runtime.cpu.instructions);
598
        }
599
 
600
      switch (config.sim.exe_log_type)
601
        {
602
        case EXE_LOG_HARDWARE:
603
          fprintf (runtime.sim.fexe_log,
604
                   "\nEXECUTED(%11llu): %" PRIxADDR ":  ",
605
                   runtime.cpu.instructions, insn_addr);
606
          fprintf (runtime.sim.fexe_log, "%.2x%.2x",
607
                   eval_direct8 (insn_addr, 0, 0),
608
                   eval_direct8 (insn_addr + 1, 0, 0));
609
          fprintf (runtime.sim.fexe_log, "%.2x%.2x",
610
                   eval_direct8 (insn_addr + 2, 0, 0),
611
                   eval_direct8 (insn_addr + 3, 0, 0));
612
 
613
          for (i = 0; i < MAX_GPRS; i++)
614
            {
615
              if (i % 4 == 0)
616
                {
617
                  fprintf (runtime.sim.fexe_log, "\n");
618
                }
619
 
620
              fprintf (runtime.sim.fexe_log, "GPR%2u: %" PRIxREG "  ", i,
621
                       cpu_state.reg[i]);
622
            }
623
 
624
          fprintf (runtime.sim.fexe_log, "\n");
625
          fprintf (runtime.sim.fexe_log, "SR   : %.8" PRIx32 "  ",
626
                   cpu_state.sprs[SPR_SR]);
627
          fprintf (runtime.sim.fexe_log, "EPCR0: %" PRIxADDR "  ",
628
                   cpu_state.sprs[SPR_EPCR_BASE]);
629
          fprintf (runtime.sim.fexe_log, "EEAR0: %" PRIxADDR "  ",
630
                   cpu_state.sprs[SPR_EEAR_BASE]);
631
          fprintf (runtime.sim.fexe_log, "ESR0 : %.8" PRIx32 "\n",
632
                   cpu_state.sprs[SPR_ESR_BASE]);
633
          break;
634
 
635
        case EXE_LOG_SIMPLE:
636
        case EXE_LOG_SOFTWARE:
637
          disassemble_index (cpu_state.iqueue.insn,
638
                             cpu_state.iqueue.insn_index);
639
 
640
          entry = get_label (insn_addr);
641
          if (entry)
642
            {
643
              fprintf (runtime.sim.fexe_log, "%s:\n", entry->name);
644
            }
645
 
646
          if (config.sim.exe_log_type == EXE_LOG_SOFTWARE)
647
            {
648
              struct insn_op_struct *opd =
649
                op_start[cpu_state.iqueue.insn_index];
650
 
651
              j = 0;
652
              while (1)
653
                {
654
                  operand = eval_operand_val (cpu_state.iqueue.insn, opd);
655
                  while (!(opd->type & OPTYPE_OP))
656
                    {
657
                      opd++;
658
                    }
659
                  if (opd->type & OPTYPE_DIS)
660
                    {
661
                      fprintf (runtime.sim.fexe_log,
662
                               "EA =%" PRIxADDR " PA =%" PRIxADDR " ",
663
                               cpu_state.insn_ea,
664
                               peek_into_dtlb (cpu_state.insn_ea, 0, 0));
665
                      opd++;    /* Skip of register operand */
666
                      j++;
667
                    }
668
                  else if ((opd->type & OPTYPE_REG) && operand)
669
                    {
670
                      fprintf (runtime.sim.fexe_log, "r%-2i=%" PRIxREG " ",
671
                               (int) operand, evalsim_reg (operand));
672
                    }
673
                  else
674
                    {
675
                      fprintf (runtime.sim.fexe_log, "             ");
676
                    }
677
                  j++;
678
                  if (opd->type & OPTYPE_LAST)
679
                    {
680
                      break;
681
                    }
682
                  opd++;
683
                }
684
              if (or32_opcodes[cpu_state.iqueue.insn_index].flags & OR32_R_FLAG)
685
                {
686
                  fprintf (runtime.sim.fexe_log, "SR =%08x ",
687
                           cpu_state.sprs[SPR_SR]);
688
                  j++;
689
                }
690
              while (j < 3)
691
                {
692
                  fprintf (runtime.sim.fexe_log, "             ");
693
                  j++;
694
                }
695
            }
696
          fprintf (runtime.sim.fexe_log, "%" PRIxADDR " ", insn_addr);
697
          fprintf (runtime.sim.fexe_log, "%s\n", disassembled);
698
        }
699 672 markom
    }
700 1748 jeremybenn
}       /* dump_exe_log() */
701 294 markom
 
702 1748 jeremybenn
 
703
/*---------------------------------------------------------------------------*/
704
/*!Dump registers
705
 
706
   Supports the CLI 'r' and 't' commands                                     */
707
/*---------------------------------------------------------------------------*/
708
void
709
dumpreg ()
710 2 cvs
{
711 1748 jeremybenn
  int       i;
712
  oraddr_t  physical_pc;
713 269 markom
 
714 1748 jeremybenn
  if ((physical_pc = peek_into_itlb (cpu_state.iqueue.insn_addr)))
715
    {
716
      disassemble_memory (physical_pc, physical_pc + 4, 0);
717
    }
718
  else
719
    {
720
      PRINTF ("INTERNAL SIMULATOR ERROR:\n");
721
      PRINTF ("no translation for currently executed instruction\n");
722
    }
723
 
724 1319 phoenix
  // generate_time_pretty (temp, runtime.sim.cycles * config.sim.clkcycle_ps);
725 1748 jeremybenn
  PRINTF (" (executed) [cycle %lld, #%lld]\n", runtime.sim.cycles,
726
          runtime.cpu.instructions);
727 293 markom
  if (config.cpu.superscalar)
728 1748 jeremybenn
    {
729
      PRINTF ("Superscalar CYCLES: %u", runtime.cpu.supercycles);
730
    }
731 293 markom
  if (config.cpu.hazards)
732 1748 jeremybenn
    {
733
      PRINTF ("  HAZARDWAIT: %u\n", runtime.cpu.hazardwait);
734
    }
735
  else if (config.cpu.superscalar)
736
    {
737 997 markom
      PRINTF ("\n");
738 1748 jeremybenn
    }
739 293 markom
 
740 1748 jeremybenn
  if ((physical_pc = peek_into_itlb (cpu_state.pc)))
741
    {
742
      disassemble_memory (physical_pc, physical_pc + 4, 0);
743
    }
744 1174 phoenix
  else
745 1748 jeremybenn
    {
746
      PRINTF ("%" PRIxADDR ": : xxxxxxxx  ITLB miss follows", cpu_state.pc);
747
    }
748 123 markom
 
749 1748 jeremybenn
  PRINTF (" (next insn) %s", (cpu_state.delay_insn ? "(delay insn)" : ""));
750 706 markom
 
751 1748 jeremybenn
  for (i = 0; i < MAX_GPRS; i++)
752
    {
753
      if (i % 4 == 0)
754
        {
755
          PRINTF ("\n");
756
        }
757
 
758
      PRINTF ("GPR%.2u: %" PRIxREG "  ", i, evalsim_reg (i));
759
    }
760
 
761
  PRINTF ("flag: %u\n", cpu_state.sprs[SPR_SR] & SPR_SR_F ? 1 : 0);
762
 
763
}       /* dumpreg() */
764
 
765
 
766
/*---------------------------------------------------------------------------*/
767
/*!Wrapper around real decode_execute function
768
 
769
   Some statistics here only
770
 
771
   @param[in] current  Instruction being executed                            */
772
/*---------------------------------------------------------------------------*/
773
static void
774
decode_execute_wrapper (struct iqueue_entry *current)
775 123 markom
{
776 712 markom
  breakpoint = 0;
777 138 markom
 
778 1748 jeremybenn
#ifndef HAVE_EXECUTION
779
#error HAVE_EXECUTION has to be defined in order to execute programs.
780 123 markom
#endif
781 1748 jeremybenn
 
782 1452 nogj
  /* FIXME: Most of this file is not needed with DYNAMIC_EXECUTION */
783
#if !(DYNAMIC_EXECUTION)
784 712 markom
  decode_execute (current);
785 1452 nogj
#endif
786 1748 jeremybenn
 
787 717 markom
#if SET_OV_FLAG
788 458 simons
  /* Check for range exception */
789 1748 jeremybenn
  if ((cpu_state.sprs[SPR_SR] & SPR_SR_OVE) &&
790
      (cpu_state.sprs[SPR_SR] & SPR_SR_OV))
791
    {
792
      except_handle (EXCEPT_RANGE, cpu_state.sprs[SPR_EEAR_BASE]);
793
    }
794 717 markom
#endif
795 458 simons
 
796 1748 jeremybenn
  if (breakpoint)
797
    {
798
      except_handle (EXCEPT_TRAP, cpu_state.sprs[SPR_EEAR_BASE]);
799
    }
800
}       /* decode_execute_wrapper() */
801 123 markom
 
802 1748 jeremybenn
/*---------------------------------------------------------------------------*/
803
/*!Reset the CPU                                                             */
804
/*---------------------------------------------------------------------------*/
805
void
806
cpu_reset ()
807 557 markom
{
808 1748 jeremybenn
  int               i;
809 1352 nogj
  struct hist_exec *hist_exec_head = NULL;
810
  struct hist_exec *hist_exec_new;
811
 
812 1748 jeremybenn
  runtime.sim.cycles       = 0;
813
  runtime.sim.loadcycles   = 0;
814
  runtime.sim.storecycles  = 0;
815 884 markom
  runtime.cpu.instructions = 0;
816 1748 jeremybenn
  runtime.cpu.supercycles  = 0;
817
  runtime.cpu.hazardwait   = 0;
818
 
819 606 markom
  for (i = 0; i < MAX_GPRS; i++)
820 1748 jeremybenn
    {
821
      setsim_reg (i, 0);
822
    }
823
 
824
  memset (&cpu_state.iqueue,   0, sizeof (cpu_state.iqueue));
825
  memset (&cpu_state.icomplet, 0, sizeof (cpu_state.icomplet));
826
 
827
  sbuf_head        = 0;
828
  sbuf_tail        = 0;
829
  sbuf_count       = 0;
830 626 markom
  sbuf_prev_cycles = 0;
831 557 markom
 
832 1352 nogj
  /* Initialise execution history circular buffer */
833 1748 jeremybenn
  for (i = 0; i < HISTEXEC_LEN; i++)
834
    {
835
      hist_exec_new = malloc (sizeof (struct hist_exec));
836
 
837
      if (!hist_exec_new)
838
        {
839
          fprintf (stderr, "Out-of-memory\n");
840
          exit (1);
841
        }
842
 
843
      if (!hist_exec_head)
844
        {
845
          hist_exec_head = hist_exec_new;
846
        }
847
      else
848
        {
849
          hist_exec_tail->next = hist_exec_new;
850
        }
851
 
852
      hist_exec_new->prev = hist_exec_tail;
853
      hist_exec_tail = hist_exec_new;
854 1352 nogj
    }
855
 
856
  /* Make hist_exec_tail->next point to hist_exec_head */
857
  hist_exec_tail->next = hist_exec_head;
858
  hist_exec_head->prev = hist_exec_tail;
859
 
860 1748 jeremybenn
  /* MM1409: All progs should start at reset vector entry! This sorted out by
861
     setting the cpu_state.pc field below. Not clear this is very good code! */
862
  pcnext = 0x0;
863 557 markom
 
864 1748 jeremybenn
  if (config.sim.verbose)
865
    {
866
      PRINTF ("Starting at 0x%" PRIxADDR "\n", pcnext);
867
    }
868 1452 nogj
 
869 1748 jeremybenn
  cpu_state.pc  = pcnext;
870
  pcnext       += 4;
871
 
872 557 markom
  /* MM1409: All programs should set their stack pointer!  */
873 1692 nogj
#if !(DYNAMIC_EXECUTION)
874 1748 jeremybenn
  except_handle (EXCEPT_RESET, 0);
875
  update_pc ();
876 1692 nogj
#endif
877 1748 jeremybenn
 
878 1386 nogj
  except_pending = 0;
879 1748 jeremybenn
  cpu_state.pc   = EXCEPT_RESET;
880 557 markom
 
881 1748 jeremybenn
}       /* cpu_reset() */
882
 
883
 
884
/*---------------------------------------------------------------------------*/
885
/*!Simulates one CPU clock cycle
886
 
887
  @return  non-zero if a breakpoint is hit, zero otherwise.                  */
888
/*---------------------------------------------------------------------------*/
889
int
890
cpu_clock ()
891 557 markom
{
892 1748 jeremybenn
  except_pending  = 0;
893 1386 nogj
  next_delay_insn = 0;
894
 
895 1748 jeremybenn
  if (fetch ())
896
    {
897
      PRINTF ("Breakpoint hit.\n");
898
      return  1;
899
    }
900 1386 nogj
 
901 1748 jeremybenn
  if (except_pending)
902
    {
903
      update_pc ();
904
      except_pending = 0;
905
      return  0;
906
    }
907 1386 nogj
 
908 1748 jeremybenn
  if (breakpoint)
909
    {
910
      except_handle (EXCEPT_TRAP, cpu_state.sprs[SPR_EEAR_BASE]);
911
      update_pc ();
912
      except_pending = 0;
913
      return  0;
914
    }
915
 
916 1432 nogj
  decode_execute_wrapper (&cpu_state.iqueue);
917 1748 jeremybenn
  update_pc ();
918
  return  0;
919 557 markom
 
920 1748 jeremybenn
}       /* cpu_clock() */
921
 
922
 
923
/*---------------------------------------------------------------------------*/
924
/*!If decoding cannot be found, call this function                           */
925
/*---------------------------------------------------------------------------*/
926 1342 nogj
#if SIMPLE_EXECUTION
927 1748 jeremybenn
void
928
l_invalid (struct iqueue_entry *current)
929
{
930 1342 nogj
#else
931 1748 jeremybenn
void
932
l_invalid ()
933
{
934 1342 nogj
#endif
935 1748 jeremybenn
  except_handle (EXCEPT_ILLEGAL, cpu_state.iqueue.insn_addr);
936 641 ivang
 
937 1748 jeremybenn
}       /* l_invalid() */
938
 
939
 
940
/*---------------------------------------------------------------------------*/
941
/*!The main execution loop                                                   */
942
/*---------------------------------------------------------------------------*/
943
void
944
exec_main ()
945 1690 nogj
{
946
  long long time_start;
947
 
948 1748 jeremybenn
  while (1)
949
    {
950
      time_start = runtime.sim.cycles;
951
      if (config.debug.enabled)
952
        {
953
          while (runtime.cpu.stalled)
954
            {
955
              if (config.debug.gdb_enabled)
956
                {
957
                  block_jtag ();
958
                  handle_server_socket (FALSE);
959
                }
960
              else
961
                {
962
                  fprintf (stderr,
963
                           "WARNING: CPU stalled and gdb connection not enabled.\n");
964
                  /* Dump the user into interactive mode.  From there he can decide what
965
                   * to do. */
966
                  handle_sim_command ();
967
                  sim_done ();
968
                }
969
              if (runtime.sim.iprompt)
970
                handle_sim_command ();
971
            }
972
        }
973 1690 nogj
 
974 1748 jeremybenn
      /* Each cycle has counter of mem_cycles; this value is joined with cycles
975
         at the end of the cycle; no sim originated memory accesses should be
976
         performed inbetween. */
977
      runtime.sim.mem_cycles = 0;
978 1690 nogj
 
979 1748 jeremybenn
      if (!config.pm.enabled ||
980
          !(config.pm.enabled &
981
            (cpu_state.sprs[SPR_PMR] & (SPR_PMR_DME | SPR_PMR_SME))))
982
        {
983
          if (cpu_clock ())
984
            {
985
              /* A breakpoint has been hit, drop to interactive mode */
986
              handle_sim_command ();
987
            }
988
        }
989 1690 nogj
 
990 1748 jeremybenn
      if (config.vapi.enabled && runtime.vapi.enabled)
991
        {
992
          vapi_check ();
993
        }
994
 
995
      if (config.debug.gdb_enabled)
996
        {
997
          handle_server_socket (FALSE); /* block & check_stdin = false */
998
        }
999
 
1000
      if (config.debug.enabled)
1001
        {
1002
          if (cpu_state.sprs[SPR_DMR1] & SPR_DMR1_ST)
1003
            {
1004
              set_stall_state (1);
1005
            }
1006
        }
1007
 
1008
      runtime.sim.cycles        += runtime.sim.mem_cycles;
1009
      scheduler.job_queue->time -= runtime.sim.cycles - time_start;
1010
 
1011
      if (scheduler.job_queue->time <= 0)
1012
        {
1013
          do_scheduler ();
1014
        }
1015
    }
1016
}       /* exec_main() */
1017
 
1018 1452 nogj
#if COMPLEX_EXECUTION
1019 717 markom
 
1020 1748 jeremybenn
/* Include generated/built in decode_execute function */
1021 717 markom
#include "execgen.c"
1022
 
1023 1452 nogj
#elif SIMPLE_EXECUTION
1024 717 markom
 
1025 720 markom
 
1026 1342 nogj
#define INSTRUCTION(name) void name (struct iqueue_entry *current)
1027 641 ivang
 
1028 1748 jeremybenn
/*---------------------------------------------------------------------------*/
1029
/*!Evaluates source operand
1030 1350 nogj
 
1031 1748 jeremybenn
   Implementation specific.
1032 1350 nogj
 
1033 1748 jeremybenn
   @param[in] op_no       The operand
1034
   @param[in] insn_index  Address of the instruction
1035
   @param[in] insn        The instruction
1036 641 ivang
 
1037 1748 jeremybenn
   @return  The value of the operand                                         */
1038
/*---------------------------------------------------------------------------*/
1039
static uorreg_t
1040
eval_operand (int            op_no,
1041
              unsigned long  insn_index,
1042
              uint32_t       insn)
1043 717 markom
{
1044
  struct insn_op_struct *opd = op_start[insn_index];
1045 1748 jeremybenn
  uorreg_t               ret;
1046 717 markom
 
1047 1748 jeremybenn
  while (op_no)
1048
    {
1049
      if (opd->type & OPTYPE_LAST)
1050
        {
1051
          fprintf (stderr,
1052
                   "Instruction requested more operands than it has\n");
1053
          exit (1);
1054
        }
1055
 
1056
      if ((opd->type & OPTYPE_OP) && !(opd->type & OPTYPE_DIS))
1057
        {
1058
          op_no--;
1059
        }
1060
 
1061
      opd++;
1062 717 markom
    }
1063
 
1064 1748 jeremybenn
  if (opd->type & OPTYPE_DIS)
1065
    {
1066
      ret = eval_operand_val (insn, opd);
1067
 
1068
      while (!(opd->type & OPTYPE_OP))
1069
        {
1070
          opd++;
1071
        }
1072
 
1073 1346 nogj
      opd++;
1074 1748 jeremybenn
      ret               += evalsim_reg (eval_operand_val (insn, opd));
1075
      cpu_state.insn_ea  = ret;
1076
 
1077
      return  ret;
1078
    }
1079
 
1080 1346 nogj
  if (opd->type & OPTYPE_REG)
1081 1748 jeremybenn
    {
1082
      return  evalsim_reg (eval_operand_val (insn, opd));
1083
    }
1084 717 markom
 
1085 1748 jeremybenn
  return  eval_operand_val (insn, opd);
1086 717 markom
 
1087 1748 jeremybenn
}       /* eval_operand() */
1088
 
1089
 
1090
/*---------------------------------------------------------------------------*/
1091
/*!Set destination operand (register direct) with value.
1092
 
1093
   Implementation specific.
1094
 
1095
   @param[in] op_no       The operand
1096
   @param[in] value       The value to set
1097
   @param[in] insn_index  Address of the instruction
1098
   @param[in] insn        The instruction                                    */
1099
/*---------------------------------------------------------------------------*/
1100
static void
1101
set_operand (int            op_no,
1102
             orreg_t        value,
1103
             unsigned long  insn_index,
1104
             uint32_t       insn)
1105 717 markom
{
1106 1346 nogj
  struct insn_op_struct *opd = op_start[insn_index];
1107
 
1108 1748 jeremybenn
  while (op_no)
1109
    {
1110
      if (opd->type & OPTYPE_LAST)
1111
        {
1112
          fprintf (stderr,
1113
                   "Instruction requested more operands than it has\n");
1114
          exit (1);
1115
        }
1116
 
1117
      if ((opd->type & OPTYPE_OP) && !(opd->type & OPTYPE_DIS))
1118
        {
1119
          op_no--;
1120
        }
1121
 
1122
      opd++;
1123
    }
1124
 
1125
  if (!(opd->type & OPTYPE_REG))
1126
    {
1127
      fprintf (stderr, "Trying to set a non-register operand\n");
1128 1346 nogj
      exit (1);
1129
    }
1130
 
1131 1748 jeremybenn
  setsim_reg (eval_operand_val (insn, opd), value);
1132 717 markom
 
1133 1748 jeremybenn
}       /* set_operand() */
1134
 
1135
 
1136
/*---------------------------------------------------------------------------*/
1137
/*!Simple and rather slow decoding function
1138
 
1139
   Based on built automata.
1140
 
1141
   @param[in] current  The current instruction to execute                    */
1142
/*---------------------------------------------------------------------------*/
1143
static void
1144
decode_execute (struct iqueue_entry *current)
1145 706 markom
{
1146
  int insn_index;
1147 641 ivang
 
1148 1748 jeremybenn
  current->insn_index = insn_index = insn_decode (current->insn);
1149
 
1150 706 markom
  if (insn_index < 0)
1151 1748 jeremybenn
    {
1152
      l_invalid (current);
1153
    }
1154
  else
1155
    {
1156
      or32_opcodes[insn_index].exec (current);
1157
    }
1158 1432 nogj
 
1159 1748 jeremybenn
  if (do_stats)
1160
    analysis (&cpu_state.iqueue);
1161 123 markom
}
1162
 
1163 720 markom
#include "insnset.c"
1164
 
1165 1452 nogj
#elif defined(DYNAMIC_EXECUTION)
1166
 
1167
#else
1168 1748 jeremybenn
# error "Must define SIMPLE_EXECUTION, COMPLEX_EXECUTION or DYNAMIC_EXECUTION"
1169 1452 nogj
#endif

powered by: WebSVN 2.1.0

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