OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [or1ksim/] [cpu/] [or32/] [execute.c] - Blame information for rev 124

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

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

powered by: WebSVN 2.1.0

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