mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-07 01:33:56 -06:00
target-ppc: Split out SO, OV, CA fields from XER
In preparation for more efficient setting of these fields. Cc: Alexander Graf <agraf@suse.de> Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
parent
23ad1d5d3c
commit
da91a00f19
6 changed files with 160 additions and 106 deletions
|
@ -33,9 +33,9 @@ uint64_t helper_mulldo(CPUPPCState *env, uint64_t arg1, uint64_t arg2)
|
|||
muls64(&tl, (uint64_t *)&th, arg1, arg2);
|
||||
/* If th != 0 && th != -1, then we had an overflow */
|
||||
if (likely((uint64_t)(th + 1) <= 1)) {
|
||||
env->xer &= ~(1 << XER_OV);
|
||||
env->ov = 0;
|
||||
} else {
|
||||
env->xer |= (1 << XER_OV) | (1 << XER_SO);
|
||||
env->so = env->ov = 1;
|
||||
}
|
||||
return (int64_t)tl;
|
||||
}
|
||||
|
@ -64,21 +64,17 @@ target_ulong helper_sraw(CPUPPCState *env, target_ulong value,
|
|||
shift &= 0x1f;
|
||||
ret = (int32_t)value >> shift;
|
||||
if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
|
||||
env->xer &= ~(1 << XER_CA);
|
||||
env->ca = 0;
|
||||
} else {
|
||||
env->xer |= (1 << XER_CA);
|
||||
env->ca = 1;
|
||||
}
|
||||
} else {
|
||||
ret = (int32_t)value;
|
||||
env->xer &= ~(1 << XER_CA);
|
||||
env->ca = 0;
|
||||
}
|
||||
} else {
|
||||
ret = (int32_t)value >> 31;
|
||||
if (ret) {
|
||||
env->xer |= (1 << XER_CA);
|
||||
} else {
|
||||
env->xer &= ~(1 << XER_CA);
|
||||
}
|
||||
env->ca = (ret != 0);
|
||||
}
|
||||
return (target_long)ret;
|
||||
}
|
||||
|
@ -94,21 +90,17 @@ target_ulong helper_srad(CPUPPCState *env, target_ulong value,
|
|||
shift &= 0x3f;
|
||||
ret = (int64_t)value >> shift;
|
||||
if (likely(ret >= 0 || (value & ((1 << shift) - 1)) == 0)) {
|
||||
env->xer &= ~(1 << XER_CA);
|
||||
env->ca = 0;
|
||||
} else {
|
||||
env->xer |= (1 << XER_CA);
|
||||
env->ca = 1;
|
||||
}
|
||||
} else {
|
||||
ret = (int64_t)value;
|
||||
env->xer &= ~(1 << XER_CA);
|
||||
env->ca = 0;
|
||||
}
|
||||
} else {
|
||||
ret = (int64_t)value >> 63;
|
||||
if (ret) {
|
||||
env->xer |= (1 << XER_CA);
|
||||
} else {
|
||||
env->xer &= ~(1 << XER_CA);
|
||||
}
|
||||
env->ca = (ret != 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -188,16 +180,16 @@ target_ulong helper_divo(CPUPPCState *env, target_ulong arg1,
|
|||
|
||||
if (((int32_t)tmp == INT32_MIN && (int32_t)arg2 == (int32_t)-1) ||
|
||||
(int32_t)arg2 == 0) {
|
||||
env->xer |= (1 << XER_OV) | (1 << XER_SO);
|
||||
env->so = env->ov = 1;
|
||||
env->spr[SPR_MQ] = 0;
|
||||
return INT32_MIN;
|
||||
} else {
|
||||
env->spr[SPR_MQ] = tmp % arg2;
|
||||
tmp /= (int32_t)arg2;
|
||||
if ((int32_t)tmp != tmp) {
|
||||
env->xer |= (1 << XER_OV) | (1 << XER_SO);
|
||||
env->so = env->ov = 1;
|
||||
} else {
|
||||
env->xer &= ~(1 << XER_OV);
|
||||
env->ov = 0;
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
@ -221,11 +213,11 @@ target_ulong helper_divso(CPUPPCState *env, target_ulong arg1,
|
|||
{
|
||||
if (((int32_t)arg1 == INT32_MIN && (int32_t)arg2 == (int32_t)-1) ||
|
||||
(int32_t)arg2 == 0) {
|
||||
env->xer |= (1 << XER_OV) | (1 << XER_SO);
|
||||
env->so = env->ov = 1;
|
||||
env->spr[SPR_MQ] = 0;
|
||||
return INT32_MIN;
|
||||
} else {
|
||||
env->xer &= ~(1 << XER_OV);
|
||||
env->ov = 0;
|
||||
env->spr[SPR_MQ] = (int32_t)arg1 % (int32_t)arg2;
|
||||
return (int32_t)arg1 / (int32_t)arg2;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue