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

📄 float.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
#ifdef MIPS_HAS_FPU

/*++


Module Name:

    floatem.c

Abstract:

    This module implements a software emulation of the IEEE single and
    double floating operations. It is required on MIPS processors since
    the hardware does not fully support all of the operations required
    by the IEEE standard. In particular, infinitives and Nans are not
    handled by the hardware, but rather cause an exception. On receipt
    of the exception, a software emulation of the floating operation
    is performed to determine the real result of the operation and if
    an exception will actually be raised.

    Since floating exceptions are rather rare events, this routine is
    written in C. Should a higher performance implementation be required,
    then the algorithms contained herein, can be used to guide a higher
    performance assembly language implementation.

    N.B. This routine does not emulate floating loads, floating stores,
        control to/from floating, or move to/from floating instructions.
        These instructions either do not fault or are emulated elsewhere.

    Floating point operations are carried out by unpacking the operands,
    normalizing denormalized numbers, checking for NaNs, interpreting
    infinities, and computing results.

    Floating operands are converted to a format that has a value with the
    appropriate number of leading zeros, an overflow bit, the mantissa, a
    guard bit, a round bit, and a set of sticky bits.

    The overflow bit is needed for addition and is also used for multiply.
    The mantissa is 24-bits for single operations and 53-bits for double
    operations. The guard bit and round bit are used to hold precise values
    for normalization and rounding.

    If the result of an operation is normalized, then the guard bit becomes
    the round bit and the round bit is accumulated with the sticky bits. If
    the result of an operation needs to be shifted left one bit for purposes
    of nomalization, then the guard bit becomes part of the mantissa and the
    round bit is used for rounding.

    The round bit plus the sticky bits are used to determine how rounding is
    performed.

Environment:

    Kernel mode only.

--*/

#include "kernel.h"
#include "ntxcapi.h"

//
// Define signaling NaN mask values.
//

#define DOUBLE_SIGNAL_NAN_MASK (1 << (53 - 32))
#define SINGLE_SIGNAL_NAN_MASK (1 << 24)

//
// Define quite NaN mask values.
//

#define DOUBLE_QUIET_NAN_MASK (1 << (51 - 32))
#define SINGLE_QUIET_NAN_MASK (1 << 22)

//
// Define quiet NaN prefix values.
//

#define DOUBLE_QUIET_NAN_PREFIX 0x7ff00000
#define SINGLE_QUIET_NAN_PREFIX 0x7f800000

//
// Define compare function masks.
//

#define COMPARE_UNORDERED_MASK (1 << 0)
#define COMPARE_EQUAL_MASK (1 << 1)
#define COMPARE_LESS_MASK (1 << 2)
#define COMPARE_ORDERED_MASK (1 << 3)

//
// Define context block structure.
//

typedef struct _FP_CONTEXT_BLOCK {
    ULONG Fd;
    ULONG BranchAddress;
    PEXCEPTION_RECORD ExceptionRecord;
    PCONTEXT pctx;
    ULONG Round;
} FP_CONTEXT_BLOCK, *PFP_CONTEXT_BLOCK;

//
// Define single and double operand value structures.
//

typedef struct _FP_DOUBLE_OPERAND {
    union {
        struct {
            ULONG MantissaLow;
            LONG MantissaHigh;
        };

        LONGLONG Mantissa;
    };

    LONG Exponent;
    LONG Sign;
    BOOLEAN Infinity;
    BOOLEAN Nan;
} FP_DOUBLE_OPERAND, *PFP_DOUBLE_OPERAND;

typedef struct _FP_SINGLE_OPERAND {
    LONG Mantissa;
    LONG Exponent;
    LONG Sign;
    BOOLEAN Infinity;
    BOOLEAN Nan;
} FP_SINGLE_OPERAND, *PFP_SINGLE_OPERAND;

//
// Define forward referenced function protypes.
//

BOOLEAN
KiDivideByZeroDouble (
    IN PFP_CONTEXT_BLOCK ContextBlock,
    IN PFP_DOUBLE_OPERAND DoubleOperand1,
    IN PFP_DOUBLE_OPERAND DoubleOperand2
    );

BOOLEAN
KiDivideByZeroSingle (
    IN PFP_CONTEXT_BLOCK ContextBlock,
    IN PFP_SINGLE_OPERAND SingleOperand1,
    IN PFP_SINGLE_OPERAND SingleOperand2
    );

BOOLEAN
KiInvalidCompareDouble (
    IN PFP_CONTEXT_BLOCK ContextBlock,
    IN BOOLEAN CheckForNan,
    IN PFP_DOUBLE_OPERAND DoubleOperand1,
    IN PFP_DOUBLE_OPERAND DoubleOperand2
    );

BOOLEAN
KiInvalidCompareSingle (
    IN PFP_CONTEXT_BLOCK ContextBlock,
    IN BOOLEAN CheckForNan,
    IN PFP_SINGLE_OPERAND SingleOperand1,
    IN PFP_SINGLE_OPERAND SingleOperand2
    );

BOOLEAN
KiInvalidOperationDouble (
    IN PFP_CONTEXT_BLOCK ContextBlock,
    IN BOOLEAN CheckForNan,
    IN PFP_DOUBLE_OPERAND DoubleOperand1,
    IN PFP_DOUBLE_OPERAND DoubleOperand2
    );

BOOLEAN
KiInvalidOperationLongword (
    IN PFP_CONTEXT_BLOCK ContextBlock,
    IN BOOLEAN Infinity,
    IN LONG Sign
    );

BOOLEAN
KiInvalidOperationQuadword (
    IN PFP_CONTEXT_BLOCK ContextBlock,
    IN BOOLEAN Infinity,
    IN LONG Sign
    );

BOOLEAN
KiInvalidOperationSingle (
    IN PFP_CONTEXT_BLOCK ContextBlock,
    IN BOOLEAN CheckForNan,
    IN PFP_SINGLE_OPERAND SingleOperand1,
    IN PFP_SINGLE_OPERAND SingleOperand2
    );

BOOLEAN
KiNormalizeDouble (
    IN PFP_CONTEXT_BLOCK ContextBlock,
    IN PFP_DOUBLE_OPERAND ResultOperand,
    IN ULONG StickyBits
    );

BOOLEAN
KiNormalizeLongword (
    IN PFP_CONTEXT_BLOCK ContextBlock,
    IN PFP_DOUBLE_OPERAND ResultOperand
    );

BOOLEAN
KiNormalizeQuadword (
    IN PFP_CONTEXT_BLOCK ContextBlock,
    IN PFP_DOUBLE_OPERAND ResultOperand
    );

BOOLEAN
KiNormalizeSingle (
    IN PFP_CONTEXT_BLOCK ContextBlock,
    IN PFP_SINGLE_OPERAND ResultOperand,
    IN ULONG StickyBits
    );

ULONG
KiSquareRootDouble (
    IN PULARGE_INTEGER DoubleValue
    );

ULONG
KiSquareRootSingle (
    IN PULONG SingleValue
    );

VOID
KiUnpackDouble (
    IN ULONG Source,
    IN PFP_CONTEXT_BLOCK ContextBlock,
    OUT PFP_DOUBLE_OPERAND DoubleOperand
    );

VOID
KiUnpackSingle (
    IN ULONG Source,
    IN PFP_CONTEXT_BLOCK ContextBlock,
    OUT PFP_SINGLE_OPERAND SingleOperand
    );

ULONG
KiEmulateBranch (
    IN PCONTEXT pctx
    );
    
VOID
KiSetRegisterValue (
    IN ULONG Register,
    IN ULONG Value,
    IN PCONTEXT pctx
    );

ULONG
KiGetRegisterValue (
    IN ULONG Register,
    IN PCONTEXT pctx
    );

VOID
KiSetRegisterDouble (
    IN ULONG Register,
    IN ULONGLONG Value,
    IN PCONTEXT pctx
    );

ULONGLONG
KiGetRegisterDouble (
    IN ULONG Register,
    IN PCONTEXT pctx
    );

BOOL HandleHWFloatException(EXCEPTION_RECORD *ExceptionRecord, PCONTEXT pctx, CAUSE cause) {

//BOOLEAN
//KiEmulateFloating (
//    IN OUT PEXCEPTION_RECORD ExceptionRecord,
//    IN OUT PKEXCEPTION_FRAME ExceptionFrame,
//    IN OUT PKTRAP_FRAME TrapFrame
//    )

/*++

Routine Description:

    This function is called to emulate a floating operation and convert the
    exception status to the proper value. If the exception is an unimplemented
    operation, then the operation is emulated. Otherwise, the status code is
    just converted to its proper value.

Arguments:

    ExceptionRecord - Supplies a pointer to an exception record.

    ExceptionFrame - Supplies a pointer to an exception frame.

    TrapFrame - Supplies a pointer to a trap frame.

Return Value:

    A value of TRUE is returned if the floating exception is successfully
    emulated. Otherwise, a value of FALSE is returned.

--*/

    ULARGE_INTEGER AhighBhigh;
    ULARGE_INTEGER AhighBlow;
    ULARGE_INTEGER AlowBhigh;
    ULARGE_INTEGER AlowBlow;
    ULONG Carry1;
    ULONG Carry2;
    BOOLEAN CompareEqual;
    ULONG CompareFunction;
    BOOLEAN CompareLess;
    FP_CONTEXT_BLOCK ContextBlock;
    LARGE_INTEGER DoubleDividend;
    LARGE_INTEGER DoubleDivisor;
    ULARGE_INTEGER DoubleValue;
    ULONG DoubleMantissaLow;
    LONG DoubleMantissaHigh;
    FP_DOUBLE_OPERAND DoubleOperand1;
    FP_DOUBLE_OPERAND DoubleOperand2;
    FP_DOUBLE_OPERAND DoubleOperand3;
    LARGE_INTEGER DoubleQuotient;
    PVOID ExceptionAddress;
    ULONG ExponentDifference;
    ULONG Format;
    ULONG Fs;
    ULONG Ft;
#ifdef _MIPS64
    ULONG Fr;

⌨️ 快捷键说明

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