aboutsummaryrefslogtreecommitdiffstats
path: root/target-ppc/op.c
diff options
context:
space:
mode:
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-11-11 00:18:34 +0000
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-11-11 00:18:34 +0000
commitc3e10c7b4377c1cbc0a4fbc12312c2cf41c0cda7 (patch)
treea49e92ffaeb9672c585601f608bc726e3fab134c /target-ppc/op.c
parenta76dc35afd2663343229d9dc05d493950d067b56 (diff)
Optimize PowerPC overflow flag computation in most useful cases.
Use the same routines to check overflow for addo, subfo and PowerPC 405 multiply and add cases. Fix carry reset in addme(o) and subfme(o) cases. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3574 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-ppc/op.c')
-rw-r--r--target-ppc/op.c70
1 files changed, 22 insertions, 48 deletions
diff --git a/target-ppc/op.c b/target-ppc/op.c
index 730dc0e90..bbc5c5b9a 100644
--- a/target-ppc/op.c
+++ b/target-ppc/op.c
@@ -191,6 +191,12 @@ void OPPROTO op_move_T2_T0 (void)
RETURN();
}
+void OPPROTO op_moven_T2_T0 (void)
+{
+ T2 = ~T0;
+ RETURN();
+}
+
/* Generate exceptions */
void OPPROTO op_raise_exception_err (void)
{
@@ -847,26 +853,18 @@ void OPPROTO op_add (void)
void OPPROTO op_check_addo (void)
{
- if (likely(!(((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
- ((uint32_t)T2 ^ (uint32_t)T0) & (1UL << 31)))) {
- xer_ov = 0;
- } else {
- xer_ov = 1;
- xer_so = 1;
- }
+ xer_ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) &
+ ((uint32_t)T2 ^ (uint32_t)T0)) >> 31;
+ xer_so |= xer_ov;
RETURN();
}
#if defined(TARGET_PPC64)
void OPPROTO op_check_addo_64 (void)
{
- if (likely(!(((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
- ((uint64_t)T2 ^ (uint64_t)T0) & (1ULL << 63)))) {
- xer_ov = 0;
- } else {
- xer_ov = 1;
- xer_so = 1;
- }
+ xer_ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) &
+ ((uint64_t)T2 ^ (uint64_t)T0)) >> 63;
+ xer_so |= xer_ov;
RETURN();
}
#endif
@@ -922,6 +920,8 @@ void OPPROTO op_add_me (void)
T0 += xer_ca + (-1);
if (likely((uint32_t)T1 != 0))
xer_ca = 1;
+ else
+ xer_ca = 0;
RETURN();
}
@@ -931,6 +931,8 @@ void OPPROTO op_add_me_64 (void)
T0 += xer_ca + (-1);
if (likely((uint64_t)T1 != 0))
xer_ca = 1;
+ else
+ xer_ca = 0;
RETURN();
}
#endif
@@ -1142,32 +1144,6 @@ void OPPROTO op_subf (void)
RETURN();
}
-void OPPROTO op_check_subfo (void)
-{
- if (likely(!(((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) &
- ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)))) {
- xer_ov = 0;
- } else {
- xer_ov = 1;
- xer_so = 1;
- }
- RETURN();
-}
-
-#if defined(TARGET_PPC64)
-void OPPROTO op_check_subfo_64 (void)
-{
- if (likely(!(((uint64_t)(~T2) ^ (uint64_t)T1 ^ UINT64_MAX) &
- ((uint64_t)(~T2) ^ (uint64_t)T0) & (1ULL << 63)))) {
- xer_ov = 0;
- } else {
- xer_ov = 1;
- xer_so = 1;
- }
- RETURN();
-}
-#endif
-
/* subtract from carrying */
void OPPROTO op_check_subfc (void)
{
@@ -1235,8 +1211,10 @@ void OPPROTO op_subfic_64 (void)
void OPPROTO op_subfme (void)
{
T0 = ~T0 + xer_ca - 1;
- if (likely((uint32_t)T0 != (uint32_t)-1))
+ if (likely((uint32_t)T0 != UINT32_MAX))
xer_ca = 1;
+ else
+ xer_ca = 0;
RETURN();
}
@@ -1244,8 +1222,10 @@ void OPPROTO op_subfme (void)
void OPPROTO op_subfme_64 (void)
{
T0 = ~T0 + xer_ca - 1;
- if (likely((uint64_t)T0 != (uint64_t)-1))
+ if (likely((uint64_t)T0 != UINT64_MAX))
xer_ca = 1;
+ else
+ xer_ca = 0;
RETURN();
}
#endif
@@ -2528,12 +2508,6 @@ void OPPROTO op_405_mullhwu (void)
RETURN();
}
-void OPPROTO op_405_check_ov (void)
-{
- do_405_check_ov();
- RETURN();
-}
-
void OPPROTO op_405_check_sat (void)
{
do_405_check_sat();