From: Richard Henderson <rth@twiddle.net>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, viro@ZenIV.linux.org.uk
Subject: [Qemu-devel] [PULL 09/18] target-alpha: Fix integer overflow checking insns
Date: Wed, 9 Jul 2014 09:20:25 -0700 [thread overview]
Message-ID: <1404922834-28169-10-git-send-email-rth@twiddle.net> (raw)
In-Reply-To: <1404922834-28169-1-git-send-email-rth@twiddle.net>
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>
---
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 173db01..2cc100b 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 183573d..6ea33f3 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -1377,7 +1377,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;
@@ -1589,11 +1589,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 */
@@ -1601,11 +1613,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 */
@@ -1900,11 +1934,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;
--
1.9.3
next prev parent reply other threads:[~2014-07-09 16:21 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-09 16:20 [Qemu-devel] [PULL for-2.1 00/18] target-alpha patch queue Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 01/18] target-alpha: Forget installed round mode after MT_FPCR Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 02/18] target-alpha: Set PC correctly for floating-point exceptions Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 03/18] target-alpha: Store IOV exception in fp_status Richard Henderson
2014-07-09 16:28 ` Peter Maydell
2014-07-09 16:48 ` Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 04/18] target-alpha: Set fpcr_exc_status even for disabled exceptions Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 05/18] target-alpha: Set EXC_M_SWC for exceptions from /S insns Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 06/18] target-alpha: Raise IOV from CVTTQ Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 07/18] target-alpha: Fix cvttq vs large integers Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 08/18] target-alpha: Fix cvttq vs inf Richard Henderson
2014-07-09 16:20 ` Richard Henderson [this message]
2014-07-09 16:20 ` [Qemu-devel] [PULL 10/18] target-alpha: Implement WH64EN Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 11/18] target-alpha: Disallow literal operand to 1C.30 to 1C.37 Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 12/18] target-alpha: Ignore the unused fp_status exceptions Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 13/18] target-alpha: Raise EXC_M_INV properly for fp inputs Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 14/18] target-alpha: Suppress underflow from CVTTQ if DNZ Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 15/18] target-alpha: Raise IOV from CVTQL Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 16/18] target-alpha: Rename fcvtql Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 17/18] target-alpha: Fix fpcr_flush_to_zero initialization Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 18/18] target-alpha: Remove DNOD bit from FPCR Richard Henderson
2014-07-09 16:30 ` [Qemu-devel] [PULL for-2.1 00/18] target-alpha patch queue Peter Maydell
2014-07-09 16:37 ` Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1404922834-28169-10-git-send-email-rth@twiddle.net \
--to=rth@twiddle.net \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=viro@ZenIV.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).