Commit a16336e4 authored by Thiemo Seufer's avatar Thiemo Seufer
Browse files

Convert remaining MIPS FP instructions to TCG.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4753 c046a42c-6fe2-441c-8c8c-71466251a162
parent 8f2ad0a3
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -154,6 +154,7 @@ DEF_HELPER(void, do_float_mulr_ps, (void))
#define FOP_PROTO(op)                            \
DEF_HELPER(void, do_float_ ## op ## _s, (void))  \
DEF_HELPER(void, do_float_ ## op ## _d, (void))
FOP_PROTO(sqrt)
FOP_PROTO(roundl)
FOP_PROTO(roundw)
FOP_PROTO(truncl)
@@ -174,6 +175,12 @@ FOP_PROTO(add)
FOP_PROTO(sub)
FOP_PROTO(mul)
FOP_PROTO(div)
FOP_PROTO(abs)
FOP_PROTO(chs)
FOP_PROTO(muladd)
FOP_PROTO(mulsub)
FOP_PROTO(nmuladd)
FOP_PROTO(nmulsub)
FOP_PROTO(recip1)
FOP_PROTO(recip2)
FOP_PROTO(rsqrt1)
+0 −292
Original line number Diff line number Diff line
@@ -295,295 +295,3 @@ void op_mulshiu (void)
#else
# define DEBUG_FPU_STATE() do { } while(0)
#endif

/* Float support.
   Single precition routines have a "s" suffix, double precision a
   "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps",
   paired single lowwer "pl", paired single upper "pu".  */

#define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void)

FLOAT_OP(pll, ps)
{
    DT2 = ((uint64_t)WT0 << 32) | WT1;
    DEBUG_FPU_STATE();
    FORCE_RET();
}
FLOAT_OP(plu, ps)
{
    DT2 = ((uint64_t)WT0 << 32) | WTH1;
    DEBUG_FPU_STATE();
    FORCE_RET();
}
FLOAT_OP(pul, ps)
{
    DT2 = ((uint64_t)WTH0 << 32) | WT1;
    DEBUG_FPU_STATE();
    FORCE_RET();
}
FLOAT_OP(puu, ps)
{
    DT2 = ((uint64_t)WTH0 << 32) | WTH1;
    DEBUG_FPU_STATE();
    FORCE_RET();
}

FLOAT_OP(movf, d)
{
    if (!(env->fpu->fcr31 & PARAM1))
        DT2 = DT0;
    DEBUG_FPU_STATE();
    FORCE_RET();
}
FLOAT_OP(movf, s)
{
    if (!(env->fpu->fcr31 & PARAM1))
        WT2 = WT0;
    DEBUG_FPU_STATE();
    FORCE_RET();
}
FLOAT_OP(movf, ps)
{
    unsigned int mask = GET_FP_COND (env->fpu) >> PARAM1;
    if (!(mask & 1))
        WT2 = WT0;
    if (!(mask & 2))
        WTH2 = WTH0;
    DEBUG_FPU_STATE();
    FORCE_RET();
}
FLOAT_OP(movt, d)
{
    if (env->fpu->fcr31 & PARAM1)
        DT2 = DT0;
    DEBUG_FPU_STATE();
    FORCE_RET();
}
FLOAT_OP(movt, s)
{
    if (env->fpu->fcr31 & PARAM1)
        WT2 = WT0;
    DEBUG_FPU_STATE();
    FORCE_RET();
}
FLOAT_OP(movt, ps)
{
    unsigned int mask = GET_FP_COND (env->fpu) >> PARAM1;
    if (mask & 1)
        WT2 = WT0;
    if (mask & 2)
        WTH2 = WTH0;
    DEBUG_FPU_STATE();
    FORCE_RET();
}
FLOAT_OP(movz, d)
{
    if (!T0)
        DT2 = DT0;
    DEBUG_FPU_STATE();
    FORCE_RET();
}
FLOAT_OP(movz, s)
{
    if (!T0)
        WT2 = WT0;
    DEBUG_FPU_STATE();
    FORCE_RET();
}
FLOAT_OP(movz, ps)
{
    if (!T0) {
        WT2 = WT0;
        WTH2 = WTH0;
    }
    DEBUG_FPU_STATE();
    FORCE_RET();
}
FLOAT_OP(movn, d)
{
    if (T0)
        DT2 = DT0;
    DEBUG_FPU_STATE();
    FORCE_RET();
}
FLOAT_OP(movn, s)
{
    if (T0)
        WT2 = WT0;
    DEBUG_FPU_STATE();
    FORCE_RET();
}
FLOAT_OP(movn, ps)
{
    if (T0) {
        WT2 = WT0;
        WTH2 = WTH0;
    }
    DEBUG_FPU_STATE();
    FORCE_RET();
}

/* ternary operations */
#define FLOAT_TERNOP(name1, name2) \
FLOAT_OP(name1 ## name2, d)        \
{                                  \
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
    DEBUG_FPU_STATE();             \
    FORCE_RET();                   \
}                                  \
FLOAT_OP(name1 ## name2, s)        \
{                                  \
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
    DEBUG_FPU_STATE();             \
    FORCE_RET();                   \
}                                  \
FLOAT_OP(name1 ## name2, ps)       \
{                                  \
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
    DEBUG_FPU_STATE();             \
    FORCE_RET();                   \
}
FLOAT_TERNOP(mul, add)
FLOAT_TERNOP(mul, sub)
#undef FLOAT_TERNOP

/* negated ternary operations */
#define FLOAT_NTERNOP(name1, name2) \
FLOAT_OP(n ## name1 ## name2, d)    \
{                                   \
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
    FDT2 = float64_chs(FDT2);       \
    DEBUG_FPU_STATE();              \
    FORCE_RET();                    \
}                                   \
FLOAT_OP(n ## name1 ## name2, s)    \
{                                   \
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
    FST2 = float32_chs(FST2);       \
    DEBUG_FPU_STATE();              \
    FORCE_RET();                    \
}                                   \
FLOAT_OP(n ## name1 ## name2, ps)   \
{                                   \
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
    FST2 = float32_chs(FST2);       \
    FSTH2 = float32_chs(FSTH2);     \
    DEBUG_FPU_STATE();              \
    FORCE_RET();                    \
}
FLOAT_NTERNOP(mul, add)
FLOAT_NTERNOP(mul, sub)
#undef FLOAT_NTERNOP

/* unary operations, modifying fp status  */
#define FLOAT_UNOP(name)  \
FLOAT_OP(name, d)         \
{                         \
    FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
    DEBUG_FPU_STATE();    \
    FORCE_RET();          \
}                         \
FLOAT_OP(name, s)         \
{                         \
    FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
    DEBUG_FPU_STATE();    \
    FORCE_RET();          \
}
FLOAT_UNOP(sqrt)
#undef FLOAT_UNOP

/* unary operations, not modifying fp status  */
#define FLOAT_UNOP(name)  \
FLOAT_OP(name, d)         \
{                         \
    FDT2 = float64_ ## name(FDT0);   \
    DEBUG_FPU_STATE();    \
    FORCE_RET();          \
}                         \
FLOAT_OP(name, s)         \
{                         \
    FST2 = float32_ ## name(FST0);   \
    DEBUG_FPU_STATE();    \
    FORCE_RET();          \
}                         \
FLOAT_OP(name, ps)        \
{                         \
    FST2 = float32_ ## name(FST0);   \
    FSTH2 = float32_ ## name(FSTH0); \
    DEBUG_FPU_STATE();    \
    FORCE_RET();          \
}
FLOAT_UNOP(abs)
FLOAT_UNOP(chs)
#undef FLOAT_UNOP

FLOAT_OP(alnv, ps)
{
    switch (T0 & 0x7) {
    case 0:
        FST2 = FST0;
        FSTH2 = FSTH0;
        break;
    case 4:
#ifdef TARGET_WORDS_BIGENDIAN
        FSTH2 = FST0;
        FST2 = FSTH1;
#else
        FSTH2 = FST1;
        FST2 = FSTH0;
#endif
        break;
    default: /* unpredictable */
        break;
    }
    DEBUG_FPU_STATE();
    FORCE_RET();
}

void op_bc1f (void)
{
    T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1));
    DEBUG_FPU_STATE();
    FORCE_RET();
}
void op_bc1any2f (void)
{
    T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1));
    DEBUG_FPU_STATE();
    FORCE_RET();
}
void op_bc1any4f (void)
{
    T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1));
    DEBUG_FPU_STATE();
    FORCE_RET();
}

void op_bc1t (void)
{
    T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1));
    DEBUG_FPU_STATE();
    FORCE_RET();
}
void op_bc1any2t (void)
{
    T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1));
    DEBUG_FPU_STATE();
    FORCE_RET();
}
void op_bc1any4t (void)
{
    T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1));
    DEBUG_FPU_STATE();
    FORCE_RET();
}
+87 −0
Original line number Diff line number Diff line
@@ -1703,8 +1703,26 @@ static always_inline void update_fcr31(void)
        UPDATE_FP_FLAGS(env->fpu->fcr31, tmp);
}

