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

📄 fpusettings.h

📁 这是整套横扫千军3D版游戏的源码
💻 H
📖 第 1 页 / 共 2 页
字号:
    STREFLOP_STMXCSR(sse_mode);
    sse_mode &= ~( excepts << 7 ); // generate error for selection
    STREFLOP_LDMXCSR(sse_mode);

    return 0;
}

/// Clear exceptions for these flags
inline int feclearexcept(int excepts) {
    // Just in case the compiler would store a value on the st(x) registers
    unsigned short x87_mode;
    STREFLOP_FSTCW(x87_mode);
    x87_mode |= excepts;
    STREFLOP_FLDCW(x87_mode);

    int sse_mode;
    STREFLOP_STMXCSR(sse_mode);
    sse_mode |= excepts << 7;
    STREFLOP_LDMXCSR(sse_mode);

    return 0;
}

/// Get current rounding mode
inline int fegetround() {
    int sse_mode;
    STREFLOP_STMXCSR(sse_mode);
    return (sse_mode>>3) & 0x00000C00;
}

/// Set a new rounding mode
inline int fesetround(FPU_RoundMode roundMode) {
    int sse_mode;
    STREFLOP_STMXCSR(sse_mode);
    sse_mode &= 0xFFFF9FFF; // clear current mode
    sse_mode |= roundMode<<3; // sets new mode
    STREFLOP_LDMXCSR(sse_mode);
    return 0;
}

/// stores both x87 and SSE words
struct fenv_t {
    int sse_mode;
    short int x87_mode;
};

/// Default env. Defined in Math.cpp, structs are initialized to 0
extern fenv_t FE_DFL_ENV;

/// Get FP env into the given structure
inline int fegetenv(fenv_t *envp) {
    // check that default env exists, otherwise save it now
    if (!FE_DFL_ENV.x87_mode) STREFLOP_FSTCW(FE_DFL_ENV.x87_mode);
    // Now store env into argument
    STREFLOP_FSTCW(envp->x87_mode);

    // For SSE
    if (!FE_DFL_ENV.sse_mode) STREFLOP_STMXCSR(FE_DFL_ENV.sse_mode);
    // Now store env into argument
    STREFLOP_STMXCSR(envp->sse_mode);
    return 0;
}

/// Sets FP env from the given structure
inline int fesetenv(const fenv_t *envp) {
    // check that default env exists, otherwise save it now
    if (!FE_DFL_ENV.x87_mode) STREFLOP_FSTCW(FE_DFL_ENV.x87_mode);
    // Now overwrite current env by argument
    STREFLOP_FLDCW(envp->x87_mode);

    // For SSE
    if (!FE_DFL_ENV.sse_mode) STREFLOP_STMXCSR(FE_DFL_ENV.sse_mode);
    // Now overwrite current env by argument
    STREFLOP_LDMXCSR(envp->sse_mode);
    return 0;
}

/// get env and clear exceptions
inline int feholdexcept(fenv_t *envp) {
    fegetenv(envp);
    feclearexcept(FE_ALL_EXCEPT);
    return 0;
}


template<typename T> inline void streflop_init() {
    // Do nothing by default, or for unknown types
}

/// Initialize the FPU for the different types
/// this may also be called to switch between code sections using
/// different precisions
template<> inline void streflop_init<Simple>() {
    // Just in case the compiler would store a value on the st(x) registers
    unsigned short x87_mode;
    STREFLOP_FSTCW(x87_mode);
    x87_mode &= 0xFCFF; // 32 bits internal operations
    STREFLOP_FLDCW(x87_mode);

    int sse_mode;
    STREFLOP_STMXCSR(sse_mode);
#if defined(STREFLOP_NO_DENORMALS)
    sse_mode |= 0x8040; // set DAZ and FTZ
#else
    sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ
#endif
    STREFLOP_LDMXCSR(sse_mode);
}

template<> inline void streflop_init<Double>() {
    // Just in case the compiler would store a value on the st(x) registers
    unsigned short x87_mode;
    STREFLOP_FSTCW(x87_mode);
    x87_mode &= 0xFCFF;
    x87_mode |= 0x0200; // 64 bits internal operations
    STREFLOP_FLDCW(x87_mode);

    int sse_mode;
    STREFLOP_STMXCSR(sse_mode);
#if defined(STREFLOP_NO_DENORMALS)
    sse_mode |= 0x8040; // set DAZ and FTZ
#else
    sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ
#endif
    STREFLOP_LDMXCSR(sse_mode);
}

