⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cp1.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*> cp1.c <*//* MIPS Simulator FPU (CoProcessor 1) support.   Copyright (C) 2002 Free Software Foundation, Inc.   Originally created by Cygnus Solutions.  Extensive modifications,   including paired-single operation support and MIPS-3D support   contributed by Ed Satterthwaite and Chris Demetriou, of Broadcom   Corporation (SiByte).This file is part of GDB, the GNU debugger.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public License alongwith this program; if not, write to the Free Software Foundation, Inc.,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  *//* XXX: The following notice should be removed as soon as is practical:  *//* Floating Point Support for gdb MIPS simulators   This file is part of the MIPS sim		THIS SOFTWARE IS NOT COPYRIGHTED   (by Cygnus.)   Cygnus offers the following for use in the public domain.  Cygnus   makes no warranty with regard to the software or it's performance   and the user accepts the software "AS IS" with all faults.   CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO   THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.   (Originally, this code was in interp.c)*/#include "sim-main.h"/* Within cp1.c we refer to sim_cpu directly.  */#define CPU cpu#define SD CPU_STATE(cpu)/*-- FPU support routines ---------------------------------------------------*//* Numbers are held in normalized form. The SINGLE and DOUBLE binary   formats conform to ANSI/IEEE Std 754-1985.   SINGLE precision floating:      seeeeeeeefffffffffffffffffffffff        s =  1bit  = sign        e =  8bits = exponent        f = 23bits = fraction   SINGLE precision fixed:      siiiiiiiiiiiiiiiiiiiiiiiiiiiiiii        s =  1bit  = sign        i = 31bits = integer   DOUBLE precision floating:      seeeeeeeeeeeffffffffffffffffffffffffffffffffffffffffffffffffffff        s =  1bit  = sign        e = 11bits = exponent        f = 52bits = fraction   DOUBLE precision fixed:      siiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii        s =  1bit  = sign        i = 63bits = integer   PAIRED SINGLE precision floating:      seeeeeeeefffffffffffffffffffffffseeeeeeeefffffffffffffffffffffff      |         upper                ||         lower                |        s =  1bit  = sign        e =  8bits = exponent        f = 23bits = fraction    Note: upper = [63..32], lower = [31..0] *//* Extract packed single values:  */#define FP_PS_upper(v) (((v) >> 32) & (unsigned)0xFFFFFFFF)#define FP_PS_lower(v) ((v) & (unsigned)0xFFFFFFFF)#define FP_PS_cat(u,l) (((unsigned64)((u) & (unsigned)0xFFFFFFFF) << 32) \                        | (unsigned64)((l) & 0xFFFFFFFF))/* Explicit QNaN values.  */#define FPQNaN_SINGLE   (0x7FBFFFFF)#define FPQNaN_WORD     (0x7FFFFFFF)#define FPQNaN_DOUBLE   (UNSIGNED64 (0x7FF7FFFFFFFFFFFF))#define FPQNaN_LONG     (UNSIGNED64 (0x7FFFFFFFFFFFFFFF))#define FPQNaN_PS       (FP_PS_cat (FPQNaN_SINGLE, FPQNaN_SINGLE))static const char *fpu_format_name (FP_formats fmt);#ifdef DEBUGstatic const char *fpu_rounding_mode_name (int rm);#endifuword64value_fpr (sim_cpu *cpu,	   address_word cia,	   int fpr,	   FP_formats fmt){  uword64 value = 0;  int err = 0;  /* Treat unused register values, as fixed-point 64bit values.  */  if ((fmt == fmt_uninterpreted) || (fmt == fmt_unknown))    {#if 1      /* If request to read data as "uninterpreted", then use the current	 encoding:  */      fmt = FPR_STATE[fpr];#else      fmt = fmt_long;#endif    }  /* For values not yet accessed, set to the desired format.  */  if (FPR_STATE[fpr] == fmt_uninterpreted)    {      FPR_STATE[fpr] = fmt;#ifdef DEBUG      printf ("DBG: Register %d was fmt_uninterpreted. Now %s\n", fpr,	      fpu_format_name (fmt));#endif /* DEBUG */    }  if (fmt != FPR_STATE[fpr])    {      sim_io_eprintf (SD, "FPR %d (format %s) being accessed with format %s - setting to unknown (PC = 0x%s)\n",		      fpr, fpu_format_name (FPR_STATE[fpr]),		      fpu_format_name (fmt), pr_addr (cia));      FPR_STATE[fpr] = fmt_unknown;    }  if (FPR_STATE[fpr] == fmt_unknown)    {      /* Set QNaN value:  */      switch (fmt)	{	case fmt_single:  value = FPQNaN_SINGLE;  break;	case fmt_double:  value = FPQNaN_DOUBLE;  break;	case fmt_word:    value = FPQNaN_WORD;    break;	case fmt_long:    value = FPQNaN_LONG;    break;	case fmt_ps:      value = FPQNaN_PS;      break;	default:          err = -1;               break;	}    }  else if (SizeFGR () == 64)    {      switch (fmt)	{	case fmt_single:	case fmt_word:	  value = (FGR[fpr] & 0xFFFFFFFF);	  break;	case fmt_uninterpreted:	case fmt_double:	case fmt_long:	case fmt_ps:	  value = FGR[fpr];	  break;	default:	  err = -1;	  break;	}    }  else    {      switch (fmt)	{	case fmt_single:	case fmt_word:	  value = (FGR[fpr] & 0xFFFFFFFF);	  break;	case fmt_uninterpreted:	case fmt_double:	case fmt_long:	  if ((fpr & 1) == 0)	    {	      /* Even register numbers only.  */#ifdef DEBUG	      printf ("DBG: ValueFPR: FGR[%d] = %s, FGR[%d] = %s\n",		      fpr + 1, pr_uword64 ((uword64) FGR[fpr+1]),		      fpr, pr_uword64 ((uword64) FGR[fpr]));#endif	      value = ((((uword64) FGR[fpr+1]) << 32)		       | (FGR[fpr] & 0xFFFFFFFF));	    }	  else	    {	      SignalException (ReservedInstruction, 0);	    }	  break;	case fmt_ps:	  SignalException (ReservedInstruction, 0);	  break;	default:	  err = -1;	  break;	}    }  if (err)    SignalExceptionSimulatorFault ("Unrecognised FP format in ValueFPR ()");#ifdef DEBUG  printf ("DBG: ValueFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d\n",	  fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),	  SizeFGR ());#endif /* DEBUG */  return (value);}voidstore_fpr (sim_cpu *cpu,	   address_word cia,	   int fpr,	   FP_formats fmt,	   uword64 value){  int err = 0;#ifdef DEBUG  printf ("DBG: StoreFPR: fpr = %d, fmt = %s, value = 0x%s : PC = 0x%s : SizeFGR () = %d, \n",	  fpr, fpu_format_name (fmt), pr_uword64 (value), pr_addr (cia),	  SizeFGR ());#endif /* DEBUG */  if (SizeFGR () == 64)    {      switch (fmt)	{	case fmt_uninterpreted_32:	  fmt = fmt_uninterpreted;	case fmt_single:	case fmt_word:	  if (STATE_VERBOSE_P (SD))	    sim_io_eprintf (SD,			    "Warning: PC 0x%s: interp.c store_fpr DEADCODE\n",			    pr_addr (cia));	  FGR[fpr] = (((uword64) 0xDEADC0DE << 32) | (value & 0xFFFFFFFF));	  FPR_STATE[fpr] = fmt;	  break;	case fmt_uninterpreted_64:	  fmt = fmt_uninterpreted;	case fmt_uninterpreted:	case fmt_double:	case fmt_long:	case fmt_ps:	  FGR[fpr] = value;	  FPR_STATE[fpr] = fmt;	  break;	default:	  FPR_STATE[fpr] = fmt_unknown;	  err = -1;	  break;	}    }  else    {      switch (fmt)	{	case fmt_uninterpreted_32:	  fmt = fmt_uninterpreted;	case fmt_single:	case fmt_word:	  FGR[fpr] = (value & 0xFFFFFFFF);	  FPR_STATE[fpr] = fmt;	  break;	case fmt_uninterpreted_64:	  fmt = fmt_uninterpreted;	case fmt_uninterpreted:	case fmt_double:	case fmt_long:	  if ((fpr & 1) == 0)	    {	      /* Even register numbers only.  */	      FGR[fpr+1] = (value >> 32);	      FGR[fpr] = (value & 0xFFFFFFFF);	      FPR_STATE[fpr + 1] = fmt;	      FPR_STATE[fpr] = fmt;	    }	  else	    {	      FPR_STATE[fpr] = fmt_unknown;	      FPR_STATE[fpr + 1] = fmt_unknown;	      SignalException (ReservedInstruction, 0);	    }	  break;	case fmt_ps:	  FPR_STATE[fpr] = fmt_unknown;	  SignalException (ReservedInstruction, 0);	  break;	default:	  FPR_STATE[fpr] = fmt_unknown;	  err = -1;	  break;	}    }  if (err)    SignalExceptionSimulatorFault ("Unrecognised FP format in StoreFPR ()");#ifdef DEBUG  printf ("DBG: StoreFPR: fpr[%d] = 0x%s (format %s)\n",	  fpr, pr_uword64 (FGR[fpr]), fpu_format_name (fmt));#endif /* DEBUG */  return;}/* CP1 control/status register access functions.  */voidtest_fcsr (sim_cpu *cpu,	   address_word cia){  unsigned int cause;  cause = (FCSR & fcsr_CAUSE_mask) >> fcsr_CAUSE_shift;  if ((cause & ((FCSR & fcsr_ENABLES_mask) >> fcsr_ENABLES_shift)) != 0      || (cause & (1 << UO)))    {      SignalExceptionFPE();    }}unsigned_wordvalue_fcr(sim_cpu *cpu,	  address_word cia,	  int fcr){  unsigned32 value = 0;  switch (fcr)    {    case 0:  /* FP Implementation and Revision Register.  */      value = FCR0;      break;    case 25:  /* FP Condition Codes Register (derived from FCSR).  */      value = (FCR31 & fcsr_FCC_mask) >> fcsr_FCC_shift;      value = (value & 0x1) | (value >> 1);   /* Close FCC gap.  */      break;    case 26:  /* FP Exceptions Register (derived from FCSR).  */      value = FCR31 & (fcsr_CAUSE_mask | fcsr_FLAGS_mask);      break;    case 28:  /* FP Enables Register (derived from FCSR).  */      value = FCR31 & (fcsr_ENABLES_mask | fcsr_RM_mask);      if ((FCR31 & fcsr_FS) != 0)	value |= fenr_FS;      break;    case 31:  /* FP Control/Status Register (FCSR).  */      value = FCR31 & ~fcsr_ZERO_mask;      break;    }  return (EXTEND32 (value));}voidstore_fcr(sim_cpu *cpu,	  address_word cia,	  int fcr,	  unsigned_word value){  unsigned32 v;  v = VL4_8(value);  switch (fcr)    {    case 25:  /* FP Condition Codes Register (stored into FCSR).  */      v = (v << 1) | (v & 0x1);             /* Adjust for FCC gap.  */      FCR31 &= ~fcsr_FCC_mask;      FCR31 |= ((v << fcsr_FCC_shift) & fcsr_FCC_mask);      break;    case 26:  /* FP Exceptions Register (stored into FCSR).  */      FCR31 &= ~(fcsr_CAUSE_mask | fcsr_FLAGS_mask);      FCR31 |= (v & (fcsr_CAUSE_mask | fcsr_FLAGS_mask));      test_fcsr(cpu, cia);      break;    case 28:  /* FP Enables Register (stored into FCSR).  */      if ((v & fenr_FS) != 0)	v |= fcsr_FS;      else	v &= ~fcsr_FS;      FCR31 &= (fcsr_FCC_mask | fcsr_CAUSE_mask | fcsr_FLAGS_mask);      FCR31 |= (v & (fcsr_FS | fcsr_ENABLES_mask | fcsr_RM_mask));      test_fcsr(cpu, cia);      break;    case 31:  /* FP Control/Status Register (FCSR).  */      FCR31 = v & ~fcsr_ZERO_mask;      test_fcsr(cpu, cia);      break;    }}voidupdate_fcsr (sim_cpu *cpu,	     address_word cia,	     sim_fpu_status status){  FCSR &= ~fcsr_CAUSE_mask;  if (status != 0)    {      unsigned int cause = 0;      /* map between sim_fpu codes and MIPS FCSR */      if (status & (sim_fpu_status_invalid_snan		    | sim_fpu_status_invalid_isi		    | sim_fpu_status_invalid_idi		    | sim_fpu_status_invalid_zdz		    | sim_fpu_status_invalid_imz		    | sim_fpu_status_invalid_cmp		    | sim_fpu_status_invalid_sqrt		    | sim_fpu_status_invalid_cvi))	cause |= (1 << IO);      if (status & sim_fpu_status_invalid_div0)	cause |= (1 << DZ);      if (status & sim_fpu_status_overflow)	cause |= (1 << OF);      if (status & sim_fpu_status_underflow)	cause |= (1 << UF);      if (status & sim_fpu_status_inexact)	cause |= (1 << IR);#if 0 /* Not yet.  */      /* Implicit clearing of other bits by unimplemented done by callers.  */      if (status & sim_fpu_status_unimplemented)	cause |= (1 << UO);#endif      FCSR |= (cause << fcsr_CAUSE_shift);      test_fcsr (cpu, cia);      FCSR |= ((cause & ~(1 << UO)) << fcsr_FLAGS_shift);    }  return;}static sim_fpu_roundrounding_mode(int rm){  sim_fpu_round round;  switch (rm)    {    case FP_RM_NEAREST:      /* Round result to nearest representable value. When two	 representable values are equally near, round to the value	 that has a least significant bit of zero (i.e. is even).  */      round = sim_fpu_round_near;      break;    case FP_RM_TOZERO:      /* Round result to the value closest to, and not greater in	 magnitude than, the result.  */      round = sim_fpu_round_zero;      break;    case FP_RM_TOPINF:      /* Round result to the value closest to, and not less than,	 the result.  */      round = sim_fpu_round_up;      break;    case FP_RM_TOMINF:      /* Round result to the value closest to, and not greater than,	 the result.  */      round = sim_fpu_round_down;      break;    default:      round = 0;      fprintf (stderr, "Bad switch\n");      abort ();    }  return round;}/* When the FS bit is set, MIPS processors return zero for   denormalized results and optionally replace denormalized inputs   with zero.  When FS is clear, some implementation trap on input   and/or output, while other perform the operation in hardware.  */static sim_fpu_denormdenorm_mode(sim_cpu *cpu){  sim_fpu_denorm denorm;  /* XXX: FIXME: Eventually should be CPU model dependent.  */  if (GETFS())    denorm = sim_fpu_denorm_zero;  else    denorm = 0;  return denorm;}/* Comparison operations.  */static sim_fpu_statusfp_test(unsigned64 op1,	unsigned64 op2,	FP_formats fmt,	int abs,	int cond,	int *condition){  sim_fpu wop1;  sim_fpu wop2;  sim_fpu_status status = 0;  int  less, equal, unordered;  /* The format type has already been checked:  */  switch (fmt)    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -