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

Subversion Repositories openrisc

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

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

Rev 230 Rev 233
Line 1... Line 1...
/* execute.c -- OR1K architecture dependent simulation
/* execute.c -- OR1K architecture dependent simulation
 
 
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
   Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
   Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
   Copyright (C) 2008 Embecosm Limited
   Copyright (C) 2008 Embecosm Limited
 
   Copyright (C) 2010 ORSoC AB
 
 
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
 
   Contributor Julius Baxter <julius.baxter@orsoc.se>
 
 
   This file is part of OpenRISC 1000 Architectural Simulator.
   This file is part of OpenRISC 1000 Architectural Simulator.
 
 
   This program is free software; you can redistribute it and/or modify it
   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the Free
   under the terms of the GNU General Public License as published by the Free
Line 52... Line 54...
#include "vapi.h"
#include "vapi.h"
#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 "softfloat.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 105... Line 107...
 
 
/* 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;
 
 
/* A place to store the host's FPU rounding mode while OR1k's is used */
 
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 1050... Line 1049...
          do_scheduler ();
          do_scheduler ();
        }
        }
    }
    }
}       /* exec_main() */
}       /* exec_main() */
 
 
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Floating point operation setup function
/*!Update the rounding mode variable the softfloat library reads             */
 
 
   Save host rounding mode, set it to OR1K's according to FPCSR
 
   This function should be called before performing any FP instructions to
 
   ensure the OR1K's rounding mode is installed in the host
 
                                                                             */
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void
fp_set_or1k_rm(void)
float_set_rm ()
 {
 {
   // Set OR1K's RM in host machine
  //
   // First save host RM to restore it later
  // float_rounding_mode is used by the softfloat library, it is declared in
   host_fp_rm = fegetround();
  // "softfloat.h"
   // Now map OR1K RM to host RM
  //
   int or1k_rm = 0;
 
   switch(cpu_state.sprs[SPR_FPCSR] & SPR_FPCSR_RM)
   switch(cpu_state.sprs[SPR_FPCSR] & SPR_FPCSR_RM)
     {
     {
     case FPCSR_RM_RN:
     case FPCSR_RM_RN:
       or1k_rm = FE_TONEAREST;
      //printf("or1ksim <%s>: rounding mode RN\n",__FUNCTION__);
 
      float_rounding_mode = float_round_nearest_even;
       break;
       break;
     case FPCSR_RM_RZ:
     case FPCSR_RM_RZ:
       or1k_rm = FE_TOWARDZERO;
      //printf("or1ksim <%s>: rounding mode RZ\n",__FUNCTION__);
 
      float_rounding_mode = float_round_to_zero;
       break;
       break;
     case FPCSR_RM_RIP:
     case FPCSR_RM_RIP:
       or1k_rm = FE_UPWARD;
      //printf("or1ksim <%s>: rounding mode R+\n",__FUNCTION__);
 
      float_rounding_mode = float_round_up;
       break;
       break;
     case FPCSR_RM_RIN:
     case FPCSR_RM_RIN:
       or1k_rm = FE_TOWARDZERO;
      //printf("or1ksim <%s>: rounding mode R-\n",__FUNCTION__);
 
      float_rounding_mode = float_round_down;
       break;
       break;
     }
     }
   // Now set this RM for the host
 
   fesetround(or1k_rm); // TODO - check for nonzero return here, if RM not
 
                        // able to be set, maybe warn user
 
 }
 }
 
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
/*!Floating point operation flag set and host restore function
/*!Update the OR1K's FPCSR after each floating point instruction             */
 
 
  Copy flags from floating point op into OR1K's FPCSR, and restore the host's
 
  rounding mode.
 
                                                                             */
 
/*---------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------*/
static void
static void
fp_set_flags_restore_host_rm(void)
float_set_flags ()
 {
 {
   // Check FP flags on host, convert to OR1K FPCSR bits
  // Get the flags from softfloat's variable and set the OR1K's FPCR values
   // 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;
 
 
   // Test host flags, set appropriate OR1K flags
  if (float_exception_flags & float_flag_invalid)
   if (fetestexcept(FE_DIVBYZERO)) cpu_state.sprs[SPR_FPCSR] |= SPR_FPCSR_DZF;
    cpu_state.sprs[SPR_FPCSR] |= SPR_FPCSR_IVF;
   if (fetestexcept(FE_INEXACT)) cpu_state.sprs[SPR_FPCSR] |= SPR_FPCSR_IXF;
  if (float_exception_flags & float_flag_divbyzero)
   if (fetestexcept(FE_INVALID)) cpu_state.sprs[SPR_FPCSR] |= SPR_FPCSR_IVF;
    cpu_state.sprs[SPR_FPCSR] |= SPR_FPCSR_DZF;
   if (fetestexcept(FE_OVERFLOW)) cpu_state.sprs[SPR_FPCSR] |= SPR_FPCSR_OVF;
  if (float_exception_flags & float_flag_overflow)
   if (fetestexcept(FE_UNDERFLOW)) cpu_state.sprs[SPR_FPCSR] |= SPR_FPCSR_UNF;
    cpu_state.sprs[SPR_FPCSR] |= SPR_FPCSR_OVF;
 
  if (float_exception_flags & float_flag_underflow)
   // Restore the hosts's rounding mode
    cpu_state.sprs[SPR_FPCSR] |= SPR_FPCSR_UNF;
   fesetround(host_fp_rm);
  if (float_exception_flags & float_flag_inexact)
 
    cpu_state.sprs[SPR_FPCSR] |= SPR_FPCSR_IXF;
 
  /*
 
  printf("or1ksim: post-fp-op flags from softfloat: %x%x%x%x%x\n",
 
         !!(float_exception_flags & float_flag_invalid),
 
         !!(float_exception_flags & float_flag_divbyzero),
 
         !!(float_exception_flags & float_flag_overflow),
 
         !!(float_exception_flags & float_flag_underflow),
 
         !!(float_exception_flags & float_flag_inexact));
 
  */
   // TODO: Call FP exception is FPEE set and any of the flags were set
   // TODO: Call FP exception is FPEE set and any of the flags were set
   /*
   /*
     if ((cpu_state.sprs[SPR_FPCSR] & SPR_FPCSR_FPEE) &
     if ((cpu_state.sprs[SPR_FPCSR] & SPR_FPCSR_FPEE) &
     (|(cpu_state.sprs[SPR_FPCSR] & SPR_FPCSR_ALLF)))
     (|(cpu_state.sprs[SPR_FPCSR] & SPR_FPCSR_ALLF)))
     except_handle (EXCEPT_FPE, cpu_state.iqueue.insn_addr);
     except_handle (EXCEPT_FPE, cpu_state.iqueue.insn_addr);
   */
   */
 
  // Now clear softfloat's flags:
 
  float_exception_flags = 0;
 
 
 }
 }
 
 
#if COMPLEX_EXECUTION
#if COMPLEX_EXECUTION
 
 
/* Include generated/built in decode_execute function */
/* Include generated/built in decode_execute function */

powered by: WebSVN 2.1.0

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