From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47687) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ay3DH-0004YC-C2 for qemu-devel@nongnu.org; Wed, 04 May 2016 16:16:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ay3D5-0004cB-68 for qemu-devel@nongnu.org; Wed, 04 May 2016 16:15:57 -0400 Received: from smtp1-g21.free.fr ([212.27.42.1]:35819) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ay3D4-0004U4-Pi for qemu-devel@nongnu.org; Wed, 04 May 2016 16:15:51 -0400 From: Laurent Vivier Date: Wed, 4 May 2016 22:12:07 +0200 Message-Id: <1462392752-17703-28-git-send-email-laurent@vivier.eu> In-Reply-To: <1462392752-17703-1-git-send-email-laurent@vivier.eu> References: <1462392752-17703-1-git-send-email-laurent@vivier.eu> Subject: [Qemu-devel] [PATCH 27/52] target-m68k: Inline addx, subx, negx List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: gerg@uclinux.org, schwab@linux-m68k.org, agraf@suse.de, rth@twiddle.net, Laurent Vivier From: Richard Henderson Signed-off-by: Richard Henderson Signed-off-by: Laurent Vivier --- target-m68k/helper.c | 40 ----------------------------- target-m68k/helper.h | 2 -- target-m68k/translate.c | 67 +++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 56 insertions(+), 53 deletions(-) diff --git a/target-m68k/helper.c b/target-m68k/helper.c index 0ca8d3f..42a2f1c 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -276,46 +276,6 @@ uint32_t HELPER(sats)(uint32_t val, uint32_t v) return val; } -uint32_t HELPER(subx_cc)(CPUM68KState *env, uint32_t op1, uint32_t op2) -{ - uint32_t res, new_x; - - if (env->cc_x) { - new_x = (op1 <= op2); - res = op1 - (op2 + 1); - } else { - new_x = (op1 < op2); - res = op1 - op2; - } - env->cc_x = new_x; - env->cc_c = new_x; - env->cc_n = res; - env->cc_z |= res; /* !Z is sticky */ - env->cc_v = (res ^ op1) & (op1 ^ op2); - - return res; -} - -uint32_t HELPER(addx_cc)(CPUM68KState *env, uint32_t op1, uint32_t op2) -{ - uint32_t res, new_x; - - if (env->cc_x) { - res = op1 + op2 + 1; - new_x = (res <= op2); - } else { - res = op1 + op2; - new_x = (res < op2); - } - env->cc_x = new_x; - env->cc_c = new_x; - env->cc_n = res; - env->cc_z |= res; /* !Z is sticky. */ - env->cc_v = (res ^ op1) & ~(op1 ^ op2); - - return res; -} - void HELPER(set_sr)(CPUM68KState *env, uint32_t val) { env->sr = val & 0xffe0; diff --git a/target-m68k/helper.h b/target-m68k/helper.h index 9985f9b..aae01f9 100644 --- a/target-m68k/helper.h +++ b/target-m68k/helper.h @@ -3,8 +3,6 @@ DEF_HELPER_1(ff1, i32, i32) DEF_HELPER_FLAGS_2(sats, TCG_CALL_NO_RWG_SE, i32, i32, i32) DEF_HELPER_2(divu, void, env, i32) DEF_HELPER_2(divs, void, env, i32) -DEF_HELPER_3(addx_cc, i32, env, i32, i32) -DEF_HELPER_3(subx_cc, i32, env, i32, i32) DEF_HELPER_2(set_sr, void, env, i32) DEF_HELPER_3(movec, void, env, i32, i32) diff --git a/target-m68k/translate.c b/target-m68k/translate.c index 1e8cb37..13ae953 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -1503,11 +1503,27 @@ DISAS_INSN(move) DISAS_INSN(negx) { - TCGv reg; + TCGv reg, z; - gen_flush_flags(s); reg = DREG(insn, 0); - gen_helper_subx_cc(reg, cpu_env, tcg_const_i32(0), reg); + + /* Perform subtraction with borrow. */ + z = tcg_const_i32(0); + tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, reg, z, QREG_CC_X, z); + tcg_gen_sub2_i32(QREG_CC_N, QREG_CC_X, z, z, QREG_CC_N, QREG_CC_X); + tcg_temp_free(z); + tcg_gen_andi_i32(QREG_CC_X, QREG_CC_X, 1); + + /* Compute signed-overflow for negation. The normal formula for + subtraction is (res ^ src1) & (src1 ^ src2), but with src1==0 + this simplies to res & src2. */ + tcg_gen_and_i32(QREG_CC_V, QREG_CC_N, reg); + + /* Copy the rest of the results into place. */ + tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N); + tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X); + tcg_gen_mov_i32(reg, QREG_CC_N); + set_cc_op(s, CC_OP_FLAGS); } DISAS_INSN(lea) @@ -1929,13 +1945,28 @@ DISAS_INSN(suba) DISAS_INSN(subx) { - TCGv reg; - TCGv src; + TCGv reg, src, z; - gen_flush_flags(s); reg = DREG(insn, 9); src = DREG(insn, 0); - gen_helper_subx_cc(reg, cpu_env, reg, src); + + /* Perform subtract with borrow. */ + z = tcg_const_i32(0); + tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, src, z, QREG_CC_X, z); + tcg_gen_sub2_i32(QREG_CC_N, QREG_CC_X, reg, z, QREG_CC_N, QREG_CC_X); + tcg_temp_free(z); + tcg_gen_andi_i32(QREG_CC_X, QREG_CC_X, 1); + + /* Compute signed-overflow for subtraction. */ + tcg_gen_xor_i32(QREG_CC_V, QREG_CC_N, reg); + tcg_gen_xor_i32(QREG_CC_Z, reg, src); + tcg_gen_and_i32(QREG_CC_V, QREG_CC_V, QREG_CC_Z); + + /* Copy the rest of the results into place. */ + tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N); + tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X); + tcg_gen_mov_i32(reg, QREG_CC_N); + set_cc_op(s, CC_OP_FLAGS); } DISAS_INSN(mov3q) @@ -2029,13 +2060,27 @@ DISAS_INSN(adda) DISAS_INSN(addx) { - TCGv reg; - TCGv src; + TCGv reg, src, z; - gen_flush_flags(s); reg = DREG(insn, 9); src = DREG(insn, 0); - gen_helper_addx_cc(reg, cpu_env, reg, src); + + /* Perform addition with carry. */ + z = tcg_const_i32(0); + tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, QREG_CC_X, z, reg, z); + tcg_gen_add2_i32(QREG_CC_N, QREG_CC_X, QREG_CC_N, QREG_CC_X, src, z); + tcg_temp_free(z); + + /* Compute signed-overflow for addition. */ + tcg_gen_xor_i32(QREG_CC_V, QREG_CC_N, reg); + tcg_gen_xor_i32(QREG_CC_Z, reg, src); + tcg_gen_andc_i32(QREG_CC_V, QREG_CC_V, QREG_CC_Z); + + /* Copy the rest of the results into place. */ + tcg_gen_mov_i32(QREG_CC_Z, QREG_CC_N); + tcg_gen_mov_i32(QREG_CC_C, QREG_CC_X); + tcg_gen_mov_i32(reg, QREG_CC_N); + set_cc_op(s, CC_OP_FLAGS); } DISAS_INSN(shift_im) -- 2.5.5