提交 a16336e4 编写于 作者: T ths

Convert remaining MIPS FP instructions to TCG.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4753 c046a42c-6fe2-441c-8c8c-71466251a162
上级 8f2ad0a3
......@@ -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)
......
......@@ -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();
}
......@@ -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)
{
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册