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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [cpu/] [or32/] [execute.c] - Diff between revs 226 and 230

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 226 Rev 230
Line 53... Line 53...
#include "debug-unit.h"
#include "debug-unit.h"
#include "branch-predict.h"
#include "branch-predict.h"
#include "sprs.h"
#include "sprs.h"
#include "rsp-server.h"
#include "rsp-server.h"
#include <fenv.h> // Floating point environment for FPU instructions
#include <fenv.h> // Floating point environment for FPU instructions
#include "execute-fp.h"
 
 
 
/* Includes and macros for simple execution */
/* Includes and macros for simple execution */
#if SIMPLE_EXECUTION
#if SIMPLE_EXECUTION
 
 
#define SET_PARAM0(val) set_operand(0, val, current->insn_index, current->insn)
#define SET_PARAM0(val) set_operand(0, val, current->insn_index, current->insn)
Line 106... Line 105...
 
 
/* Variables used throughout this file to share information */
/* Variables used throughout this file to share information */
static int  breakpoint;
static int  breakpoint;
static int  next_delay_insn;
static int  next_delay_insn;
 
 
/* Functions to configure the host machine's FPU before doing simulated OR1k
 
   FP ops, handle flags and restore things when it's done. One for before and
 
   one for afterwards.
 
*/
 
void fp_set_or1k_rm(void);
 
void fp_set_flags_restore_host_rm(void);
 
 
 
/* A place to store the host's FPU rounding mode while OR1k's is used */
/* A place to store the host's FPU rounding mode while OR1k's is used */
int host_fp_rm;
static int host_fp_rm;
 
 
/* Forward declaration of static functions */
/* Forward declaration of static functions */
#if !(DYNAMIC_EXECUTION)
#if !(DYNAMIC_EXECUTION)
static void decode_execute (struct iqueue_entry *current);
static void decode_execute (struct iqueue_entry *current);
#endif
#endif
Line 267... Line 259...
  int                    prev_dis;
  int                    prev_dis;
  int                    next_dis;
  int                    next_dis;
  orreg_t                prev_reg_val = 0;
  orreg_t                prev_reg_val = 0;
  struct insn_op_struct *opd;
  struct insn_op_struct *opd;
 
 
  if (or32_opcodes[prev->insn_index].flags & OR32_W_FLAG
  if (or1ksim_or32_opcodes[prev->insn_index].flags & OR32_W_FLAG
      && or32_opcodes[next->insn_index].flags & OR32_R_FLAG)
      && or1ksim_or32_opcodes[next->insn_index].flags & OR32_R_FLAG)
    {
    {
      return  1;
      return  1;
    }
    }
 
 
  opd      = op_start[prev->insn_index];
  opd      = or1ksim_op_start[prev->insn_index];
  prev_dis = 0;
  prev_dis = 0;
 
 
  while (1)
  while (1)
    {
    {
      if (opd->type & OPTYPE_DIS)
      if (opd->type & OPTYPE_DIS)
Line 311... Line 303...
 
 
      opd++;
      opd++;
    }
    }
 
 
  /* We search all source operands - if we find confict => return 1 */
  /* We search all source operands - if we find confict => return 1 */
  opd      = op_start[next->insn_index];
  opd      = or1ksim_op_start[next->insn_index];
  next_dis = 0;
  next_dis = 0;
 
 
  while (1)
  while (1)
    {
    {
      if (opd->type & OPTYPE_DIS)
      if (opd->type & OPTYPE_DIS)
Line 426... Line 418...
      /* Dynamic, dependency stats. */
      /* Dynamic, dependency stats. */
      adddstats (cpu_state.icomplet.insn_index, current->insn_index, 1,
      adddstats (cpu_state.icomplet.insn_index, current->insn_index, 1,
                 check_depend (&cpu_state.icomplet, current));
                 check_depend (&cpu_state.icomplet, current));
 
 
      /* Dynamic, functional units stats. */
      /* Dynamic, functional units stats. */
      addfstats (or32_opcodes[cpu_state.icomplet.insn_index].func_unit,
      addfstats (or1ksim_or32_opcodes[cpu_state.icomplet.insn_index].func_unit,
                 or32_opcodes[current->insn_index].func_unit, 1,
                 or1ksim_or32_opcodes[current->insn_index].func_unit, 1,
                 check_depend (&cpu_state.icomplet, current));
                 check_depend (&cpu_state.icomplet, current));
 
 
      /* Dynamic, single stats. */
      /* Dynamic, single stats. */
      addsstats (current->insn_index, 1);
      addsstats (current->insn_index, 1);
    }
    }
 
 
  if (config.cpu.superscalar)
  if (config.cpu.superscalar)
    {
    {
      if ((or32_opcodes[current->insn_index].func_unit == it_branch) ||
      if ((or1ksim_or32_opcodes[current->insn_index].func_unit == it_branch) ||
          (or32_opcodes[current->insn_index].func_unit == it_jump))
          (or1ksim_or32_opcodes[current->insn_index].func_unit == it_jump))
        runtime.sim.storecycles += 0;
        runtime.sim.storecycles += 0;
 
 
      if (or32_opcodes[current->insn_index].func_unit == it_store)
      if (or1ksim_or32_opcodes[current->insn_index].func_unit == it_store)
        runtime.sim.storecycles += 1;
        runtime.sim.storecycles += 1;
 
 
      if (or32_opcodes[current->insn_index].func_unit == it_load)
      if (or1ksim_or32_opcodes[current->insn_index].func_unit == it_load)
        runtime.sim.loadcycles += 1;
        runtime.sim.loadcycles += 1;
 
 
      /* Pseudo multiple issue benchmark */
      /* Pseudo multiple issue benchmark */
      if ((multissue[or32_opcodes[current->insn_index].func_unit] < 1) ||
      if ((multissue[or1ksim_or32_opcodes[current->insn_index].func_unit] < 1) ||
          (check_depend (&cpu_state.icomplet, current))
          (check_depend (&cpu_state.icomplet, current))
          || (issued_per_cycle < 1))
          || (issued_per_cycle < 1))
        {
        {
          int i;
          int i;
          for (i = 0; i < 20; i++)
          for (i = 0; i < 20; i++)
Line 471... Line 463...
          multissue[it_movimm] = 2;
          multissue[it_movimm] = 2;
          multissue[it_arith] = 2;
          multissue[it_arith] = 2;
          multissue[it_store] = 2;
          multissue[it_store] = 2;
          multissue[it_load] = 2;
          multissue[it_load] = 2;
        }
        }
      multissue[or32_opcodes[current->insn_index].func_unit]--;
      multissue[or1ksim_or32_opcodes[current->insn_index].func_unit]--;
      issued_per_cycle--;
      issued_per_cycle--;
    }
    }
 
 
  if (config.cpu.dependstats)
  if (config.cpu.dependstats)
    /* Instruction waits in completition buffer until retired. */
    /* Instruction waits in completition buffer until retired. */
