aboutsummaryrefslogtreecommitdiff
path: root/target-alpha/int_helper.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2014-07-03 13:18:26 -0700
committerRichard Henderson <rth@twiddle.net>2015-05-18 13:03:47 -0700
commit4d1628e832dfc6ec02b0d196f6cc250aaa7bf3b3 (patch)
tree9db81b4c7e9833618daaeaa4f81bdb1ee848cf88 /target-alpha/int_helper.c
parent7b4dde839e86ca6c254d4e3cd28260e9d668afb5 (diff)
target-alpha: Fix integer overflow checking insns
We need to write the result to the destination register before raising any exception. Thus inline the code for each insn, and check for any exception after we're done. Reported-by: Al Viro <viro@ZenIV.linux.org.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-alpha/int_helper.c')
-rw-r--r--target-alpha/int_helper.c59
1 files changed, 2 insertions, 57 deletions
diff --git a/target-alpha/int_helper.c b/target-alpha/int_helper.c
index 7a205eb9fa..8e4537f5b7 100644
--- a/target-alpha/int_helper.c
+++ b/target-alpha/int_helper.c
@@ -249,64 +249,9 @@ uint64_t helper_unpkbw(uint64_t op1)
| ((op1 & 0xff000000) << 24));
}
-uint64_t helper_addqv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
+void helper_check_overflow(CPUAlphaState *env, uint64_t op1, uint64_t op2)
{
- uint64_t tmp = op1;
- op1 += op2;
- if (unlikely((tmp ^ op2 ^ (-1ULL)) & (tmp ^ op1) & (1ULL << 63))) {
+ if (unlikely(op1 != op2)) {
arith_excp(env, GETPC(), EXC_M_IOV, 0);
}
- return op1;
-}
-
-uint64_t helper_addlv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
-{
- uint64_t tmp = op1;
- op1 = (uint32_t)(op1 + op2);
- if (unlikely((tmp ^ op2 ^ (-1UL)) & (tmp ^ op1) & (1UL << 31))) {
- arith_excp(env, GETPC(), EXC_M_IOV, 0);
- }
- return op1;
-}
-
-uint64_t helper_subqv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
-{
- uint64_t res;
- res = op1 - op2;
- if (unlikely((op1 ^ op2) & (res ^ op1) & (1ULL << 63))) {
- arith_excp(env, GETPC(), EXC_M_IOV, 0);
- }
- return res;
-}
-
-uint64_t helper_sublv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
-{
- uint32_t res;
- res = op1 - op2;
- if (unlikely((op1 ^ op2) & (res ^ op1) & (1UL << 31))) {
- arith_excp(env, GETPC(), EXC_M_IOV, 0);
- }
- return res;
-}
-
-uint64_t helper_mullv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
-{
- int64_t res = (int64_t)op1 * (int64_t)op2;
-
- if (unlikely((int32_t)res != res)) {
- arith_excp(env, GETPC(), EXC_M_IOV, 0);
- }
- return (int64_t)((int32_t)res);
-}
-
-uint64_t helper_mulqv(CPUAlphaState *env, uint64_t op1, uint64_t op2)
-{
- uint64_t tl, th;
-
- muls64(&tl, &th, op1, op2);
- /* If th != 0 && th != -1, then we had an overflow */
- if (unlikely((th + 1) > 1)) {
- arith_excp(env, GETPC(), EXC_M_IOV, 0);
- }
- return tl;
}