提交 1c97856d 编写于 作者: A aurel32

target-ppc: convert SPE FP ops to TCG

Including a few bug fixes:
- Don't clear high part for instruction with 32-bit destination
- Fix efscmp* and etstcmp* return value
Signed-off-by: NAurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5783 c046a42c-6fe2-441c-8c8c-71466251a162
上级 f4887919
......@@ -60,10 +60,77 @@ DEF_HELPER_3(fnmsub, i64, i64, i64, i64)
DEF_HELPER_1(fabs, i64, i64)
DEF_HELPER_1(fnabs, i64, i64)
DEF_HELPER_1(fneg, i64, i64)
DEF_HELPER_1(fsqrt, i64, i64);
DEF_HELPER_1(fre, i64, i64);
DEF_HELPER_1(fres, i64, i64);
DEF_HELPER_1(frsqrte, i64, i64);
DEF_HELPER_1(fsqrt, i64, i64)
DEF_HELPER_1(fre, i64, i64)
DEF_HELPER_1(fres, i64, i64)
DEF_HELPER_1(frsqrte, i64, i64)
DEF_HELPER_3(fsel, i64, i64, i64, i64)
DEF_HELPER_1(efscfsi, i32, i32)
DEF_HELPER_1(efscfui, i32, i32)
DEF_HELPER_1(efscfuf, i32, i32)
DEF_HELPER_1(efscfsf, i32, i32)
DEF_HELPER_1(efsctsi, i32, i32)
DEF_HELPER_1(efsctui, i32, i32)
DEF_HELPER_1(efsctsiz, i32, i32)
DEF_HELPER_1(efsctuiz, i32, i32)
DEF_HELPER_1(efsctsf, i32, i32)
DEF_HELPER_1(efsctuf, i32, i32)
DEF_HELPER_1(evfscfsi, i64, i64)
DEF_HELPER_1(evfscfui, i64, i64)
DEF_HELPER_1(evfscfuf, i64, i64)
DEF_HELPER_1(evfscfsf, i64, i64)
DEF_HELPER_1(evfsctsi, i64, i64)
DEF_HELPER_1(evfsctui, i64, i64)
DEF_HELPER_1(evfsctsiz, i64, i64)
DEF_HELPER_1(evfsctuiz, i64, i64)
DEF_HELPER_1(evfsctsf, i64, i64)
DEF_HELPER_1(evfsctuf, i64, i64)
DEF_HELPER_2(efsadd, i32, i32, i32)
DEF_HELPER_2(efssub, i32, i32, i32)
DEF_HELPER_2(efsmul, i32, i32, i32)
DEF_HELPER_2(efsdiv, i32, i32, i32)
DEF_HELPER_2(evfsadd, i64, i64, i64)
DEF_HELPER_2(evfssub, i64, i64, i64)
DEF_HELPER_2(evfsmul, i64, i64, i64)
DEF_HELPER_2(evfsdiv, i64, i64, i64)
DEF_HELPER_2(efststlt, i32, i32, i32)
DEF_HELPER_2(efststgt, i32, i32, i32)
DEF_HELPER_2(efststeq, i32, i32, i32)
DEF_HELPER_2(efscmplt, i32, i32, i32)
DEF_HELPER_2(efscmpgt, i32, i32, i32)
DEF_HELPER_2(efscmpeq, i32, i32, i32)
DEF_HELPER_2(evfststlt, i32, i64, i64)
DEF_HELPER_2(evfststgt, i32, i64, i64)
DEF_HELPER_2(evfststeq, i32, i64, i64)
DEF_HELPER_2(evfscmplt, i32, i64, i64)
DEF_HELPER_2(evfscmpgt, i32, i64, i64)
DEF_HELPER_2(evfscmpeq, i32, i64, i64)
DEF_HELPER_1(efdcfsi, i64, i32)
DEF_HELPER_1(efdcfsid, i64, i64)
DEF_HELPER_1(efdcfui, i64, i32)
DEF_HELPER_1(efdcfuid, i64, i64)
DEF_HELPER_1(efdctsi, i32, i64)
DEF_HELPER_1(efdctui, i32, i64)
DEF_HELPER_1(efdctsiz, i32, i64)
DEF_HELPER_1(efdctsidz, i64, i64)
DEF_HELPER_1(efdctuiz, i32, i64)
DEF_HELPER_1(efdctuidz, i64, i64)
DEF_HELPER_1(efdcfsf, i64, i32)
DEF_HELPER_1(efdcfuf, i64, i32)
DEF_HELPER_1(efdctsf, i32, i64)
DEF_HELPER_1(efdctuf, i32, i64)
DEF_HELPER_1(efscfd, i32, i64)
DEF_HELPER_1(efdcfs, i64, i32)
DEF_HELPER_2(efdadd, i64, i64, i64)
DEF_HELPER_2(efdsub, i64, i64, i64)
DEF_HELPER_2(efdmul, i64, i64, i64)
DEF_HELPER_2(efddiv, i64, i64, i64)
DEF_HELPER_2(efdtstlt, i32, i64, i64)
DEF_HELPER_2(efdtstgt, i32, i64, i64)
DEF_HELPER_2(efdtsteq, i32, i64, i64)
DEF_HELPER_2(efdcmplt, i32, i64, i64)
DEF_HELPER_2(efdcmpgt, i32, i64, i64)
DEF_HELPER_2(efdcmpeq, i32, i64, i64)
#include "def-helper.h"
......@@ -960,468 +960,4 @@ void OPPROTO op_srli32_T1_64 (void)
RETURN();
}
void OPPROTO op_evfssub (void)
{
do_evfssub();
RETURN();
}
void OPPROTO op_evfsadd (void)
{
do_evfsadd();
RETURN();
}
void OPPROTO op_evfsnabs (void)
{
do_evfsnabs();
RETURN();
}
void OPPROTO op_evfsabs (void)
{
do_evfsabs();
RETURN();
}
void OPPROTO op_evfsneg (void)
{
do_evfsneg();
RETURN();
}
void OPPROTO op_evfsdiv (void)
{
do_evfsdiv();
RETURN();
}
void OPPROTO op_evfsmul (void)
{
do_evfsmul();
RETURN();
}
void OPPROTO op_evfscmplt (void)
{
do_evfscmplt();
RETURN();
}
void OPPROTO op_evfscmpgt (void)
{
do_evfscmpgt();
RETURN();
}
void OPPROTO op_evfscmpeq (void)
{
do_evfscmpeq();
RETURN();
}
void OPPROTO op_evfscfsi (void)
{
do_evfscfsi();
RETURN();
}
void OPPROTO op_evfscfui (void)
{
do_evfscfui();
RETURN();
}
void OPPROTO op_evfscfsf (void)
{
do_evfscfsf();
RETURN();
}
void OPPROTO op_evfscfuf (void)
{
do_evfscfuf();
RETURN();
}
void OPPROTO op_evfsctsi (void)
{
do_evfsctsi();
RETURN();
}
void OPPROTO op_evfsctui (void)
{
do_evfsctui();
RETURN();
}
void OPPROTO op_evfsctsf (void)
{
do_evfsctsf();
RETURN();
}
void OPPROTO op_evfsctuf (void)
{
do_evfsctuf();
RETURN();
}
void OPPROTO op_evfsctuiz (void)
{
do_evfsctuiz();
RETURN();
}
void OPPROTO op_evfsctsiz (void)
{
do_evfsctsiz();
RETURN();
}
void OPPROTO op_evfststlt (void)
{
do_evfststlt();
RETURN();
}
void OPPROTO op_evfststgt (void)
{
do_evfststgt();
RETURN();
}
void OPPROTO op_evfststeq (void)
{
do_evfststeq();
RETURN();
}
void OPPROTO op_efssub (void)
{
T0_64 = _do_efssub(T0_64, T1_64);
RETURN();
}
void OPPROTO op_efsadd (void)
{
T0_64 = _do_efsadd(T0_64, T1_64);
RETURN();
}
void OPPROTO op_efsnabs (void)
{
T0_64 = _do_efsnabs(T0_64);
RETURN();
}
void OPPROTO op_efsabs (void)
{
T0_64 = _do_efsabs(T0_64);
RETURN();
}
void OPPROTO op_efsneg (void)
{
T0_64 = _do_efsneg(T0_64);
RETURN();
}
void OPPROTO op_efsdiv (void)
{
T0_64 = _do_efsdiv(T0_64, T1_64);
RETURN();
}
void OPPROTO op_efsmul (void)
{
T0_64 = _do_efsmul(T0_64, T1_64);
RETURN();
}
void OPPROTO op_efscmplt (void)
{
do_efscmplt();
RETURN();
}
void OPPROTO op_efscmpgt (void)
{
do_efscmpgt();
RETURN();
}
void OPPROTO op_efscfd (void)
{
do_efscfd();
RETURN();
}
void OPPROTO op_efscmpeq (void)
{
do_efscmpeq();
RETURN();
}
void OPPROTO op_efscfsi (void)
{
do_efscfsi();
RETURN();
}
void OPPROTO op_efscfui (void)
{
do_efscfui();
RETURN();
}
void OPPROTO op_efscfsf (void)
{
do_efscfsf();
RETURN();
}
void OPPROTO op_efscfuf (void)
{
do_efscfuf();
RETURN();
}
void OPPROTO op_efsctsi (void)
{
do_efsctsi();
RETURN();
}
void OPPROTO op_efsctui (void)
{
do_efsctui();
RETURN();
}
void OPPROTO op_efsctsf (void)
{
do_efsctsf();
RETURN();
}
void OPPROTO op_efsctuf (void)
{
do_efsctuf();
RETURN();
}
void OPPROTO op_efsctsiz (void)
{
do_efsctsiz();
RETURN();
}
void OPPROTO op_efsctuiz (void)
{
do_efsctuiz();
RETURN();
}
void OPPROTO op_efststlt (void)
{
T0 = _do_efststlt(T0_64, T1_64);
RETURN();
}
void OPPROTO op_efststgt (void)
{
T0 = _do_efststgt(T0_64, T1_64);
RETURN();
}
void OPPROTO op_efststeq (void)
{
T0 = _do_efststeq(T0_64, T1_64);
RETURN();
}
void OPPROTO op_efdsub (void)
{
CPU_DoubleU u1, u2;
u1.ll = T0_64;
u2.ll = T1_64;
u1.d = float64_sub(u1.d, u2.d, &env->spe_status);
T0_64 = u1.ll;
RETURN();
}
void OPPROTO op_efdadd (void)
{
CPU_DoubleU u1, u2;
u1.ll = T0_64;
u2.ll = T1_64;
u1.d = float64_add(u1.d, u2.d, &env->spe_status);
T0_64 = u1.ll;
RETURN();
}
void OPPROTO op_efdcfsid (void)
{
do_efdcfsi();
RETURN();
}
void OPPROTO op_efdcfuid (void)
{
do_efdcfui();
RETURN();
}
void OPPROTO op_efdnabs (void)
{
T0_64 |= 0x8000000000000000ULL;
RETURN();
}
void OPPROTO op_efdabs (void)
{
T0_64 &= ~0x8000000000000000ULL;
RETURN();
}
void OPPROTO op_efdneg (void)
{
T0_64 ^= 0x8000000000000000ULL;
RETURN();
}
void OPPROTO op_efddiv (void)
{
CPU_DoubleU u1, u2;
u1.ll = T0_64;
u2.ll = T1_64;
u1.d = float64_div(u1.d, u2.d, &env->spe_status);
T0_64 = u1.ll;
RETURN();
}
void OPPROTO op_efdmul (void)
{
CPU_DoubleU u1, u2;
u1.ll = T0_64;
u2.ll = T1_64;
u1.d = float64_mul(u1.d, u2.d, &env->spe_status);
T0_64 = u1.ll;
RETURN();
}
void OPPROTO op_efdctsidz (void)
{
do_efdctsiz();
RETURN();
}
void OPPROTO op_efdctuidz (void)
{
do_efdctuiz();
RETURN();
}
void OPPROTO op_efdcmplt (void)
{
do_efdcmplt();
RETURN();
}
void OPPROTO op_efdcmpgt (void)
{
do_efdcmpgt();
RETURN();
}
void OPPROTO op_efdcfs (void)
{
do_efdcfs();
RETURN();
}
void OPPROTO op_efdcmpeq (void)
{
do_efdcmpeq();
RETURN();
}
void OPPROTO op_efdcfsi (void)
{
do_efdcfsi();
RETURN();
}
void OPPROTO op_efdcfui (void)
{
do_efdcfui();
RETURN();
}
void OPPROTO op_efdcfsf (void)
{
do_efdcfsf();
RETURN();
}
void OPPROTO op_efdcfuf (void)
{
do_efdcfuf();
RETURN();
}
void OPPROTO op_efdctsi (void)
{
do_efdctsi();
RETURN();
}
void OPPROTO op_efdctui (void)
{
do_efdctui();
RETURN();
}
void OPPROTO op_efdctsf (void)
{
do_efdctsf();
RETURN();
}
void OPPROTO op_efdctuf (void)
{
do_efdctuf();
RETURN();
}
void OPPROTO op_efdctuiz (void)
{
do_efdctuiz();
RETURN();
}
void OPPROTO op_efdctsiz (void)
{
do_efdctsiz();
RETURN();
}
void OPPROTO op_efdtstlt (void)
{
T0 = _do_efdtstlt(T0_64, T1_64);
RETURN();
}
void OPPROTO op_efdtstgt (void)
{
T0 = _do_efdtstgt(T0_64, T1_64);
RETURN();
}
void OPPROTO op_efdtsteq (void)
{
T0 = _do_efdtsteq(T0_64, T1_64);
RETURN();
}
此差异已折叠。
......@@ -125,155 +125,4 @@ void do_load_403_pb (int num);
void do_store_403_pb (int num);
#endif
/* SPE extension helpers */
/* Single precision floating-point helpers */
void do_efscmplt (void);
void do_efscmpgt (void);
void do_efscmpeq (void);
void do_efscfsf (void);
void do_efscfuf (void);
void do_efsctsf (void);
void do_efsctuf (void);
void do_efscfsi (void);
void do_efscfui (void);
void do_efsctsi (void);
void do_efsctui (void);
void do_efsctsiz (void);
void do_efsctuiz (void);
/* Double precision floating-point helpers */
void do_efdcmplt (void);
void do_efdcmpgt (void);
void do_efdcmpeq (void);
void do_efdcfsf (void);
void do_efdcfuf (void);
void do_efdctsf (void);
void do_efdctuf (void);
void do_efdcfsi (void);
void do_efdcfui (void);
void do_efdctsi (void);
void do_efdctui (void);
void do_efdctsiz (void);
void do_efdctuiz (void);
void do_efdcfs (void);
void do_efscfd (void);
/* Floating-point vector helpers */
void do_evfsabs (void);
void do_evfsnabs (void);
void do_evfsneg (void);
void do_evfsadd (void);
void do_evfssub (void);
void do_evfsmul (void);
void do_evfsdiv (void);
void do_evfscmplt (void);
void do_evfscmpgt (void);
void do_evfscmpeq (void);
void do_evfststlt (void);
void do_evfststgt (void);
void do_evfststeq (void);
void do_evfscfsi (void);
void do_evfscfui (void);
void do_evfscfsf (void);
void do_evfscfuf (void);
void do_evfsctsf (void);
void do_evfsctuf (void);
void do_evfsctsi (void);
void do_evfsctui (void);
void do_evfsctsiz (void);
void do_evfsctuiz (void);
/* SPE extension */
/* Single precision floating-point helpers */
static always_inline uint32_t _do_efsabs (uint32_t val)
{
return val & ~0x80000000;
}
static always_inline uint32_t _do_efsnabs (uint32_t val)
{
return val | 0x80000000;
}
static always_inline uint32_t _do_efsneg (uint32_t val)
{
return val ^ 0x80000000;
}
static always_inline uint32_t _do_efsadd (uint32_t op1, uint32_t op2)
{
CPU_FloatU u1, u2;
u1.l = op1;
u2.l = op2;
u1.f = float32_add(u1.f, u2.f, &env->spe_status);
return u1.l;
}
static always_inline uint32_t _do_efssub (uint32_t op1, uint32_t op2)
{
CPU_FloatU u1, u2;
u1.l = op1;
u2.l = op2;
u1.f = float32_sub(u1.f, u2.f, &env->spe_status);
return u1.l;
}
static always_inline uint32_t _do_efsmul (uint32_t op1, uint32_t op2)
{
CPU_FloatU u1, u2;
u1.l = op1;
u2.l = op2;
u1.f = float32_mul(u1.f, u2.f, &env->spe_status);
return u1.l;
}
static always_inline uint32_t _do_efsdiv (uint32_t op1, uint32_t op2)
{
CPU_FloatU u1, u2;
u1.l = op1;
u2.l = op2;
u1.f = float32_div(u1.f, u2.f, &env->spe_status);
return u1.l;
}
static always_inline int _do_efststlt (uint32_t op1, uint32_t op2)
{
CPU_FloatU u1, u2;
u1.l = op1;
u2.l = op2;
return float32_lt(u1.f, u2.f, &env->spe_status) ? 4 : 0;
}
static always_inline int _do_efststgt (uint32_t op1, uint32_t op2)
{
CPU_FloatU u1, u2;
u1.l = op1;
u2.l = op2;
return float32_le(u1.f, u2.f, &env->spe_status) ? 0 : 4;
}
static always_inline int _do_efststeq (uint32_t op1, uint32_t op2)
{
CPU_FloatU u1, u2;
u1.l = op1;
u2.l = op2;
return float32_eq(u1.f, u2.f, &env->spe_status) ? 4 : 0;
}
/* Double precision floating-point helpers */
static always_inline int _do_efdtstlt (uint64_t op1, uint64_t op2)
{
CPU_DoubleU u1, u2;
u1.ll = op1;
u2.ll = op2;
return float64_lt(u1.d, u2.d, &env->spe_status) ? 4 : 0;
}
static always_inline int _do_efdtstgt (uint64_t op1, uint64_t op2)
{
CPU_DoubleU u1, u2;
u1.ll = op1;
u2.ll = op2;
return float64_le(u1.d, u2.d, &env->spe_status) ? 0 : 4;
}
static always_inline int _do_efdtsteq (uint64_t op1, uint64_t op2)
{
CPU_DoubleU u1, u2;
u1.ll = op1;
u2.ll = op2;
return float64_eq(u1.d, u2.d, &env->spe_status) ? 4 : 0;
}
#endif
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册