From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6560 invoked by alias); 30 Jul 2012 22:33:18 -0000 Received: (qmail 6508 invoked by uid 22791); 30 Jul 2012 22:33:16 -0000 X-SWARE-Spam-Status: No, hits=-4.8 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,KHOP_RCVD_TRUST,KHOP_THREADED,RCVD_IN_DNSWL_LOW,RCVD_IN_HOSTKARMA_YE X-Spam-Check-By: sourceware.org Received: from mail-pb0-f47.google.com (HELO mail-pb0-f47.google.com) (209.85.160.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 30 Jul 2012 22:33:02 +0000 Received: by pbbrq2 with SMTP id rq2so10266248pbb.20 for ; Mon, 30 Jul 2012 15:33:02 -0700 (PDT) Received: by 10.68.212.70 with SMTP id ni6mr38735638pbc.22.1343687581928; Mon, 30 Jul 2012 15:33:01 -0700 (PDT) Received: from anchor.twiddle.home.com ([173.160.232.49]) by mx.google.com with ESMTPS id wa14sm8717563pbc.10.2012.07.30.15.33.01 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 30 Jul 2012 15:33:01 -0700 (PDT) From: Richard Henderson To: uweigand@de.ibm.com Cc: gcc-patches@gcc.gnu.org Subject: [PATCH 1/2] s390: Reorg s390_expand_insv Date: Mon, 30 Jul 2012 22:33:00 -0000 Message-Id: <1343687574-3244-2-git-send-email-rth@redhat.com> In-Reply-To: <1343687574-3244-1-git-send-email-rth@redhat.com> References: <5016C81E.5020709@redhat.com> <1343687574-3244-1-git-send-email-rth@redhat.com> X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2012-07/txt/msg01521.txt.bz2 Try RISBG last, after other mechanisms have failed; don't require operands in registers for it but force them there instead. Try a limited form of ICM. --- gcc/config/s390/s390.c | 129 ++++++++++++++++++++++++++++++----------------- 1 files changed, 82 insertions(+), 47 deletions(-) diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index f72f49f..240fb7e 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -4538,48 +4538,70 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src) { int bitsize = INTVAL (op1); int bitpos = INTVAL (op2); + enum machine_mode mode = GET_MODE (dest); + enum machine_mode smode = smallest_mode_for_size (bitsize, MODE_INT); + rtx op, clobber; - /* On z10 we can use the risbg instruction to implement insv. */ - if (TARGET_Z10 - && ((GET_MODE (dest) == DImode && GET_MODE (src) == DImode) - || (GET_MODE (dest) == SImode && GET_MODE (src) == SImode))) + /* Generate INSERT IMMEDIATE (IILL et al). */ + /* (set (ze (reg)) (const_int)). */ + if (TARGET_ZARCH + && register_operand (dest, word_mode) + && (bitpos % 16) == 0 + && (bitsize % 16) == 0 + && const_int_operand (src, VOIDmode)) { - rtx op; - rtx clobber; + HOST_WIDE_INT val = INTVAL (src); + int regpos = bitpos + bitsize; - op = gen_rtx_SET (GET_MODE(src), - gen_rtx_ZERO_EXTRACT (GET_MODE (dest), dest, op1, op2), - src); - clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM)); - emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clobber))); + while (regpos > bitpos) + { + enum machine_mode putmode; + int putsize; + + if (TARGET_EXTIMM && (regpos % 32 == 0) && (regpos >= bitpos + 32)) + putmode = SImode; + else + putmode = HImode; + putsize = GET_MODE_BITSIZE (putmode); + regpos -= putsize; + emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, + GEN_INT (putsize), + GEN_INT (regpos)), + gen_int_mode (val, putmode)); + val >>= putsize; + } + gcc_assert (regpos == bitpos); return true; } - /* We need byte alignment. */ - if (bitsize % BITS_PER_UNIT) - return false; - + /* Generate STORE CHARACTERS UNDER MASK (STCM et al). */ if (bitpos == 0 - && memory_operand (dest, VOIDmode) + && (bitsize % BITS_PER_UNIT) == 0 + && MEM_P (dest) && (register_operand (src, word_mode) || const_int_operand (src, VOIDmode))) { /* Emit standard pattern if possible. */ - enum machine_mode mode = smallest_mode_for_size (bitsize, MODE_INT); - if (GET_MODE_BITSIZE (mode) == bitsize) - emit_move_insn (adjust_address (dest, mode, 0), gen_lowpart (mode, src)); + if (GET_MODE_BITSIZE (smode) == bitsize) + { + emit_move_insn (adjust_address (dest, smode, 0), + gen_lowpart (smode, src)); + return true; + } /* (set (ze (mem)) (const_int)). */ else if (const_int_operand (src, VOIDmode)) { int size = bitsize / BITS_PER_UNIT; - rtx src_mem = adjust_address (force_const_mem (word_mode, src), BLKmode, + rtx src_mem = adjust_address (force_const_mem (word_mode, src), + BLKmode, GET_MODE_SIZE (word_mode) - size); dest = adjust_address (dest, BLKmode, 0); set_mem_size (dest, size); s390_expand_movmem (dest, src_mem, GEN_INT (size)); + return true; } /* (set (ze (mem)) (reg)). */ @@ -4602,42 +4624,55 @@ s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src) gen_rtx_LSHIFTRT (word_mode, src, GEN_INT (GET_MODE_BITSIZE (SImode)))); } + return true; } - else - return false; + } - return true; + /* Generate INSERT CHARACTERS UNDER MASK (IC, ICM et al). */ + if ((bitpos % BITS_PER_UNIT) == 0 + && (bitsize % BITS_PER_UNIT) == 0 + && (bitpos & 32) == ((bitpos + bitsize - 1) & 32) + && MEM_P (src) + && (mode == DImode || mode == SImode) + && register_operand (dest, mode)) + { + /* Emit a strict_low_part pattern if possible. */ + if (bitpos == 0 && GET_MODE_BITSIZE (smode) == bitsize) + { + op = gen_rtx_STRICT_LOW_PART (VOIDmode, gen_lowpart (smode, dest)); + op = gen_rtx_SET (VOIDmode, op, gen_lowpart (smode, src)); + clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM)); + emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clobber))); + return true; + } + + /* ??? There are more powerful versions of ICM that are not + completely represented in the md file. */ } - /* (set (ze (reg)) (const_int)). */ - if (TARGET_ZARCH - && register_operand (dest, word_mode) - && (bitpos % 16) == 0 - && (bitsize % 16) == 0 - && const_int_operand (src, VOIDmode)) + /* For z10, generate ROTATE THEN INSERT SELECTED BITS (RISBG et al). */ + if (TARGET_Z10 && (mode == DImode || mode == SImode)) { - HOST_WIDE_INT val = INTVAL (src); - int regpos = bitpos + bitsize; + enum machine_mode mode_s = GET_MODE (src); - while (regpos > bitpos) + if (mode_s == VOIDmode) { - enum machine_mode putmode; - int putsize; + /* Assume const_int etc already in the proper mode. */ + src = force_reg (mode, src); + } + else if (mode_s != mode) + { + gcc_assert (GET_MODE_BITSIZE (mode_s) >= bitsize); + src = force_reg (mode_s, src); + src = gen_lowpart (mode, src); + } - if (TARGET_EXTIMM && (regpos % 32 == 0) && (regpos >= bitpos + 32)) - putmode = SImode; - else - putmode = HImode; + op = gen_rtx_SET (mode, + gen_rtx_ZERO_EXTRACT (mode, dest, op1, op2), + src); + clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM)); + emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clobber))); - putsize = GET_MODE_BITSIZE (putmode); - regpos -= putsize; - emit_move_insn (gen_rtx_ZERO_EXTRACT (word_mode, dest, - GEN_INT (putsize), - GEN_INT (regpos)), - gen_int_mode (val, putmode)); - val >>= putsize; - } - gcc_assert (regpos == bitpos); return true; } -- 1.7.7.6