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

📄 mipsfp.c

📁 eCos1.31版
💻 C
📖 第 1 页 / 共 2 页
字号:
                // that's inadvisable if both numbers are very small.                // Particularly if this is DIV_INSN, when we could therefore                // get 0/0 even when the program explicitly checked for                // denominator != 0. That's also why we check s1 first.                else if (  issubnormal( s2 ) ) {  // flush to 0 and restart                    // but preserve sign                    if (s2.number.sign)                        s2.value = -0.0;                    else                        s2.value = 0.0;                    *srcreg2 = s2.asi64;                    handled++;                }            } else { // 32-bit                Cyg_libm_ieee_float_shape_type s1, s2;                reg2flt( srcreg1, &s1 );                reg2flt( srcreg2, &s2 );                if ( issubnormal( s1 )) {  // flush to 0 and restart                    // but preserve sign                    if (s1.number.sign)                        s1.value = -0.0;                    else                        s1.value = 0.0;                    flt2reg( &s1, srcreg1 );                    handled++;                }                else if ( issubnormal( s2 ) ) {  // flush to 0 and restart                    // but preserve sign                    if (s2.number.sign)                        s2.value = -0.0;                    else                        s2.value = 0.0;                    flt2reg( &s2, srcreg2 );                    handled++;                }            }            break;        case SQRT_INSN:            if ( fp64bit ) {                Cyg_libm_ieee_double_shape_type d, s;                d.asi64 = *dstreg;                s.asi64 = *srcreg1;                if ( issubnormal( s ) ) {  // Sqrt of something tiny is 0                    // if this is a delay slot, we can't restart properly                    // so if it is subnormal, clear the source register instead                    if ( delay_slot ) {                        // but preserve sign                        if (s.number.sign)                            s.value = -0.0;                        else                            s.value = 0.0;                        *srcreg1 = s.asi64;                    } else {                        // but preserve sign                        if (s.number.sign)                            d.value = -0.0;                        else                            d.value = 0.0;                        *dstreg = d.asi64;                        regs->pc += 4; // We've dealt with this so move on                    }                    handled++;                }            } else { // 32-bit                Cyg_libm_ieee_float_shape_type d, s;                reg2flt( dstreg, &d );                reg2flt( srcreg1, &s );                if ( issubnormal( s ) ) {  // Sqrt of something tiny is 0                    // if this is a delay slot, we can't restart properly                    // so if it is subnormal, clear the source register instead                    if ( delay_slot ) {                        // but preserve sign                        if (s.number.sign)                            s.value = -0.0;                        else                            s.value = 0.0;                        flt2reg( &s, srcreg1 );                    } else {                        // but preserve sign                        if (s.number.sign)                            d.value = -0.0;                        else                            d.value = 0.0;                        flt2reg( &d, dstreg );                        regs->pc += 4; // We've dealt with this so move on                    }                    handled++;                }            }            break;        case ABS_INSN:            // We may as well do this right if we can            if ( fp64bit ) {                Cyg_libm_ieee_double_shape_type d, s;                d.asi64 = *dstreg;                s.asi64 = *srcreg1;                // if this is a delay slot, we can't restart properly                // so if it is subnormal, clear the source register instead                if ( delay_slot ) {                    if ( issubnormal( s ) ) {                        // The sign is still important for abs in case                        // there are any further operations on the same                        // register                        if (s.number.sign)                            s.value = -0.0;                        else                            s.value = 0.0;                        *srcreg1 = s.asi64;                        handled++;                    }                } else {                    d.asi64 = s.asi64;                    d.number.sign = 0;                    *dstreg = d.asi64;                    regs->pc += 4;                    handled++;                }            } else { // 32-bit                Cyg_libm_ieee_float_shape_type d, s;                reg2flt( dstreg, &d );                reg2flt( srcreg1, &s );                // if this is a delay slot, we can't restart properly                // so if it is subnormal, clear the source register instead                if ( delay_slot ) {                    if ( issubnormal( s ) ) {                        // The sign is still important for abs in case                        // there are any further operations on the same                        // register                        if (s.number.sign)                            s.value = -0.0;                        else                            s.value = 0.0;                        flt2reg( &s, srcreg1 );                        handled++;                    }                } else {                    d.asi32 = s.asi32;                    d.number.sign = 0;                    flt2reg( &d, dstreg );                    regs->pc += 4;                    handled++;                }            }            break;        case MOV_INSN:            // We may as well do this right if we can            if ( fp64bit ) {                Cyg_libm_ieee_double_shape_type d, s;                d.asi64 = *dstreg;                s.asi64 = *srcreg1;                // if this is a delay slot, we can't restart properly                // so if it is subnormal, clear the source register instead                if ( delay_slot ) {                    if ( issubnormal( s ) ) {                        // but preserve sign                        if (s.number.sign)                            s.value = -0.0;                        else                            s.value = 0.0;                        *srcreg1 = s.asi64;                        handled++;                    }                } else {                    d.asi64 = s.asi64;                    *dstreg = d.asi64;                    regs->pc += 4;                    handled++;                }            } else { // 32-bit                Cyg_libm_ieee_float_shape_type d, s;                reg2flt( dstreg, &d );                reg2flt( srcreg1, &s );                // if this is a delay slot, we can't restart properly                // so if it is subnormal, clear the source register instead                if ( delay_slot ) {                    if ( issubnormal( s ) ) {                        // The sign is still important for abs in case                        // there are any further operations on the same                        // register                        if (s.number.sign)                            s.value = -0.0;                        else                            s.value = 0.0;                        flt2reg( &s, srcreg1 );                        handled++;                    }                } else {                    d.asi32 = s.asi32;                    flt2reg( &d, dstreg );                    regs->pc += 4;                    handled++;                }            }            break;        case NEG_INSN:            // We may as well do this right if we can            if ( fp64bit ) {                Cyg_libm_ieee_double_shape_type d, s;                d.asi64 = *dstreg;                s.asi64 = *srcreg1;                // if this is a delay slot, we can't restart properly                // so if it is subnormal, clear the source register instead                if ( delay_slot ) {                    if ( issubnormal( s ) ) {                        // but preserve sign                        if (s.number.sign)                            s.value = -0.0;                        else                            s.value = 0.0;                        *srcreg1 = s.asi64;                        handled++;                    }                } else {                    d.asi64 = s.asi64;                    d.number.sign = s.number.sign ? 0 : 1;                    *dstreg = d.asi64;                    regs->pc += 4;                    handled++;                }            } else { // 32-bit                Cyg_libm_ieee_float_shape_type d, s;                reg2flt( dstreg, &d );                reg2flt( srcreg1, &s );                // if this is a delay slot, we can't restart properly                // so if it is subnormal, clear the source register instead                if ( delay_slot ) {                    if ( issubnormal( s ) ) {                        // but preserve sign                        if (s.number.sign)                            s.value = -0.0;                        else                            s.value = 0.0;                        flt2reg( &s, srcreg1 );                        handled++;                    }                } else {                    d.asi32 = s.asi32;                    d.number.sign = s.number.sign ? 0 : 1;                    flt2reg( &d, dstreg );                    regs->pc += 4;                    handled++;                }            }            break;        // We can't do much about floating-point to fixed-point arithmetic        // without emulating the FPU here ourselves!        // So simply zero denormalized numbers        case ROUNDL_INSN:        case TRUNCL_INSN:        case CEILL_INSN:        case FLOORL_INSN:        case ROUNDW_INSN:        case TRUNCW_INSN:        case CEILW_INSN:        case FLOORW_INSN:        case CVTS_INSN:        case CVTD_INSN:        case CVTW_INSN:        case CVTL_INSN:                        if ( fp64bit ) {                Cyg_libm_ieee_double_shape_type s;                s.asi64 = *srcreg1;                // just try and 0 the source register if it is subnormal                if ( issubnormal( s ) ) {                    // but preserve sign                    if (s.number.sign)                        s.value = -0.0;                    else                        s.value = 0.0;                    *srcreg1 = s.asi64;                    handled++;                }            } else { // 32-bit                Cyg_libm_ieee_float_shape_type s;                reg2flt( srcreg1, &s );                // just try and 0 the source register if it is subnormal                if ( issubnormal( s ) ) {                    // but preserve sign                    if (s.number.sign)                        s.value = -0.0;                    else                        s.value = 0.0;                    flt2reg( &s, srcreg1 );                    handled++;                }            }            break;        default:            // check for floating-point compare (C.cond.fmt)            if ( (insn & 0x30) == 0x30 ) {                if (fp64bit) {                    Cyg_libm_ieee_double_shape_type s1, s2;                                        s1.asi64 = *srcreg1;                    s2.asi64 = *srcreg2;                                        if ( issubnormal( s1 ) ) {  // flush to 0 and restart                        // but preserve sign                        if (s1.number.sign)                            s1.value = -0.0;                        else                            s1.value = 0.0;                        *srcreg1 = s1.asi64;                        handled++;                    }                                        if (  issubnormal( s2 ) ) {  // flush to 0 and restart                        // but preserve sign                        if (s2.number.sign)                            s2.value = -0.0;                        else                            s2.value = 0.0;                        *srcreg2 = s2.asi64;                        handled++;                    }                                    } else { // 32-bit                    Cyg_libm_ieee_float_shape_type s1, s2;                                        reg2flt( srcreg1, &s1 );                    reg2flt( srcreg2, &s2 );                                        if ( issubnormal( s1 )) {  // flush to 0 and restart                        // but preserve sign                        if (s1.number.sign)                            s1.value = -0.0;                        else                            s1.value = 0.0;                        flt2reg( &s1, srcreg1 );                        handled++;                    }                    if ( issubnormal( s2 ) ) {  // flush to 0 and restart                        // but preserve sign                        if (s2.number.sign)                            s2.value = -0.0;                        else                            s2.value = 0.0;                        flt2reg( &s2, srcreg2 );                        handled++;                    }                } // else             } // if            break;        } // switch    } // if (computational_insn && !fixedpoint)        if ( handled != 0) {        // We must clear the cause and flag bits before restoring FPCR31        regs->fcr31 &= ~(FCR31_CAUSE_E | FCR31_CAUSE_V | FCR31_CAUSE_Z |                         FCR31_CAUSE_O | FCR31_CAUSE_U | FCR31_CAUSE_I |                         FCR31_FLAGS_V | FCR31_FLAGS_Z |                         FCR31_FLAGS_O | FCR31_FLAGS_U | FCR31_FLAGS_I);    }    CYG_REPORT_RETVAL( handled );    return handled;} // cyg_hal_mips_process_fpe()#endif // ifdef CYGHWR_HAL_MIPS_FPU// EOF mipsfp.c

⌨️ 快捷键说明

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