/* Float support.
   Single precition routines have a "s" suffix, double precision a
   "d" suffix, 32bit integer "w", 64bit integer "l", paired single "ps",
   paired single lower "pl", paired single upper "pu".  */

#define FLOAT_OP(name, p) void do_float_##name##_##p(void)

/* unary operations, modifying fp status  */
#define FLOAT_UNOP(name)  \
FLOAT_OP(name, d)         \
{                         \
    FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \
}                         \
FLOAT_OP(name, s)         \
{                         \
    FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \
}
FLOAT_UNOP(sqrt)
#undef FLOAT_UNOP

FLOAT_OP(cvtd, s)
{
    set_float_exception_flags(0, &env->fpu->fp_status);
@@ -1943,6 +1961,25 @@ FLOAT_OP(floorw, s)
        WT2 = FLOAT_SNAN32;
}

/* unary operations, not modifying fp status  */
#define FLOAT_UNOP(name)  \
FLOAT_OP(name, d)         \
{                         \
    FDT2 = float64_ ## name(FDT0);   \
}                         \
FLOAT_OP(name, s)         \
{                         \
    FST2 = float32_ ## name(FST0);   \
}                         \
FLOAT_OP(name, ps)        \
{                         \
    FST2 = float32_ ## name(FST0);   \
    FSTH2 = float32_ ## name(FSTH0); \
}
FLOAT_UNOP(abs)
FLOAT_UNOP(chs)
#undef FLOAT_UNOP

