From patchwork Sun Sep 13 21:18:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aurelien Jarno X-Patchwork-Id: 517232 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 A4C66140549 for ; Mon, 14 Sep 2015 07:19:35 +1000 (AEST) Received: from localhost ([::1]:37207 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZbEgP-0001IA-Og for incoming@patchwork.ozlabs.org; Sun, 13 Sep 2015 17:19:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44941) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZbEfi-000091-Iu for qemu-devel@nongnu.org; Sun, 13 Sep 2015 17:18:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZbEfh-0003rU-9Z for qemu-devel@nongnu.org; Sun, 13 Sep 2015 17:18:50 -0400 Received: from hall.aurel32.net ([2001:bc8:30d7:100::1]:33207) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZbEfh-0003qu-4Z for qemu-devel@nongnu.org; Sun, 13 Sep 2015 17:18:49 -0400 Received: from weber.rr44.fr ([2001:bc8:30d7:120:7e05:7ff:fe0d:f152]) by hall.aurel32.net with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.84) (envelope-from ) id 1ZbEff-0001Xy-ML; Sun, 13 Sep 2015 23:18:47 +0200 Received: from aurel32 by weber.rr44.fr with local (Exim 4.85) (envelope-from ) id 1ZbEfe-0007in-Vh; Sun, 13 Sep 2015 23:18:46 +0200 From: Aurelien Jarno To: qemu-devel@nongnu.org Date: Sun, 13 Sep 2015 23:18:44 +0200 Message-Id: <1442179125-29608-6-git-send-email-aurelien@aurel32.net> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1442179125-29608-1-git-send-email-aurelien@aurel32.net> References: <1442179125-29608-1-git-send-email-aurelien@aurel32.net> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:bc8:30d7:100::1 Cc: Aurelien Jarno Subject: [Qemu-devel] [PULL 5/6] target-sh4: improve shad instruction 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 The SH4 shad instruction can shift in both direction, depending on the sign of the shift. This is currently implemented using branches, which is not really efficient and prevents the optimizer to do its job. In practice it is often used with a constant loaded in a register just before. Simplify the implementation by computing both the value shifted to the left and to the right, and then selecting the correct one with a movcond. As with a negative value the shift amount can go up to 32 which is undefined, we shift the value in two steps. Reviewed-by: Richard Henderson Signed-off-by: Aurelien Jarno --- target-sh4/translate.c | 53 +++++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/target-sh4/translate.c b/target-sh4/translate.c index c8dd3a7..724c0e7 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -832,37 +832,28 @@ static void _decode_opc(DisasContext * ctx) return; case 0x400c: /* shad Rm,Rn */ { - TCGLabel *label1 = gen_new_label(); - TCGLabel *label2 = gen_new_label(); - TCGLabel *label3 = gen_new_label(); - TCGLabel *label4 = gen_new_label(); - TCGv shift; - tcg_gen_brcondi_i32(TCG_COND_LT, REG(B7_4), 0, label1); - /* Rm positive, shift to the left */ - shift = tcg_temp_new(); - tcg_gen_andi_i32(shift, REG(B7_4), 0x1f); - tcg_gen_shl_i32(REG(B11_8), REG(B11_8), shift); - tcg_temp_free(shift); - tcg_gen_br(label4); - /* Rm negative, shift to the right */ - gen_set_label(label1); - shift = tcg_temp_new(); - tcg_gen_andi_i32(shift, REG(B7_4), 0x1f); - tcg_gen_brcondi_i32(TCG_COND_EQ, shift, 0, label2); - tcg_gen_not_i32(shift, REG(B7_4)); - tcg_gen_andi_i32(shift, shift, 0x1f); - tcg_gen_addi_i32(shift, shift, 1); - tcg_gen_sar_i32(REG(B11_8), REG(B11_8), shift); - tcg_temp_free(shift); - tcg_gen_br(label4); - /* Rm = -32 */ - gen_set_label(label2); - tcg_gen_brcondi_i32(TCG_COND_LT, REG(B11_8), 0, label3); - tcg_gen_movi_i32(REG(B11_8), 0); - tcg_gen_br(label4); - gen_set_label(label3); - tcg_gen_movi_i32(REG(B11_8), 0xffffffff); - gen_set_label(label4); + TCGv t0 = tcg_temp_new(); + TCGv t1 = tcg_temp_new(); + TCGv t2 = tcg_temp_new(); + + tcg_gen_andi_i32(t0, REG(B7_4), 0x1f); + + /* positive case: shift to the left */ + tcg_gen_shl_i32(t1, REG(B11_8), t0); + + /* negative case: shift to the right in two steps to + correctly handle the -32 case */ + tcg_gen_xori_i32(t0, t0, 0x1f); + tcg_gen_sar_i32(t2, REG(B11_8), t0); + tcg_gen_sari_i32(t2, t2, 1); + + /* select between the two cases */ + tcg_gen_movi_i32(t0, 0); + tcg_gen_movcond_i32(TCG_COND_GE, REG(B11_8), REG(B7_4), t0, t1, t2); + + tcg_temp_free(t0); + tcg_temp_free(t1); + tcg_temp_free(t2); } return; case 0x400d: /* shld Rm,Rn */