Line 649... Line 641...
                   cpu_state.sprs[SPR_ESR_BASE]);
                   cpu_state.sprs[SPR_ESR_BASE]);
          break;
          break;
 
 
        case EXE_LOG_SIMPLE:
        case EXE_LOG_SIMPLE:
        case EXE_LOG_SOFTWARE:
        case EXE_LOG_SOFTWARE:
          disassemble_index (cpu_state.iqueue.insn,
          or1ksim_disassemble_index (cpu_state.iqueue.insn,
                             cpu_state.iqueue.insn_index);
                             cpu_state.iqueue.insn_index);
 
 
          entry = get_label (insn_addr);
          entry = get_label (insn_addr);
          if (entry)
          if (entry)
            {
            {
Line 661... Line 653...
            }
            }
 
 
          if (config.sim.exe_log_type == EXE_LOG_SOFTWARE)
          if (config.sim.exe_log_type == EXE_LOG_SOFTWARE)
            {
            {
              struct insn_op_struct *opd =
              struct insn_op_struct *opd =
                op_start[cpu_state.iqueue.insn_index];
                or1ksim_op_start[cpu_state.iqueue.insn_index];
 
 
              j = 0;
              j = 0;
              while (1)
              while (1)
                {
                {
                  operand = eval_operand_val (cpu_state.iqueue.insn, opd);
                  operand = eval_operand_val (cpu_state.iqueue.insn, opd);
Line 696... Line 688...
                    {
                    {
                      break;
                      break;
                    }
                    }
                  opd++;
                  opd++;
                }
                }
              if (or32_opcodes[cpu_state.iqueue.insn_index].flags & OR32_R_FLAG)
              if (or1ksim_or32_opcodes[cpu_state.iqueue.insn_index].flags & OR32_R_FLAG)
                {
                {
                  fprintf (runtime.sim.fexe_log, "SR =%" PRIxREG " ",
                  fprintf (runtime.sim.fexe_log, "SR =%" PRIxREG " ",
                           cpu_state.sprs[SPR_SR]);
                           cpu_state.sprs[SPR_SR]);
                  j++;
                  j++;
                }
                }
Line 709... Line 701...
                  fprintf (runtime.sim.fexe_log, "             ");
                  fprintf (runtime.sim.fexe_log, "             ");
                  j++;
                  j++;
                }
                }
            }
            }
          fprintf (runtime.sim.fexe_log, "%" PRIxADDR " ", insn_addr);
          fprintf (runtime.sim.fexe_log, "%" PRIxADDR " ", insn_addr);
          fprintf (runtime.sim.fexe_log, "%s\n", disassembled);
          fprintf (runtime.sim.fexe_log, "%s\n", or1ksim_disassembled);
        }
        }
    }
    }
}       /* dump_exe_log() */
}       /* dump_exe_log() */
 
 
 
 
Line 1067... Line 1059...
   Save host rounding mode, set it to OR1K's according to FPCSR
   Save host rounding mode, set it to OR1K's according to FPCSR
   This function should be called before performing any FP instructions to
   This function should be called before performing any FP instructions to
   ensure the OR1K's rounding mode is installed in the host
   ensure the OR1K's rounding mode is installed in the host
                                                                             */
                                                                             */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
 void fp_set_or1k_rm(void)
