[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 11/17] target-alpha: Fix integer overflow checkin
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH v2 11/17] target-alpha: Fix integer overflow checking insns |
Date: |
Tue, 12 May 2015 10:39:41 -0700 |
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 <address@hidden>
Signed-off-by: Richard Henderson <address@hidden>
---
target-alpha/helper.h | 7 +-----
target-alpha/int_helper.c | 59 ++--------------------------------------------
target-alpha/translate.c | 60 +++++++++++++++++++++++++++++++++++++++++------
3 files changed, 56 insertions(+), 70 deletions(-)
diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index 9e7b771..5b1a5d9 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -1,12 +1,7 @@
DEF_HELPER_3(excp, noreturn, env, int, int)
DEF_HELPER_FLAGS_1(load_pcc, TCG_CALL_NO_RWG_SE, i64, env)
-DEF_HELPER_FLAGS_3(addqv, TCG_CALL_NO_WG, i64, env, i64, i64)
-DEF_HELPER_FLAGS_3(addlv, TCG_CALL_NO_WG, i64, env, i64, i64)
-DEF_HELPER_FLAGS_3(subqv, TCG_CALL_NO_WG, i64, env, i64, i64)
-DEF_HELPER_FLAGS_3(sublv, TCG_CALL_NO_WG, i64, env, i64, i64)
-DEF_HELPER_FLAGS_3(mullv, TCG_CALL_NO_WG, i64, env, i64, i64)
-DEF_HELPER_FLAGS_3(mulqv, TCG_CALL_NO_WG, i64, env, i64, i64)
+DEF_HELPER_FLAGS_3(check_overflow, TCG_CALL_NO_WG, void, env, i64, i64)
DEF_HELPER_FLAGS_1(ctpop, TCG_CALL_NO_RWG_SE, i64, i64)
DEF_HELPER_FLAGS_1(ctlz, TCG_CALL_NO_RWG_SE, i64, i64)
diff --git a/target-alpha/int_helper.c b/target-alpha/int_helper.c
index 7a205eb..8e4537f 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;
}
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 7868cc4..74f5d07 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1362,7 +1362,7 @@ static ExitStatus translate_one(DisasContext *ctx,
uint32_t insn)
uint16_t fn11;
uint8_t opc, ra, rb, rc, fpfn, fn7, lit;
bool islit;
- TCGv va, vb, vc, tmp;
+ TCGv va, vb, vc, tmp, tmp2;
TCGv_i32 t32;
ExitStatus ret;
@@ -1574,11 +1574,23 @@ static ExitStatus translate_one(DisasContext *ctx,
uint32_t insn)
break;
case 0x40:
/* ADDL/V */
- gen_helper_addlv(vc, cpu_env, va, vb);
+ tmp = tcg_temp_new();
+ tcg_gen_ext32s_i64(tmp, va);
+ tcg_gen_ext32s_i64(vc, vb);
+ tcg_gen_add_i64(tmp, tmp, vc);
+ tcg_gen_ext32s_i64(vc, tmp);
+ gen_helper_check_overflow(cpu_env, vc, tmp);
+ tcg_temp_free(tmp);
break;
case 0x49:
/* SUBL/V */
- gen_helper_sublv(vc, cpu_env, va, vb);
+ tmp = tcg_temp_new();
+ tcg_gen_ext32s_i64(tmp, va);
+ tcg_gen_ext32s_i64(vc, vb);
+ tcg_gen_sub_i64(tmp, tmp, vc);
+ tcg_gen_ext32s_i64(vc, tmp);
+ gen_helper_check_overflow(cpu_env, vc, tmp);
+ tcg_temp_free(tmp);
break;
case 0x4D:
/* CMPLT */
@@ -1586,11 +1598,33 @@ static ExitStatus translate_one(DisasContext *ctx,
uint32_t insn)
break;
case 0x60:
/* ADDQ/V */
- gen_helper_addqv(vc, cpu_env, va, vb);
+ tmp = tcg_temp_new();
+ tmp2 = tcg_temp_new();
+ tcg_gen_eqv_i64(tmp, va, vb);
+ tcg_gen_mov_i64(tmp2, va);
+ tcg_gen_add_i64(vc, va, vb);
+ tcg_gen_xor_i64(tmp2, tmp2, vc);
+ tcg_gen_and_i64(tmp, tmp, tmp2);
+ tcg_gen_shri_i64(tmp, tmp, 63);
+ tcg_gen_movi_i64(tmp2, 0);
+ gen_helper_check_overflow(cpu_env, tmp, tmp2);
+ tcg_temp_free(tmp);
+ tcg_temp_free(tmp2);
break;
case 0x69:
/* SUBQ/V */
- gen_helper_subqv(vc, cpu_env, va, vb);
+ tmp = tcg_temp_new();
+ tmp2 = tcg_temp_new();
+ tcg_gen_xor_i64(tmp, va, vb);
+ tcg_gen_mov_i64(tmp2, va);
+ tcg_gen_sub_i64(vc, va, vb);
+ tcg_gen_xor_i64(tmp2, tmp2, vc);
+ tcg_gen_and_i64(tmp, tmp, tmp2);
+ tcg_gen_shri_i64(tmp, tmp, 63);
+ tcg_gen_movi_i64(tmp2, 0);
+ gen_helper_check_overflow(cpu_env, tmp, tmp2);
+ tcg_temp_free(tmp);
+ tcg_temp_free(tmp2);
break;
case 0x6D:
/* CMPLE */
@@ -1885,11 +1919,23 @@ static ExitStatus translate_one(DisasContext *ctx,
uint32_t insn)
break;
case 0x40:
/* MULL/V */
- gen_helper_mullv(vc, cpu_env, va, vb);
+ tmp = tcg_temp_new();
+ tcg_gen_ext32s_i64(tmp, va);
+ tcg_gen_ext32s_i64(vc, vb);
+ tcg_gen_mul_i64(tmp, tmp, vc);
+ tcg_gen_ext32s_i64(vc, tmp);
+ gen_helper_check_overflow(cpu_env, vc, tmp);
+ tcg_temp_free(tmp);
break;
case 0x60:
/* MULQ/V */
- gen_helper_mulqv(vc, cpu_env, va, vb);
+ tmp = tcg_temp_new();
+ tmp2 = tcg_temp_new();
+ tcg_gen_muls2_i64(vc, tmp, va, vb);
+ tcg_gen_sari_i64(tmp2, vc, 63);
+ gen_helper_check_overflow(cpu_env, tmp, tmp2);
+ tcg_temp_free(tmp);
+ tcg_temp_free(tmp2);
break;
default:
goto invalid_opc;
--
2.1.0
- [Qemu-devel] [PATCH v2 00/17] target-alpha fpu improvments, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 02/17] target-alpha: Rename floating-point subroutines, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 04/17] target-alpha: Set PC correctly for floating-point exceptions, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 01/17] target-alpha: Move VAX helpers to a new file, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 05/17] target-alpha: Tidy FPCR representation, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 06/17] target-alpha: Set fpcr_exc_status even for disabled exceptions, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 03/17] target-alpha: Forget installed round mode after MT_FPCR, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 07/17] target-alpha: Set EXC_M_SWC for exceptions from /S insns, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 09/17] target-alpha: Fix cvttq vs large integers, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 08/17] target-alpha: Raise IOV from CVTTQ, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 11/17] target-alpha: Fix integer overflow checking insns,
Richard Henderson <=
- [Qemu-devel] [PATCH v2 12/17] target-alpha: Implement WH64EN, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 10/17] target-alpha: Fix cvttq vs inf, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 13/17] target-alpha: Disallow literal operand to 1C.30 to 1C.37, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 14/17] target-alpha: Raise EXC_M_INV properly for fp inputs, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 17/17] target-alpha: Rewrite helper_zapnot, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 15/17] target-alpha: Suppress underflow from CVTTQ if DNZ, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 16/17] target-alpha: Raise IOV from CVTQL, Richard Henderson, 2015/05/12