Пример #1
0
int FPU_to_exp16(FPU_REG const *a, FPU_REG *x)
{
	int sign = getsign(a);

	*(long long *)&(x->sigl) = *(const long long *)&(a->sigl);

	/* Set up the exponent as a 16 bit quantity. */
	setexponent16(x, exponent(a));

	if (exponent16(x) == EXP_UNDER) {
		/* The number is a de-normal or pseudodenormal. */
		/* We only deal with the significand and exponent. */

		if (x->sigh & 0x80000000) {
			/* Is a pseudodenormal. */
			/* This is non-80486 behaviour because the number
			   loses its 'denormal' identity. */
			addexponent(x, 1);
		} else {
			/* Is a denormal. */
			addexponent(x, 1);
			FPU_normalize_nuo(x);
		}
	}

	if (!(x->sigh & 0x80000000)) {
		EXCEPTION(EX_INTERNAL | 0x180);
	}

	return sign;
}
int FPU_to_exp16(FPU_REG const *a, FPU_REG *x)
{
	int sign = getsign(a);

	*(long long *)&(x->sigl) = *(const long long *)&(a->sigl);

	
	setexponent16(x, exponent(a));

	if (exponent16(x) == EXP_UNDER) {
		
		

		if (x->sigh & 0x80000000) {
			
			addexponent(x, 1);
		} else {
			
			addexponent(x, 1);
			FPU_normalize_nuo(x);
		}
	}

	if (!(x->sigh & 0x80000000)) {
		EXCEPTION(EX_INTERNAL | 0x180);
	}

	return sign;
}
static
int add_sub_specials(FPU_REG const *a, u_char taga, u_char signa,
		     FPU_REG const *b, u_char tagb, u_char signb,
		     FPU_REG * dest, int deststnr, int control_w)
{
	if (((taga == TW_Denormal) || (tagb == TW_Denormal))
	    && (denormal_operand() < 0))
		return FPU_Exception;

	if (taga == TAG_Zero) {
		if (tagb == TAG_Zero) {
			
			u_char different_signs = signa ^ signb;

			FPU_copy_to_regi(a, TAG_Zero, deststnr);
			if (different_signs) {
				
				
				setsign(dest, ((control_w & CW_RC) != RC_DOWN)
					? SIGN_POS : SIGN_NEG);
			} else
				setsign(dest, signa);	
			return TAG_Zero;
		} else {
			reg_copy(b, dest);
			if ((tagb == TW_Denormal) && (b->sigh & 0x80000000)) {
				
				addexponent(dest, 1);
				tagb = TAG_Valid;
			} else if (tagb > TAG_Empty)
				tagb = TAG_Special;
			setsign(dest, signb);	
			FPU_settagi(deststnr, tagb);
			return tagb;
		}
	} else if (tagb == TAG_Zero) {
		reg_copy(a, dest);
		if ((taga == TW_Denormal) && (a->sigh & 0x80000000)) {
			
			addexponent(dest, 1);
			taga = TAG_Valid;
		} else if (taga > TAG_Empty)
			taga = TAG_Special;
		setsign(dest, signa);	
		FPU_settagi(deststnr, taga);
		return taga;
	} else if (taga == TW_Infinity) {
		if ((tagb != TW_Infinity) || (signa == signb)) {
			FPU_copy_to_regi(a, TAG_Special, deststnr);
			setsign(dest, signa);	
			return taga;
		}
		
		return arith_invalid(deststnr);
	} else if (tagb == TW_Infinity) {
		FPU_copy_to_regi(b, TAG_Special, deststnr);
		setsign(dest, signb);	
		return tagb;
	}
#ifdef PARANOID
	EXCEPTION(EX_INTERNAL | 0x101);
#endif

	return FPU_Exception;
}
Пример #4
0
static
int add_sub_specials(FPU_REG const *a, u_char taga, u_char signa,
		     FPU_REG const *b, u_char tagb, u_char signb,
		     FPU_REG *dest, int deststnr, int control_w)
{
  if ( ((taga == TW_Denormal) || (tagb == TW_Denormal))
       && (denormal_operand() < 0) )
    return FPU_Exception;

  if (taga == TAG_Zero)
    {
      if (tagb == TAG_Zero)
	{
	  /* Both are zero, result will be zero. */
	  u_char different_signs = signa ^ signb;

	  FPU_copy_to_regi(a, TAG_Zero, deststnr);
	  if ( different_signs )
	    {
	      /* Signs are different. */
	      /* Sign of answer depends upon rounding mode. */
	      setsign(dest, ((control_w & CW_RC) != RC_DOWN)
		      ? SIGN_POS : SIGN_NEG);
	    }
	  else
	    setsign(dest, signa);  /* signa may differ from the sign of a. */
	  return TAG_Zero;
	}
      else
	{
	  reg_copy(b, dest);
	  if ( (tagb == TW_Denormal) && (b->sigh & 0x80000000) )
	    {
	      /* A pseudoDenormal, convert it. */
	      addexponent(dest, 1);
	      tagb = TAG_Valid;
	    }
	  else if ( tagb > TAG_Empty )
	    tagb = TAG_Special;
	  setsign(dest, signb);  /* signb may differ from the sign of b. */
	  FPU_settagi(deststnr, tagb);
	  return tagb;
	}
    }
  else if (tagb == TAG_Zero)
    {
      reg_copy(a, dest);
      if ( (taga == TW_Denormal) && (a->sigh & 0x80000000) )
	{
	  /* A pseudoDenormal */
	  addexponent(dest, 1);
	  taga = TAG_Valid;
	}
      else if ( taga > TAG_Empty )
	taga = TAG_Special;
      setsign(dest, signa);  /* signa may differ from the sign of a. */
      FPU_settagi(deststnr, taga);
      return taga;
    }
  else if (taga == TW_Infinity)
    {
      if ( (tagb != TW_Infinity) || (signa == signb) )
	{
	  FPU_copy_to_regi(a, TAG_Special, deststnr);
	  setsign(dest, signa);  /* signa may differ from the sign of a. */
	  return taga;
	}
      /* Infinity-Infinity is undefined. */
      return arith_invalid(deststnr);
    }
  else if (tagb == TW_Infinity)
    {
      FPU_copy_to_regi(b, TAG_Special, deststnr);
      setsign(dest, signb);  /* signb may differ from the sign of b. */
      return tagb;
    }

#ifdef PARANOID
  EXCEPTION(EX_INTERNAL|0x101);
#endif

  return FPU_Exception;
}