static void
 
fp_set_or1k_rm(void)
 {
 {
   // Set OR1K's RM in host machine
   // Set OR1K's RM in host machine
   // First save host RM to restore it later
   // First save host RM to restore it later
   host_fp_rm = fegetround();
   host_fp_rm = fegetround();
   // Now map OR1K RM to host RM
   // Now map OR1K RM to host RM
Line 1101... Line 1094...
 
 
  Copy flags from floating point op into OR1K's FPCSR, and restore the host's
  Copy flags from floating point op into OR1K's FPCSR, and restore the host's
  rounding mode.
  rounding mode.
                                                                             */
                                                                             */
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
void fp_set_flags_restore_host_rm(void)
static void
 
fp_set_flags_restore_host_rm(void)
 {
 {
   // Check FP flags on host, convert to OR1K FPCSR bits
   // Check FP flags on host, convert to OR1K FPCSR bits
   // First clear all flags in OR1K FPCSR
   // First clear all flags in OR1K FPCSR
   cpu_state.sprs[SPR_FPCSR] &= ~SPR_FPCSR_ALLF;
   cpu_state.sprs[SPR_FPCSR] &= ~SPR_FPCSR_ALLF;
 
 
Line 1149... Line 1143...
static uorreg_t
static uorreg_t
eval_operand (int            op_no,
eval_operand (int            op_no,
              unsigned long  insn_index,
              unsigned long  insn_index,
              uint32_t       insn)
              uint32_t       insn)
{
{
  struct insn_op_struct *opd = op_start[insn_index];
  struct insn_op_struct *opd = or1ksim_op_start[insn_index];
  uorreg_t               ret;
  uorreg_t               ret;
 
 
  while (op_no)
  while (op_no)
    {
    {
      if (opd->type & OPTYPE_LAST)
      if (opd->type & OPTYPE_LAST)
Line 1211... Line 1205...
set_operand (int            op_no,
set_operand (int            op_no,
             orreg_t        value,
             orreg_t        value,
             unsigned long  insn_index,
             unsigned long  insn_index,
             uint32_t       insn)
             uint32_t       insn)
{
{
  struct insn_op_struct *opd = op_start[insn_index];
  struct insn_op_struct *opd = or1ksim_op_start[insn_index];
 
 
  while (op_no)
  while (op_no)
    {
    {
      if (opd->type & OPTYPE_LAST)
      if (opd->type & OPTYPE_LAST)
        {
        {
Line 1253... Line 1247...
static void
static void
decode_execute (struct iqueue_entry *current)
decode_execute (struct iqueue_entry *current)
{
{
  int insn_index;
  int insn_index;
 
 
  current->insn_index = insn_index = insn_decode (current->insn);
  current->insn_index = insn_index = or1ksim_insn_decode (current->insn);
 
 
  if (insn_index < 0)
  if (insn_index < 0)
    {
    {
      l_invalid (current);
      l_invalid (current);
    }
    }
  else
  else
    {
    {
      or32_opcodes[insn_index].exec (current);
      or1ksim_or32_opcodes[insn_index].exec (current);
    }
    }
 
 
  if (do_stats)
  if (do_stats)
    analysis (&cpu_state.iqueue);
    analysis (&cpu_state.iqueue);
}
}

powered by: WebSVN 2.1.0

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