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

Subversion Repositories openrisc

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

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 202 julius
  if (config.sim.exe_bin_insn_log)
484
    dump_exe_bin_insn_log (current);
485
 
486 19 jeremybenn
}       /* analysis() */
487
 
488
 
489
#if !(DYNAMIC_EXECUTION)
490
 
491
/*---------------------------------------------------------------------------*/
492
/*!Store buffer analysis for store instructions
493
 
494
   Stores are accumulated and commited when IO is idle
495
 
496
   @param[in] cyc  Number of cycles being analysed                           */
497
/*---------------------------------------------------------------------------*/
498
static void
499
sbuf_store (int cyc)
500
{
501
  int delta = runtime.sim.cycles - sbuf_prev_cycles;
502
 
503
  sbuf_total_cyc   += cyc;
504
  sbuf_prev_cycles  = runtime.sim.cycles;
505
 
506
  /* Take stores from buffer, that occured meanwhile */
507
  while (sbuf_count && delta >= sbuf_buf[sbuf_tail])
508
    {
509
      delta     -= sbuf_buf[sbuf_tail];
510
      sbuf_tail  = (sbuf_tail + 1) % MAX_SBUF_LEN;
511
      sbuf_count--;
512
    }
513
 
514
  if (sbuf_count)
515
    {
516
      sbuf_buf[sbuf_tail] -= delta;
517
    }
518
 
519
  /* Store buffer is full, take one out */
520
  if (sbuf_count >= config.cpu.sbuf_len)
521
    {
522
      sbuf_wait_cyc          += sbuf_buf[sbuf_tail];
523
      runtime.sim.mem_cycles += sbuf_buf[sbuf_tail];
524
      sbuf_prev_cycles       += sbuf_buf[sbuf_tail];
525
      sbuf_tail               = (sbuf_tail + 1) % MAX_SBUF_LEN;
526
      sbuf_count--;
527
    }
528
 
529
  /* Put newest store in the buffer */
530
  sbuf_buf[sbuf_head] = cyc;
531
  sbuf_head           = (sbuf_head + 1) % MAX_SBUF_LEN;
532
  sbuf_count++;
533
 
534
}       /* sbuf_store() */
535
 
536
 
537
/*---------------------------------------------------------------------------*/
538
/*!Store buffer analysis for load instructions
539
 
540
   Previous stores should commit, before any load                            */
541
/*---------------------------------------------------------------------------*/
542
static void
543
sbuf_load ()
544
{
545
  int delta = runtime.sim.cycles - sbuf_prev_cycles;
546
  sbuf_prev_cycles = runtime.sim.cycles;
547
 
548
  /* Take stores from buffer, that occured meanwhile */
549
  while (sbuf_count && delta >= sbuf_buf[sbuf_tail])
550
    {
551
      delta     -= sbuf_buf[sbuf_tail];
552
      sbuf_tail  = (sbuf_tail + 1) % MAX_SBUF_LEN;
553
      sbuf_count--;
554
    }
555
 
556
  if (sbuf_count)
557
    {
558
      sbuf_buf[sbuf_tail] -= delta;
559
    }
560
 
561
  /* Wait for all stores to complete */
562
  while (sbuf_count > 0)
563
    {
564
      sbuf_wait_cyc          += sbuf_buf[sbuf_tail];
565
      runtime.sim.mem_cycles += sbuf_buf[sbuf_tail];
566
      sbuf_prev_cycles       += sbuf_buf[sbuf_tail];
567
      sbuf_tail               = (sbuf_tail + 1) % MAX_SBUF_LEN;
568
      sbuf_count--;
569
    }
570
}       /* sbuf_load() */
571
 
572
#endif  /* !DYNAMIC_EXECUTION */
573
 
574
 
