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

📄 op_helper.c

📁 QEMU 0.91 source code, supports ARM processor including S3C24xx series
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Complex FPU operations which may need stack space. */#define FLOAT_ONE32 make_float32(0x3f8 << 20)#define FLOAT_ONE64 make_float64(0x3ffULL << 52)#define FLOAT_TWO32 make_float32(1 << 30)#define FLOAT_TWO64 make_float64(1ULL << 62)#define FLOAT_QNAN32 0x7fbfffff#define FLOAT_QNAN64 0x7ff7ffffffffffffULL#define FLOAT_SNAN32 0x7fffffff#define FLOAT_SNAN64 0x7fffffffffffffffULL/* convert MIPS rounding mode in FCR31 to IEEE library */unsigned int ieee_rm[] = {    float_round_nearest_even,    float_round_to_zero,    float_round_up,    float_round_down};#define RESTORE_ROUNDING_MODE \    set_float_rounding_mode(ieee_rm[env->fpu->fcr31 & 3], &env->fpu->fp_status)void do_cfc1 (int reg){    switch (reg) {    case 0:        T0 = (int32_t)env->fpu->fcr0;        break;    case 25:        T0 = ((env->fpu->fcr31 >> 24) & 0xfe) | ((env->fpu->fcr31 >> 23) & 0x1);        break;    case 26:        T0 = env->fpu->fcr31 & 0x0003f07c;        break;    case 28:        T0 = (env->fpu->fcr31 & 0x00000f83) | ((env->fpu->fcr31 >> 22) & 0x4);        break;    default:        T0 = (int32_t)env->fpu->fcr31;        break;    }}void do_ctc1 (int reg){    switch(reg) {    case 25:        if (T0 & 0xffffff00)            return;        env->fpu->fcr31 = (env->fpu->fcr31 & 0x017fffff) | ((T0 & 0xfe) << 24) |                     ((T0 & 0x1) << 23);        break;    case 26:        if (T0 & 0x007c0000)            return;        env->fpu->fcr31 = (env->fpu->fcr31 & 0xfffc0f83) | (T0 & 0x0003f07c);        break;    case 28:        if (T0 & 0x007c0000)            return;        env->fpu->fcr31 = (env->fpu->fcr31 & 0xfefff07c) | (T0 & 0x00000f83) |                     ((T0 & 0x4) << 22);        break;    case 31:        if (T0 & 0x007c0000)            return;        env->fpu->fcr31 = T0;        break;    default:        return;    }    /* set rounding mode */    RESTORE_ROUNDING_MODE;    set_float_exception_flags(0, &env->fpu->fp_status);    if ((GET_FP_ENABLE(env->fpu->fcr31) | 0x20) & GET_FP_CAUSE(env->fpu->fcr31))        do_raise_exception(EXCP_FPE);}static always_inline char ieee_ex_to_mips(char xcpt){    return (xcpt & float_flag_inexact) >> 5 |           (xcpt & float_flag_underflow) >> 3 |           (xcpt & float_flag_overflow) >> 1 |           (xcpt & float_flag_divbyzero) << 1 |           (xcpt & float_flag_invalid) << 4;}static always_inline char mips_ex_to_ieee(char xcpt){    return (xcpt & FP_INEXACT) << 5 |           (xcpt & FP_UNDERFLOW) << 3 |           (xcpt & FP_OVERFLOW) << 1 |           (xcpt & FP_DIV0) >> 1 |           (xcpt & FP_INVALID) >> 4;}static always_inline void update_fcr31(void){    int tmp = ieee_ex_to_mips(get_float_exception_flags(&env->fpu->fp_status));    SET_FP_CAUSE(env->fpu->fcr31, tmp);    if (GET_FP_ENABLE(env->fpu->fcr31) & tmp)        do_raise_exception(EXCP_FPE);    else        UPDATE_FP_FLAGS(env->fpu->fcr31, tmp);}#define FLOAT_OP(name, p) void do_float_##name##_##p(void)FLOAT_OP(cvtd, s){    set_float_exception_flags(0, &env->fpu->fp_status);    FDT2 = float32_to_float64(FST0, &env->fpu->fp_status);    update_fcr31();}FLOAT_OP(cvtd, w){    set_float_exception_flags(0, &env->fpu->fp_status);    FDT2 = int32_to_float64(WT0, &env->fpu->fp_status);    update_fcr31();}FLOAT_OP(cvtd, l){    set_float_exception_flags(0, &env->fpu->fp_status);    FDT2 = int64_to_float64(DT0, &env->fpu->fp_status);    update_fcr31();}FLOAT_OP(cvtl, d){    set_float_exception_flags(0, &env->fpu->fp_status);    DT2 = float64_to_int64(FDT0, &env->fpu->fp_status);    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        DT2 = FLOAT_SNAN64;}FLOAT_OP(cvtl, s){    set_float_exception_flags(0, &env->fpu->fp_status);    DT2 = float32_to_int64(FST0, &env->fpu->fp_status);    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        DT2 = FLOAT_SNAN64;}FLOAT_OP(cvtps, pw){    set_float_exception_flags(0, &env->fpu->fp_status);    FST2 = int32_to_float32(WT0, &env->fpu->fp_status);    FSTH2 = int32_to_float32(WTH0, &env->fpu->fp_status);    update_fcr31();}FLOAT_OP(cvtpw, ps){    set_float_exception_flags(0, &env->fpu->fp_status);    WT2 = float32_to_int32(FST0, &env->fpu->fp_status);    WTH2 = float32_to_int32(FSTH0, &env->fpu->fp_status);    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        WT2 = FLOAT_SNAN32;}FLOAT_OP(cvts, d){    set_float_exception_flags(0, &env->fpu->fp_status);    FST2 = float64_to_float32(FDT0, &env->fpu->fp_status);    update_fcr31();}FLOAT_OP(cvts, w){    set_float_exception_flags(0, &env->fpu->fp_status);    FST2 = int32_to_float32(WT0, &env->fpu->fp_status);    update_fcr31();}FLOAT_OP(cvts, l){    set_float_exception_flags(0, &env->fpu->fp_status);    FST2 = int64_to_float32(DT0, &env->fpu->fp_status);    update_fcr31();}FLOAT_OP(cvts, pl){    set_float_exception_flags(0, &env->fpu->fp_status);    WT2 = WT0;    update_fcr31();}FLOAT_OP(cvts, pu){    set_float_exception_flags(0, &env->fpu->fp_status);    WT2 = WTH0;    update_fcr31();}FLOAT_OP(cvtw, s){    set_float_exception_flags(0, &env->fpu->fp_status);    WT2 = float32_to_int32(FST0, &env->fpu->fp_status);    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        WT2 = FLOAT_SNAN32;}FLOAT_OP(cvtw, d){    set_float_exception_flags(0, &env->fpu->fp_status);    WT2 = float64_to_int32(FDT0, &env->fpu->fp_status);    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        WT2 = FLOAT_SNAN32;}FLOAT_OP(roundl, d){    set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status);    DT2 = float64_to_int64(FDT0, &env->fpu->fp_status);    RESTORE_ROUNDING_MODE;    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        DT2 = FLOAT_SNAN64;}FLOAT_OP(roundl, s){    set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status);    DT2 = float32_to_int64(FST0, &env->fpu->fp_status);    RESTORE_ROUNDING_MODE;    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        DT2 = FLOAT_SNAN64;}FLOAT_OP(roundw, d){    set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status);    WT2 = float64_to_int32(FDT0, &env->fpu->fp_status);    RESTORE_ROUNDING_MODE;    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        WT2 = FLOAT_SNAN32;}FLOAT_OP(roundw, s){    set_float_rounding_mode(float_round_nearest_even, &env->fpu->fp_status);    WT2 = float32_to_int32(FST0, &env->fpu->fp_status);    RESTORE_ROUNDING_MODE;    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        WT2 = FLOAT_SNAN32;}FLOAT_OP(truncl, d){    DT2 = float64_to_int64_round_to_zero(FDT0, &env->fpu->fp_status);    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        DT2 = FLOAT_SNAN64;}FLOAT_OP(truncl, s){    DT2 = float32_to_int64_round_to_zero(FST0, &env->fpu->fp_status);    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        DT2 = FLOAT_SNAN64;}FLOAT_OP(truncw, d){    WT2 = float64_to_int32_round_to_zero(FDT0, &env->fpu->fp_status);    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        WT2 = FLOAT_SNAN32;}FLOAT_OP(truncw, s){    WT2 = float32_to_int32_round_to_zero(FST0, &env->fpu->fp_status);    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        WT2 = FLOAT_SNAN32;}FLOAT_OP(ceill, d){    set_float_rounding_mode(float_round_up, &env->fpu->fp_status);    DT2 = float64_to_int64(FDT0, &env->fpu->fp_status);    RESTORE_ROUNDING_MODE;    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        DT2 = FLOAT_SNAN64;}FLOAT_OP(ceill, s){    set_float_rounding_mode(float_round_up, &env->fpu->fp_status);    DT2 = float32_to_int64(FST0, &env->fpu->fp_status);    RESTORE_ROUNDING_MODE;    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        DT2 = FLOAT_SNAN64;}FLOAT_OP(ceilw, d){    set_float_rounding_mode(float_round_up, &env->fpu->fp_status);    WT2 = float64_to_int32(FDT0, &env->fpu->fp_status);    RESTORE_ROUNDING_MODE;    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        WT2 = FLOAT_SNAN32;}FLOAT_OP(ceilw, s){    set_float_rounding_mode(float_round_up, &env->fpu->fp_status);    WT2 = float32_to_int32(FST0, &env->fpu->fp_status);    RESTORE_ROUNDING_MODE;    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        WT2 = FLOAT_SNAN32;}FLOAT_OP(floorl, d){    set_float_rounding_mode(float_round_down, &env->fpu->fp_status);    DT2 = float64_to_int64(FDT0, &env->fpu->fp_status);    RESTORE_ROUNDING_MODE;    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        DT2 = FLOAT_SNAN64;}FLOAT_OP(floorl, s){    set_float_rounding_mode(float_round_down, &env->fpu->fp_status);    DT2 = float32_to_int64(FST0, &env->fpu->fp_status);    RESTORE_ROUNDING_MODE;    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        DT2 = FLOAT_SNAN64;}FLOAT_OP(floorw, d){    set_float_rounding_mode(float_round_down, &env->fpu->fp_status);    WT2 = float64_to_int32(FDT0, &env->fpu->fp_status);    RESTORE_ROUNDING_MODE;    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        WT2 = FLOAT_SNAN32;}FLOAT_OP(floorw, s){    set_float_rounding_mode(float_round_down, &env->fpu->fp_status);    WT2 = float32_to_int32(FST0, &env->fpu->fp_status);    RESTORE_ROUNDING_MODE;    update_fcr31();    if (GET_FP_CAUSE(env->fpu->fcr31) & (FP_OVERFLOW | FP_INVALID))        WT2 = FLOAT_SNAN32;}/* MIPS specific unary operations */FLOAT_OP(recip, d){    set_float_exception_flags(0, &env->fpu->fp_status);    FDT2 = float64_div(FLOAT_ONE64, FDT0, &env->fpu->fp_status);    update_fcr31();}FLOAT_OP(recip, s){    set_float_exception_flags(0, &env->fpu->fp_status);

⌨️ 快捷键说明

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