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.
 
 
 
 
 
 

135 lines
2.7 KiB

#if defined(R3000)
/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
softsqrt.c
Abstract:
This module implements single precision IEEE square root.
Author:
David N. Cutler (davec) 16-Nov-1992
Environment:
User mode only.
Revision History:
--*/
#include "nt.h"
#include "ntrtl.h"
#include "nturtl.h"
#include "windows.h"
//
// Define square root table.
//
ULONG GreSquareRootTable[] = {
83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581,
16499, 12183, 8588, 5674, 3403, 1742, 661, 130,
0, 1204, 3062, 5746, 9193, 13348, 18162, 23592,
29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215};
VOID
vSqrtEFLOAT (
IN PFLOAT Value
)
/*++
Routine Description:
This function computes the single precision IEEE square root of a
specified value.
N.B. The algorithm used is taken from the MIPS math library. It
produces results that are 100% IEEE compliant and compatible
with the R4000 square root instruction.
Arguments:
Value - Supplies a pointer to the value for which the square root is
computed.
Return Value:
The single precision square root of the specified value is returned as
the function value.
--*/
{
DOUBLE DoubleValue;
ULONG Index;
FLOAT SingleEstimate;
FLOAT SingleResult;
FLOAT SingleValue;
DOUBLE TempValue;
union {
DOUBLE DoubleEstimate;
struct {
ULONG LowPart;
ULONG HighPart;
} s;
} u;
//
// Extract bits 19-23 of the mantissa to select the correct entry from
// the square root table.
//
SingleValue = *Value;
Index = ((*(PULONG)&SingleValue) >> 19) & 0x1f;
//
// Bias the mantissa by (127 << 23) - (127 << 22) and subtract out the
// value selected from the square root table multipled by eight.
//
*((PULONG)&SingleEstimate) = (((*(PULONG)&SingleValue) >> 1) +
((127 << 23) - (127 << 22))) - (GreSquareRootTable[Index] << 3);
//
// Refine the estimate value.
//
SingleEstimate = SingleEstimate + *Value / SingleEstimate;
*((PULONG)&SingleEstimate) = *(PULONG)&SingleEstimate - ((1 << 23) + (6 << 3));
//
// Convert to double precision.
//
u.DoubleEstimate = SingleEstimate;
DoubleValue = *Value;
//
// Refine the estimate value.
//
u.DoubleEstimate = u.DoubleEstimate + DoubleValue / u.DoubleEstimate;
TempValue = DoubleValue / u.DoubleEstimate;
u.s.HighPart -= (2 << 20);
//
// Compute the final result and convert to single precision.
//
SingleResult = u.DoubleEstimate + TempValue;
*Value = SingleResult;
return;
}
#endif