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

Subversion Repositories openrisc_me

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

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

powered by: WebSVN 2.1.0

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