575
/*---------------------------------------------------------------------------*/
576
/*!Outputs dissasembled instruction                                          */
577
/*---------------------------------------------------------------------------*/
578
void
579
dump_exe_log ()
580
{
581
  oraddr_t      insn_addr = cpu_state.iqueue.insn_addr;
582
  unsigned int  i;
583
  unsigned int  j;
584
  uorreg_t      operand;
585
 
586
  if (insn_addr == 0xffffffff)
587
    {
588
      return;
589
    }
590
 
591
  if ((config.sim.exe_log_start <= runtime.cpu.instructions) &&
592
      ((config.sim.exe_log_end <= 0) ||
593
       (runtime.cpu.instructions <= config.sim.exe_log_end)))
594
    {
595
      struct label_entry *entry;
596
 
597
      if (config.sim.exe_log_marker &&
598
          !(runtime.cpu.instructions % config.sim.exe_log_marker))
599
        {
600
          fprintf (runtime.sim.fexe_log,
601
                   "--------------------- %8lli instruction "
602
                   "---------------------\n",
603
                   runtime.cpu.instructions);
604
        }
605
 
606
      switch (config.sim.exe_log_type)
607
        {
608
        case EXE_LOG_HARDWARE:
609
          fprintf (runtime.sim.fexe_log,
610
                   "\nEXECUTED(%11llu): %" PRIxADDR ":  ",
611
                   runtime.cpu.instructions, insn_addr);
612
          fprintf (runtime.sim.fexe_log, "%.2x%.2x",
613
                   eval_direct8 (insn_addr, 0, 0),
614
                   eval_direct8 (insn_addr + 1, 0, 0));
615
          fprintf (runtime.sim.fexe_log, "%.2x%.2x",
616
                   eval_direct8 (insn_addr + 2, 0, 0),
617
                   eval_direct8 (insn_addr + 3, 0, 0));
618
 
619
          for (i = 0; i < MAX_GPRS; i++)
620
            {
621
              if (i % 4 == 0)
622
                {
623
                  fprintf (runtime.sim.fexe_log, "\n");
624
                }
625
 
626
              fprintf (runtime.sim.fexe_log, "GPR%2u: %" PRIxREG "  ", i,
627
                       cpu_state.reg[i]);
628
            }
629
 
630
          fprintf (runtime.sim.fexe_log, "\n");
631
          fprintf (runtime.sim.fexe_log, "SR   : %.8" PRIx32 "  ",
632
                   cpu_state.sprs[SPR_SR]);
633
          fprintf (runtime.sim.fexe_log, "EPCR0: %" PRIxADDR "  ",
634
                   cpu_state.sprs[SPR_EPCR_BASE]);
635
          fprintf (runtime.sim.fexe_log, "EEAR0: %" PRIxADDR "  ",
636
                   cpu_state.sprs[SPR_EEAR_BASE]);
637
          fprintf (runtime.sim.fexe_log, "ESR0 : %.8" PRIx32 "\n",
638
                   cpu_state.sprs[SPR_ESR_BASE]);
639
          break;
640
 
641
        case EXE_LOG_SIMPLE:
642
        case EXE_LOG_SOFTWARE:
643
          disassemble_index (cpu_state.iqueue.insn,
644
                             cpu_state.iqueue.insn_index);
645
 
646
          entry = get_label (insn_addr);
647
          if (entry)
648
            {
649
              fprintf (runtime.sim.fexe_log, "%s:\n", entry->name);
650
            }
651
 
652
          if (config.sim.exe_log_type == EXE_LOG_SOFTWARE)
653
            {
654
              struct insn_op_struct *opd =
655
                op_start[cpu_state.iqueue.insn_index];
656
 
657
              j = 0;
658
              while (1)
659
                {
660
                  operand = eval_operand_val (cpu_state.iqueue.insn, opd);
661
                  while (!(opd->type & OPTYPE_OP))
662
                    {
663
                      opd++;
664
                    }
665
                  if (opd->type & OPTYPE_DIS)
666
                    {
667
                      fprintf (runtime.sim.fexe_log,
668
                               "EA =%" PRIxADDR " PA =%" PRIxADDR " ",
669
                               cpu_state.insn_ea,
670
                               peek_into_dtlb (cpu_state.insn_ea, 0, 0));
671
                      opd++;    /* Skip of register operand */
672
                      j++;
673
                    }
674
                  else if ((opd->type & OPTYPE_REG) && operand)
675
                    {
676
                      fprintf (runtime.sim.fexe_log, "r%-2i=%" PRIxREG " ",
677
                               (int) operand, evalsim_reg (operand));
678
                    }
679
                  else
680
                    {
681
                      fprintf (runtime.sim.fexe_log, "             ");
682
                    }
683
                  j++;
684
                  if (opd->type & OPTYPE_LAST)
685
                    {
686
                      break;
687
                    }
688
                  opd++;
689
                }
690
              if (or32_opcodes[cpu_state.iqueue.insn_index].flags & OR32_R_FLAG)
691
                {
692
                  fprintf (runtime.sim.fexe_log, "SR =%" PRIxREG " ",
693
                           cpu_state.sprs[SPR_SR]);
694
                  j++;
695
                }
696
              while (j < 3)
697
                {
698
                  fprintf (runtime.sim.fexe_log, "             ");
699
                  j++;
700
                }
701
            }
702
          fprintf (runtime.sim.fexe_log, "%" PRIxADDR " ", insn_addr);
703
          fprintf (runtime.sim.fexe_log, "%s\n", disassembled);
704
        }
705
    }
706
}       /* dump_exe_log() */
707
 
