From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48855) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bvcHh-0003N1-5J for qemu-devel@nongnu.org; Sat, 15 Oct 2016 23:38:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bvcHg-0005rb-5H for qemu-devel@nongnu.org; Sat, 15 Oct 2016 23:38:49 -0400 Received: from mail-qk0-x242.google.com ([2607:f8b0:400d:c09::242]:36596) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1bvcHg-0005rN-03 for qemu-devel@nongnu.org; Sat, 15 Oct 2016 23:38:48 -0400 Received: by mail-qk0-x242.google.com with SMTP id z190so11409352qkc.3 for ; Sat, 15 Oct 2016 20:38:47 -0700 (PDT) Sender: Richard Henderson From: Richard Henderson Date: Sat, 15 Oct 2016 20:37:46 -0700 Message-Id: <1476589070-5792-12-git-send-email-rth@twiddle.net> In-Reply-To: <1476589070-5792-1-git-send-email-rth@twiddle.net> References: <1476589070-5792-1-git-send-email-rth@twiddle.net> Subject: [Qemu-devel] [PATCH 11/15] target-arm: Use tcg_gen_*extract List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell Use the new primitives for UBFX and SBFX. Cc: Peter Maydell Signed-off-by: Richard Henderson --- target-arm/translate-a64.c | 48 ++++++++++++++++++++++------------------------ target-arm/translate.c | 37 ++++++++--------------------------- 2 files changed, 31 insertions(+), 54 deletions(-) diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 2d5c1a2..7df4e84 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -3171,11 +3171,8 @@ static void disas_bitfield(DisasContext *s, uint32_t insn) goto done; } } - if (si == 63 || (si == 31 && ri <= si)) { /* ASR */ - if (si == 31) { - tcg_gen_ext32s_i64(tcg_tmp, tcg_tmp); - } - tcg_gen_sari_i64(tcg_rd, tcg_tmp, ri); + if (ri <= si) { /* ASR, SBFX */ + tcg_gen_sextract_i64(tcg_rd, tcg_tmp, ri, (si - ri) + 1); goto done; } } else if (opc == 2) { /* UBFM */ @@ -3183,41 +3180,42 @@ static void disas_bitfield(DisasContext *s, uint32_t insn) tcg_gen_andi_i64(tcg_rd, tcg_tmp, bitmask64(si + 1)); return; } - if (si == 63 || (si == 31 && ri <= si)) { /* LSR */ - if (si == 31) { - tcg_gen_ext32u_i64(tcg_tmp, tcg_tmp); - } - tcg_gen_shri_i64(tcg_rd, tcg_tmp, ri); - return; - } if (si + 1 == ri && si != bitsize - 1) { /* LSL */ int shift = bitsize - 1 - si; tcg_gen_shli_i64(tcg_rd, tcg_tmp, shift); goto done; } + if (ri <= si) { /* UBFX, LSR */ + tcg_gen_extract_i64(tcg_rd, tcg_tmp, ri, (si - ri) + 1); + return; + } } if (opc != 1) { /* SBFM or UBFM */ tcg_gen_movi_i64(tcg_rd, 0); } - /* do the bit move operation */ - if (si >= ri) { - /* Wd = Wn */ - tcg_gen_shri_i64(tcg_tmp, tcg_tmp, ri); - pos = 0; - len = (si - ri) + 1; - } else { - /* Wd<32+s-r,32-r> = Wn */ - pos = bitsize - ri; - len = si + 1; + /* Do the bit move operation. Note that above we handled ri <= si, + Wd = Wn, via tcg_gen_*extract_i64. Now we handle + the ri > si case, Wd<32+s-r,32-r> = Wn, via deposit. */ + pos = bitsize - ri; + len = si + 1; + + if (opc == 0 && len < ri) { + /* SBFM - sign extend the destination field from len to fill + the balance of the word. Let the deposit below insert all + of those sign bits. */ + tcg_gen_sextract_i64(tcg_tmp, tcg_tmp, 0, len); + len = ri; } tcg_gen_deposit_i64(tcg_rd, tcg_rd, tcg_tmp, pos, len); - if (opc == 0) { /* SBFM - sign extend the destination field */ - tcg_gen_shli_i64(tcg_rd, tcg_rd, 64 - (pos + len)); - tcg_gen_sari_i64(tcg_rd, tcg_rd, 64 - (pos + len)); + if (opc != 1) { + /* SBFM or UBFM: We started with zero above, and we haven't + modified any bits outside bitsize, therefore the zero-extension + below is unneeded. */ + return; } done: diff --git a/target-arm/translate.c b/target-arm/translate.c index aaf6135..37ad61d 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -297,29 +297,6 @@ static void gen_revsh(TCGv_i32 var) tcg_gen_ext16s_i32(var, var); } -/* Unsigned bitfield extract. */ -static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask) -{ - if (shift) - tcg_gen_shri_i32(var, var, shift); - tcg_gen_andi_i32(var, var, mask); -} - -/* Signed bitfield extract. */ -static void gen_sbfx(TCGv_i32 var, int shift, int width) -{ - uint32_t signbit; - - if (shift) - tcg_gen_sari_i32(var, var, shift); - if (shift + width < 32) { - signbit = 1u << (width - 1); - tcg_gen_andi_i32(var, var, (1u << width) - 1); - tcg_gen_xori_i32(var, var, signbit); - tcg_gen_subi_i32(var, var, signbit); - } -} - /* Return (b << 32) + a. Mark inputs as dead */ static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b) { @@ -9234,9 +9211,9 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) goto illegal_op; if (i < 32) { if (op1 & 0x20) { - gen_ubfx(tmp, shift, (1u << i) - 1); + tcg_gen_extract_i32(tmp, tmp, shift, i); } else { - gen_sbfx(tmp, shift, i); + tcg_gen_sextract_i32(tmp, tmp, shift, i); } } store_reg(s, rd, tmp); @@ -10551,15 +10528,17 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw imm++; if (shift + imm > 32) goto illegal_op; - if (imm < 32) - gen_sbfx(tmp, shift, imm); + if (imm < 32) { + tcg_gen_sextract_i32(tmp, tmp, shift, imm); + } break; case 6: /* Unsigned bitfield extract. */ imm++; if (shift + imm > 32) goto illegal_op; - if (imm < 32) - gen_ubfx(tmp, shift, (1u << imm) - 1); + if (imm < 32) { + tcg_gen_extract_i32(tmp, tmp, shift, imm); + } break; case 3: /* Bitfield insert/clear. */ if (imm < shift) -- 2.7.4