From patchwork Tue Sep 20 12:39:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dominik Vogt X-Patchwork-Id: 672246 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3sdj5B5S74z9syB for ; Tue, 20 Sep 2016 22:39:58 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=BX3SUtzV; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:reply-to:references:mime-version:content-type :in-reply-to:message-id; q=dns; s=default; b=Yo/IDgxCYryOEaxT9ra bbu1r1vhlzj2CnCMTk/rU0dIABEbEbYlPzBIwV90ZqNTmz2XbQT5yTMjzF58rA16 oUlwajo2L6TcLgvAD0Tj0Ii6iC9rEgHxlBj5UEPi+bN1P+eX6j4vp5E1hT/9NST9 yTHWmsoYGpGsoyd/rgru8/pI= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:reply-to:references:mime-version:content-type :in-reply-to:message-id; s=default; bh=X9NfI9K81Q/ugo7ZX322Rg6gR kw=; b=BX3SUtzVWF1x5+YIYQcy2VIFv+iWVIwd8C1wTRBJdz9A1CSLcFPBJdCwx KmVeCkAmHaK9823agqnnTrDaZO7AEHyVKiXBP6OUrTRKwjrHUAyREdAwGwnHhvBX x7SE6S7mrQwe5LyGWVgMqXJ9zMtLNl+JdOeA+8Ioqr7CuYji3Y= Received: (qmail 90989 invoked by alias); 20 Sep 2016 12:39:50 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 90976 invoked by uid 89); 20 Sep 2016 12:39:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.8 required=5.0 tests=AWL, BAYES_50, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW autolearn=no version=3.3.2 spammy=highest, ciao, 5512, 55, 12 X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 20 Sep 2016 12:39:39 +0000 Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.17/8.16.0.17) with SMTP id u8KCcLLn009794 for ; Tue, 20 Sep 2016 08:39:38 -0400 Received: from e06smtp15.uk.ibm.com (e06smtp15.uk.ibm.com [195.75.94.111]) by mx0a-001b2d01.pphosted.com with ESMTP id 25jkmh6wrp-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 20 Sep 2016 08:39:37 -0400 Received: from localhost by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 20 Sep 2016 13:39:35 +0100 Received: from d06dlp01.portsmouth.uk.ibm.com (9.149.20.13) by e06smtp15.uk.ibm.com (192.168.101.145) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 20 Sep 2016 13:39:32 +0100 Received: from b06cxnps3074.portsmouth.uk.ibm.com (d06relay09.portsmouth.uk.ibm.com [9.149.109.194]) by d06dlp01.portsmouth.uk.ibm.com (Postfix) with ESMTP id 6B22817D8024 for ; Tue, 20 Sep 2016 13:41:30 +0100 (BST) Received: from d06av01.portsmouth.uk.ibm.com (d06av01.portsmouth.uk.ibm.com [9.149.37.212]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u8KCdWPC12976512 for ; Tue, 20 Sep 2016 12:39:32 GMT Received: from d06av01.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av01.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u8KCdVkx017983 for ; Tue, 20 Sep 2016 06:39:31 -0600 Received: from oc5510024614.ibm.com (sig-9-145-36-245.uk.ibm.com [9.145.36.245]) by d06av01.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u8KCdVSZ017947; Tue, 20 Sep 2016 06:39:31 -0600 Received: by oc5510024614.ibm.com (Postfix, from userid 500) id 30E48C6AC; Tue, 20 Sep 2016 14:39:35 +0200 (CEST) Date: Tue, 20 Sep 2016 13:39:34 +0100 From: Dominik Vogt To: gcc-patches@gcc.gnu.org, Andreas Krebbel Subject: Re: [PATCH 2/3] S/390: Enable wraparound in s390_contiguous_bitmask_p. Reply-To: vogt@linux.vnet.ibm.com Mail-Followup-To: vogt@linux.vnet.ibm.com, gcc-patches@gcc.gnu.org, Andreas Krebbel References: <20160920123718.GA26830@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20160920123718.GA26830@linux.vnet.ibm.com> User-Agent: Mutt/1.5.20 (2009-12-10) X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16092012-0020-0000-0000-0000024EAF0F X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16092012-0021-0000-0000-00003E4155D6 Message-Id: <20160920123934.GB28823@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-09-20_05:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1609020000 definitions=main-1609200163 On Tue, Sep 20, 2016 at 01:37:18PM +0100, Dominik Vogt wrote: > The following series of patches improves usage of the risbg and > risbgn instructions on s390/s390x. The patches have been > regression tested on s390 and s390x and pass the Spec2006 > testsuite without any negative effects. > Patch 2 enables wraparound of bit ranges and rewrites portion of > the bitrange calculation code to do so. Ciao Dominik ^_^ ^_^ diff --git a/gcc/config/s390/constraints.md b/gcc/config/s390/constraints.md index 190cdc9..ee505d0 100644 --- a/gcc/config/s390/constraints.md +++ b/gcc/config/s390/constraints.md @@ -55,7 +55,12 @@ ;; D,S,H: mode of the containing operand ;; 0,F: value of the other parts (F - all bits set) ;; -- -;; xx[DS]q satisfies s390_contiguous_bitmask_p for DImode or SImode +;; xxDq satisfies s390_contiguous_bitmask_p for DImode +;; (with possible wraparound of the one-bit range) +;; xxSw satisfies s390_contiguous_bitmask_p for SImode +;; (with possible wraparound of the one-bit range) +;; xxSq satisfies s390_contiguous_bitmask_nowrap_p for SImode +;; (without wraparound of the one-bit range) ;; ;; The constraint matches if the specified part of a constant ;; has a value different from its other parts. If the letter x @@ -346,15 +351,20 @@ (and (match_code "const_int") (match_test "s390_N_constraint_str (\"xQH0\", ival)"))) -(define_constraint "NxxDq" +(define_constraint "NxxDw" "@internal" (and (match_code "const_int") - (match_test "s390_contiguous_bitmask_p (ival, 64, NULL, NULL)"))) + (match_test "s390_contiguous_bitmask_p (ival, true, 64, NULL, NULL)"))) (define_constraint "NxxSq" "@internal" (and (match_code "const_int") - (match_test "s390_contiguous_bitmask_p (ival, 32, NULL, NULL)"))) + (match_test "s390_contiguous_bitmask_p (ival, false, 32, NULL, NULL)"))) + +(define_constraint "NxxSw" + "@internal" + (and (match_code "const_int") + (match_test "s390_contiguous_bitmask_p (ival, true, 32, NULL, NULL)"))) ;; ;; Double-letter constraints starting with O follow. diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md index 75e4cb8..5b57344 100644 --- a/gcc/config/s390/predicates.md +++ b/gcc/config/s390/predicates.md @@ -176,10 +176,20 @@ return false; }) +; Predicate that always allows wraparound of the one-bit range. (define_predicate "contiguous_bitmask_operand" (match_code "const_int") { - return s390_contiguous_bitmask_p (INTVAL (op), GET_MODE_BITSIZE (mode), NULL, NULL); + return s390_contiguous_bitmask_p (INTVAL (op), true, + GET_MODE_BITSIZE (mode), NULL, NULL); +}) + +; Same without wraparound. +(define_predicate "contiguous_bitmask_nowrap_operand" + (match_code "const_int") +{ + return s390_contiguous_bitmask_p + (INTVAL (op), false, GET_MODE_BITSIZE (mode), NULL, NULL); }) ;; Return true if OP is ligitimate for any LOC instruction. diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 2ccf0bb..efef299 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -73,7 +73,7 @@ extern int s390_const_ok_for_constraint_p (HOST_WIDE_INT, int, const char *); extern int s390_const_double_ok_for_constraint_p (rtx, int, const char *); extern int s390_single_part (rtx, machine_mode, machine_mode, int); extern unsigned HOST_WIDE_INT s390_extract_part (rtx, machine_mode, int); -extern bool s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT, int, int *, int *); +extern bool s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT, bool, int, int *, int *); extern bool s390_contiguous_bitmask_vector_p (rtx, int *, int *); extern bool s390_bytemask_vector_p (rtx, unsigned *); extern bool s390_split_ok_p (rtx, rtx, machine_mode, int); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 1abb30b..5a1612e 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -2260,67 +2260,107 @@ s390_single_part (rtx op, } /* Return true if IN contains a contiguous bitfield in the lower SIZE - bits and no other bits are set in IN. POS and LENGTH can be used - to obtain the start position and the length of the bitfield. + bits and no other bits are set in (the lower SIZE bits of) IN. - POS gives the position of the first bit of the bitfield counting - from the lowest order bit starting with zero. In order to use this - value for S/390 instructions this has to be converted to "bits big - endian" style. */ + PSTART and PEND can be used to obtain the start and end + position (inclusive) of the bitfield relative to 64 + bits. *PSTART / *PEND gives the position of the first/last bit + of the bitfield counting from the highest order bit starting + with zero. */ bool -s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT in, int size, - int *pos, int *length) -{ - int tmp_pos = 0; - int tmp_length = 0; - int i; - unsigned HOST_WIDE_INT mask = 1ULL; - bool contiguous = false; +s390_contiguous_bitmask_nowrap_p (unsigned HOST_WIDE_INT in, int size, + int *pstart, int *pend) +{ + int start; + int end = -1; + int lowbit = sizeof (HOST_WIDE_INT) * BITS_PER_UNIT - 1; + int highbit = sizeof (HOST_WIDE_INT) * BITS_PER_UNIT - size; + unsigned HOST_WIDE_INT bitmask = 1ULL; + + gcc_assert (!!pstart == !!pend); + for (start = lowbit; start >= highbit; bitmask <<= 1, start--) + if (end == -1) + { + /* Look for the rightmost bit of a contiguous range of ones. */ + if (bitmask & in) + /* Found it. */ + end = start; + } + else + { + /* Look for the firt zero bit after the range of ones. */ + if (! (bitmask & in)) + /* Found it. */ + break; + } + /* We're one past the last one-bit. */ + start++; - for (i = 0; i < size; mask <<= 1, i++) + if (end == -1) + /* No one bits found. */ + return false; + + if (start > highbit) { - if (contiguous) - { - if (mask & in) - tmp_length++; - else - break; - } - else - { - if (mask & in) - { - contiguous = true; - tmp_length++; - } - else - tmp_pos++; - } + unsigned HOST_WIDE_INT mask; + + /* Calculate a mask for all bits beyond the contiguous bits. */ + mask = ((~(0ULL) >> highbit) & (~(0ULL) << (lowbit - start + 1))); + if (mask & in) + /* There are more bits set beyond the first range of one bits. */ + return false; } - if (!tmp_length) - return false; + if (pstart) + { + *pstart = start; + *pend = end; + } + + return true; +} - /* Calculate a mask for all bits beyond the contiguous bits. */ - mask = (-1LL & ~(((1ULL << (tmp_length + tmp_pos - 1)) << 1) - 1)); +/* Same as s390_contiguous_bitmask_nowrap_p but also returns true + if ~IN contains a contiguous bitfield. In that case, *END is < + *START. - if ((unsigned)size < sizeof (HOST_WIDE_INT) * BITS_PER_UNIT) - mask &= (HOST_WIDE_INT_1U << size) - 1; + If WRAP_P is true, a bitmask that wraps around is also tested. + When a wraparoud occurs *START is greater than *END (in + non-null pointers), and the uppermost (64 - SIZE) bits are thus + part of the range. If WRAP_P is false, no wraparound is + tested. */ - if (mask & in) - return false; +bool +s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT in, bool wrap_p, + int size, int *start, int *end) +{ + int bs = sizeof (HOST_WIDE_INT) * BITS_PER_UNIT; + bool b; - if (tmp_length + tmp_pos - 1 > size) + gcc_assert (!!start == !!end); + if ((in & ((~(0ULL)) >> (bs - size))) == 0) + /* This cannot be expressed as a contiguous bitmask. Exit early because + the second call of s390_contiguous_bitmask_nowrap_p would accept this as + a valid bitmask. */ return false; + b = s390_contiguous_bitmask_nowrap_p (in, size, start, end); + if (b) + return true; + if (! wrap_p) + return false; + b = s390_contiguous_bitmask_nowrap_p (~in, size, start, end); + if (b && start) + { + int s = *start; + int e = *end; - if (length) - *length = tmp_length; - - if (pos) - *pos = tmp_pos; + gcc_assert (s >= 1); + *start = ((e + 1) & (bs - 1)); + *end = ((s - 1 + bs) & (bs - 1)); + } - return true; + return b; } /* Return true if OP contains the same contiguous bitfield in *all* @@ -2336,9 +2376,11 @@ bool s390_contiguous_bitmask_vector_p (rtx op, int *start, int *end) { unsigned HOST_WIDE_INT mask; - int length, size; + int size; rtx elt; + bool b; + gcc_assert (!!start == !!end); if (!const_vec_duplicate_p (op, &elt) || !CONST_INT_P (elt)) return false; @@ -2350,25 +2392,21 @@ s390_contiguous_bitmask_vector_p (rtx op, int *start, int *end) return false; mask = UINTVAL (elt); - if (s390_contiguous_bitmask_p (mask, size, start, - end != NULL ? &length : NULL)) - { - if (end != NULL) - *end = *start + length - 1; - return true; - } - /* 0xff00000f style immediates can be covered by swapping start and - end indices in vgm. */ - if (s390_contiguous_bitmask_p (~mask, size, start, - end != NULL ? &length : NULL)) + + b = s390_contiguous_bitmask_p (mask, true, size, start, end); + if (b) { - if (end != NULL) - *end = *start - 1; - if (start != NULL) - *start = *start + length; + if (start) + { + int bs = sizeof (HOST_WIDE_INT) * BITS_PER_UNIT; + + *start -= (bs - size); + *end -= (bs - size); + } return true; } - return false; + else + return false; } /* Return true if C consists only of byte chunks being either 0 or @@ -2422,14 +2460,21 @@ s390_bytemask_vector_p (rtx op, unsigned *mask) bool s390_extzv_shift_ok (int bitsize, int rotl, unsigned HOST_WIDE_INT contig) { - int pos, len; + int start, end; bool ok; - ok = s390_contiguous_bitmask_p (contig, bitsize, &pos, &len); + ok = s390_contiguous_bitmask_nowrap_p (contig, bitsize, &start, &end); gcc_assert (ok); - return ((rotl >= 0 && rotl <= pos) - || (rotl < 0 && -rotl <= bitsize - len - pos)); + if (rotl >= 0) + return (64 - end >= rotl); + else + { + /* Translate "- rotate right" in BITSIZE mode to "rotate left" in + DIMode. */ + rotl = -rotl + (64 - bitsize); + return (start >= rotl); + } } /* Check whether we can (and want to) split a double-word @@ -7441,16 +7486,17 @@ print_operand (FILE *file, rtx x, int code) case 'e': case 'f': case 's': case 't': { - int pos, len; + int start, end; + int len; bool ok; len = (code == 's' || code == 'e' ? 64 : 32); - ok = s390_contiguous_bitmask_p (ival, len, &pos, &len); + ok = s390_contiguous_bitmask_p (ival, true, len, &start, &end); gcc_assert (ok); if (code == 's' || code == 't') - ival = 64 - pos - len; + ival = start; else - ival = 64 - 1 - pos; + ival = end; } break; default: @@ -7490,16 +7536,12 @@ print_operand (FILE *file, rtx x, int code) case 'e': case 's': { - int start, stop, inner_len; + int start, end; bool ok; - inner_len = GET_MODE_UNIT_BITSIZE (GET_MODE (x)); - ok = s390_contiguous_bitmask_vector_p (x, &start, &stop); + ok = s390_contiguous_bitmask_vector_p (x, &start, &end); gcc_assert (ok); - if (code == 's' || code == 't') - ival = inner_len - stop - 1; - else - ival = inner_len - start - 1; + ival = (code == 's') ? start : end; fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival); } break; diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 21ff33e..2848b41 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -6962,7 +6962,7 @@ [(set (reg CC_REGNUM) (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d") - (match_operand:DI 2 "general_operand" " d,d,T,NxxDq")) + (match_operand:DI 2 "general_operand" " d,d,T,NxxDw")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=d,d,d, d") (and:DI (match_dup 1) (match_dup 2)))] @@ -6980,7 +6980,7 @@ [(set (reg CC_REGNUM) (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0, d") - (match_operand:DI 2 "general_operand" " d,d,T,NxxDq")) + (match_operand:DI 2 "general_operand" " d,d,T,NxxDw")) (const_int 0))) (clobber (match_scratch:DI 0 "=d,d,d, d"))] "TARGET_ZARCH @@ -7003,7 +7003,7 @@ (match_operand:DI 1 "nonimmediate_operand" "%d,o, 0, 0, 0, 0, 0, 0,0,d,0, d, 0,0") (match_operand:DI 2 "general_operand" - "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,T,NxxDq,NxQDF,Q"))) + "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,T,NxxDw,NxQDF,Q"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ @@ -7134,7 +7134,7 @@ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,o, 0, 0, 0,0,d,0,0, d, 0,0") (match_operand:SI 2 "general_operand" - " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSq,NxQSF,Q"))) + " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxxSw,NxQSF,Q"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@