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

📄 float.c

📁 wince下的源代码集合打包
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (cause.BD)            ContextBlock.BranchAddress = KiEmulateBranch(pctx);        else            ContextBlock.BranchAddress = pctx->Fir + 4;        //        // Initialize the address of the exception record, exception frame,        // and trap frame in the context block used during the emulation of        // the floating point operation.        //        ContextBlock.ExceptionRecord = ExceptionRecord;        ContextBlock.pctx = pctx;        ContextBlock.Round = ((PFSR)&pctx->Fsr)->RM;        //        // Initialize the number of exception information parameters, set        // the branch address, and clear the IEEE exception value.        //        ExceptionRecord->NumberParameters = 6;        ExceptionRecord->ExceptionInformation[0] = 0;        ExceptionRecord->ExceptionInformation[1] = ContextBlock.BranchAddress;        ExceptionRecord->ExceptionInformation[2] = 0;        ExceptionRecord->ExceptionInformation[3] = 0;        ExceptionRecord->ExceptionInformation[4] = 0;        ExceptionRecord->ExceptionInformation[5] = 0;        //        // Clear all exception flags and emulate the floating point operation        // The return value is dependent on the results of the emulation.        //        pctx->Fsr &= ~(0x3f << 12);        Instruction = *((PMIPS_INSTRUCTION)ExceptionAddress + (cause.BD ? 1 : 0));        Function = Instruction.c_format.Function;        ContextBlock.Fd = Instruction.c_format.Fd;        Fs = Instruction.c_format.Fs;        Ft = Instruction.c_format.Ft;        Format = Instruction.c_format.Format;        Negation = 0;        //        // Check for illegal register specification or format code.        //        if (((ContextBlock.Fd & 0x1) != 0) || ((Fs & 0x1) != 0) || ((Ft & 0x1) != 0) ||            ((Format != FORMAT_LONGWORD) && (Format != FORMAT_QUADWORD) && (Format > FORMAT_DOUBLE))) {            Function = FLOAT_ILLEGAL;        }        //        // Decode operand values and dispose with NaNs.        //        if ((Function <= FLOAT_DIVIDE) || (Function >= FLOAT_COMPARE)) {            //            // The function has two operand values.            //            if (Format == FORMAT_SINGLE) {                KiUnpackSingle(Fs, &ContextBlock, &SingleOperand1);                KiUnpackSingle(Ft, &ContextBlock, &SingleOperand2);                //                // If either operand is a NaN, then check to determine if a                // compare instruction or other dyadic operation is being                // performed.                //                if ((SingleOperand1.Nan != FALSE) || (SingleOperand2.Nan != FALSE)) {                    if (Function < FLOAT_COMPARE) {                        //                        // Dyadic operation.                        //                        // Store a quite Nan if the invalid operation trap                        // is disabled, or raise an exception if the invalid                        // operation trap is enabled and either of the NaNs                        // is a signally NaN.                        //                        return KiInvalidOperationSingle(&ContextBlock,                                                        TRUE,                                                        &SingleOperand1,                                                        &SingleOperand2);                    } else {                        //                        // Compare operation.                        //                        // Set the condition based on the predicate of                        // the floating comparison.                        //                        // If the compare is a signaling compare, then                        // raise an exception if the invalid operation                        // trap is enabled. Otherwise, raise an exception                        // if one of the operands is a signaling NaN.                        //                        if ((Function & COMPARE_UNORDERED_MASK) != 0) {                            ((PFSR)&pctx->Fsr)->CC = 1;                        } else {                            ((PFSR)&pctx->Fsr)->CC = 0;                        }                        if ((Function & COMPARE_ORDERED_MASK) != 0) {                            return KiInvalidCompareSingle(&ContextBlock,                                                          FALSE,                                                          &SingleOperand1,                                                          &SingleOperand2);                        } else {                            return KiInvalidCompareSingle(&ContextBlock,                                                          TRUE,                                                          &SingleOperand1,                                                          &SingleOperand2);                        }                    }                } else if (Function >= FLOAT_COMPARE) {                    CompareFunction = Function;                    Function = FLOAT_COMPARE_SINGLE;                }            } else if (Format == FORMAT_DOUBLE) {                KiUnpackDouble(Fs, &ContextBlock, &DoubleOperand1);                KiUnpackDouble(Ft, &ContextBlock, &DoubleOperand2);                //                // If either operand is a NaN, then check to determine if a                // compare instruction or other dyadic operation is being                // performed.                //                if ((DoubleOperand1.Nan != FALSE) || (DoubleOperand2.Nan != FALSE)) {                    if (Function < FLOAT_COMPARE) {                        //                        // Dyadic operation.                        //                        // Store a quite Nan if the invalid operation trap                        // is disabled, or raise an exception if the invalid                        // operation trap is enabled and either of the NaNs                        // is a signally NaN.                        //                        return KiInvalidOperationDouble(&ContextBlock,                                                        TRUE,                                                        &DoubleOperand1,                                                        &DoubleOperand2);                    } else {                        //                        // Compare operation.                        //                        // Set the condition based on the predicate of                        // the floating comparison.                        //                        // If the compare is a signaling compare, then                        // raise an exception if the invalid operation                        // trap is enabled. Othersie, raise an exception                        // if one of the operands is a signaling NaN.                        //                        if ((Function & COMPARE_UNORDERED_MASK) != 0) {                            ((PFSR)&pctx->Fsr)->CC = 1;                        } else {                            ((PFSR)&pctx->Fsr)->CC = 0;                        }                        if ((Function & COMPARE_ORDERED_MASK) != 0) {                            return KiInvalidCompareDouble(&ContextBlock,                                                          FALSE,                                                          &DoubleOperand1,                                                          &DoubleOperand2);                        } else {                            return KiInvalidCompareDouble(&ContextBlock,                                                          TRUE,                                                          &DoubleOperand1,                                                          &DoubleOperand2);                        }                    }                } else if (Function >= FLOAT_COMPARE) {                    CompareFunction = Function;                    Function = FLOAT_COMPARE_DOUBLE;                }            } else {                Function = FLOAT_ILLEGAL;            }        } else {            //            // The function has one operand value.            //            if (Format == FORMAT_SINGLE) {                KiUnpackSingle(Fs, &ContextBlock, &SingleOperand1);                //                // If the operand is a NaN and the function is not a convert                // operation, then store a quiet NaN if the invalid operation                // trap is disabled, or raise an exception if the invalid                // operation trap is enabled and the operand is a signaling                // NaN.                //                if ((SingleOperand1.Nan != FALSE) &&                    (Function < FLOAT_ROUND_QUADWORD) ||                    (Function > FLOAT_CONVERT_QUADWORD) ||                    ((Function > FLOAT_FLOOR_LONGWORD) &&                    (Function < FLOAT_CONVERT_SINGLE))) {                    return KiInvalidOperationSingle(&ContextBlock,                                                    TRUE,                                                    &SingleOperand1,                                                    &SingleOperand1);                }            } else if (Format == FORMAT_DOUBLE) {                KiUnpackDouble(Fs, &ContextBlock, &DoubleOperand1);                //                // If the operand is a NaN and the function is not a convert                // operation, then store a quiet NaN if the invalid operation                // trap is disabled, or raise an exception if the invalid                // operation trap is enabled and the operand is a signaling                // NaN.                //                if ((DoubleOperand1.Nan != FALSE) &&                    (Function < FLOAT_ROUND_QUADWORD) ||                    (Function > FLOAT_CONVERT_QUADWORD) ||                    ((Function > FLOAT_FLOOR_LONGWORD) &&                    (Function < FLOAT_CONVERT_SINGLE))) {                    return KiInvalidOperationDouble(&ContextBlock,                                                    TRUE,                                                    &DoubleOperand1,                                                    &DoubleOperand1);                }            } else if ((Format == FORMAT_LONGWORD) &&                       (Function >= FLOAT_CONVERT_SINGLE)) {                Longword = KiGetRegisterValue(Fs + 32,                                              ContextBlock.pctx);            } else if ((Format == FORMAT_QUADWORD) &&                       (Function >= FLOAT_CONVERT_SINGLE)) {                u.LargeValue.LowPart = KiGetRegisterValue(Fs + 32,                                                          ContextBlock.pctx);                u.LargeValue.HighPart = KiGetRegisterValue(Fs + 33,                                                           ContextBlock.pctx);            } else {                Function = FLOAT_ILLEGAL;            }        }        //        // Case to the proper function routine to emulate the operation.        //        switch (Function) {            //            // Floating subtract operation.            //            // Floating subtract is accomplished by complementing the sign            // of the second operand and then performing an add operation.            //        case FLOAT_SUBTRACT:            Negation = 0x1;            //            // Floating add operation.            //            // Floating add is accomplished using signed magnitude addition.            //            // The exponent difference is calculated and the smaller number            // is right shifted by the specified amount, but no more than            // the width of the operand values (i.e., 26 for single and 55            // for double). The shifted out value is saved for rounding.            //            // If the signs of the two operands are the same, then they            // are added together after having performed the alignment            // shift.            //            // If the signs of the two operands are different, then the            // sign of the result is the sign of the larger operand and            // the smaller operand is subtracted from the larger operand.            // In order to avoid making a double level test (i.e., one on            // the exponents, and one on the mantissas if the exponents            // are equal), it is posible that the result of the subtract            // could be negative (if the exponents are equal). If this            // occurs, then the result sign and mantissa are complemented            // to obtain the correct result.            //        case FLOAT_ADD:            if (Format == FORMAT_SINGLE) {                //                // Complement the sign of the second operand if the operation                // is subtraction.                //                SingleOperand2.Sign ^= Negation;                //                // Reorder then operands according to their exponent value.                //                if (SingleOperand2.Exponent > SingleOperand1.Exponent) {                    SingleOperand3 = SingleOperand2;                    SingleOperand2 = SingleOperand1;                    SingleOperand1 = SingleOperand3;                }                //                // Compute the exponent difference and shift the smaller                // mantissa right by the difference value or 26 which ever                // is smaller. The bits shifted out are termed the sticky                // bits and are used later in the rounding operation.                //                ExponentDifference =                            SingleOperand1.Exponent - SingleOperand2.Exponent;                if (ExponentDifference > 26) {                    ExponentDifference = 26;                }                StickyBits =                        SingleOperand2.Mantissa & ((1 << ExponentDifference) - 1);                SingleMantissa = SingleOperand2.Mantissa >> ExponentDifference;                //                // If the operands both have the same sign, then perform the                // operation by adding the values together. Otherwise, perform                // the operation by subtracting the second operand from the                // first operand.                //                if ((SingleOperand1.Sign ^ SingleOperand2.Sign) == 0) {                    SingleOperand1.Mantissa += SingleMantissa;                } else {                    if ((SingleOperand1.Infinity != FALSE) &&                        (SingleOperand2.Infinity != FALSE)) {                        return KiInvalidOperationSingle(&ContextBlock,

⌨️ 快捷键说明

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