708
 
709 202 julius
 
710 19 jeremybenn
/*---------------------------------------------------------------------------*/
711 202 julius
/*!Outputs binary copy of instruction to a file                              */
712
/*---------------------------------------------------------------------------*/
713
void
714
dump_exe_bin_insn_log (struct iqueue_entry *current)
715
{
716
  // Do endian swap before spitting out (will be kept in LE on a LE machine)
717
  // but more useful to see it in big endian format.
718
  // Should probably host htonl().
719
  uint32_t insn = (((current->insn & 0xff)<<24) |
720
                   ((current->insn & 0xff00)<<8) |
721
                   ((current->insn & 0xff0000)>>8) |
722
                   ((current->insn & 0xff000000)>>24));
723
 
724
  //for(i=0;i<4;i++) tmp_insn[i] = eval_direct8 (insn_addr+i, 0, 0);
725
 
726
  // Dump it into binary log file
727
  fwrite((void*)&insn, 4, 1, runtime.sim.fexe_bin_insn_log);
728
 
729
 
730
}       /* dump_exe_bin_insn_log() */
731
 
732
 
733
/*---------------------------------------------------------------------------*/
734 19 jeremybenn
/*!Dump registers
735
 
736
   Supports the CLI 'r' and 't' commands                                     */
737
/*---------------------------------------------------------------------------*/
738
void
739
dumpreg ()
740
{
741
  int       i;
742
  oraddr_t  physical_pc;
743
 
744
  if ((physical_pc = peek_into_itlb (cpu_state.iqueue.insn_addr)))
745
    {
746
      disassemble_memory (physical_pc, physical_pc + 4, 0);
747
    }
748
  else
749
    {
750
      PRINTF ("INTERNAL SIMULATOR ERROR:\n");
751
      PRINTF ("no translation for currently executed instruction\n");
752
    }
753
 
754
  // generate_time_pretty (temp, runtime.sim.cycles * config.sim.clkcycle_ps);
755
  PRINTF (" (executed) [cycle %lld, #%lld]\n", runtime.sim.cycles,
756
          runtime.cpu.instructions);
757
  if (config.cpu.superscalar)
758
    {
759
      PRINTF ("Superscalar CYCLES: %u", runtime.cpu.supercycles);
760
    }
761
  if (config.cpu.hazards)
762
    {
763
      PRINTF ("  HAZARDWAIT: %u\n", runtime.cpu.hazardwait);
764
    }
765
  else if (config.cpu.superscalar)
766
    {
767
      PRINTF ("\n");
768
    }
769
 
770
  if ((physical_pc = peek_into_itlb (cpu_state.pc)))
771
    {
772
      disassemble_memory (physical_pc, physical_pc + 4, 0);
773
    }
774
  else
775
    {
776
      PRINTF ("%" PRIxADDR ": : xxxxxxxx  ITLB miss follows", cpu_state.pc);
777
    }
778
 
779
  PRINTF (" (next insn) %s", (cpu_state.delay_insn ? "(delay insn)" : ""));
780
 
781
  for (i = 0; i < MAX_GPRS; i++)
782
    {
783
      if (i % 4 == 0)
784
        {
785
          PRINTF ("\n");
786
        }
787
 
788
      PRINTF ("GPR%.2u: %" PRIxREG "  ", i, evalsim_reg (i));
789
    }
790
 
791
  PRINTF ("flag: %u\n", cpu_state.sprs[SPR_SR] & SPR_SR_F ? 1 : 0);
792
 
793
}       /* dumpreg() */
794
 
795
 
796
/*---------------------------------------------------------------------------*/
797
/*!Wrapper around real decode_execute function
798
 
799
   Some statistics here only
800
 
801
   @param[in] current  Instruction being executed                            */
