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

📄 reg_add_.c

📁 汇编源码大全 有各种汇编源码 希望对你有所帮助
💻 C
字号:
/*---------------------------------------------------------------------------+ |  reg_add_sub.c                                                            | |                                                                           | | Functions to add or subtract two registers and put the result in a third. | |                                                                           | | Copyright (C) 1992,1993                                                   | |                       W. Metzenthen, 22 Parker St, Ormond, Vic 3163,      | |                       Australia.  E-mail   billm@vaxc.cc.monash.edu.au    | |                                                                           | |                                                                           | +---------------------------------------------------------------------------*//*---------------------------------------------------------------------------+ | For each function, the destination may be any FPU_REG, including one of   | | the source FPU_REGs.                                                      | +---------------------------------------------------------------------------*/#include "exception.h"#include "reg_constant.h"#include "fpu_emu.h"#include "control_w.h"#include "fpu_system.h"int reg_add(FPU_REG const *a, FPU_REG const *b, FPU_REG *dest, int control_w){  char saved_sign = dest->sign;  int diff;    if ( !(a->tag | b->tag) )    {      /* Both registers are valid */      if (!(a->sign ^ b->sign))	{	  /* signs are the same */	  dest->sign = a->sign;	  if ( reg_u_add(a, b, dest, control_w) )	    {	      dest->sign = saved_sign;	      return 1;	    }	  return 0;	}            /* The signs are different, so do a subtraction */      diff = a->exp - b->exp;      if (!diff)	{	  diff = a->sigh - b->sigh;  /* Works only if ms bits are identical */	  if (!diff)	    {	      diff = a->sigl > b->sigl;	      if (!diff)		diff = -(a->sigl < b->sigl);	    }	}            if (diff > 0)	{	  dest->sign = a->sign;	  if ( reg_u_sub(a, b, dest, control_w) )	    {	      dest->sign = saved_sign;	      return 1;	    }	}      else if ( diff == 0 )	{#ifdef DENORM_OPERAND	  if ( (b->tag == TW_Valid) && (b->exp <= EXP_UNDER) &&	      denormal_operand() )	    return 1;#endif DENORM_OPERAND	  reg_move(&CONST_Z, dest);	  /* sign depends upon rounding mode */	  dest->sign = ((control_w & CW_RC) != RC_DOWN)	    ? SIGN_POS : SIGN_NEG;	}      else	{	  dest->sign = b->sign;	  if ( reg_u_sub(b, a, dest, control_w) )	    {	      dest->sign = saved_sign;	      return 1;	    }	}      return 0;    }  else    {      if ( (a->tag == TW_NaN) || (b->tag == TW_NaN) )	{ return real_2op_NaN(a, b, dest); }      else if (a->tag == TW_Zero)	{	  if (b->tag == TW_Zero)	    {	      char different_signs = a->sign ^ b->sign;	      /* Both are zero, result will be zero. */	      reg_move(a, dest);	      if (different_signs)		{		  /* Signs are different. */		  /* Sign of answer depends upon rounding mode. */		  dest->sign = ((control_w & CW_RC) != RC_DOWN)		    ? SIGN_POS : SIGN_NEG;		}	    }	  else	    {#ifdef DENORM_OPERAND	      if ( (b->tag == TW_Valid) && (b->exp <= EXP_UNDER) &&		  denormal_operand() )		return 1;#endif DENORM_OPERAND	      reg_move(b, dest);	    }	  return 0;	}      else if (b->tag == TW_Zero)	{#ifdef DENORM_OPERAND	  if ( (a->tag == TW_Valid) && (a->exp <= EXP_UNDER) &&	      denormal_operand() )	    return 1;#endif DENORM_OPERAND	  reg_move(a, dest); return 0;	}      else if (a->tag == TW_Infinity)	{	  if (b->tag != TW_Infinity)	    {#ifdef DENORM_OPERAND	      if ( (b->tag == TW_Valid) && (b->exp <= EXP_UNDER) &&		  denormal_operand() )		return 1;#endif DENORM_OPERAND	      reg_move(a, dest); return 0;	    }	  if (a->sign == b->sign)	    {	      /* They are both + or - infinity */	      reg_move(a, dest); return 0;	    }	  return arith_invalid(dest);	/* Infinity-Infinity is undefined. */	}      else if (b->tag == TW_Infinity)	{#ifdef DENORM_OPERAND	  if ( (a->tag == TW_Valid) && (a->exp <= EXP_UNDER) &&	      denormal_operand() )	    return 1;#endif DENORM_OPERAND	  reg_move(b, dest); return 0;	}    }#ifdef PARANOID  EXCEPTION(EX_INTERNAL|0x101);#endif  return 1;}/* Subtract b from a.  (a-b) -> dest */int reg_sub(FPU_REG const *a, FPU_REG const *b, FPU_REG *dest, int control_w){  char saved_sign = dest->sign;  int diff;  if ( !(a->tag | b->tag) )    {      /* Both registers are valid */      diff = a->exp - b->exp;      if (!diff)	{	  diff = a->sigh - b->sigh;  /* Works only if ms bits are identical */	  if (!diff)	    {	      diff = a->sigl > b->sigl;	      if (!diff)		diff = -(a->sigl < b->sigl);	    }	}      switch (a->sign*2 + b->sign)	{	case 0: /* P - P */	case 3: /* N - N */	  if (diff > 0)	    {	      /* |a| > |b| */	      dest->sign = a->sign;	      if ( reg_u_sub(a, b, dest, control_w) )		{		  dest->sign = saved_sign;		  return 1;		}	      return 0;	    }	  else if ( diff == 0 )	    {#ifdef DENORM_OPERAND	      if ( (b->tag == TW_Valid) && (b->exp <= EXP_UNDER) &&		  denormal_operand() )		return 1;#endif DENORM_OPERAND	      reg_move(&CONST_Z, dest);	      /* sign depends upon rounding mode */	      dest->sign = ((control_w & CW_RC) != RC_DOWN)		? SIGN_POS : SIGN_NEG;	    }	  else	    {	      dest->sign = a->sign ^ SIGN_POS^SIGN_NEG;	      if ( reg_u_sub(b, a, dest, control_w) )		{		  dest->sign = saved_sign;		  return 1;		}	    }	  break;	case 1: /* P - N */	  dest->sign = SIGN_POS;	  if ( reg_u_add(a, b, dest, control_w) )	    {	      dest->sign = saved_sign;	      return 1;	    }	  break;	case 2: /* N - P */	  dest->sign = SIGN_NEG;	  if ( reg_u_add(a, b, dest, control_w) )	    {	      dest->sign = saved_sign;	      return 1;	    }	  break;	}      return 0;    }  else    {      if ( (a->tag == TW_NaN) || (b->tag == TW_NaN) )	{ return real_2op_NaN(b, a, dest); }      else if (b->tag == TW_Zero)	{ 	  if (a->tag == TW_Zero)	    {	      char same_signs = !(a->sign ^ b->sign);	      /* Both are zero, result will be zero. */	      reg_move(a, dest); /* Answer for different signs. */	      if (same_signs)		{		  /* Sign depends upon rounding mode */		  dest->sign = ((control_w & CW_RC) != RC_DOWN)		    ? SIGN_POS : SIGN_NEG;		}	    }	  else	    {#ifdef DENORM_OPERAND	      if ( (a->tag == TW_Valid) && (a->exp <= EXP_UNDER) &&		  denormal_operand() )		return 1;#endif DENORM_OPERAND	      reg_move(a, dest);	    }	  return 0;	}      else if (a->tag == TW_Zero)	{#ifdef DENORM_OPERAND	  if ( (b->tag == TW_Valid) && (b->exp <= EXP_UNDER) &&	      denormal_operand() )	    return 1;#endif DENORM_OPERAND	  reg_move(b, dest);	  dest->sign ^= SIGN_POS^SIGN_NEG;	  return 0;	}      else if (a->tag == TW_Infinity)	{	  if (b->tag != TW_Infinity)	    {#ifdef DENORM_OPERAND	      if ( (b->tag == TW_Valid) && (b->exp <= EXP_UNDER) &&		  denormal_operand() )		return 1;#endif DENORM_OPERAND	      reg_move(a, dest); return 0;	    }	  /* Both args are Infinity */	  if (a->sign == b->sign)	    {	      /* Infinity-Infinity is undefined. */	      return arith_invalid(dest);	    }	  reg_move(a, dest);	  return 0;	}      else if (b->tag == TW_Infinity)	{#ifdef DENORM_OPERAND	  if ( (a->tag == TW_Valid) && (a->exp <= EXP_UNDER) &&	      denormal_operand() )	    return 1;#endif DENORM_OPERAND	  reg_move(b, dest);	  dest->sign ^= SIGN_POS^SIGN_NEG;	  return 0;	}    }#ifdef PARANOID  EXCEPTION(EX_INTERNAL|0x110);#endif  return 1;}

⌨️ 快捷键说明

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