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

📄 op_helper.c.svn-base

📁 我们自己开发的一个OSEK操作系统!不知道可不可以?
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
            else                T0 = 0x02;        } else {            if (isden(FT0)) {                /* Denormalized numbers */                T0 = 0x10;            } else {                /* Normalized numbers */                T0 = 0x00;            }            if (isneg) {                T0 |= 0x08;            } else {                T0 |= 0x04;            }        }    }    if (set_fprf) {        /* We update FPSCR_FPRF */        env->fpscr &= ~(0x1F << FPSCR_FPRF);        env->fpscr |= T0 << FPSCR_FPRF;    }    /* We just need fpcc to update Rc1 */    T0 &= 0xF;}/* Floating-point invalid operations exception */static always_inline void fload_invalid_op_excp (int op){    int ve;    ve = fpscr_ve;    if (op & POWERPC_EXCP_FP_VXSNAN) {        /* Operation on signaling NaN */        env->fpscr |= 1 << FPSCR_VXSNAN;    }    if (op & POWERPC_EXCP_FP_VXSOFT) {        /* Software-defined condition */        env->fpscr |= 1 << FPSCR_VXSOFT;    }    switch (op & ~(POWERPC_EXCP_FP_VXSOFT | POWERPC_EXCP_FP_VXSNAN)) {    case POWERPC_EXCP_FP_VXISI:        /* Magnitude subtraction of infinities */        env->fpscr |= 1 << FPSCR_VXISI;        goto update_arith;    case POWERPC_EXCP_FP_VXIDI:        /* Division of infinity by infinity */        env->fpscr |= 1 << FPSCR_VXIDI;        goto update_arith;    case POWERPC_EXCP_FP_VXZDZ:        /* Division of zero by zero */        env->fpscr |= 1 << FPSCR_VXZDZ;        goto update_arith;    case POWERPC_EXCP_FP_VXIMZ:        /* Multiplication of zero by infinity */        env->fpscr |= 1 << FPSCR_VXIMZ;        goto update_arith;    case POWERPC_EXCP_FP_VXVC:        /* Ordered comparison of NaN */        env->fpscr |= 1 << FPSCR_VXVC;        env->fpscr &= ~(0xF << FPSCR_FPCC);        env->fpscr |= 0x11 << FPSCR_FPCC;        /* We must update the target FPR before raising the exception */        if (ve != 0) {            env->exception_index = POWERPC_EXCP_PROGRAM;            env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_VXVC;            /* Update the floating-point enabled exception summary */            env->fpscr |= 1 << FPSCR_FEX;            /* Exception is differed */            ve = 0;        }        break;    case POWERPC_EXCP_FP_VXSQRT:        /* Square root of a negative number */        env->fpscr |= 1 << FPSCR_VXSQRT;    update_arith:        env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));        if (ve == 0) {            /* Set the result to quiet NaN */            FT0 = UINT64_MAX;            env->fpscr &= ~(0xF << FPSCR_FPCC);            env->fpscr |= 0x11 << FPSCR_FPCC;        }        break;    case POWERPC_EXCP_FP_VXCVI:        /* Invalid conversion */        env->fpscr |= 1 << FPSCR_VXCVI;        env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));        if (ve == 0) {            /* Set the result to quiet NaN */            FT0 = UINT64_MAX;            env->fpscr &= ~(0xF << FPSCR_FPCC);            env->fpscr |= 0x11 << FPSCR_FPCC;        }        break;    }    /* Update the floating-point invalid operation summary */    env->fpscr |= 1 << FPSCR_VX;    /* Update the floating-point exception summary */    env->fpscr |= 1 << FPSCR_FX;    if (ve != 0) {        /* Update the floating-point enabled exception summary */        env->fpscr |= 1 << FPSCR_FEX;        if (msr_fe0 != 0 || msr_fe1 != 0)            do_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_FP | op);    }}static always_inline void float_zero_divide_excp (void){    union {        float64 f;        uint64_t u;    } u0, u1;    env->fpscr |= 1 << FPSCR_ZX;    env->fpscr &= ~((1 << FPSCR_FR) | (1 << FPSCR_FI));    /* Update the floating-point exception summary */    env->fpscr |= 1 << FPSCR_FX;    if (fpscr_ze != 0) {        /* Update the floating-point enabled exception summary */        env->fpscr |= 1 << FPSCR_FEX;        if (msr_fe0 != 0 || msr_fe1 != 0) {            do_raise_exception_err(POWERPC_EXCP_PROGRAM,                                   POWERPC_EXCP_FP | POWERPC_EXCP_FP_ZX);        }    } else {        /* Set the result to infinity */        u0.f = FT0;        u1.f = FT1;        u0.u = ((u0.u ^ u1.u) & 0x8000000000000000ULL);        u0.u |= 0x7FFULL << 52;        FT0 = u0.f;    }}static always_inline void float_overflow_excp (void){    env->fpscr |= 1 << FPSCR_OX;    /* Update the floating-point exception summary */    env->fpscr |= 1 << FPSCR_FX;    if (fpscr_oe != 0) {        /* XXX: should adjust the result */        /* Update the floating-point enabled exception summary */        env->fpscr |= 1 << FPSCR_FEX;        /* We must update the target FPR before raising the exception */        env->exception_index = POWERPC_EXCP_PROGRAM;        env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_OX;    } else {        env->fpscr |= 1 << FPSCR_XX;        env->fpscr |= 1 << FPSCR_FI;    }}static always_inline void float_underflow_excp (void){    env->fpscr |= 1 << FPSCR_UX;    /* Update the floating-point exception summary */    env->fpscr |= 1 << FPSCR_FX;    if (fpscr_ue != 0) {        /* XXX: should adjust the result */        /* Update the floating-point enabled exception summary */        env->fpscr |= 1 << FPSCR_FEX;        /* We must update the target FPR before raising the exception */        env->exception_index = POWERPC_EXCP_PROGRAM;        env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_UX;    }}static always_inline void float_inexact_excp (void){    env->fpscr |= 1 << FPSCR_XX;    /* Update the floating-point exception summary */    env->fpscr |= 1 << FPSCR_FX;    if (fpscr_xe != 0) {        /* Update the floating-point enabled exception summary */        env->fpscr |= 1 << FPSCR_FEX;        /* We must update the target FPR before raising the exception */        env->exception_index = POWERPC_EXCP_PROGRAM;        env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_XX;    }}static always_inline void fpscr_set_rounding_mode (void){    int rnd_type;    /* Set rounding mode */    switch (fpscr_rn) {    case 0:        /* Best approximation (round to nearest) */        rnd_type = float_round_nearest_even;        break;    case 1:        /* Smaller magnitude (round toward zero) */        rnd_type = float_round_to_zero;        break;    case 2:        /* Round toward +infinite */        rnd_type = float_round_up;        break;    default:    case 3:        /* Round toward -infinite */        rnd_type = float_round_down;        break;    }    set_float_rounding_mode(rnd_type, &env->fp_status);}void do_fpscr_setbit (int bit){    int prev;    prev = (env->fpscr >> bit) & 1;    env->fpscr |= 1 << bit;    if (prev == 0) {        switch (bit) {        case FPSCR_VX:            env->fpscr |= 1 << FPSCR_FX;            if (fpscr_ve)                goto raise_ve;        case FPSCR_OX:            env->fpscr |= 1 << FPSCR_FX;            if (fpscr_oe)                goto raise_oe;            break;        case FPSCR_UX:            env->fpscr |= 1 << FPSCR_FX;            if (fpscr_ue)                goto raise_ue;            break;        case FPSCR_ZX:            env->fpscr |= 1 << FPSCR_FX;            if (fpscr_ze)                goto raise_ze;            break;        case FPSCR_XX:            env->fpscr |= 1 << FPSCR_FX;            if (fpscr_xe)                goto raise_xe;            break;        case FPSCR_VXSNAN:        case FPSCR_VXISI:        case FPSCR_VXIDI:        case FPSCR_VXZDZ:        case FPSCR_VXIMZ:        case FPSCR_VXVC:        case FPSCR_VXSOFT:        case FPSCR_VXSQRT:        case FPSCR_VXCVI:            env->fpscr |= 1 << FPSCR_VX;            env->fpscr |= 1 << FPSCR_FX;            if (fpscr_ve != 0)                goto raise_ve;            break;        case FPSCR_VE:            if (fpscr_vx != 0) {            raise_ve:                env->error_code = POWERPC_EXCP_FP;                if (fpscr_vxsnan)                    env->error_code |= POWERPC_EXCP_FP_VXSNAN;                if (fpscr_vxisi)                    env->error_code |= POWERPC_EXCP_FP_VXISI;                if (fpscr_vxidi)                    env->error_code |= POWERPC_EXCP_FP_VXIDI;                if (fpscr_vxzdz)                    env->error_code |= POWERPC_EXCP_FP_VXZDZ;                if (fpscr_vximz)                    env->error_code |= POWERPC_EXCP_FP_VXIMZ;                if (fpscr_vxvc)                    env->error_code |= POWERPC_EXCP_FP_VXVC;                if (fpscr_vxsoft)                    env->error_code |= POWERPC_EXCP_FP_VXSOFT;                if (fpscr_vxsqrt)                    env->error_code |= POWERPC_EXCP_FP_VXSQRT;                if (fpscr_vxcvi)                    env->error_code |= POWERPC_EXCP_FP_VXCVI;                goto raise_excp;            }            break;        case FPSCR_OE:            if (fpscr_ox != 0) {            raise_oe:                env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_OX;                goto raise_excp;            }            break;        case FPSCR_UE:            if (fpscr_ux != 0) {            raise_ue:                env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_UX;                goto raise_excp;            }            break;        case FPSCR_ZE:            if (fpscr_zx != 0) {            raise_ze:                env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_ZX;                goto raise_excp;            }            break;        case FPSCR_XE:            if (fpscr_xx != 0) {            raise_xe:                env->error_code = POWERPC_EXCP_FP | POWERPC_EXCP_FP_XX;                goto raise_excp;            }            break;        case FPSCR_RN1:        case FPSCR_RN:            fpscr_set_rounding_mode();            break;        default:            break;        raise_excp:            /* Update the floating-point enabled exception summary */            env->fpscr |= 1 << FPSCR_FEX;                /* We have to update Rc1 before raising the exception */            env->exception_index = POWERPC_EXCP_PROGRAM;            break;        }    }}#if defined(WORDS_BIGENDIAN)#define WORD0 0#define WORD1 1#else#define WORD0 1#define WORD1 0#endifvoid do_store_fpscr (uint32_t mask){    /*     * We use only the 32 LSB of the incoming fpr     */    union {        double d;        struct {            uint32_t u[2];        } s;    } u;    uint32_t prev, new;    int i;    u.d = FT0;    prev = env->fpscr;    new = u.s.u[WORD1];    new &= ~0x90000000;    new |= prev & 0x90000000;    for (i = 0; i < 7; i++) {        if (mask & (1 << i)) {            env->fpscr &= ~(0xF << (4 * i));            env->fpscr |= new & (0xF << (4 * i));        }    }    /* Update VX and FEX */    if (fpscr_ix != 0)        env->fpscr |= 1 << FPSCR_VX;    if ((fpscr_ex & fpscr_eex) != 0) {        env->fpscr |= 1 << FPSCR_FEX;        env->exception_index = POWERPC_EXCP_PROGRAM;        /* XXX: we should compute it properly */        env->error_code = POWERPC_EXCP_FP;    }    fpscr_set_rounding_mode();}#undef WORD0#undef WORD1#ifdef CONFIG_SOFTFLOATvoid do_float_check_status (void){    if (env->exception_index == POWERPC_EXCP_PROGRAM &&        (env->error_code & POWERPC_EXCP_FP)) {        /* Differred floating-point exception after target FPR update */        if (msr_fe0 != 0 || msr_fe1 != 0)            do_raise_exception_err(env->exception_index, env->error_code);    } else if (env->fp_status.float_exception_flags & float_flag_overflow) {        float_overflow_excp();    } else if (env->fp_status.float_exception_flags & float_flag_underflow) {        float_underflow_excp();    } else if (env->fp_status.float_exception_flags & float_flag_inexact) {        float_inexact_excp();    }}#endif#if USE_PRECISE_EMULATIONvoid do_fadd (void){    if (unlikely(float64_is_signaling_nan(FT0) ||                 float64_is_signaling_nan(FT1))) {        /* sNaN addition */        fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);    } else if (likely(isfinite(FT0) || isfinite(FT1) ||                      fpisneg(FT0) == fpisneg(FT1))) {        FT0 = float64_add(FT0, FT1, &env->fp_status);    } else {        /* Magnitude subtraction of infinities */        fload_invalid_op_excp(POWERPC_EXCP_FP_VXISI);    }}void do_fsub (void){    if (unlikely(float64_is_signaling_nan(FT0) ||                 float64_is_signaling_nan(FT1))) {        /* sNaN subtraction */        fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);    } else if (likely(isfinite(FT0) || isfinite(FT1) ||                      fpisneg(FT0) != fpisneg(FT1))) {        FT0 = float64_sub(FT0, FT1, &env->fp_status);    } else {        /* Magnitude subtraction of infinities */        fload_invalid_op_excp(POWERPC_EXCP_FP_VXISI);    }}void do_fmul (void){    if (unlikely(float64_is_signaling_nan(FT0) ||                 float64_is_signaling_nan(FT1))) {        /* sNaN multiplication */        fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);    } else if (unlikely((isinfinity(FT0) && iszero(FT1)) ||                        (iszero(FT0) && isinfinity(FT1)))) {        /* Multiplication of zero by infinity */        fload_invalid_op_excp(POWERPC_EXCP_FP_VXIMZ);    } else {        FT0 = float64_mul(FT0, FT1, &env->fp_status);    }}void do_fdiv (void){    if (unlikely(float64_is_signaling_nan(FT0) ||                 float64_is_signaling_nan(FT1))) {        /* sNaN division */        fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);    } else if (unlikely(isinfinity(FT0) && isinfinity(FT1))) {        /* Division of infinity by infinity */        fload_invalid_op_excp(POWERPC_EXCP_FP_VXIDI);    } else if (unlikely(iszero(FT1))) {        if (iszero(FT0)) {            /* Division of zero by zero */            fload_invalid_op_excp(POWERPC_EXCP_FP_VXZDZ);        } else {            /* Division by zero */            float_zero_divide_excp();        }    } else {        FT0 = float64_div(FT0, FT1, &env->fp_status);    }}#endif /* USE_PRECISE_EMULATION */void do_fctiw (void){    union {        double d;        uint64_t i;    } p;    if (unlikely(float64_is_signaling_nan(FT0))) {        /* sNaN conversion */        fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI);    } else if (unlikely(float64_is_nan(FT0) || isinfinity(FT0))) {        /* qNan / infinity conversion */        fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);    } else {        p.i = float64_to_int32(FT0, &env->fp_status);#if USE_PRECISE_EMULATION        /* XXX: higher bits are not supposed to be significant.         *     to make tests easier, return the same as a real PowerPC 750         */        p.i |= 0xFFF80000ULL << 32;#endif        FT0 = p.d;    }}void do_fctiwz (void){    union {        double d;        uint64_t i;    } p;    if (unlikely(float64_is_signaling_nan(FT0))) {        /* sNaN conversion */        fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI);    } else if (unlikely(float64_is_nan(FT0) || isinfinity(FT0))) {        /* qNan / infinity conversion */        fload_invalid_op_excp(POWERPC_EXCP_FP_VXCVI);    } else {        p.i = float64_to_int32_round_to_zero(FT0, &env->fp_status);#if USE_PRECISE_EMULATION        /* XXX: higher bits are not supposed to be significant.         *     to make tests easier, return the same as a real PowerPC 750         */        p.i |= 0xFFF80000ULL << 32;#endif        FT0 = p.d;    }}#if defined(TARGET_PPC64)void do_fcfid (void){    union {        double d;        uint64_t i;    } p;    p.d = FT0;    FT0 = int64_to_float64(p.i, &env->fp_status);}void do_fctid (void){    union {        double d;        uint64_t i;    } p;    if (unlikely(float64_is_signaling_nan(FT0))) {        /* sNaN conversion */        fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN | POWERPC_EXCP_FP_VXCVI);

⌨️ 快捷键说明

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