From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54181) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VPeEk-0003PP-6s for qemu-devel@nongnu.org; Fri, 27 Sep 2013 16:02:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VPeEb-0004DH-P7 for qemu-devel@nongnu.org; Fri, 27 Sep 2013 16:02:02 -0400 Received: from mail-yh0-x229.google.com ([2607:f8b0:4002:c01::229]:39562) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VPeEb-0004DD-Kt for qemu-devel@nongnu.org; Fri, 27 Sep 2013 16:01:53 -0400 Received: by mail-yh0-f41.google.com with SMTP id f73so1187630yha.0 for ; Fri, 27 Sep 2013 13:01:53 -0700 (PDT) Sender: Richard Henderson Message-ID: <5245E42C.6080101@twiddle.net> Date: Fri, 27 Sep 2013 13:01:48 -0700 From: Richard Henderson MIME-Version: 1.0 References: <1380242934-20953-1-git-send-email-agraf@suse.de> <1380242934-20953-32-git-send-email-agraf@suse.de> In-Reply-To: <1380242934-20953-32-git-send-email-agraf@suse.de> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [PATCH 31/60] AArch64: Add bfm family instruction emulation List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alexander Graf Cc: Peter Maydell , Michael Matz , qemu-devel@nongnu.org, C Fontana , Dirk Mueller , Laurent Desnogues , Christoffer Dall On 09/26/2013 05:48 PM, Alexander Graf wrote: > + > +uint64_t HELPER(sign_extend)(uint64_t x, uint64_t is_signed, uint64_t mask) > +{ > + if (x & is_signed) { > + x |= mask; > + } > + > + return x; > +} Why in the world do you have such a simple helper? > + tcg_gen_andi_i64(tcg_newmask, cpu_reg(source), mask); > + if (imms < immr) { > + tcg_gen_shli_i64(tcg_newmask, tcg_newmask, bitsize - immr); > + tmask <<= bitsize - immr; > + signbit <<= bitsize + imms - immr; > + if (signbit == 0x8000000000000000ULL) { > + /* Can't pad anymore - highest bit is already set */ > + topmask = 0; > + } else { > + topmask = ~((1ULL << (bitsize + imms - immr + 1)) - 1); > + } > + } else { > + tcg_gen_shri_i64(tcg_newmask, tcg_newmask, immr); > + tmask >>= immr; > + signbit <<= imms - immr; > + topmask = ~tmask; > + } > + > + if (is_32bit) { > + tcg_gen_ext32u_i64(tcg_newmask, tcg_newmask); > + } > + > + switch (opc) { > + case 0: { /* SBFM */ > + TCGv_i64 tcg_mask = tcg_const_i64(topmask); > + TCGv_i64 tcg_signbit = tcg_const_i64(signbit); > + gen_helper_sign_extend(cpu_reg(dest), tcg_newmask, tcg_signbit, > + tcg_mask); Ah. Perhaps it'll be helpful to know this can be done as dest = (newmask ^ signbit) - signbit; So you don't have to compute tcg_mask either. Although given that ASR, LSL, LSR, are all canonical aliases, we'd probably do well to detect those special cases. > + case 1: /* BFM */ > + /* replace the field inside dest */ > + tcg_gen_andi_i64(cpu_reg(dest), cpu_reg(dest), ~tmask); > + tcg_gen_or_i64(cpu_reg(dest), cpu_reg(dest), tcg_newmask); > + break; Ideally we'd emit deposit here for appropriate imms+immr. r~