From patchwork Sat May 24 15:53:53 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 352124 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 545DE140083 for ; Sun, 25 May 2014 01:58:21 +1000 (EST) Received: from localhost ([::1]:48412 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WoEKw-0000ye-Q6 for incoming@patchwork.ozlabs.org; Sat, 24 May 2014 11:58:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46453) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WoEHT-0003Tx-Cw for qemu-devel@nongnu.org; Sat, 24 May 2014 11:54:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WoEHN-0001JW-2O for qemu-devel@nongnu.org; Sat, 24 May 2014 11:54:43 -0400 Received: from mail-pb0-x22b.google.com ([2607:f8b0:400e:c01::22b]:47311) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WoEHM-0001JK-Jf for qemu-devel@nongnu.org; Sat, 24 May 2014 11:54:37 -0400 Received: by mail-pb0-f43.google.com with SMTP id up15so5531491pbc.16 for ; Sat, 24 May 2014 08:54:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=fuNNHLx8/+aeJhjRZf6OQSkwKksVOaP6lEXOCJrS1PY=; b=NQ/qeN1ufpOZlOo5Q+OV79WxJRYiudjt9cwu7Ip5N0j2VJNvC08da0a04Rk+eH1TRD nurLlcnu9Y5a8ojIUlPNbFQpdnYbwx/tNBQ8hbTgGFX29DVmFrgARqK9H2LpRuD1MUqX QzcCVDh7I81ZNzMdav8xhKrSk8LSS5UDinuiIH1F9S8fQpqvis0OkQThjbI5Ij5QT8yH vFjrJkyx16hvuMg376Z8P8xk9ffYFB7Z6LiWIyHT682AhktXgPKHhJz7ksPdBKUDl9kB xGKoeBbSsWTfvdfzrVXDhwbRv+j6G8d7sN5fssmm9OP37f+GTSdako7snOERAQDA0nPN 7Ykw== X-Received: by 10.66.161.69 with SMTP id xq5mr14837233pab.62.1400946875240; Sat, 24 May 2014 08:54:35 -0700 (PDT) Received: from pike.twiddle.home (50-194-63-110-static.hfc.comcastbusiness.net. [50.194.63.110]) by mx.google.com with ESMTPSA id ie9sm30663048pad.29.2014.05.24.08.54.33 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 24 May 2014 08:54:34 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 24 May 2014 08:53:53 -0700 Message-Id: <1400946841-21079-17-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.9.0 In-Reply-To: <1400946841-21079-1-git-send-email-rth@twiddle.net> References: <1400946841-21079-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400e:c01::22b Cc: peter.maydell@linaro.org Subject: [Qemu-devel] [PULL 16/24] tcg-mips: Improve add2/sub2 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Reduce insn count from 5 to either 3 or 4. Reviewed-by: Paolo Bonzini Signed-off-by: Richard Henderson --- tcg/mips/tcg-target.c | 87 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 31 deletions(-) diff --git a/tcg/mips/tcg-target.c b/tcg/mips/tcg-target.c index 516c2b7..76a7852 100644 --- a/tcg/mips/tcg-target.c +++ b/tcg/mips/tcg-target.c @@ -1297,6 +1297,52 @@ static void tcg_out_qemu_st_direct(TCGContext *s, TCGReg datalo, TCGReg datahi, } } +static void tcg_out_addsub2(TCGContext *s, TCGReg rl, TCGReg rh, TCGReg al, + TCGReg ah, TCGArg bl, TCGArg bh, bool cbl, + bool cbh, bool is_sub) +{ + TCGReg th = TCG_TMP1; + + /* If we have a negative constant such that negating it would + make the high part zero, we can (usually) eliminate one insn. */ + if (cbl && cbh && bh == -1 && bl != 0) { + bl = -bl; + bh = 0; + is_sub = !is_sub; + } + + /* By operating on the high part first, we get to use the final + carry operation to move back from the temporary. */ + if (!cbh) { + tcg_out_opc_reg(s, (is_sub ? OPC_SUBU : OPC_ADDU), th, ah, bh); + } else if (bh != 0 || ah == rl) { + tcg_out_opc_imm(s, OPC_ADDIU, th, ah, (is_sub ? -bh : bh)); + } else { + th = ah; + } + + /* Note that tcg optimization should eliminate the bl == 0 case. */ + if (is_sub) { + if (cbl) { + tcg_out_opc_imm(s, OPC_SLTIU, TCG_TMP0, al, bl); + tcg_out_opc_imm(s, OPC_ADDIU, rl, al, -bl); + } else { + tcg_out_opc_reg(s, OPC_SLTU, TCG_TMP0, al, bl); + tcg_out_opc_reg(s, OPC_SUBU, rl, al, bl); + } + tcg_out_opc_reg(s, OPC_SUBU, rh, th, TCG_TMP0); + } else { + if (cbl) { + tcg_out_opc_imm(s, OPC_ADDIU, rl, al, bl); + tcg_out_opc_imm(s, OPC_SLTIU, TCG_TMP0, rl, bl); + } else { + tcg_out_opc_reg(s, OPC_ADDU, rl, al, bl); + tcg_out_opc_reg(s, OPC_SLTU, TCG_TMP0, rl, (rl == bl ? al : bl)); + } + tcg_out_opc_reg(s, OPC_ADDU, rh, th, TCG_TMP0); + } +} + static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64) { TCGReg addr_regl, addr_regh __attribute__((unused)); @@ -1419,21 +1465,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_opc_reg(s, OPC_ADDU, a0, a1, a2); } break; - case INDEX_op_add2_i32: - if (const_args[4]) { - tcg_out_opc_imm(s, OPC_ADDIU, TCG_TMP0, a2, args[4]); - } else { - tcg_out_opc_reg(s, OPC_ADDU, TCG_TMP0, a2, args[4]); - } - tcg_out_opc_reg(s, OPC_SLTU, TCG_TMP1, TCG_TMP0, a2); - if (const_args[5]) { - tcg_out_opc_imm(s, OPC_ADDIU, a1, args[3], args[5]); - } else { - tcg_out_opc_reg(s, OPC_ADDU, a1, args[3], args[5]); - } - tcg_out_opc_reg(s, OPC_ADDU, a1, a1, TCG_TMP1); - tcg_out_mov(s, TCG_TYPE_I32, a0, TCG_TMP0); - break; case INDEX_op_sub_i32: if (c2) { tcg_out_opc_imm(s, OPC_ADDIU, a0, a1, -a2); @@ -1441,21 +1472,6 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_opc_reg(s, OPC_SUBU, a0, a1, a2); } break; - case INDEX_op_sub2_i32: - if (const_args[4]) { - tcg_out_opc_imm(s, OPC_ADDIU, TCG_TMP0, a2, -args[4]); - } else { - tcg_out_opc_reg(s, OPC_SUBU, TCG_TMP0, a2, args[4]); - } - tcg_out_opc_reg(s, OPC_SLTU, TCG_TMP1, a2, TCG_TMP0); - if (const_args[5]) { - tcg_out_opc_imm(s, OPC_ADDIU, a1, args[3], -args[5]); - } else { - tcg_out_opc_reg(s, OPC_SUBU, a1, args[3], args[5]); - } - tcg_out_opc_reg(s, OPC_SUBU, a1, a1, TCG_TMP1); - tcg_out_mov(s, TCG_TYPE_I32, a0, TCG_TMP0); - break; case INDEX_op_mul_i32: if (use_mips32_instructions) { tcg_out_opc_reg(s, OPC_MUL, a0, a1, a2); @@ -1621,6 +1637,15 @@ static inline void tcg_out_op(TCGContext *s, TCGOpcode opc, tcg_out_qemu_st(s, args, true); break; + case INDEX_op_add2_i32: + tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5], + const_args[4], const_args[5], false); + break; + case INDEX_op_sub2_i32: + tcg_out_addsub2(s, a0, a1, a2, args[3], args[4], args[5], + const_args[4], const_args[5], true); + break; + case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */ case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */ case INDEX_op_call: /* Always emitted via tcg_out_call. */ @@ -1680,7 +1705,7 @@ static const TCGTargetOpDef mips_op_defs[] = { { INDEX_op_setcond_i32, { "r", "rZ", "rZ" } }, { INDEX_op_setcond2_i32, { "r", "rZ", "rZ", "rZ", "rZ" } }, - { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rJ", "rJ" } }, + { INDEX_op_add2_i32, { "r", "r", "rZ", "rZ", "rN", "rN" } }, { INDEX_op_sub2_i32, { "r", "r", "rZ", "rZ", "rN", "rN" } }, { INDEX_op_brcond2_i32, { "rZ", "rZ", "rZ", "rZ" } },