target-ppc: convert logical instructions to TCG

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5506 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
aurel32 2008-10-21 11:31:27 +00:00
parent e1571908a2
commit 26d6736245
4 changed files with 248 additions and 394 deletions

View file

@ -368,96 +368,98 @@ void do_subfzeo_64 (void)
}
#endif
void do_cntlzw (void)
target_ulong helper_cntlzw (target_ulong t)
{
T0 = clz32(T0);
return clz32(t);
}
#if defined(TARGET_PPC64)
void do_cntlzd (void)
target_ulong helper_cntlzd (target_ulong t)
{
T0 = clz64(T0);
return clz64(t);
}
#endif
/* shift right arithmetic helper */
void do_sraw (void)
target_ulong helper_sraw (target_ulong value, target_ulong shift)
{
int32_t ret;
if (likely(!(T1 & 0x20UL))) {
if (likely((uint32_t)T1 != 0)) {
ret = (int32_t)T0 >> (T1 & 0x1fUL);
if (likely(ret >= 0 || ((int32_t)T0 & ((1 << T1) - 1)) == 0)) {
if (likely(!(shift & 0x20))) {
if (likely((uint32_t)shift != 0)) {
shift &= 0x1f;
ret = (int32_t)value >> shift;
if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
env->xer &= ~(1 << XER_CA);
} else {
env->xer |= (1 << XER_CA);
}
} else {
ret = T0;
ret = (int32_t)value;
env->xer &= ~(1 << XER_CA);
}
} else {
ret = UINT32_MAX * ((uint32_t)T0 >> 31);
if (likely(ret >= 0 || ((uint32_t)T0 & ~0x80000000UL) == 0)) {
env->xer &= ~(1 << XER_CA);
} else {
ret = (int32_t)value >> 31;
if (ret) {
env->xer |= (1 << XER_CA);
} else {
env->xer &= ~(1 << XER_CA);
}
}
T0 = ret;
return (target_long)ret;
}
#if defined(TARGET_PPC64)
void do_srad (void)
target_ulong helper_srad (target_ulong value, target_ulong shift)
{
int64_t ret;
if (likely(!(T1 & 0x40UL))) {
if (likely((uint64_t)T1 != 0)) {
ret = (int64_t)T0 >> (T1 & 0x3FUL);
if (likely(ret >= 0 || ((int64_t)T0 & ((1 << T1) - 1)) == 0)) {
if (likely(!(shift & 0x40))) {
if (likely((uint64_t)shift != 0)) {
shift &= 0x3f;
ret = (int64_t)value >> shift;
if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
env->xer &= ~(1 << XER_CA);
} else {
env->xer |= (1 << XER_CA);
}
} else {
ret = T0;
ret = (int64_t)value;
env->xer &= ~(1 << XER_CA);
}
} else {
ret = UINT64_MAX * ((uint64_t)T0 >> 63);
if (likely(ret >= 0 || ((uint64_t)T0 & ~0x8000000000000000ULL) == 0)) {
env->xer &= ~(1 << XER_CA);
} else {
ret = (int64_t)value >> 63;
if (ret) {
env->xer |= (1 << XER_CA);
} else {
env->xer &= ~(1 << XER_CA);
}
}
T0 = ret;
return ret;
}
#endif
void do_popcntb (void)
target_ulong helper_popcntb (target_ulong val)
{
uint32_t ret;
int i;
ret = 0;
for (i = 0; i < 32; i += 8)
ret |= ctpop8((T0 >> i) & 0xFF) << i;
T0 = ret;
ret |= ctpop8((val >> i) & 0xFF) << i;
return ret;
}
#if defined(TARGET_PPC64)
void do_popcntb_64 (void)
target_ulong helper_popcntb_64 (target_ulong val)
{
uint64_t ret;
int i;
ret = 0;
for (i = 0; i < 64; i += 8)
ret |= ctpop8((T0 >> i) & 0xFF) << i;
T0 = ret;
ret |= ctpop8((val >> i) & 0xFF) << i;
return ret;
}
#endif