From patchwork Fri Sep 21 19:33:34 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aurelien Jarno X-Patchwork-Id: 185891 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 3CC972C007A for ; Sat, 22 Sep 2012 05:34:18 +1000 (EST) Received: from localhost ([::1]:35739 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TF8zQ-0004Ju-4c for incoming@patchwork.ozlabs.org; Fri, 21 Sep 2012 15:34:16 -0400 Received: from eggs.gnu.org ([208.118.235.92]:37880) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TF8z1-00042g-QO for qemu-devel@nongnu.org; Fri, 21 Sep 2012 15:33:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TF8yz-0007YU-2C for qemu-devel@nongnu.org; Fri, 21 Sep 2012 15:33:51 -0400 Received: from hall.aurel32.net ([88.191.126.93]:46376) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TF8yy-0007Wx-Kh for qemu-devel@nongnu.org; Fri, 21 Sep 2012 15:33:48 -0400 Received: from [2001:470:d4ed:1:2db:dfff:fe14:52d] (helo=ohm.aurel32.net) by hall.aurel32.net with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.72) (envelope-from ) id 1TF8yt-0005FU-Jg; Fri, 21 Sep 2012 21:33:43 +0200 Received: from aurel32 by ohm.aurel32.net with local (Exim 4.80) (envelope-from ) id 1TF8ys-0001SP-1h; Fri, 21 Sep 2012 21:33:42 +0200 From: Aurelien Jarno To: qemu-devel@nongnu.org Date: Fri, 21 Sep 2012 21:33:34 +0200 Message-Id: <1348256016-5077-4-git-send-email-aurelien@aurel32.net> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1348256016-5077-1-git-send-email-aurelien@aurel32.net> References: <1348256016-5077-1-git-send-email-aurelien@aurel32.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 88.191.126.93 Cc: Peter Maydell , Aurelien Jarno Subject: [Qemu-devel] [PATCH v2 3/5] target-arm: convert sar, shl and shr helpers to TCG 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 Now that the movcond TCG op is available, it's possible to replace shl and shr helpers by TCG code. The code generated by TCG is slightly longer than the code generated by GCC for the helper but is still worth it as this avoid all the consequences of using an helper: globals saved back to memory, no possible optimization, call overhead, etc. Cc: Peter Maydell Signed-off-by: Aurelien Jarno --- target-arm/helper.h | 3 --- target-arm/op_helper.c | 24 ---------------------- target-arm/translate.c | 52 ++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 46 insertions(+), 33 deletions(-) diff --git a/target-arm/helper.h b/target-arm/helper.h index 7151e28..794e2b1 100644 --- a/target-arm/helper.h +++ b/target-arm/helper.h @@ -145,9 +145,6 @@ DEF_HELPER_5(neon_tbl, i32, env, i32, i32, i32, i32) DEF_HELPER_3(adc_cc, i32, env, i32, i32) DEF_HELPER_3(sbc_cc, i32, env, i32, i32) -DEF_HELPER_3(shl, i32, env, i32, i32) -DEF_HELPER_3(shr, i32, env, i32, i32) -DEF_HELPER_3(sar, i32, env, i32, i32) DEF_HELPER_3(shl_cc, i32, env, i32, i32) DEF_HELPER_3(shr_cc, i32, env, i32, i32) DEF_HELPER_3(sar_cc, i32, env, i32, i32) diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c index 6095f24..aef592a 100644 --- a/target-arm/op_helper.c +++ b/target-arm/op_helper.c @@ -355,30 +355,6 @@ uint32_t HELPER(sbc_cc)(CPUARMState *env, uint32_t a, uint32_t b) /* Similarly for variable shift instructions. */ -uint32_t HELPER(shl)(CPUARMState *env, uint32_t x, uint32_t i) -{ - int shift = i & 0xff; - if (shift >= 32) - return 0; - return x << shift; -} - -uint32_t HELPER(shr)(CPUARMState *env, uint32_t x, uint32_t i) -{ - int shift = i & 0xff; - if (shift >= 32) - return 0; - return (uint32_t)x >> shift; -} - -uint32_t HELPER(sar)(CPUARMState *env, uint32_t x, uint32_t i) -{ - int shift = i & 0xff; - if (shift >= 32) - shift = 31; - return (int32_t)x >> shift; -} - uint32_t HELPER(shl_cc)(CPUARMState *env, uint32_t x, uint32_t i) { int shift = i & 0xff; diff --git a/target-arm/translate.c b/target-arm/translate.c index 19bb1e8..9abc115 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -440,6 +440,40 @@ static void gen_sub_CC(TCGv dest, TCGv t0, TCGv t1) tcg_gen_mov_i32(dest, cpu_NF); } +#define GEN_SHIFT(name) \ +static void gen_##name(TCGv dest, TCGv t0, TCGv t1) \ +{ \ + TCGv tmp1, tmp2, tmp3; \ + tmp1 = tcg_temp_new_i32(); \ + tcg_gen_andi_i32(tmp1, t1, 0xff); \ + tmp2 = tcg_const_i32(0); \ + tmp3 = tcg_const_i32(0x1f); \ + tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \ + tcg_temp_free_i32(tmp3); \ + tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \ + tcg_gen_##name##_i32(dest, tmp2, tmp1); \ + tcg_temp_free_i32(tmp2); \ + tcg_temp_free_i32(tmp1); \ +} +GEN_SHIFT(shl) +GEN_SHIFT(shr) +#undef GEN_SHIFT + +static void gen_sar(TCGv dest, TCGv t0, TCGv t1) +{ + TCGv tmp1, tmp2, tmp3; + tmp1 = tcg_temp_new_i32(); + tcg_gen_andi_i32(tmp1, t1, 0xff); + tmp2 = tcg_const_i32(0x1f); + tmp3 = tcg_const_i32(0); + tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1); + tcg_temp_free_i32(tmp3); + tcg_temp_free_i32(tmp2); + tcg_gen_andi_i32(tmp1, tmp1, 0x1f); + tcg_gen_sar_i32(dest, t0, tmp1); + tcg_temp_free_i32(tmp1); +} + /* FIXME: Implement this natively. */ #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1) @@ -516,9 +550,15 @@ static inline void gen_arm_shift_reg(TCGv var, int shiftop, } } else { switch (shiftop) { - case 0: gen_helper_shl(var, cpu_env, var, shift); break; - case 1: gen_helper_shr(var, cpu_env, var, shift); break; - case 2: gen_helper_sar(var, cpu_env, var, shift); break; + case 0: + gen_shl(var, var, shift); + break; + case 1: + gen_shr(var, var, shift); + break; + case 2: + gen_sar(var, var, shift); + break; case 3: tcg_gen_andi_i32(shift, shift, 0x1f); tcg_gen_rotr_i32(var, var, shift); break; } @@ -9161,7 +9201,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) break; case 0x2: /* lsl */ if (s->condexec_mask) { - gen_helper_shl(tmp2, cpu_env, tmp2, tmp); + gen_shl(tmp2, tmp2, tmp); } else { gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp); gen_logic_CC(tmp2); @@ -9169,7 +9209,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) break; case 0x3: /* lsr */ if (s->condexec_mask) { - gen_helper_shr(tmp2, cpu_env, tmp2, tmp); + gen_shr(tmp2, tmp2, tmp); } else { gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp); gen_logic_CC(tmp2); @@ -9177,7 +9217,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) break; case 0x4: /* asr */ if (s->condexec_mask) { - gen_helper_sar(tmp2, cpu_env, tmp2, tmp); + gen_sar(tmp2, tmp2, tmp); } else { gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp); gen_logic_CC(tmp2);