From patchwork Wed May 4 20:12:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 9018641 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id CB6639F1D3 for ; Wed, 4 May 2016 20:28:15 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D035A2020F for ; Wed, 4 May 2016 20:28:11 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 64281201EC for ; Wed, 4 May 2016 20:28:07 +0000 (UTC) Received: from localhost ([::1]:50121 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ay3Ot-0003Ml-FP for patchwork-qemu-devel@patchwork.kernel.org; Wed, 04 May 2016 16:28:03 -0400 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 Received: from Quad.localdomain (unknown [IPv6:2a01:e34:eeee:5240:12c3:7bff:fe6b:9a76]) by smtp1-g21.free.fr (Postfix) with ESMTPS id DFE66B0051B; Wed, 4 May 2016 20:09:12 +0200 (CEST) From: Laurent Vivier To: qemu-devel@nongnu.org Date: Wed, 4 May 2016 22:12:07 +0200 Message-Id: <1462392752-17703-28-git-send-email-laurent@vivier.eu> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1462392752-17703-1-git-send-email-laurent@vivier.eu> References: <1462392752-17703-1-git-send-email-laurent@vivier.eu> X-detected-operating-system: by eggs.gnu.org: Windows NT kernel [generic] [fuzzy] X-Received-From: 212.27.42.1 Subject: [Qemu-devel] [PATCH 27/52] target-m68k: Inline addx, subx, negx X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , rth@twiddle.net, schwab@linux-m68k.org, agraf@suse.de, gerg@uclinux.org Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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)