diff options
author | Richard Henderson <rth@twiddle.net> | 2010-01-04 11:24:04 -0800 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2010-02-23 23:36:22 +0100 |
commit | 866be65dfdac0121b1dbe4a4487fb929a16ba279 (patch) | |
tree | 6056f82f90e08ffdeb70fe489bd1bc7f6cac65f5 | |
parent | dad081ee69d58e0e7c32b66b6a8a47344f830548 (diff) |
target-alpha: Clean up arithmetic traps.
Replace the EXCP_ARITH_OVERFLOW placeholder with the complete
set of bits from the EXC_SUM IPR. Use them in the existing
places where we raise arithmetic exceptions.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
-rw-r--r-- | target-alpha/cpu.h | 10 | ||||
-rw-r--r-- | target-alpha/op_helper.c | 14 |
2 files changed, 14 insertions, 10 deletions
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h index 3728d830ba..eda1b4ae83 100644 --- a/target-alpha/cpu.h +++ b/target-alpha/cpu.h @@ -450,9 +450,13 @@ enum { }; /* Arithmetic exception */ -enum { - EXCP_ARITH_OVERFLOW, -}; +#define EXC_M_IOV (1<<16) /* Integer Overflow */ +#define EXC_M_INE (1<<15) /* Inexact result */ +#define EXC_M_UNF (1<<14) /* Underflow */ +#define EXC_M_FOV (1<<13) /* Overflow */ +#define EXC_M_DZE (1<<12) /* Division by zero */ +#define EXC_M_INV (1<<11) /* Invalid operation */ +#define EXC_M_SWC (1<<10) /* Software completion */ enum { IR_V0 = 0, diff --git a/target-alpha/op_helper.c b/target-alpha/op_helper.c index b2abf6c785..00f5c1f260 100644 --- a/target-alpha/op_helper.c +++ b/target-alpha/op_helper.c @@ -78,7 +78,7 @@ uint64_t helper_addqv (uint64_t op1, uint64_t op2) uint64_t tmp = op1; op1 += op2; if (unlikely((tmp ^ op2 ^ (-1ULL)) & (tmp ^ op1) & (1ULL << 63))) { - helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); + helper_excp(EXCP_ARITH, EXC_M_IOV); } return op1; } @@ -88,7 +88,7 @@ uint64_t helper_addlv (uint64_t op1, uint64_t op2) uint64_t tmp = op1; op1 = (uint32_t)(op1 + op2); if (unlikely((tmp ^ op2 ^ (-1UL)) & (tmp ^ op1) & (1UL << 31))) { - helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); + helper_excp(EXCP_ARITH, EXC_M_IOV); } return op1; } @@ -98,7 +98,7 @@ uint64_t helper_subqv (uint64_t op1, uint64_t op2) uint64_t res; res = op1 - op2; if (unlikely((op1 ^ op2) & (res ^ op1) & (1ULL << 63))) { - helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); + helper_excp(EXCP_ARITH, EXC_M_IOV); } return res; } @@ -108,7 +108,7 @@ uint64_t helper_sublv (uint64_t op1, uint64_t op2) uint32_t res; res = op1 - op2; if (unlikely((op1 ^ op2) & (res ^ op1) & (1UL << 31))) { - helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); + helper_excp(EXCP_ARITH, EXC_M_IOV); } return res; } @@ -118,7 +118,7 @@ uint64_t helper_mullv (uint64_t op1, uint64_t op2) int64_t res = (int64_t)op1 * (int64_t)op2; if (unlikely((int32_t)res != res)) { - helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); + helper_excp(EXCP_ARITH, EXC_M_IOV); } return (int64_t)((int32_t)res); } @@ -130,7 +130,7 @@ uint64_t helper_mulqv (uint64_t op1, uint64_t op2) muls64(&tl, &th, op1, op2); /* If th != 0 && th != -1, then we had an overflow */ if (unlikely((th + 1) > 1)) { - helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); + helper_excp(EXCP_ARITH, EXC_M_IOV); } return tl; } @@ -987,7 +987,7 @@ static inline uint64_t __helper_cvtql(uint64_t a, int s, int v) r |= ((uint64_t)(a & 0x7FFFFFFF)) << 29; if (v && (int64_t)((int32_t)r) != (int64_t)r) { - helper_excp(EXCP_ARITH, EXCP_ARITH_OVERFLOW); + helper_excp(EXCP_ARITH, EXC_M_IOV); } if (s) { /* TODO */ |