#ifdef Extended
template<> inline void streflop_init<Extended>() {
    // Just in case the compiler would store a value on the st(x) registers
    unsigned short x87_mode;
    STREFLOP_FSTCW(x87_mode);
    x87_mode &= 0xFCFF;
    x87_mode |= 0x0300; // 80 bits internal operations
    STREFLOP_FLDCW(x87_mode);

    int sse_mode;
    STREFLOP_STMXCSR(sse_mode);
#if defined(STREFLOP_NO_DENORMALS)
    sse_mode |= 0x8040; // set DAZ and FTZ
#else
    sse_mode &= 0xFFFF7FBF; // clear DAZ and FTZ
#endif
    STREFLOP_LDMXCSR(sse_mode);
}
#endif


#elif defined(STREFLOP_SOFT)
/// Raise exception for these flags
inline int feraiseexcept(FPU_Exceptions excepts) {
    // Use positive logic
    SoftFloat::float_exception_realtraps |= excepts;
    return 0;
}

/// Clear exceptions for these flags
inline int feclearexcept(int excepts) {
    // Use positive logic
    SoftFloat::float_exception_realtraps &= ~( excepts );
    return 0;
}

/// Get current rounding mode
inline int fegetround() {
    // see softfloat.h for the definition
    switch (SoftFloat::float_rounding_mode) {
        case SoftFloat::float_round_down: return FE_DOWNWARD;
        case SoftFloat::float_round_up: return FE_UPWARD;
        case SoftFloat::float_round_to_zero: return FE_TOWARDZERO;
        default:; // is also initial mode
    }
    // case SoftFloat::float_round_nearest_even:
    return FE_TONEAREST;
}

/// Set a new rounding mode
inline int fesetround(FPU_RoundMode roundMode) {
    // see softfloat.h for the definition
    switch (roundMode) {
        case FE_DOWNWARD: SoftFloat::float_rounding_mode = SoftFloat::float_round_down; return 0;
        case FE_UPWARD: SoftFloat::float_rounding_mode = SoftFloat::float_round_up; return 0;
        case FE_TOWARDZERO: SoftFloat::float_rounding_mode = SoftFloat::float_round_to_zero; return 0;
        case FE_TONEAREST: SoftFloat::float_rounding_mode = SoftFloat::float_round_nearest_even; return 0;
    }
    // Error, invalid mode
    return 1;
}

/// SoftFloat environment comprises non-volatile state variables
struct fenv_t {
    char tininess;
    char rounding_mode;
    int exception_realtraps;
};

/// Default env. Defined in Math.cpp, initialized to some invalid value for detection
extern fenv_t FE_DFL_ENV;

/// Get FP env into the given structure
inline int fegetenv(fenv_t *envp) {
    // check that default env exists, otherwise save it now
    if (FE_DFL_ENV.tininess==42) {
        // First use: save default environment now
        FE_DFL_ENV.tininess = SoftFloat::float_detect_tininess;
        FE_DFL_ENV.rounding_mode = SoftFloat::float_rounding_mode;
        FE_DFL_ENV.exception_realtraps = SoftFloat::float_exception_realtraps;
    }
    // Now get the current env in the given argument
    envp->tininess = SoftFloat::float_detect_tininess;
    envp->rounding_mode = SoftFloat::float_rounding_mode;
    envp->exception_realtraps = SoftFloat::float_exception_realtraps;
    return 0;
}

/// Sets FP env from the given structure
inline int fesetenv(const fenv_t *envp) {
    // check that default env exists, otherwise save it now
    if (FE_DFL_ENV.tininess==42) {
        // First use: save default environment now
        FE_DFL_ENV.tininess = SoftFloat::float_detect_tininess;
        FE_DFL_ENV.rounding_mode = SoftFloat::float_rounding_mode;
        FE_DFL_ENV.exception_realtraps = SoftFloat::float_exception_realtraps;
    }
    // Now get the current env in the given argument
    SoftFloat::float_detect_tininess = envp->tininess;
    SoftFloat::float_rounding_mode = envp->rounding_mode;
    SoftFloat::float_exception_realtraps = envp->exception_realtraps;
    return 0;
}

/// get env and clear exceptions
inline int feholdexcept(fenv_t *envp) {
    fegetenv(envp);
    feclearexcept(FE_ALL_EXCEPT);
    return 0;
}

template<typename T> inline void streflop_init() {
    // Do nothing by default, or for unknown types
}

/// Initialize the FPU for the different types
/// this may also be called to switch between code sections using
/// different precisions
template<> inline void streflop_init<Simple>() {
}
template<> inline void streflop_init<Double>() {
}
template<> inline void streflop_init<Extended>() {
}

#else
#error STREFLOP: Invalid combination or unknown FPU type.
#endif

}

#endif

⌨️ 快捷键说明

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