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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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