From patchwork Thu Dec 1 16:28:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dominik Vogt X-Patchwork-Id: 701585 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 3tV2mW4WpNz9t15 for ; Fri, 2 Dec 2016 03:29:15 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="NTpwPw+8"; 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=ZBkWHGt0c3AvqFdHriU FQyMAVzNjV5kCRqpsUQYcItDGSOXip0sl7owWf9bsaX/TSSjXBiD2gszcjENT7vp UqWj61HPpSfqOHtyEFYsATG7rufKXHfJX4ISO0P7kJIKhp55k7+tVd2ClT66l5kd F213L3izmi2JGPhiTRxhs9bk= 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=SkE7OSzTC78OhuIZV0ayqv1Og R4=; b=NTpwPw+8mcpH3BBkd5/SNPOax9pNnHfRH+973mEWg0ld/QgaL+Ym4x+ep hkFgIYop/OJtpxuffyjvE20vF4xbqbcJUkqo9wmWE/qMfTk/lkbwEgTWifLDkVDQ VazOAvAAanjGgyoxwP3at1btyqbuY061LEEM24si7v4bpcMKhQ= Received: (qmail 92259 invoked by alias); 1 Dec 2016 16:29:06 -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 92250 invoked by uid 89); 1 Dec 2016 16:29:06 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW autolearn=no version=3.3.2 spammy=sk:vogt@li, U*vogt, sk:vogtli, vogtlinuxvnetibmcom X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0b-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.158.5) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 01 Dec 2016 16:28:56 +0000 Received: from pps.filterd (m0098416.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.17/8.16.0.17) with SMTP id uB1GP36X088076 for ; Thu, 1 Dec 2016 11:28:54 -0500 Received: from e06smtp10.uk.ibm.com (e06smtp10.uk.ibm.com [195.75.94.106]) by mx0b-001b2d01.pphosted.com with ESMTP id 272mvhjhpm-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Thu, 01 Dec 2016 11:28:54 -0500 Received: from localhost by e06smtp10.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 1 Dec 2016 16:28:52 -0000 Received: from d06dlp01.portsmouth.uk.ibm.com (9.149.20.13) by e06smtp10.uk.ibm.com (192.168.101.140) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 1 Dec 2016 16:28:49 -0000 Received: from b06cxnps4074.portsmouth.uk.ibm.com (d06relay11.portsmouth.uk.ibm.com [9.149.109.196]) by d06dlp01.portsmouth.uk.ibm.com (Postfix) with ESMTP id 9CB9217D805A for ; Thu, 1 Dec 2016 16:31:20 +0000 (GMT) Received: from d06av02.portsmouth.uk.ibm.com (d06av02.portsmouth.uk.ibm.com [9.149.37.228]) by b06cxnps4074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id uB1GSnqN59572240 for ; Thu, 1 Dec 2016 16:28:49 GMT Received: from d06av02.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id uB1GSnDY026040 for ; Thu, 1 Dec 2016 09:28:49 -0700 Received: from oc5510024614.ibm.com (sig-9-145-51-151.uk.ibm.com [9.145.51.151]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id uB1GSm8c026029 for ; Thu, 1 Dec 2016 09:28:48 -0700 Received: by oc5510024614.ibm.com (Postfix, from userid 500) id 152A91AA22; Thu, 1 Dec 2016 17:28:47 +0100 (CET) Date: Thu, 1 Dec 2016 17:28:46 +0100 From: Dominik Vogt To: gcc-patches@gcc.gnu.org Subject: Re: [PATCH 0/2] S/390: New patterns for extzv, risbg and r[ox]sbg. Reply-To: vogt@linux.vnet.ibm.com Mail-Followup-To: vogt@linux.vnet.ibm.com, gcc-patches@gcc.gnu.org References: <20161201162616.GA15785@linux.vnet.ibm.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20161201162616.GA15785@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: 16120116-0040-0000-0000-0000026D9571 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16120116-0041-0000-0000-000022C97C5D Message-Id: <20161201162846.GC15785@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-12-01_13:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1609300000 definitions=main-1612010281 On Thu, Dec 01, 2016 at 05:26:16PM +0100, Dominik Vogt wrote: > The following patch series adds some patterns for enhanced use of > the r[ixo]sbg instructions on S/390. > > - 0001-* fixes some test regressions with the existing risbg > patterns that are broken because of recent trunkt changes. > > - 0002-* adds new patterns for the r[xo]sbg instructions and an > SI mode variant of "extzv". > > For details, please chech the commit comments of the patches. All > patches have been bootstrapped on s390x biarch and regression > tested on s390x biarch and s390. r[xo]sbg patch. Ciao Dominik ^_^ ^_^ diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 43b9371..15f0a41 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -3728,26 +3728,24 @@ ; extv instruction patterns ; -; FIXME: This expander needs to be converted from DI to GPR as well -; after resolving some issues with it. - -(define_expand "extzv" +(define_expand "extzv" [(parallel - [(set (match_operand:DI 0 "register_operand" "=d") - (zero_extract:DI - (match_operand:DI 1 "register_operand" "d") + [(set (match_operand:GPR 0 "register_operand" "=d") + (zero_extract:GPR + (match_operand:GPR 1 "register_operand" "d") (match_operand 2 "const_int_operand" "") ; size (match_operand 3 "const_int_operand" ""))) ; start (clobber (reg:CC CC_REGNUM))])] "TARGET_Z10" { - if (! EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), 64)) + if (! EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), + GET_MODE_BITSIZE (mode))) FAIL; /* Starting with zEC12 there is risbgn not clobbering CC. */ if (TARGET_ZEC12) { emit_move_insn (operands[0], - gen_rtx_ZERO_EXTRACT (DImode, + gen_rtx_ZERO_EXTRACT (mode, operands[1], operands[2], operands[3])); @@ -3787,6 +3785,19 @@ [(set_attr "op_type" "RIE") (set_attr "z10prop" "z10_super_E1")]) +(define_insn "*extzvdisi" + [(set (match_operand:DI 0 "register_operand" "=d") + (zero_extract:DI + (match_operand:SI 1 "register_operand" "d") + (match_operand 2 "const_int_operand" "") ; size + (match_operand 3 "const_int_operand" ""))) ; start + ] + " + && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), 32)" + "\t%0,%1,64-%2,128+63,32+%3+%2" ; dst, src, start, end, shift + [(set_attr "op_type" "RIE") + (set_attr "z10prop" "z10_super_E1")]) + ; 64 bit: (a & -16) | ((b >> 8) & 15) (define_insn "*extzvdi_lshiftrt" [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+d") @@ -3820,17 +3831,36 @@ [(set_attr "op_type" "RIE") (set_attr "z10prop" "z10_super_E1")]) +(define_insn "*__ior_and_ze" + [(set (match_operand:GPR 0 "register_operand" "=d") + (ior:GPR (and:GPR + (match_operand:GPR 1 "register_operand" "0") + (match_operand:GPR 2 "const_int_operand" "")) + (zero_extract:GPR + (match_operand:GPR 3 "register_operand" "d") + (match_operand 4 "const_int_operand" "") ; size + (match_operand 5 "const_int_operand" "")) ; start + ))] + " + && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[4]), INTVAL (operands[5]), + GET_MODE_BITSIZE (mode)) + && UINTVAL (operands[2]) == (~(0ULL) << UINTVAL (operands[4]))" + "\t%0,%3,64-%4,63,%4+%5" + [(set_attr "op_type" "RIE") + (set_attr "z10prop" "z10_super_E1")]) + ; ((int)foo >> 10) & 1; -(define_insn "*extract1bitdi" +(define_insn "*extract1bit" [(set (match_operand:DI 0 "register_operand" "=d") - (ne:DI (zero_extract:DI - (match_operand:DI 1 "register_operand" "d") + (ne:DI (zero_extract:GPR + (match_operand:GPR 1 "register_operand" "d") (const_int 1) ; size (match_operand 2 "const_int_operand" "")) ; start (const_int 0)))] " - && EXTRACT_ARGS_IN_RANGE (1, INTVAL (operands[2]), 64)" - "\t%0,%1,64-1,128+63,%2+1" ; dst, src, start, end, shift + && EXTRACT_ARGS_IN_RANGE (1, INTVAL (operands[2]), + GET_MODE_BITSIZE (mode))" + "\t%0,%1,63,128+63,%2+1" ; dst, src, start, end, shift [(set_attr "op_type" "RIE") (set_attr "z10prop" "z10_super_E1")]) @@ -4221,6 +4251,22 @@ "rsbg\t%0,%1,%2,63,64-%2" [(set_attr "op_type" "RIE")]) +;; a = a | ((b >> const_int) & 15) +;; a = a ^ ((b >> const_int) & 15) +(define_insn "*rsbg__ze" + [(set (match_operand:GPR 0 "nonimmediate_operand" "=d") + (IXOR:GPR + (zero_extract:GPR (match_operand:GPR 1 "register_operand" "d") + (match_operand 2 "const_int_operand" "") ; size + (match_operand 3 "const_int_operand" "")) ; start + (match_operand:GPR 4 "nonimmediate_operand" "0"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_Z10 + && EXTRACT_ARGS_IN_RANGE (INTVAL (operands[2]), INTVAL (operands[3]), + GET_MODE_BITSIZE (mode))" + "rsbg\t%0,%1,64-%2,63,%3+%2" + [(set_attr "op_type" "RIE")]) + ;; These two are generated by combine for s.bf &= val. ;; ??? For bitfields smaller than 32-bits, we wind up with SImode ;; shifts and ands, which results in some truly awful patterns diff --git a/gcc/testsuite/gcc.target/s390/risbg-ll-1.c b/gcc/testsuite/gcc.target/s390/risbg-ll-1.c index 17a9000..665dc71 100644 --- a/gcc/testsuite/gcc.target/s390/risbg-ll-1.c +++ b/gcc/testsuite/gcc.target/s390/risbg-ll-1.c @@ -16,7 +16,8 @@ // Test an extraction of bit 0 from a right-shifted value. i32 f1 (i32 v_foo) { - /* { dg-final { scan-assembler "f1:\n\trisbg\t%r2,%r2,64-1,128\\\+63,53\\\+1" } } */ + /* { dg-final { scan-assembler "f1:\n\trisbg\t%r2,%r2,64-1,128\\\+63,53\\\+1" { target { lp64 } } } } */ + /* { dg-final { scan-assembler "f1:\n\trisbg\t%r2,%r2,64-1,128\\\+63,32\\\+21\\\+1" { target { ! lp64 } } } } */ i32 v_shr = ((ui32)v_foo) >> 10; i32 v_and = v_shr & 1; return v_and; @@ -26,7 +27,7 @@ i32 f1 (i32 v_foo) i64 f2 (i64 v_foo) { /* { dg-final { scan-assembler "f2:\n\trisbg\t%r2,%r2,64-1,128\\\+63,53\\\+1" { target { lp64 } } } } */ - /* { dg-final { scan-assembler "f2:\n\trisbg\t%r3,%r3,64-1,128\\\+63,53\\\+1\n\tlhi\t%r2,0" { target { ! lp64 } } } } */ + /* { dg-final { scan-assembler "f2:\n\trisbg\t%r3,%r3,64-1,128\\\+63,32\\\+21\\\+1\n\tlhi\t%r2,0" { target { ! lp64 } } } } */ i64 v_shr = ((ui64)v_foo) >> 10; i64 v_and = v_shr & 1; return v_and; @@ -263,7 +264,7 @@ i64 f22 (i64 v_foo) i64 f23 (i64 v_foo) { /* { dg-final { scan-assembler "f23:\n\trisbg\t%r2,%r2,64-8,128\\\+63,54\\\+8" { target { lp64 } } } } */ - /* { dg-final { scan-assembler "f23:\n\trisbg\t%r3,%r3,64-8,128\\\+63,54\\\+8\n\tlhi\t%r2,0" { target { ! lp64 } } } } */ + /* { dg-final { scan-assembler "f23:\n\trisbg\t%r3,%r3,64-8,128\\\+63,32\\\+22\\\+8\n\tlhi\t%r2,0" { target { ! lp64 } } } } */ i64 v_shr = ((ui64)v_foo) >> 2; i64 v_and = v_shr & 255; return v_and; @@ -378,7 +379,8 @@ i64 f33 (i64 v_foo) // Test a case where the AND comes before a shift right. i32 f34 (i32 v_foo) { - /* { dg-final { scan-assembler "f34:\n\trisbg\t%r2,%r2,64-7,128\\\+63,48\\\+7" } } */ + /* { dg-final { scan-assembler "f34:\n\trisbg\t%r2,%r2,64-7,128\\\+63,48\\\+7" { target { lp64 } } } } */ + /* { dg-final { scan-assembler "f34:\n\trisbg\t%r2,%r2,64-7,128\\\+63,32\\\+16\\\+7" { target { ! lp64 } } } } */ i32 v_and = v_foo & 65535; i32 v_shl = ((ui32)v_and) >> 9; return v_shl; @@ -388,7 +390,7 @@ i32 f34 (i32 v_foo) i64 f35 (i64 v_foo) { /* { dg-final { scan-assembler "f35:\n\trisbg\t%r2,%r2,64-7,128\\\+63,48\\\+7" { target { lp64 } } } } */ - /* { dg-final { scan-assembler "f35:\n\trisbg\t%r3,%r3,64-7,128\\\+63,48\\\+7\n\tlhi\t%r2,0" { target { ! lp64 } } } } */ + /* { dg-final { scan-assembler "f35:\n\trisbg\t%r3,%r3,64-7,128\\\+63,32\\\+16\\\+7\n\tlhi\t%r2,0" { target { ! lp64 } } } } */ i64 v_and = v_foo & 65535; i64 v_shl = ((ui64)v_and) >> 9; return v_shl; @@ -454,7 +456,7 @@ i64 f40 (i64 v_foo, i64 *v_dest) i64 f41 (i32 v_a) { /* { dg-final { scan-assembler "f41:\n\trisbg\t%r2,%r2,64-28,128\\\+63,34\\\+28" { target { lp64 } } } } */ - /* { dg-final { scan-assembler "f41:\n\trisbg\t%r3,%r2,64-28,128\\\+63,34\\\+28\n\tlhi\t%r2,0" { target { ! lp64 } } } } */ + /* { dg-final { scan-assembler "f41:\n\trisbg\t%r3,%r2,64-28,128\\\+63,32\\\+2\\\+28\n\tlhi\t%r2,0" { target { ! lp64 } } } } */ i32 v_shl = v_a << 2; i32 v_shr = ((ui32)v_shl) >> 4; i64 v_ext = (ui64)v_shr; @@ -496,3 +498,25 @@ i32 f44 (i64 v_x) i32 v_and = v_conv & 10; return v_and; } + +// Check whether risbg is used to extract the lsb of an SI. +i64 g1 (i32 a) +{ + /* { dg-final { scan-assembler "g1:\n\trisbg\t%r2,%r2,63,128\\\+63,0" { target { lp64 } } } } */ + /* { dg-final { scan-assembler "g1:\n\trisbg\t%r3,%r2,63,128\\\+63,0" { target { ! lp64 } } } } */ + i64 b; + + b = !(i64)(a & 1); + return b; +} + +// Check whether risbg is used to extract the second lowest bit of an SI. +void g2_foo (i32, i32); +i32 g2 (i32 a, i32 *b) +{ + /* { dg-final { scan-assembler "g2:\n\(\t.*\n\)*\trisbg\t%r3,%r1,62,128\\\+62,0" } } */ + if (a) + g2_foo (0, *b & 2); + + return *b; +} diff --git a/gcc/testsuite/gcc.target/s390/risbg-ll-2.c b/gcc/testsuite/gcc.target/s390/risbg-ll-2.c index 3628192..0c3db1b 100644 --- a/gcc/testsuite/gcc.target/s390/risbg-ll-2.c +++ b/gcc/testsuite/gcc.target/s390/risbg-ll-2.c @@ -34,7 +34,7 @@ i64 f2 (i64 v_a, i64 v_b) // Test a case with two ANDs and a shift. i32 f3 (i32 v_a, i32 v_b) { - /* { dg-final { scan-assembler "f3:\n\trisbg\t%r2,%r3,64-4,63,4\\\+52" } } */ + /* { dg-final { scan-assembler "f3:\n\trisbg\t%r2,%r3,64-4,63,32\\\+4\\\+20" } } */ i32 v_anda = v_a & -16; i32 v_shr = ((ui32)v_b) >> 8; i32 v_andb = v_shr & 15; @@ -45,8 +45,8 @@ i32 f3 (i32 v_a, i32 v_b) // ...and again with i64. i64 f4 (i64 v_a, i64 v_b) { - /* { dg-final { scan-assembler "f4:\n\trisbg\t%r2,%r3,60,60\\\+4-1,128-60-4-8" { target { lp64 } } } } */ - /* { dg-final { scan-assembler "f4:\n\(\t.*\n\)*\trisbg\t%r5,%r5,64-4,128\\\+63,52\\\+4" { target { ! lp64 } } } } */ + /* { dg-final { scan-assembler "f4:\n\trisbg\t%r2,%r3,64-4,63,4\\\+52" { target { lp64 } } } } */ + /* { dg-final { scan-assembler "f4:\n\(\t.*\n\)*\trosbg\t%r3,%r5,64-4,63,52\\\+4" { target { ! lp64 } } } } */ i64 v_anda = v_a & -16; i64 v_shr = ((ui64)v_b) >> 8; i64 v_andb = v_shr & 15; diff --git a/gcc/testsuite/gcc.target/s390/risbg-ll-3.c b/gcc/testsuite/gcc.target/s390/risbg-ll-3.c index 838f1ff..4bdb224 100644 --- a/gcc/testsuite/gcc.target/s390/risbg-ll-3.c +++ b/gcc/testsuite/gcc.target/s390/risbg-ll-3.c @@ -5,6 +5,8 @@ /* { dg-do compile { target s390x-*-* } } */ /* { dg-options "-O3 -march=zEC12 -mzarch -fno-asynchronous-unwind-tables" } */ +#define i32 signed int +#define ui32 unsigned int #define i64 signed long long #define ui64 unsigned long long diff --git a/gcc/testsuite/gcc.target/s390/rosbg-1.c b/gcc/testsuite/gcc.target/s390/rosbg-1.c new file mode 100644 index 0000000..3c22794 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/rosbg-1.c @@ -0,0 +1,80 @@ +/* Test use of ROSBG and RXSBG. */ + +/* { dg-do compile { target s390x-*-* } } */ +/* { dg-options "-O3 -march=z10 -mzarch -fno-asynchronous-unwind-tables" } */ + +unsigned long long ior1 (unsigned long long v_a, unsigned long long v_b) +{ + /* { dg-final { scan-assembler "ior1:\n\trosbg\t%r2,%r3,64-4,63,1\\\+4" { target { lp64 } } } } */ + unsigned long long v_shift = (v_b >> 59); + unsigned long long v_and = (v_shift & 15); + unsigned long long v_or = v_a | v_and; + return v_or; +} + +unsigned int ior2 (unsigned int v_a, unsigned int v_b) +{ + /* { dg-final { scan-assembler "ior2:\n\trosbg\t%r2,%r3,64-4,63,32\\\+1\\\+4" } } */ + unsigned int v_shift = (v_b >> 27); + unsigned int v_and = (v_shift & 15); + unsigned int v_or = v_a | v_and; + return v_or; +} + +unsigned short ior3 (unsigned short v_a, unsigned short v_b) +{ + /* { dg-final { scan-assembler "ior3:\n\trosbg\t%r2,%r3,64-4,63,49\\\+4" { target { lp64 } } } } */ + /* { dg-final { scan-assembler "ior3:\n\trosbg\t%r2,%r3,64-4,63,32\\\+17\\\+4" { target { ! lp64 } } } } */ + unsigned short v_shift = (v_b >> 11); + unsigned short v_and = (v_shift & 15); + unsigned short v_or = v_a | v_and; + return v_or; +} + +unsigned char ior4 (unsigned char v_a, unsigned char v_b) +{ + /* { dg-final { scan-assembler "ior4:\n\trosbg\t%r2,%r3,64-4,63,57\\\+4" { target { lp64 } } } } */ + /* { dg-final { scan-assembler "ior4:\n\trosbg\t%r2,%r3,64-4,63,32\\\+25\\\+4" { target { ! lp64 } } } } */ + unsigned char v_shift = (v_b >> 3); + unsigned char v_and = (v_shift & 15); + unsigned char v_or = v_a | v_and; + return v_or; +} + +unsigned long long xor1 (unsigned long long v_a, unsigned long long v_b) +{ + /* { dg-final { scan-assembler "xor1:\n\trxsbg\t%r2,%r3,64-4,63,1\\\+4" { target { lp64 } } } } */ + unsigned long long v_shift = (v_b >> 59); + unsigned long long v_and = (v_shift & 15); + unsigned long long v_or = v_a ^ v_and; + return v_or; +} + +unsigned int xor2 (unsigned int v_a, unsigned int v_b) +{ + /* { dg-final { scan-assembler "xor2:\n\trxsbg\t%r2,%r3,64-4,63,32\\\+1\\\+4" } } */ + unsigned int v_shift = (v_b >> 27); + unsigned int v_and = (v_shift & 15); + unsigned int v_or = v_a ^ v_and; + return v_or; +} + +unsigned short xor3 (unsigned short v_a, unsigned short v_b) +{ + /* { dg-final { scan-assembler "xor3:\n\trxsbg\t%r2,%r3,64-4,63,49\\\+4" { target { lp64 } } } } */ + /* { dg-final { scan-assembler "xor3:\n\trxsbg\t%r2,%r3,64-4,63,32\\\+17\\\+4" { target { ! lp64 } } } } */ + unsigned short v_shift = (v_b >> 11); + unsigned short v_and = (v_shift & 15); + unsigned short v_or = v_a ^ v_and; + return v_or; +} + +unsigned char xor4 (unsigned char v_a, unsigned char v_b) +{ + /* { dg-final { scan-assembler "xor4:\n\trxsbg\t%r2,%r3,64-4,63,57\\\+4" { target { lp64 } } } } */ + /* { dg-final { scan-assembler "xor4:\n\trxsbg\t%r2,%r3,64-4,63,32\\\+25\\\+4" { target { ! lp64 } } } } */ + unsigned char v_shift = (v_b >> 3); + unsigned char v_and = (v_shift & 15); + unsigned char v_or = v_a ^ v_and; + return v_or; +}