Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

85 lines
1.7 KiB

/***
*sqrt4000.c - square root for the R4000
*
* Copyright (c) 1991-1991, Microsoft Corporation. All rights reserved.
*
*Purpose:
*
*Revision History:
* 3-31-92 GDP written
*******************************************************************************/
#ifdef R4000
#include <math.h>
#include <trans.h>
static double scale = 4503599627370496.0; // 2^52
static double lgscale = 26; // log2(2^52) / 2
#define SWMASK 0x78
#define INEXACT_MASK 0x4
/***
*double sqrt(double x) - square root
*
*Purpose:
* Compute the square root of a number.
* This function should be provided by the underlying
* hardware (IEEE spec).
*Entry:
*
*Exit:
*
*Exceptions:
* I P
*******************************************************************************/
double sqrt(double x)
{
unsigned int savedcw,cw,sw;
double result,savedx;
int scaled = 0;
// mask exceptions, keep user's rounding mode
savedcw = _ctrlfp(ICW, IMCW & ~IMCW_RC);
if (IS_D_SPECIAL(x)){
switch (_sptype(x)) {
case T_PINF:
RETURN(savedcw, x);
case T_QNAN:
return _handle_qnan1(OP_SQRT, x, savedcw);
case T_SNAN:
return _except1(FP_I,OP_SQRT,x,QNAN_SQRT,savedcw);
}
/* -INF will be handled in the x<0 case */
}
if (x < 0.0) {
return _except1(FP_I, OP_SQRT, x, QNAN_SQRT,savedcw);
}
savedx = x;
if (IS_D_DENORM(x)) {
x *= scale;
scaled = 1;
}
sw = _clrfp();
result = _fsqrt(x);
cw = _get_fsr();
_set_fsr(cw & ~SWMASK | sw & SWMASK); // restore all but inexact
if (scaled) {
result = _add_exp(result, -lgscale);
}
if ((cw & INEXACT_MASK) == INEXACT_MASK) {
return _except1(FP_P,OP_SQRT,savedx,result,savedcw);
}
RETURN(savedcw,result);
}
#endif