diff options
author | Tom Musta <tommusta@gmail.com> | 2014-08-12 08:45:08 -0500 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2014-09-08 12:50:50 +0200 |
commit | 9824d01d5d789a57d27360c0f5e8ee44955eb1d7 (patch) | |
tree | aed8b85b25a9ac501f7df056fd4110cb5d259bb7 /target-ppc/int_helper.c | |
parent | 1fa74845f2bab36bfa37108b9054b53c1b8264b9 (diff) |
target-ppc: Bug Fix: mulldo OV Detection
Fix the code to properly detect overflow; the 128 bit signed
product must have all zeroes or all ones in the first 65 bits
otherwise OV should be set.
Example:
R3 45F086A5D5887509
R4 0000000000000002
mulldo 3,3,4
Should set XER[OV].
Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'target-ppc/int_helper.c')
-rw-r--r-- | target-ppc/int_helper.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c index f6e8846707..e83a25d05a 100644 --- a/target-ppc/int_helper.c +++ b/target-ppc/int_helper.c @@ -32,12 +32,22 @@ uint64_t helper_mulldo(CPUPPCState *env, uint64_t arg1, uint64_t arg2) uint64_t tl; muls64(&tl, (uint64_t *)&th, arg1, arg2); - /* If th != 0 && th != -1, then we had an overflow */ - if (likely((uint64_t)(th + 1) <= 1)) { + + /* th should either contain all 1 bits or all 0 bits and should + * match the sign bit of tl; otherwise we have overflowed. */ + + if ((int64_t)tl < 0) { + if (likely(th == -1LL)) { + env->ov = 0; + } else { + env->so = env->ov = 1; + } + } else if (likely(th == 0LL)) { env->ov = 0; } else { env->so = env->ov = 1; } + return (int64_t)tl; } #endif |