802
/*---------------------------------------------------------------------------*/
803
static void
804
decode_execute_wrapper (struct iqueue_entry *current)
805
{
806
  breakpoint = 0;
807
 
808
#ifndef HAVE_EXECUTION
809
#error HAVE_EXECUTION has to be defined in order to execute programs.
810
#endif
811
 
812
  /* FIXME: Most of this file is not needed with DYNAMIC_EXECUTION */
813
#if !(DYNAMIC_EXECUTION)
814
  decode_execute (current);
815
#endif
816
 
817
  if (breakpoint)
818
    {
819
      except_handle (EXCEPT_TRAP, cpu_state.sprs[SPR_EEAR_BASE]);
820
    }
821
}       /* decode_execute_wrapper() */
822
 
823
/*---------------------------------------------------------------------------*/
824
/*!Reset the CPU                                                             */
825
/*---------------------------------------------------------------------------*/
826
void
827
cpu_reset ()
828
{
829
  int               i;
830
  struct hist_exec *hist_exec_head = NULL;
831
  struct hist_exec *hist_exec_new;
832
 
833
  runtime.sim.cycles       = 0;
834
  runtime.sim.loadcycles   = 0;
835
  runtime.sim.storecycles  = 0;
836
  runtime.cpu.instructions = 0;
837
  runtime.cpu.supercycles  = 0;
838
  runtime.cpu.hazardwait   = 0;
839
 
840
  for (i = 0; i < MAX_GPRS; i++)
841
    {
842
      setsim_reg (i, 0);
843
    }
844
 
845
  memset (&cpu_state.iqueue,   0, sizeof (cpu_state.iqueue));
846
  memset (&cpu_state.icomplet, 0, sizeof (cpu_state.icomplet));
847
 
848
  sbuf_head        = 0;
849
  sbuf_tail        = 0;
850
  sbuf_count       = 0;
851
  sbuf_prev_cycles = 0;
852
 
853
  /* Initialise execution history circular buffer */
854
  for (i = 0; i < HISTEXEC_LEN; i++)
855
    {
856
      hist_exec_new = malloc (sizeof (struct hist_exec));
857
 
858
      if (!hist_exec_new)
859
        {
860
          fprintf (stderr, "Out-of-memory\n");
861
          exit (1);
862
        }
863
 
864
      if (!hist_exec_head)
865
        {
866
          hist_exec_head = hist_exec_new;
867
        }
868
      else
869
        {
870
          hist_exec_tail->next = hist_exec_new;
871
        }
872
 
873
      hist_exec_new->prev = hist_exec_tail;
874
      hist_exec_tail = hist_exec_new;
875
    }
876
 
877
  /* Make hist_exec_tail->next point to hist_exec_head */
878
  hist_exec_tail->next = hist_exec_head;
879
  hist_exec_head->prev = hist_exec_tail;
880
 
881
  /* MM1409: All progs should start at reset vector entry! This sorted out by
882
     setting the cpu_state.pc field below. Not clear this is very good code! */
883
 
884
  /* Patches suggested by Shinji Wakatsuki, so that the vector address takes
885
     notice of the Exception Prefix High bit of the Supervision register */
886
  pcnext = (cpu_state.sprs[SPR_SR] & SPR_SR_EPH ? 0xf0000000 : 0x00000000);
887
 
888
  if (config.sim.verbose)
889
    {
890
      PRINTF ("Starting at 0x%" PRIxADDR "\n", pcnext);
891
    }
892
 
893
  cpu_state.pc  = pcnext;
894
  pcnext       += 4;
895
 
896
  /* MM1409: All programs should set their stack pointer!  */
897
#if !(DYNAMIC_EXECUTION)
898
  except_handle (EXCEPT_RESET, 0);
899
  update_pc ();
900
#endif
901
 
902
  except_pending = 0;
903
  cpu_state.pc   = cpu_state.sprs[SPR_SR] & SPR_SR_EPH ?
904
    0xf0000000 + EXCEPT_RESET : EXCEPT_RESET;
905
 
906
}       /* cpu_reset() */
907
 
908
 
909
/*---------------------------------------------------------------------------*/
910
/*!Simulates one CPU clock cycle
911
 
912
  @return  non-zero if a breakpoint is hit, zero otherwise.                  */