/* MIPS specific unary operations */
FLOAT_OP(recip, d)
{
@@ -2051,6 +2088,56 @@ FLOAT_BINOP(mul)
FLOAT_BINOP(div)
#undef FLOAT_BINOP

/* ternary operations */
#define FLOAT_TERNOP(name1, name2) \
FLOAT_OP(name1 ## name2, d)        \
{                                  \
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
}                                  \
FLOAT_OP(name1 ## name2, s)        \
{                                  \
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
}                                  \
FLOAT_OP(name1 ## name2, ps)       \
{                                  \
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
}
FLOAT_TERNOP(mul, add)
FLOAT_TERNOP(mul, sub)
#undef FLOAT_TERNOP

/* negated ternary operations */
#define FLOAT_NTERNOP(name1, name2) \
FLOAT_OP(n ## name1 ## name2, d)    \
{                                   \
    FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status);    \
    FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status);    \
    FDT2 = float64_chs(FDT2);       \
}                                   \
FLOAT_OP(n ## name1 ## name2, s)    \
{                                   \
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
    FST2 = float32_chs(FST2);       \
}                                   \
FLOAT_OP(n ## name1 ## name2, ps)   \
{                                   \
    FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status);    \
    FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \
    FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status);    \
    FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \
    FST2 = float32_chs(FST2);       \
    FSTH2 = float32_chs(FSTH2);     \
}
FLOAT_NTERNOP(mul, add)
FLOAT_NTERNOP(mul, sub)
#undef FLOAT_NTERNOP

/* MIPS specific binary operations */
FLOAT_OP(recip2, d)
{
+332 −71

File changed.

Preview size limit exceeded, changes collapsed.