From patchwork Thu Apr 23 19:16:04 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Bergner X-Patchwork-Id: 464032 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 7C22A14012C for ; Fri, 24 Apr 2015 05:16:26 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass reason="1024-bit key; unprotected key" header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=YbhpvSgJ; dkim-adsp=none (unprotected policy); 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 :subject:from:to:cc:in-reply-to:references:content-type:date :message-id:mime-version:content-transfer-encoding; q=dns; s= default; b=h6w2ri6K9XGBuF8okm31DwwMrF64evDDHsjC/Xww7zPT0osPsEA5y BofZHGA030RiKSkoiM4BEO7ntHp8C8sftHixAXjHJWkVs4x1gZ+rPxJkfNRA8zci hRRxhZxripjesMb6hUhO8vN9TN/LnUWJmbyIAlp8IASOH8u31etmG8= 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 :subject:from:to:cc:in-reply-to:references:content-type:date :message-id:mime-version:content-transfer-encoding; s=default; bh=y+OzBDRZmDIGB5rItQc3iHL6B7c=; b=YbhpvSgJCQKqDQW7kYLN53VjGifD UJ4cWX8ZdWeWwKunS48/vAnmbRUdf4t7wzxNk0PlZ8VjqiahzYLZcctqbWAmLJGr 1u3H2MIILDUe7/vqBGv66E4TUTbZlHq10zWzS2CinpBoQkJAMsaapYJgpoyEhX7b crIYIVPyndJJ5ww= Received: (qmail 59132 invoked by alias); 23 Apr 2015 19:16:18 -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 59119 invoked by uid 89); 23 Apr 2015 19:16:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.2 required=5.0 tests=AWL, BAYES_50, KAM_ASCII_DIVIDERS, SPF_SOFTFAIL, T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: e37.co.us.ibm.com Received: from e37.co.us.ibm.com (HELO e37.co.us.ibm.com) (32.97.110.158) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Thu, 23 Apr 2015 19:16:12 +0000 Received: from /spool/local by e37.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 23 Apr 2015 13:16:10 -0600 Received: from d03dlp03.boulder.ibm.com (9.17.202.179) by e37.co.us.ibm.com (192.168.1.137) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 23 Apr 2015 13:16:08 -0600 Received: from b03cxnp07029.gho.boulder.ibm.com (b03cxnp07029.gho.boulder.ibm.com [9.17.130.16]) by d03dlp03.boulder.ibm.com (Postfix) with ESMTP id 5166A19D8047 for ; Thu, 23 Apr 2015 13:07:12 -0600 (MDT) Received: from d03av04.boulder.ibm.com (d03av04.boulder.ibm.com [9.17.195.170]) by b03cxnp07029.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t3NJG6vU42991654 for ; Thu, 23 Apr 2015 12:16:06 -0700 Received: from d03av04.boulder.ibm.com (loopback [127.0.0.1]) by d03av04.boulder.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t3NJG5rB017977 for ; Thu, 23 Apr 2015 13:16:05 -0600 Received: from [9.65.156.67] (sig-9-65-156-67.ibm.com [9.65.156.67]) by d03av04.boulder.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id t3NJG4VT017778; Thu, 23 Apr 2015 13:16:04 -0600 Subject: Re: [PATCH, rs6000, testsuite] Fix PR target/64579, __TM_end __builtin_tend failed to return transactional state From: Peter Bergner To: Segher Boessenkool Cc: GCC Patches , David Edelsohn , Michael Meissner , Bill Schmidt In-Reply-To: <20150422221633.GA29172@gate.crashing.org> References: <1426879660.13627.71.camel@otta> <20150320205200.GA32613@gate.crashing.org> <1426891319.13627.101.camel@otta> <1429649778.21947.25.camel@otta> <20150422021759.GC23315@gate.crashing.org> <1429710190.21947.48.camel@otta> <20150422221633.GA29172@gate.crashing.org> Date: Thu, 23 Apr 2015 14:16:04 -0500 Message-ID: <1429816564.21947.110.camel@otta> Mime-Version: 1.0 X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 15042319-0025-0000-0000-00000A162462 X-IsSubscribed: yes On Wed, 2015-04-22 at 17:16 -0500, Segher Boessenkool wrote: > On Wed, Apr 22, 2015 at 08:43:10AM -0500, Peter Bergner wrote: > > > Maybe you can fold tabortdc with tabortwc now? Use one UNSPEC name > > > for both, :GPR and ? > > > > Wouldn't that change the tabortwc pattern to use DImode rather > > than SImode when compiled with -m64 or -m32 -mpowerpc64? > > I'm not sure we want that. > > The GPR mode iterator creates two patterns, one for SI and one for DI, > and the tabortwc would be the one for SI if you use . Ok, I combined the tabortdc and tabortwc patterns, as well as the tabortdci and tabortwci patterns. Thanks for the suggestion. > I'm still a bit worried about putting a reg in the RTL (while the instruction > doesn't actually use one), but perhaps it's harmless. Ok, I created a separate ttest define_insn that hard codes the operands. I switched to using r1 rather than r0 as the second operand, for the reason that there could be code that sets r0 directly before this insn and I didn't want to create a unneeded read-after-write dependency. I thought r1 should be safe to use, since it's only updated in the prologue/epilogue and should be constant for the life of the function. > > > > +/* { dg-final { scan-assembler-times "tabortdci\\." 1 { target lp64 } } } */ > > > > > > This skips this test on -m32 -mpowerpc64, is that on purpose? > > > > Ummm, not exactly. :-) Not that many people test that though. > > I'll see if I can find a replacement for lp64 that covers that case. > > Maybe just { powerpc64 } works? powerpc64 doesn't work. It tells us whether the target will execute 64-bit instructions or not. When you run on a 64-bit host, then both 32-bit binaries and 64-bit binaries will gladly execute the 64-bit category extsw instruction just fine. This doesn't tell us that the target has underlying 64-bit registers for its use or not. Given that, I think we should just leave this as lp64. Updated patch below passed bootstrap and regtesting with no regressions, so how does this look for trunk? I'd also like to backport this to the open release branches so everything matches. Is that ok once I've verified bootstrap and regtesting on each branch? Peter gcc/ PR target/64579 * config/rs6000/htm.md: Remove all define_expands. (UNSPECV_HTM_TABORTDC, UNSPECV_HTM_TABORTDCI, UNSPECV_HTM_TABORTWC, UNSPECV_HTM_TABORTWCI): Remove. (UNSPECV_HTM_TABORTXC, UNSPECV_HTM_TABORTXCI, UNSPECV_HTM_TTEST): New. (tabort_internal, tbegin_internal, tcheck_internal, tend_internal, trechkpt_internal, treclaim_internal, tsr_internal): Rename from this... (tabort, tbegin, tcheck, tend, trechkpt, treclaim, tsr): ...to this. (tabortdc_internal, tabortdci_internal, tabortwc_internal, tabortwci_internal): Remove define_insns. (tabortc, tabortci): New define_insns. (tabort): Use gpc_reg_operand. (tcheck): Remove operand. (htm_mfspr_, htm_mtspr_): Use GPR mode macro. * config/rs6000/htmxlintrin.h (__TM_end): Use _HTM_TRANSACTIONAL as expected value. * config/rs6000/rs6000-builtin.def (BU_HTM_SPR0): Remove. (BU_HTM_SPR1): Rename to BU_HTM_V1. Remove use of RS6000_BTC_SPR. (tabort, tabortdc, tabortdci, tabortwc, tabortwci, tbegin, tcheck, tend, tendall, trechkpt, treclaim, tresume, tsuspend, tsr, ttest): Pass in the RS6000_BTC_CR attribute. (get_tfhar, set_tfhar, get_tfiar, set_tfiar, get_texasr, set_texasr, get_texasru, set_texasru): Pass in the RS6000_BTC_SPR attribute. (tcheck): Remove builtin argument. * config/rs6000/rs6000.c (rs6000_htm_spr_icode): Use TARGET_POWERPC64 not TARGET_64BIT. (htm_expand_builtin): Fix usage of expandedp. Disallow usage of the tabortdc and tabortdci builtins when not in 64-bit mode. Modify code to handle the loss of the HTM define_expands. Emit code to copy the CR register to TARGET. (htm_init_builtins): Modify code to handle the loss of the HTM define_expands. * config/rs6000/rs6000.h (RS6000_BTC_32BIT): Delete. (RS6000_BTC_64BIT): Likewise. (RS6000_BTC_CR): New macro. * doc/extend.texi: Update documentation for htm builtins. gcc/testsuite/ PR target/64579 * gcc.target/powerpc/htm-1.c: New test. * gcc.target/powerpc/htm-builtin-1.c (__builtin_tabortdc): Only test on 64-bit compiles. (__builtin_tabortdci): Likewise. (__builtin_tcheck): Remove operand. * lib/target-supports.exp (check_htm_hw_available): New function. Index: gcc/config/rs6000/htm.md =================================================================== --- gcc/config/rs6000/htm.md (revision 222127) +++ gcc/config/rs6000/htm.md (working copy) @@ -32,197 +32,52 @@ (define_constants (define_c_enum "unspecv" [UNSPECV_HTM_TABORT - UNSPECV_HTM_TABORTDC - UNSPECV_HTM_TABORTDCI - UNSPECV_HTM_TABORTWC - UNSPECV_HTM_TABORTWCI + UNSPECV_HTM_TABORTXC + UNSPECV_HTM_TABORTXCI UNSPECV_HTM_TBEGIN UNSPECV_HTM_TCHECK UNSPECV_HTM_TEND UNSPECV_HTM_TRECHKPT UNSPECV_HTM_TRECLAIM UNSPECV_HTM_TSR + UNSPECV_HTM_TTEST UNSPECV_HTM_MFSPR UNSPECV_HTM_MTSPR ]) -(define_expand "tabort" - [(set (match_dup 2) - (unspec_volatile:CC [(match_operand:SI 1 "int_reg_operand" "")] - UNSPECV_HTM_TABORT)) - (set (match_dup 3) - (eq:SI (match_dup 2) - (const_int 0))) - (set (match_operand:SI 0 "int_reg_operand" "") - (xor:SI (match_dup 3) - (const_int 1)))] - "TARGET_HTM" -{ - operands[2] = gen_rtx_REG (CCmode, CR0_REGNO); - operands[3] = gen_reg_rtx (SImode); -}) - -(define_insn "*tabort_internal" +(define_insn "tabort" [(set (match_operand:CC 1 "cc_reg_operand" "=x") - (unspec_volatile:CC [(match_operand:SI 0 "int_reg_operand" "r")] + (unspec_volatile:CC [(match_operand:SI 0 "gpc_reg_operand" "r")] UNSPECV_HTM_TABORT))] "TARGET_HTM" "tabort. %0" [(set_attr "type" "htm") (set_attr "length" "4")]) -(define_expand "tabortdc" - [(set (match_dup 4) - (unspec_volatile:CC [(match_operand 1 "u5bit_cint_operand" "n") - (match_operand:SI 2 "gpc_reg_operand" "r") - (match_operand:SI 3 "gpc_reg_operand" "r")] - UNSPECV_HTM_TABORTDC)) - (set (match_dup 5) - (eq:SI (match_dup 4) - (const_int 0))) - (set (match_operand:SI 0 "int_reg_operand" "") - (xor:SI (match_dup 5) - (const_int 1)))] - "TARGET_HTM" -{ - operands[4] = gen_rtx_REG (CCmode, CR0_REGNO); - operands[5] = gen_reg_rtx (SImode); -}) - -(define_insn "*tabortdc_internal" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n") - (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "gpc_reg_operand" "r")] - UNSPECV_HTM_TABORTDC))] - "TARGET_HTM" - "tabortdc. %0,%1,%2" - [(set_attr "type" "htm") - (set_attr "length" "4")]) - -(define_expand "tabortdci" - [(set (match_dup 4) - (unspec_volatile:CC [(match_operand 1 "u5bit_cint_operand" "n") - (match_operand:SI 2 "gpc_reg_operand" "r") - (match_operand 3 "s5bit_cint_operand" "n")] - UNSPECV_HTM_TABORTDCI)) - (set (match_dup 5) - (eq:SI (match_dup 4) - (const_int 0))) - (set (match_operand:SI 0 "int_reg_operand" "") - (xor:SI (match_dup 5) - (const_int 1)))] - "TARGET_HTM" -{ - operands[4] = gen_rtx_REG (CCmode, CR0_REGNO); - operands[5] = gen_reg_rtx (SImode); -}) - -(define_insn "*tabortdci_internal" +(define_insn "tabortc" [(set (match_operand:CC 3 "cc_reg_operand" "=x") (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n") - (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand 2 "s5bit_cint_operand" "n")] - UNSPECV_HTM_TABORTDCI))] + (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:GPR 2 "gpc_reg_operand" "r")] + UNSPECV_HTM_TABORTXC))] "TARGET_HTM" - "tabortdci. %0,%1,%2" - [(set_attr "type" "htm") - (set_attr "length" "4")]) - -(define_expand "tabortwc" - [(set (match_dup 4) - (unspec_volatile:CC [(match_operand 1 "u5bit_cint_operand" "n") - (match_operand:SI 2 "gpc_reg_operand" "r") - (match_operand:SI 3 "gpc_reg_operand" "r")] - UNSPECV_HTM_TABORTWC)) - (set (match_dup 5) - (eq:SI (match_dup 4) - (const_int 0))) - (set (match_operand:SI 0 "int_reg_operand" "") - (xor:SI (match_dup 5) - (const_int 1)))] - "TARGET_HTM" -{ - operands[4] = gen_rtx_REG (CCmode, CR0_REGNO); - operands[5] = gen_reg_rtx (SImode); -}) - -(define_insn "*tabortwc_internal" - [(set (match_operand:CC 3 "cc_reg_operand" "=x") - (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n") - (match_operand:SI 1 "gpc_reg_operand" "r") - (match_operand:SI 2 "gpc_reg_operand" "r")] - UNSPECV_HTM_TABORTWC))] - "TARGET_HTM" - "tabortwc. %0,%1,%2" + "tabortc. %0,%1,%2" [(set_attr "type" "htm") (set_attr "length" "4")]) -(define_expand "tabortwci" - [(set (match_dup 4) - (unspec_volatile:CC [(match_operand 1 "u5bit_cint_operand" "n") - (match_operand:SI 2 "gpc_reg_operand" "r") - (match_operand 3 "s5bit_cint_operand" "n")] - UNSPECV_HTM_TABORTWCI)) - (set (match_dup 5) - (eq:SI (match_dup 4) - (const_int 0))) - (set (match_operand:SI 0 "int_reg_operand" "") - (xor:SI (match_dup 5) - (const_int 1)))] - "TARGET_HTM" -{ - operands[4] = gen_rtx_REG (CCmode, CR0_REGNO); - operands[5] = gen_reg_rtx (SImode); -}) - -(define_expand "ttest" - [(set (match_dup 1) - (unspec_volatile:CC [(const_int 0) - (reg:SI 0) - (const_int 0)] - UNSPECV_HTM_TABORTWCI)) - (set (subreg:CC (match_dup 2) 0) (match_dup 1)) - (set (match_dup 3) (lshiftrt:SI (match_dup 2) (const_int 28))) - (set (match_operand:SI 0 "int_reg_operand" "") - (and:SI (match_dup 3) - (const_int 15)))] - "TARGET_HTM" -{ - operands[1] = gen_rtx_REG (CCmode, CR0_REGNO); - operands[2] = gen_reg_rtx (SImode); - operands[3] = gen_reg_rtx (SImode); -}) - -(define_insn "*tabortwci_internal" +(define_insn "tabortci" [(set (match_operand:CC 3 "cc_reg_operand" "=x") (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n") - (match_operand:SI 1 "gpc_reg_operand" "r") + (match_operand:GPR 1 "gpc_reg_operand" "r") (match_operand 2 "s5bit_cint_operand" "n")] - UNSPECV_HTM_TABORTWCI))] + UNSPECV_HTM_TABORTXCI))] "TARGET_HTM" - "tabortwci. %0,%1,%2" + "tabortci. %0,%1,%2" [(set_attr "type" "htm") (set_attr "length" "4")]) -(define_expand "tbegin" - [(set (match_dup 2) - (unspec_volatile:CC [(match_operand 1 "const_0_to_1_operand" "n")] - UNSPECV_HTM_TBEGIN)) - (set (match_dup 3) - (eq:SI (match_dup 2) - (const_int 0))) - (set (match_operand:SI 0 "int_reg_operand" "") - (xor:SI (match_dup 3) - (const_int 1)))] - "TARGET_HTM" -{ - operands[2] = gen_rtx_REG (CCmode, CR0_REGNO); - operands[3] = gen_reg_rtx (SImode); -}) - -(define_insn "*tbegin_internal" +(define_insn "tbegin" [(set (match_operand:CC 1 "cc_reg_operand" "=x") (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] UNSPECV_HTM_TBEGIN))] @@ -231,48 +86,16 @@ (define_insn "*tbegin_internal" [(set_attr "type" "htm") (set_attr "length" "4")]) -(define_expand "tcheck" - [(set (match_dup 2) - (unspec_volatile:CC [(match_operand 1 "u3bit_cint_operand" "n")] - UNSPECV_HTM_TCHECK)) - (set (match_dup 3) - (eq:SI (match_dup 2) - (const_int 0))) - (set (match_operand:SI 0 "int_reg_operand" "") - (xor:SI (match_dup 3) - (const_int 1)))] - "TARGET_HTM" -{ - operands[2] = gen_rtx_REG (CCmode, CR0_REGNO); - operands[3] = gen_reg_rtx (SImode); -}) - -(define_insn "*tcheck_internal" - [(set (match_operand:CC 1 "cc_reg_operand" "=x") - (unspec_volatile:CC [(match_operand 0 "u3bit_cint_operand" "n")] +(define_insn "tcheck" + [(set (match_operand:CC 0 "cc_reg_operand" "=y") + (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TCHECK))] "TARGET_HTM" "tcheck %0" [(set_attr "type" "htm") (set_attr "length" "4")]) -(define_expand "tend" - [(set (match_dup 2) - (unspec_volatile:CC [(match_operand 1 "const_0_to_1_operand" "n")] - UNSPECV_HTM_TEND)) - (set (match_dup 3) - (eq:SI (match_dup 2) - (const_int 0))) - (set (match_operand:SI 0 "int_reg_operand" "") - (xor:SI (match_dup 3) - (const_int 1)))] - "TARGET_HTM" -{ - operands[2] = gen_rtx_REG (CCmode, CR0_REGNO); - operands[3] = gen_reg_rtx (SImode); -}) - -(define_insn "*tend_internal" +(define_insn "tend" [(set (match_operand:CC 1 "cc_reg_operand" "=x") (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] UNSPECV_HTM_TEND))] @@ -281,23 +104,7 @@ (define_insn "*tend_internal" [(set_attr "type" "htm") (set_attr "length" "4")]) -(define_expand "trechkpt" - [(set (match_dup 1) - (unspec_volatile:CC [(const_int 0)] - UNSPECV_HTM_TRECHKPT)) - (set (match_dup 2) - (eq:SI (match_dup 1) - (const_int 0))) - (set (match_operand:SI 0 "int_reg_operand" "") - (xor:SI (match_dup 2) - (const_int 1)))] - "TARGET_HTM" -{ - operands[1] = gen_rtx_REG (CCmode, CR0_REGNO); - operands[2] = gen_reg_rtx (SImode); -}) - -(define_insn "*trechkpt_internal" +(define_insn "trechkpt" [(set (match_operand:CC 0 "cc_reg_operand" "=x") (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TRECHKPT))] @@ -306,23 +113,7 @@ (define_insn "*trechkpt_internal" [(set_attr "type" "htm") (set_attr "length" "4")]) -(define_expand "treclaim" - [(set (match_dup 2) - (unspec_volatile:CC [(match_operand:SI 1 "gpc_reg_operand" "r")] - UNSPECV_HTM_TRECLAIM)) - (set (match_dup 3) - (eq:SI (match_dup 2) - (const_int 0))) - (set (match_operand:SI 0 "int_reg_operand" "") - (xor:SI (match_dup 3) - (const_int 1)))] - "TARGET_HTM" -{ - operands[2] = gen_rtx_REG (CCmode, CR0_REGNO); - operands[3] = gen_reg_rtx (SImode); -}) - -(define_insn "*treclaim_internal" +(define_insn "treclaim" [(set (match_operand:CC 1 "cc_reg_operand" "=x") (unspec_volatile:CC [(match_operand:SI 0 "gpc_reg_operand" "r")] UNSPECV_HTM_TRECLAIM))] @@ -331,23 +122,7 @@ (define_insn "*treclaim_internal" [(set_attr "type" "htm") (set_attr "length" "4")]) -(define_expand "tsr" - [(set (match_dup 2) - (unspec_volatile:CC [(match_operand 1 "const_0_to_1_operand" "n")] - UNSPECV_HTM_TSR)) - (set (match_dup 3) - (eq:SI (match_dup 2) - (const_int 0))) - (set (match_operand:SI 0 "int_reg_operand" "") - (xor:SI (match_dup 3) - (const_int 1)))] - "TARGET_HTM" -{ - operands[2] = gen_rtx_REG (CCmode, CR0_REGNO); - operands[3] = gen_reg_rtx (SImode); -}) - -(define_insn "*tsr_internal" +(define_insn "tsr" [(set (match_operand:CC 1 "cc_reg_operand" "=x") (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] UNSPECV_HTM_TSR))] @@ -356,21 +131,30 @@ (define_insn "*tsr_internal" [(set_attr "type" "htm") (set_attr "length" "4")]) +(define_insn "ttest" + [(set (match_operand:CC 0 "cc_reg_operand" "=x") + (unspec_volatile:CC [(const_int 0)] + UNSPECV_HTM_TTEST))] + "TARGET_HTM" + "tabortwci. 0,1,0" + [(set_attr "type" "htm") + (set_attr "length" "4")]) + (define_insn "htm_mfspr_" - [(set (match_operand:P 0 "gpc_reg_operand" "=r") - (unspec_volatile:P [(match_operand 1 "u10bit_cint_operand" "n") - (match_operand:P 2 "htm_spr_reg_operand" "")] - UNSPECV_HTM_MFSPR))] + [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") + (unspec_volatile:GPR [(match_operand 1 "u10bit_cint_operand" "n") + (match_operand:GPR 2 "htm_spr_reg_operand" "")] + UNSPECV_HTM_MFSPR))] "TARGET_HTM" "mfspr %0,%1"; [(set_attr "type" "htm") (set_attr "length" "4")]) (define_insn "htm_mtspr_" - [(set (match_operand:P 2 "htm_spr_reg_operand" "") - (unspec_volatile:P [(match_operand:P 0 "gpc_reg_operand" "r") - (match_operand 1 "u10bit_cint_operand" "n")] - UNSPECV_HTM_MTSPR))] + [(set (match_operand:GPR 2 "htm_spr_reg_operand" "") + (unspec_volatile:GPR [(match_operand:GPR 0 "gpc_reg_operand" "r") + (match_operand 1 "u10bit_cint_operand" "n")] + UNSPECV_HTM_MTSPR))] "TARGET_HTM" "mtspr %1,%0"; [(set_attr "type" "htm") Index: gcc/config/rs6000/htmxlintrin.h =================================================================== --- gcc/config/rs6000/htmxlintrin.h (revision 222127) +++ gcc/config/rs6000/htmxlintrin.h (working copy) @@ -81,7 +81,8 @@ extern __inline long __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) __TM_end (void) { - if (__builtin_expect (__builtin_tend (0), 1)) + unsigned char status = _HTM_STATE (__builtin_tend (0)); + if (__builtin_expect (status, _HTM_TRANSACTIONAL)) return 1; return 0; } Index: gcc/config/rs6000/rs6000-builtin.def =================================================================== --- gcc/config/rs6000/rs6000-builtin.def (revision 222127) +++ gcc/config/rs6000/rs6000-builtin.def (working copy) @@ -456,21 +456,12 @@ | RS6000_BTC_TERNARY), \ CODE_FOR_ ## ICODE) /* ICODE */ -#define BU_HTM_SPR0(ENUM, NAME, ATTR, ICODE) \ - RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM, /* ENUM */ \ - "__builtin_" NAME, /* NAME */ \ - RS6000_BTM_HTM, /* MASK */ \ - (RS6000_BTC_ ## ATTR /* ATTR */ \ - | RS6000_BTC_SPR), \ - CODE_FOR_ ## ICODE) /* ICODE */ - -#define BU_HTM_SPR1(ENUM, NAME, ATTR, ICODE) \ +#define BU_HTM_V1(ENUM, NAME, ATTR, ICODE) \ RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM, /* ENUM */ \ "__builtin_" NAME, /* NAME */ \ RS6000_BTM_HTM, /* MASK */ \ (RS6000_BTC_ ## ATTR /* ATTR */ \ | RS6000_BTC_UNARY \ - | RS6000_BTC_SPR \ | RS6000_BTC_VOID), \ CODE_FOR_ ## ICODE) /* ICODE */ @@ -1633,30 +1624,30 @@ BU_CRYPTO_OVERLOAD_3 (VSHASIGMA, "vshasi /* HTM functions. */ -BU_HTM_1 (TABORT, "tabort", MISC, tabort) -BU_HTM_3 (TABORTDC, "tabortdc", MISC, tabortdc) -BU_HTM_3 (TABORTDCI, "tabortdci", MISC, tabortdci) -BU_HTM_3 (TABORTWC, "tabortwc", MISC, tabortwc) -BU_HTM_3 (TABORTWCI, "tabortwci", MISC, tabortwci) -BU_HTM_1 (TBEGIN, "tbegin", MISC, tbegin) -BU_HTM_1 (TCHECK, "tcheck", MISC, tcheck) -BU_HTM_1 (TEND, "tend", MISC, tend) -BU_HTM_0 (TENDALL, "tendall", MISC, tend) -BU_HTM_0 (TRECHKPT, "trechkpt", MISC, trechkpt) -BU_HTM_1 (TRECLAIM, "treclaim", MISC, treclaim) -BU_HTM_0 (TRESUME, "tresume", MISC, tsr) -BU_HTM_0 (TSUSPEND, "tsuspend", MISC, tsr) -BU_HTM_1 (TSR, "tsr", MISC, tsr) -BU_HTM_0 (TTEST, "ttest", MISC, ttest) - -BU_HTM_SPR0 (GET_TFHAR, "get_tfhar", MISC, nothing) -BU_HTM_SPR1 (SET_TFHAR, "set_tfhar", MISC, nothing) -BU_HTM_SPR0 (GET_TFIAR, "get_tfiar", MISC, nothing) -BU_HTM_SPR1 (SET_TFIAR, "set_tfiar", MISC, nothing) -BU_HTM_SPR0 (GET_TEXASR, "get_texasr", MISC, nothing) -BU_HTM_SPR1 (SET_TEXASR, "set_texasr", MISC, nothing) -BU_HTM_SPR0 (GET_TEXASRU, "get_texasru", MISC, nothing) -BU_HTM_SPR1 (SET_TEXASRU, "set_texasru", MISC, nothing) +BU_HTM_1 (TABORT, "tabort", CR, tabort) +BU_HTM_3 (TABORTDC, "tabortdc", CR, tabortdc) +BU_HTM_3 (TABORTDCI, "tabortdci", CR, tabortdci) +BU_HTM_3 (TABORTWC, "tabortwc", CR, tabortwc) +BU_HTM_3 (TABORTWCI, "tabortwci", CR, tabortwci) +BU_HTM_1 (TBEGIN, "tbegin", CR, tbegin) +BU_HTM_0 (TCHECK, "tcheck", CR, tcheck) +BU_HTM_1 (TEND, "tend", CR, tend) +BU_HTM_0 (TENDALL, "tendall", CR, tend) +BU_HTM_0 (TRECHKPT, "trechkpt", CR, trechkpt) +BU_HTM_1 (TRECLAIM, "treclaim", CR, treclaim) +BU_HTM_0 (TRESUME, "tresume", CR, tsr) +BU_HTM_0 (TSUSPEND, "tsuspend", CR, tsr) +BU_HTM_1 (TSR, "tsr", CR, tsr) +BU_HTM_0 (TTEST, "ttest", CR, ttest) + +BU_HTM_0 (GET_TFHAR, "get_tfhar", SPR, nothing) +BU_HTM_V1 (SET_TFHAR, "set_tfhar", SPR, nothing) +BU_HTM_0 (GET_TFIAR, "get_tfiar", SPR, nothing) +BU_HTM_V1 (SET_TFIAR, "set_tfiar", SPR, nothing) +BU_HTM_0 (GET_TEXASR, "get_texasr", SPR, nothing) +BU_HTM_V1 (SET_TEXASR, "set_texasr", SPR, nothing) +BU_HTM_0 (GET_TEXASRU, "get_texasru", SPR, nothing) +BU_HTM_V1 (SET_TEXASRU, "set_texasru", SPR, nothing) /* 3 argument paired floating point builtins. */ Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 222127) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -12655,9 +12655,9 @@ static inline enum insn_code rs6000_htm_spr_icode (bool nonvoid) { if (nonvoid) - return (TARGET_64BIT) ? CODE_FOR_htm_mfspr_di : CODE_FOR_htm_mfspr_si; + return (TARGET_POWERPC64) ? CODE_FOR_htm_mfspr_di : CODE_FOR_htm_mfspr_si; else - return (TARGET_64BIT) ? CODE_FOR_htm_mtspr_di : CODE_FOR_htm_mtspr_si; + return (TARGET_POWERPC64) ? CODE_FOR_htm_mtspr_di : CODE_FOR_htm_mtspr_si; } /* Expand the HTM builtin in EXP and store the result in TARGET. @@ -12671,7 +12671,17 @@ htm_expand_builtin (tree exp, rtx target const struct builtin_description *d; size_t i; - *expandedp = false; + *expandedp = true; + + if (!TARGET_POWERPC64 + && (fcode == HTM_BUILTIN_TABORTDC + || fcode == HTM_BUILTIN_TABORTDCI)) + { + size_t uns_fcode = (size_t)fcode; + const char *name = rs6000_builtin_info[uns_fcode].name; + error ("builtin %s is only valid in 64-bit mode", name); + return const0_rtx; + } /* Expand the HTM builtins. */ d = bdesc_htm; @@ -12684,26 +12694,29 @@ htm_expand_builtin (tree exp, rtx target call_expr_arg_iterator iter; unsigned attr = rs6000_builtin_info[fcode].attr; enum insn_code icode = d->icode; + const struct insn_operand_data *insn_op; + bool uses_spr = (attr & RS6000_BTC_SPR); + rtx cr = NULL_RTX; - if (attr & RS6000_BTC_SPR) + if (uses_spr) icode = rs6000_htm_spr_icode (nonvoid); + insn_op = &insn_data[icode].operand[0]; if (nonvoid) { - machine_mode tmode = insn_data[icode].operand[0].mode; + machine_mode tmode = (uses_spr) ? insn_op->mode : SImode; if (!target || GET_MODE (target) != tmode - || !(*insn_data[icode].operand[0].predicate) (target, tmode)) + || (uses_spr && !(*insn_op->predicate) (target, tmode))) target = gen_reg_rtx (tmode); - op[nopnds++] = target; + if (uses_spr) + op[nopnds++] = target; } FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) { - const struct insn_operand_data *insn_op; - if (arg == error_mark_node || nopnds >= MAX_HTM_OPERANDS) - return NULL_RTX; + return const0_rtx; insn_op = &insn_data[icode].operand[nopnds]; @@ -12750,10 +12763,17 @@ htm_expand_builtin (tree exp, rtx target /* If this builtin accesses SPRs, then pass in the appropriate SPR number and SPR regno as the last two operands. */ - if (attr & RS6000_BTC_SPR) + if (uses_spr) { - op[nopnds++] = gen_rtx_CONST_INT (Pmode, htm_spr_num (fcode)); - op[nopnds++] = gen_rtx_REG (Pmode, htm_spr_regno (fcode)); + machine_mode mode = (TARGET_POWERPC64) ? DImode : SImode; + op[nopnds++] = gen_rtx_CONST_INT (mode, htm_spr_num (fcode)); + op[nopnds++] = gen_rtx_REG (mode, htm_spr_regno (fcode)); + } + /* If this builtin accesses a CR, then pass in a scratch + CR as the last operand. */ + else if (attr & RS6000_BTC_CR) + { cr = gen_reg_rtx (CCmode); + op[nopnds++] = cr; } #ifdef ENABLE_CHECKING @@ -12766,7 +12786,7 @@ htm_expand_builtin (tree exp, rtx target expected_nopnds = 3; if (!(attr & RS6000_BTC_VOID)) expected_nopnds += 1; - if (attr & RS6000_BTC_SPR) + if (uses_spr) expected_nopnds += 2; gcc_assert (nopnds == expected_nopnds && nopnds <= MAX_HTM_OPERANDS); @@ -12793,12 +12813,41 @@ htm_expand_builtin (tree exp, rtx target return NULL_RTX; emit_insn (pat); - *expandedp = true; + if (attr & RS6000_BTC_CR) + { + if (fcode == HTM_BUILTIN_TBEGIN) + { + /* Emit code to set TARGET to true or false depending on + whether the tbegin. instruction successfully or failed + to start a transaction. We do this by placing the 1's + complement of CR's EQ bit into TARGET. */ + rtx scratch = gen_reg_rtx (SImode); + emit_insn (gen_rtx_SET (VOIDmode, scratch, + gen_rtx_EQ (SImode, cr, + const0_rtx))); + emit_insn (gen_rtx_SET (VOIDmode, target, + gen_rtx_XOR (SImode, scratch, + GEN_INT (1)))); + } + else + { + /* Emit code to copy the 4-bit condition register field + CR into the least significant end of register TARGET. */ + rtx scratch1 = gen_reg_rtx (SImode); + rtx scratch2 = gen_reg_rtx (SImode); + rtx subreg = simplify_gen_subreg (CCmode, scratch1, SImode, 0); + emit_insn (gen_movcc (subreg, cr)); + emit_insn (gen_lshrsi3 (scratch2, scratch1, GEN_INT (28))); + emit_insn (gen_andsi3 (target, scratch2, GEN_INT (0xf))); + } + } + if (nonvoid) return target; return const0_rtx; } + *expandedp = false; return NULL_RTX; } @@ -15287,8 +15336,31 @@ htm_init_builtins (void) bool void_func = (attr & RS6000_BTC_VOID); int attr_args = (attr & RS6000_BTC_TYPE_MASK); int nopnds = 0; - tree argtype = (attr & RS6000_BTC_SPR) ? long_unsigned_type_node - : unsigned_type_node; + tree gpr_type_node; + tree rettype; + tree argtype; + + if (TARGET_32BIT && TARGET_POWERPC64) + gpr_type_node = long_long_unsigned_type_node; + else + gpr_type_node = long_unsigned_type_node; + + if (attr & RS6000_BTC_SPR) + { + rettype = gpr_type_node; + argtype = gpr_type_node; + } + else if (d->code == HTM_BUILTIN_TABORTDC + || d->code == HTM_BUILTIN_TABORTDCI) + { + rettype = unsigned_type_node; + argtype = gpr_type_node; + } + else + { + rettype = unsigned_type_node; + argtype = unsigned_type_node; + } if ((mask & builtin_mask) != mask) { @@ -15305,7 +15377,7 @@ htm_init_builtins (void) continue; } - op[nopnds++] = (void_func) ? void_type_node : argtype; + op[nopnds++] = (void_func) ? void_type_node : rettype; if (attr_args == RS6000_BTC_UNARY) op[nopnds++] = argtype; Index: gcc/config/rs6000/rs6000.h =================================================================== --- gcc/config/rs6000/rs6000.h (revision 222127) +++ gcc/config/rs6000/rs6000.h (working copy) @@ -2573,9 +2573,8 @@ extern int frame_pointer_needed; /* Miscellaneous information. */ #define RS6000_BTC_SPR 0x01000000 /* function references SPRs. */ #define RS6000_BTC_VOID 0x02000000 /* function has no return value. */ -#define RS6000_BTC_OVERLOADED 0x04000000 /* function is overloaded. */ -#define RS6000_BTC_32BIT 0x08000000 /* function references SPRs. */ -#define RS6000_BTC_64BIT 0x10000000 /* function references SPRs. */ +#define RS6000_BTC_CR 0x04000000 /* function references a CR. */ +#define RS6000_BTC_OVERLOADED 0x08000000 /* function is overloaded. */ #define RS6000_BTC_MISC_MASK 0x1f000000 /* Mask of the misc info. */ /* Convenience macros to document the instruction type. */ Index: gcc/doc/extend.texi =================================================================== --- gcc/doc/extend.texi (revision 222127) +++ gcc/doc/extend.texi (working copy) @@ -15121,10 +15121,15 @@ The following low level built-in functio @option{-mhtm} or @option{-mcpu=CPU} where CPU is `power8' or later. They all generate the machine instruction that is part of the name. -The HTM built-ins return true or false depending on their success and -their arguments match exactly the type and order of the associated -hardware instruction's operands. Refer to the ISA manual for a -description of each instruction's operands. +The HTM builtins (with the exception of @code{__builtin_tbegin}) return +the full 4-bit condition register value set by their associated hardware +instruction. The header file @code{htmintrin.h} defines some macros that can +be used to decipher the return value. The @code{__builtin_tbegin} builtin +returns a simple true or false value depending on whether a transaction was +successfully started or not. The arguments of the builtins match exactly the +type and order of the associated hardware instruction's operands, except for +the @code{__builtin_tcheck} builtin, which does not take any input arguments. +Refer to the ISA manual for a description of each instruction's operands. @smallexample unsigned int __builtin_tbegin (unsigned int) @@ -15136,7 +15141,7 @@ unsigned int __builtin_tabortdci (unsign unsigned int __builtin_tabortwc (unsigned int, unsigned int, unsigned int) unsigned int __builtin_tabortwci (unsigned int, unsigned int, int) -unsigned int __builtin_tcheck (unsigned int) +unsigned int __builtin_tcheck (void) unsigned int __builtin_treclaim (unsigned int) unsigned int __builtin_trechkpt (void) unsigned int __builtin_tsr (unsigned int) @@ -15271,7 +15276,7 @@ TM_buff_type TM_buff; while (1) @{ - if (__TM_begin (TM_buff)) + if (__TM_begin (TM_buff) == _HTM_TBEGIN_STARTED) @{ /* Transaction State Initiated. */ if (is_locked (lock)) Index: gcc/testsuite/gcc.target/powerpc/htm-1.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/htm-1.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/htm-1.c (working copy) @@ -0,0 +1,52 @@ +/* { dg-do run { target { powerpc*-*-* && htm_hw } } } */ +/* { dg-require-effective-target powerpc_htm_ok } */ +/* { dg-options "-mhtm" } */ + +/* Program to test PowerPC HTM instructions. */ + +#include +#include + +int +main (void) +{ + long i; + unsigned long mask = 0; + +repeat: + if (__builtin_tbegin (0)) + { + mask++; + } + else + abort(); + + if (mask == 1) + { + __builtin_tsuspend (); + + if (_HTM_STATE (__builtin_tcheck ()) != _HTM_SUSPENDED) + abort (); + + __builtin_tresume (); + + if (_HTM_STATE (__builtin_tcheck ()) != _HTM_TRANSACTIONAL) + abort (); + } + else + mask++; + + if (_HTM_STATE (__builtin_tendall ()) != _HTM_TRANSACTIONAL) + abort (); + + if (mask == 1) + goto repeat; + + if (_HTM_STATE (__builtin_tendall ()) != _HTM_NONTRANSACTIONAL) + abort (); + + if (mask != 3) + abort (); + + return 0; +} Index: gcc/testsuite/gcc.target/powerpc/htm-builtin-1.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/htm-builtin-1.c (revision 222127) +++ gcc/testsuite/gcc.target/powerpc/htm-builtin-1.c (working copy) @@ -6,8 +6,8 @@ /* { dg-final { scan-assembler-times "tbegin\\." 1 } } */ /* { dg-final { scan-assembler-times "tend\\." 2 } } */ /* { dg-final { scan-assembler-times "tabort\\." 2 } } */ -/* { dg-final { scan-assembler-times "tabortdc\\." 1 } } */ -/* { dg-final { scan-assembler-times "tabortdci\\." 1 } } */ +/* { dg-final { scan-assembler-times "tabortdc\\." 1 { target lp64 } } } */ +/* { dg-final { scan-assembler-times "tabortdci\\." 1 { target lp64 } } } */ /* { dg-final { scan-assembler-times "tabortwc\\." 1 } } */ /* { dg-final { scan-assembler-times "tabortwci\\." 2 } } */ /* { dg-final { scan-assembler-times "tcheck" 1 } } */ @@ -25,12 +25,14 @@ void use_builtins (long *p, char code, l p[3] = __builtin_tabort (0); p[4] = __builtin_tabort (code); +#ifdef __powerpc64__ p[5] = __builtin_tabortdc (0xf, a[5], b[5]); p[6] = __builtin_tabortdci (0xf, a[6], 13); +#endif p[7] = __builtin_tabortwc (0xf, a[7], b[7]); p[8] = __builtin_tabortwci (0xf, a[8], 13); - p[9] = __builtin_tcheck (5); + p[9] = __builtin_tcheck (); p[10] = __builtin_trechkpt (); p[11] = __builtin_treclaim (0); p[12] = __builtin_tresume (); Index: gcc/testsuite/lib/target-supports.exp =================================================================== --- gcc/testsuite/lib/target-supports.exp (revision 222127) +++ gcc/testsuite/lib/target-supports.exp (working copy) @@ -3279,6 +3279,25 @@ proc check_effective_target_powerpc_htm_ } } +# Return 1 if the target supports executing HTM hardware instructions, +# 0 otherwise. Cache the result. + +proc check_htm_hw_available { } { + return [check_cached_effective_target htm_hw_available { + # For now, disable on Darwin + if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} { + expr 0 + } else { + check_runtime_nocache htm_hw_available { + int main() + { + __builtin_ttest (); + return 0; + } + } "-mhtm" + } + }] +} # Return 1 if this is a PowerPC target supporting -mcpu=cell. proc check_effective_target_powerpc_ppu_ok { } { @@ -5278,6 +5297,7 @@ proc is-effective-target { arg } { "p8vector_hw" { set selected [check_p8vector_hw_available] } "ppc_recip_hw" { set selected [check_ppc_recip_hw_available] } "dfp_hw" { set selected [check_dfp_hw_available] } + "htm_hw" { set selected [check_htm_hw_available] } "named_sections" { set selected [check_named_sections_available] } "gc_sections" { set selected [check_gc_sections_available] } "cxa_atexit" { set selected [check_cxa_atexit_available] } @@ -5301,6 +5321,7 @@ proc is-effective-target-keyword { arg } "p8vector_hw" { return 1 } "ppc_recip_hw" { return 1 } "dfp_hw" { return 1 } + "htm_hw" { return 1 } "named_sections" { return 1 } "gc_sections" { return 1 } "cxa_atexit" { return 1 }