913
/*---------------------------------------------------------------------------*/
914
int
915
cpu_clock ()
916
{
917
  except_pending  = 0;
918
  next_delay_insn = 0;
919
 
920
  if (fetch ())
921
    {
922
      PRINTF ("Breakpoint hit.\n");
923
      return  1;
924
    }
925
 
926
  if (except_pending)
927
    {
928
      update_pc ();
929
      except_pending = 0;
930
      return  0;
931
    }
932
 
933
  if (breakpoint)
934
    {
935
      except_handle (EXCEPT_TRAP, cpu_state.sprs[SPR_EEAR_BASE]);
936
      update_pc ();
937
      except_pending = 0;
938
      return  0;
939
    }
940
 
941
  decode_execute_wrapper (&cpu_state.iqueue);
942
  update_pc ();
943
  return  0;
944
 
945
}       /* cpu_clock() */
946
 
947
 
948
/*---------------------------------------------------------------------------*/
949
/*!If decoding cannot be found, call this function                           */
950
/*---------------------------------------------------------------------------*/
951
#if SIMPLE_EXECUTION
952
void
953
l_invalid (struct iqueue_entry *current)
954
{
955
#else
956
void
957
l_invalid ()
958
{
959
#endif
960
  except_handle (EXCEPT_ILLEGAL, cpu_state.iqueue.insn_addr);
961
 
962
}       /* l_invalid() */
963
 
964
 
965
/*---------------------------------------------------------------------------*/
966
/*!The main execution loop                                                   */
967
/*---------------------------------------------------------------------------*/
968
void
969
exec_main ()
970
{
971
  long long time_start;
972
 
973
  while (1)
974
    {
975
      time_start = runtime.sim.cycles;
976
      if (config.debug.enabled)
977
        {
978
          while (runtime.cpu.stalled)
979
            {
980
              if (config.debug.rsp_enabled)
981
                {
982
                  handle_rsp ();
983
                }
984
              else if (config.debug.gdb_enabled)
985
                {
986
                  block_jtag ();
987
                  handle_server_socket (FALSE);
988
                }
989
              else
990
                {
991
                  fprintf (stderr, "ERROR: CPU stalled and GDB connection not "
992
                           "enabled: Invoking CLI and terminating.\n");
993
                  /* Dump the user into interactive mode.  From there he or
994
                     she can decide what to do. */
995
                  handle_sim_command ();
996
                  sim_done ();
997
                }
998
              if (runtime.sim.iprompt)
999
                handle_sim_command ();
1000
            }
1001
        }
1002
 
1003
      /* Each cycle has counter of mem_cycles; this value is joined with cycles
1004
         at the end of the cycle; no sim originated memory accesses should be
1005
         performed inbetween. */
1006
      runtime.sim.mem_cycles = 0;
1007
 
1008
      if (!config.pm.enabled ||
1009
          !(config.pm.enabled &
1010
            (cpu_state.sprs[SPR_PMR] & (SPR_PMR_DME | SPR_PMR_SME))))
1011
        {
1012
          if (cpu_clock ())
1013
            {
1014
              /* A breakpoint has been hit, drop to interactive mode */
1015
              handle_sim_command ();
1016
            }
1017
        }
1018
 
1019
      if (config.vapi.enabled && runtime.vapi.enabled)
1020
        {
1021
          vapi_check ();
1022
        }
1023
 
1024
      if (config.debug.gdb_enabled)
1025
        {
1026
          handle_server_socket (FALSE); /* block & check_stdin = false */
1027
        }
1028
 
1029
      if (config.debug.enabled)
1030
        {
1031
          if (cpu_state.sprs[SPR_DMR1] & SPR_DMR1_ST)
1032
            {
1033
              set_stall_state (1);
1034
 
1035
              if (config.debug.rsp_enabled)
1036
                {
1037
                  rsp_exception (EXCEPT_TRAP);
1038
                }
1039
            }
1040
        }
1041
 
1042
      runtime.sim.cycles        += runtime.sim.mem_cycles;
1043
      scheduler.job_queue->time -= runtime.sim.cycles - time_start;
1044
 
1045
      if (scheduler.job_queue->time <= 0)
1046
        {
1047
          do_scheduler ();
1048
        }
1049
    }
1050
}       /* exec_main() */
1051
 
1052
#if COMPLEX_EXECUTION
1053
 
1054
/* Include generated/built in decode_execute function */
1055
#include "execgen.c"
1056
 
1057
#elif SIMPLE_EXECUTION
1058
 
1059
 
1060
/*---------------------------------------------------------------------------*/
1061
/*!Evaluates source operand
1062
 
1063
   Implementation specific.
1064
 
1065
   @param[in] op_no       The operand
1066
   @param[in] insn_index  Address of the instruction
1067
   @param[in] insn        The instruction
1068
 
1069
   @return  The value of the operand                                         */
1070
/*---------------------------------------------------------------------------*/
1071
static uorreg_t
1072
eval_operand (int            op_no,
1073
              unsigned long  insn_index,
1074
              uint32_t       insn)
1075
{
1076
  struct insn_op_struct *opd = op_start[insn_index];
1077
  uorreg_t               ret;
1078
 
1079
  while (op_no)
1080
    {
1081
      if (opd->type & OPTYPE_LAST)
1082
        {
1083
          fprintf (stderr,
1084
                   "Instruction requested more operands than it has\n");
1085
          exit (1);
1086
        }
1087
 
1088
      if ((opd->type & OPTYPE_OP) && !(opd->type & OPTYPE_DIS))
1089
        {
1090
          op_no--;
1091
        }
1092
 
1093
      opd++;
1094
    }
1095
 
1096
  if (opd->type & OPTYPE_DIS)
1097
    {
1098
      ret = eval_operand_val (insn, opd);
1099
 
1100
      while (!(opd->type & OPTYPE_OP))
1101
        {
1102
          opd++;
1103
        }
1104
 
1105
      opd++;
1106
      ret               += evalsim_reg (eval_operand_val (insn, opd));
1107
      cpu_state.insn_ea  = ret;
1108
 
1109
      return  ret;
1110
    }
1111
 
1112
  if (opd->type & OPTYPE_REG)
1113
    {
1114
      return  evalsim_reg (eval_operand_val (insn, opd));
1115
    }
1116
 
1117
  return  eval_operand_val (insn, opd);
1118
 
1119
}       /* eval_operand() */
1120
 
1121
 
1122
/*---------------------------------------------------------------------------*/
1123
/*!Set destination operand (register direct) with value.
1124
 
1125
   Implementation specific.
1126
 
1127
   @param[in] op_no       The operand
1128
   @param[in] value       The value to set
1129
   @param[in] insn_index  Address of the instruction
1130
   @param[in] insn        The instruction                                    */
1131
/*---------------------------------------------------------------------------*/
1132
static void
1133
set_operand (int            op_no,
1134
             orreg_t        value,
1135
             unsigned long  insn_index,
1136
             uint32_t       insn)
1137
{
1138
  struct insn_op_struct *opd = op_start[insn_index];
1139
 
1140
  while (op_no)
1141
    {
1142
      if (opd->type & OPTYPE_LAST)
1143
        {
1144
          fprintf (stderr,
1145
                   "Instruction requested more operands than it has\n");
1146
          exit (1);
1147
        }
1148
 
1149
      if ((opd->type & OPTYPE_OP) && !(opd->type & OPTYPE_DIS))
1150
        {
1151
          op_no--;
1152
        }
1153
 
1154
      opd++;
1155
    }
1156
 
1157
  if (!(opd->type & OPTYPE_REG))
1158
    {
1159
      fprintf (stderr, "Trying to set a non-register operand\n");
1160
      exit (1);
1161
    }
1162
 
1163
  setsim_reg (eval_operand_val (insn, opd), value);
1164
 
1165
}       /* set_operand() */
1166
 
1167
 
1168
/*---------------------------------------------------------------------------*/
1169
/*!Simple and rather slow decoding function
1170
 
1171
   Based on built automata.
1172
 
1173
   @param[in] current  The current instruction to execute                    */
1174
/*---------------------------------------------------------------------------*/
1175
static void
1176
decode_execute (struct iqueue_entry *current)
1177
{
1178
  int insn_index;
1179
 
1180
  current->insn_index = insn_index = insn_decode (current->insn);
1181
 
1182
  if (insn_index < 0)
1183
    {
1184
      l_invalid (current);
1185
    }
1186
  else
1187
    {
1188
      or32_opcodes[insn_index].exec (current);
1189
    }
1190
 
1191
  if (do_stats)
1192
    analysis (&cpu_state.iqueue);
1193
}
1194
 
1195
#include "insnset.c"
1196
 
1197
#elif defined(DYNAMIC_EXECUTION)
1198
 
1199
#else
1200
# error "Must define SIMPLE_EXECUTION, COMPLEX_EXECUTION or DYNAMIC_EXECUTION"
1201
#endif

powered by: WebSVN 2.1.0

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