From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:51483) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UOBgd-0005Gy-DZ for qemu-devel@nongnu.org; Fri, 05 Apr 2013 14:48:35 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UOBgZ-0003rS-Vl for qemu-devel@nongnu.org; Fri, 05 Apr 2013 14:48:31 -0400 Received: from mail-qe0-f41.google.com ([209.85.128.41]:37086) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UOBgZ-0003rE-RQ for qemu-devel@nongnu.org; Fri, 05 Apr 2013 14:48:27 -0400 Received: by mail-qe0-f41.google.com with SMTP id b10so957120qen.14 for ; Fri, 05 Apr 2013 11:48:27 -0700 (PDT) Sender: Richard Henderson From: Richard Henderson Date: Fri, 5 Apr 2013 13:47:37 -0500 Message-Id: <1365187661-17023-10-git-send-email-rth@twiddle.net> In-Reply-To: <1365187661-17023-1-git-send-email-rth@twiddle.net> References: <1365187661-17023-1-git-send-email-rth@twiddle.net> Subject: [Qemu-devel] [PULL v2 09/13] tcg-s390: Use risbgz for andi List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: aliguori@us.ibm.com, aurelien@aurel32.net This is immediately usable by the tlb lookup code. Signed-off-by: Richard Henderson --- tcg/s390/tcg-target.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/tcg/s390/tcg-target.c b/tcg/s390/tcg-target.c index 203cbb5..2bab245 100644 --- a/tcg/s390/tcg-target.c +++ b/tcg/s390/tcg-target.c @@ -827,6 +827,15 @@ static void tcg_out_ld_abs(TCGContext *s, TCGType type, TCGReg dest, void *abs) tcg_out_ld(s, type, dest, dest, addr & 0xffff); } +static inline void tcg_out_risbg(TCGContext *s, TCGReg dest, TCGReg src, + int msb, int lsb, int ofs, int z) +{ + /* Format RIE-f */ + tcg_out16(s, (RIE_RISBG & 0xff00) | (dest << 4) | src); + tcg_out16(s, (msb << 8) | (z << 7) | lsb); + tcg_out16(s, (ofs << 8) | (RIE_RISBG & 0xff)); +} + static void tgen_ext8s(TCGContext *s, TCGType type, TCGReg dest, TCGReg src) { if (facilities & FACILITY_EXT_IMM) { @@ -940,6 +949,36 @@ static inline void tgen64_addi(TCGContext *s, TCGReg dest, int64_t val) } +/* Accept bit patterns like these: + 0....01....1 + 1....10....0 + 1..10..01..1 + 0..01..10..0 + Copied from gcc sources. */ +static inline bool risbg_mask(uint64_t c) +{ + uint64_t lsb; + /* We don't change the number of transitions by inverting, + so make sure we start with the LSB zero. */ + if (c & 1) { + c = ~c; + } + /* Reject all zeros or all ones. */ + if (c == 0) { + return false; + } + /* Find the first transition. */ + lsb = c & -c; + /* Invert to look for a second transition. */ + c = ~c; + /* Erase the first transition. */ + c &= -lsb; + /* Find the second transition, if any. */ + lsb = c & -c; + /* Match if all the bits are 1's, or if c is zero. */ + return c == -lsb; +} + static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val) { static const S390Opcode ni_insns[4] = { @@ -986,6 +1025,19 @@ static void tgen_andi(TCGContext *s, TCGType type, TCGReg dest, uint64_t val) } } } + if ((facilities & FACILITY_GEN_INST_EXT) && risbg_mask(val)) { + int msb, lsb; + if ((val & 0x8000000000000001ull) == 0x8000000000000001ull) { + /* Achieve wraparound by swapping msb and lsb. */ + msb = 63 - ctz64(~val); + lsb = clz64(~val) + 1; + } else { + msb = clz64(val); + lsb = 63 - ctz64(val); + } + tcg_out_risbg(s, dest, dest, msb, lsb, 0, 1); + return; + } /* Fall back to loading the constant. */ tcg_out_movi(s, type, TCG_TMP0, val); @@ -1142,11 +1194,7 @@ static void tgen_deposit(TCGContext *s, TCGReg dest, TCGReg src, { int lsb = (63 - ofs); int msb = lsb - (len - 1); - - /* Format RIE-f */ - tcg_out16(s, (RIE_RISBG & 0xff00) | (dest << 4) | src); - tcg_out16(s, (msb << 8) | lsb); - tcg_out16(s, (ofs << 8) | (RIE_RISBG & 0xff)); + tcg_out_risbg(s, dest, src, msb, lsb, ofs, 0); } static void tgen_gotoi(TCGContext *s, int cc, tcg_target_long dest) -- 1.8.1.4