]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
acinclude.m4 (LIBITM_CHECK_AS_HTM): New.
authorPeter Bergner <bergner@vnet.ibm.com>
Mon, 15 Jul 2013 17:23:49 +0000 (12:23 -0500)
committerPeter Bergner <bergner@gcc.gnu.org>
Mon, 15 Jul 2013 17:23:49 +0000 (12:23 -0500)
libitm/
        * acinclude.m4 (LIBITM_CHECK_AS_HTM): New.
        * configure.ac: Use it.
(AC_CHECK_HEADERS): Check for sys/auxv.h.
(AC_CHECK_FUNCS): Check for getauxval.
        * config.h.in, configure: Rebuild.
* configure.tgt (target_cpu): Add -mhtm to XCFLAGS.
* config/powerpc/target.h: Include sys/auxv.h and htmintrin.h.
(USE_HTM_FASTPATH): Define.
(_TBEGIN_STARTED, _TBEGIN_INDETERMINATE, _TBEGIN_PERSISTENT,
_HTM_RETRIES) New macros.
(htm_abort, htm_abort_should_retry, htm_available, htm_begin, htm_init,
htm_begin_success, htm_commit, htm_transaction_active): New functions.

gcc/
* config.gcc (powerpc*-*-*): Install htmintrin.h and htmxlintrin.h.
* config/rs6000/t-rs6000 (MD_INCLUDES): Add htm.md.
* config/rs6000/rs6000.opt: Add -mhtm option.
* config/rs6000/rs6000-cpus.def (POWERPC_MASKS): Add OPTION_MASK_HTM.
(ISA_2_7_MASKS_SERVER): Add OPTION_MASK_HTM.
* config/rs6000/rs6000-c.c (rs6000_target_modify_macros): Define
__HTM__ if the HTM instructions are available.
* config/rs6000/predicates.md (u3bit_cint_operand, u10bit_cint_operand,
htm_spr_reg_operand): New define_predicates.
* config/rs6000/rs6000.md (define_attr "type"): Add htm.
(TFHAR_REGNO, TFIAR_REGNO, TEXASR_REGNO): New define_constants.
Include htm.md.
* config/rs6000/rs6000-builtin.def (BU_HTM_0, BU_HTM_1, BU_HTM_2,
BU_HTM_3, BU_HTM_SPR0, BU_HTM_SPR1): Add support macros for defining
HTM builtin functions.
* config/rs6000/rs6000.c (RS6000_BUILTIN_H): New macro.
(rs6000_reg_names, alt_reg_names): Add HTM SPR register names.
(rs6000_init_hard_regno_mode_ok): Add support for HTM instructions.
(rs6000_builtin_mask_calculate): Likewise.
(rs6000_option_override_internal): Likewise.
(bdesc_htm): Add new HTM builtin support.
(htm_spr_num): New function.
(htm_spr_regno): Likewise.
(rs6000_htm_spr_icode): Likewise.
(htm_expand_builtin): Likewise.
(htm_init_builtins): Likewise.
(rs6000_expand_builtin): Add support for HTM builtin functions.
(rs6000_init_builtins): Likewise.
(rs6000_invalid_builtin, rs6000_opt_mask): Add support for -mhtm option.
* config/rs6000/rs6000.h (ASM_CPU_SPEC): Add support for -mhtm.
(TARGET_HTM, MASK_HTM): Define macros.
(FIRST_PSEUDO_REGISTER): Adjust for new HTM SPR registers.
(FIXED_REGISTERS): Likewise.
(CALL_USED_REGISTERS): Likewise.
(CALL_REALLY_USED_REGISTERS): Likewise.
(REG_ALLOC_ORDER): Likewise.
(enum reg_class): Likewise.
(REG_CLASS_NAMES): Likewise.
(REG_CLASS_CONTENTS): Likewise.
(REGISTER_NAMES): Likewise.
(ADDITIONAL_REGISTER_NAMES): Likewise.
(RS6000_BTC_SPR, RS6000_BTC_VOID, RS6000_BTC_32BIT, RS6000_BTC_64BIT,
RS6000_BTC_MISC_MASK, RS6000_BTM_HTM): New macros.
(RS6000_BTM_COMMON): Add RS6000_BTM_HTM.
* config/rs6000/htm.md: New file.
* config/rs6000/htmintrin.h: New file.
* config/rs6000/htmxlintrin.h: New file.

gcc/testsuite/
        * lib/target-supports.exp (check_effective_target_powerpc_htm_ok): New
        function to test if HTM is available.
* gcc.target/powerpc/htm-xl-intrin-1.c: New test.
* gcc.target/powerpc/htm-builtin-1.c: New test.

From-SVN: r200960

25 files changed:
gcc/ChangeLog
gcc/config.gcc
gcc/config/rs6000/htm.md [new file with mode: 0644]
gcc/config/rs6000/htmintrin.h [new file with mode: 0644]
gcc/config/rs6000/htmxlintrin.h [new file with mode: 0644]
gcc/config/rs6000/predicates.md
gcc/config/rs6000/rs6000-builtin.def
gcc/config/rs6000/rs6000-c.c
gcc/config/rs6000/rs6000-cpus.def
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md
gcc/config/rs6000/rs6000.opt
gcc/config/rs6000/t-rs6000
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/htm-builtin-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/htm-xl-intrin-1.c [new file with mode: 0644]
gcc/testsuite/lib/target-supports.exp
libitm/ChangeLog
libitm/acinclude.m4
libitm/config.h.in
libitm/config/powerpc/target.h
libitm/configure
libitm/configure.ac
libitm/configure.tgt

index 4949bffd6421c17f74419ef9d05805f372b52252..d9c58e9e0cf9f849101e5537706aa42418e93c63 100644 (file)
@@ -1,3 +1,53 @@
+2013-07-15  Peter Bergner <bergner@vnet.ibm.com>
+
+       * config.gcc (powerpc*-*-*): Install htmintrin.h and htmxlintrin.h.
+       * config/rs6000/t-rs6000 (MD_INCLUDES): Add htm.md.
+       * config/rs6000/rs6000.opt: Add -mhtm option.
+       * config/rs6000/rs6000-cpus.def (POWERPC_MASKS): Add OPTION_MASK_HTM.
+       (ISA_2_7_MASKS_SERVER): Add OPTION_MASK_HTM.
+       * config/rs6000/rs6000-c.c (rs6000_target_modify_macros): Define
+       __HTM__ if the HTM instructions are available.
+       * config/rs6000/predicates.md (u3bit_cint_operand, u10bit_cint_operand,
+       htm_spr_reg_operand): New define_predicates.
+       * config/rs6000/rs6000.md (define_attr "type"): Add htm.
+       (TFHAR_REGNO, TFIAR_REGNO, TEXASR_REGNO): New define_constants.
+       Include htm.md.
+       * config/rs6000/rs6000-builtin.def (BU_HTM_0, BU_HTM_1, BU_HTM_2,
+       BU_HTM_3, BU_HTM_SPR0, BU_HTM_SPR1): Add support macros for defining
+       HTM builtin functions.
+       * config/rs6000/rs6000.c (RS6000_BUILTIN_H): New macro.
+       (rs6000_reg_names, alt_reg_names): Add HTM SPR register names.
+       (rs6000_init_hard_regno_mode_ok): Add support for HTM instructions.
+       (rs6000_builtin_mask_calculate): Likewise.
+       (rs6000_option_override_internal): Likewise.
+       (bdesc_htm): Add new HTM builtin support.
+       (htm_spr_num): New function.
+       (htm_spr_regno): Likewise.
+       (rs6000_htm_spr_icode): Likewise.
+       (htm_expand_builtin): Likewise.
+       (htm_init_builtins): Likewise.
+       (rs6000_expand_builtin): Add support for HTM builtin functions.
+       (rs6000_init_builtins): Likewise.
+       (rs6000_invalid_builtin, rs6000_opt_mask): Add support for -mhtm option.
+       * config/rs6000/rs6000.h (ASM_CPU_SPEC): Add support for -mhtm.
+       (TARGET_HTM, MASK_HTM): Define macros.
+       (FIRST_PSEUDO_REGISTER): Adjust for new HTM SPR registers.
+       (FIXED_REGISTERS): Likewise.
+       (CALL_USED_REGISTERS): Likewise.
+       (CALL_REALLY_USED_REGISTERS): Likewise.
+       (REG_ALLOC_ORDER): Likewise.
+       (enum reg_class): Likewise.
+       (REG_CLASS_NAMES): Likewise.
+       (REG_CLASS_CONTENTS): Likewise.
+       (REGISTER_NAMES): Likewise.
+       (ADDITIONAL_REGISTER_NAMES): Likewise.
+       (RS6000_BTC_SPR, RS6000_BTC_VOID, RS6000_BTC_32BIT, RS6000_BTC_64BIT,
+       RS6000_BTC_MISC_MASK, RS6000_BTM_HTM): New macros.
+       (RS6000_BTM_COMMON): Add RS6000_BTM_HTM.
+       * config/rs6000/htm.md: New file.
+       * config/rs6000/htmintrin.h: New file.
+       * config/rs6000/htmxlintrin.h: New file.
+
 2013-07-15  Marcus Shawcroft  <marcus.shawcroft@arm.com>
 
        * config/aarch64/aarch64-protos.h (aarch64_symbol_type):
index fd55d5545c7e361736fae02d7cebce8770638fae..e1b688fd43488323eab9a7b5135a5ef42be7c744 100644 (file)
@@ -421,7 +421,7 @@ picochip-*-*)
         ;;
 powerpc*-*-*)
        cpu_type=rs6000
-       extra_headers="ppc-asm.h altivec.h spe.h ppu_intrinsics.h paired.h spu2vmx.h vec_types.h si2vmx.h"
+       extra_headers="ppc-asm.h altivec.h spe.h ppu_intrinsics.h paired.h spu2vmx.h vec_types.h si2vmx.h htmintrin.h htmxlintrin.h"
        need_64bit_hwint=yes
        case x$with_cpu in
            xpowerpc64|xdefault64|x6[23]0|x970|xG5|xpower[345678]|xpower6x|xrs64a|xcell|xa2|xe500mc64|xe5500|Xe6500)
diff --git a/gcc/config/rs6000/htm.md b/gcc/config/rs6000/htm.md
new file mode 100644 (file)
index 0000000..e8ec91a
--- /dev/null
@@ -0,0 +1,366 @@
+;; Hardware Transactional Memory (HTM) patterns.
+;; Copyright (C) 2013 Free Software Foundation, Inc.
+;; Contributed by Peter Bergner <bergner@vnet.ibm.com>.
+
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published
+;; by the Free Software Foundation; either version 3, or (at your
+;; option) any later version.
+
+;; GCC is distributed in the hope that it will be useful, but WITHOUT
+;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+;; License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_constants
+  [(TFHAR_SPR          128)
+   (TFIAR_SPR          129)
+   (TEXASR_SPR         130)
+   (TEXASRU_SPR                131)
+   (MAX_HTM_OPERANDS   4)
+  ])
+
+;;
+;; UNSPEC_VOLATILE usage
+;;
+
+(define_c_enum "unspecv"
+  [UNSPECV_HTM_TABORT
+   UNSPECV_HTM_TABORTDC
+   UNSPECV_HTM_TABORTDCI
+   UNSPECV_HTM_TABORTWC
+   UNSPECV_HTM_TABORTWCI
+   UNSPECV_HTM_TBEGIN
+   UNSPECV_HTM_TCHECK
+   UNSPECV_HTM_TEND
+   UNSPECV_HTM_TRECHKPT
+   UNSPECV_HTM_TRECLAIM
+   UNSPECV_HTM_TSR
+   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" "")
+       (minus:SI (const_int 1) (match_dup 3)))]
+  "TARGET_HTM"
+{
+  operands[2] = gen_rtx_REG (CCmode, CR0_REGNO);
+  operands[3] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*tabort_internal"
+  [(set (match_operand:CC 1 "cc_reg_operand" "=x")
+       (unspec_volatile:CC [(match_operand:SI 0 "int_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" "")
+       (minus:SI (const_int 1) (match_dup 5)))]
+  "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" "")
+       (minus:SI (const_int 1) (match_dup 5)))]
+  "TARGET_HTM"
+{
+  operands[4] = gen_rtx_REG (CCmode, CR0_REGNO);
+  operands[5] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*tabortdci_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 2 "s5bit_cint_operand" "n")]
+                           UNSPECV_HTM_TABORTDCI))]
+  "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" "")
+       (minus:SI (const_int 1) (match_dup 5)))]
+  "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"
+  [(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" "")
+       (minus:SI (const_int 1) (match_dup 5)))]
+  "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 24)))
+   (parallel [(set (match_operand:SI 0 "int_reg_operand" "")
+                  (and:SI (match_dup 3) (const_int 15)))
+              (clobber (scratch:CC))])]
+  "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"
+  [(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_TABORTWCI))]
+  "TARGET_HTM"
+  "tabortwci. %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" "")
+       (minus:SI (const_int 1) (match_dup 3)))]
+  "TARGET_HTM"
+{
+  operands[2] = gen_rtx_REG (CCmode, CR0_REGNO);
+  operands[3] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*tbegin_internal"
+  [(set (match_operand:CC 1 "cc_reg_operand" "=x")
+       (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
+                           UNSPECV_HTM_TBEGIN))]
+  "TARGET_HTM"
+  "tbegin. %0"
+  [(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" "")
+       (minus:SI (const_int 1) (match_dup 3)))]
+  "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")]
+                           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" "")
+       (minus:SI (const_int 1) (match_dup 3)))]
+  "TARGET_HTM"
+{
+  operands[2] = gen_rtx_REG (CCmode, CR0_REGNO);
+  operands[3] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*tend_internal"
+  [(set (match_operand:CC 1 "cc_reg_operand" "=x")
+       (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
+                           UNSPECV_HTM_TEND))]
+  "TARGET_HTM"
+  "tend. %0"
+  [(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" "")
+       (minus:SI (const_int 1) (match_dup 2)))]
+  "TARGET_HTM"
+{
+  operands[1] = gen_rtx_REG (CCmode, CR0_REGNO);
+  operands[2] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*trechkpt_internal"
+  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+       (unspec_volatile:CC [(const_int 0)]
+                           UNSPECV_HTM_TRECHKPT))]
+  "TARGET_HTM"
+  "trechkpt."
+  [(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" "")
+       (minus:SI (const_int 1) (match_dup 3)))]
+  "TARGET_HTM"
+{
+  operands[2] = gen_rtx_REG (CCmode, CR0_REGNO);
+  operands[3] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*treclaim_internal"
+  [(set (match_operand:CC 1 "cc_reg_operand" "=x")
+       (unspec_volatile:CC [(match_operand:SI 0 "gpc_reg_operand" "r")]
+                           UNSPECV_HTM_TRECLAIM))]
+  "TARGET_HTM"
+  "treclaim. %0"
+  [(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" "")
+       (minus:SI (const_int 1) (match_dup 3)))]
+  "TARGET_HTM"
+{
+  operands[2] = gen_rtx_REG (CCmode, CR0_REGNO);
+  operands[3] = gen_reg_rtx (SImode);
+})
+
+(define_insn "*tsr_internal"
+  [(set (match_operand:CC 1 "cc_reg_operand" "=x")
+       (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
+                           UNSPECV_HTM_TSR))]
+  "TARGET_HTM"
+  "tsr. %0"
+  [(set_attr "type" "htm")
+   (set_attr "length" "4")])
+
+(define_insn "htm_mfspr_<mode>"
+  [(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))]
+  "TARGET_HTM"
+  "mfspr %0,%1";
+  [(set_attr "type" "htm")
+   (set_attr "length" "4")])
+
+(define_insn "htm_mtspr_<mode>"
+  [(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))]
+  "TARGET_HTM"
+  "mtspr %1,%0";
+  [(set_attr "type" "htm")
+   (set_attr "length" "4")])
diff --git a/gcc/config/rs6000/htmintrin.h b/gcc/config/rs6000/htmintrin.h
new file mode 100644 (file)
index 0000000..10f3e2e
--- /dev/null
@@ -0,0 +1,131 @@
+/* Hardware Transactional Memory (HTM) intrinsics.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   Contributed by Peter Bergner <bergner@vnet.ibm.com>.
+
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 3 of the License, or (at your option)
+   any later version.
+
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef __HTM__
+# error "HTM instruction set not enabled"
+#endif /* __HTM__ */
+
+#ifndef _HTMINTRIN_H
+#define _HTMINTRIN_H
+
+#include <stdint.h>
+
+typedef uint64_t texasr_t;
+typedef uint32_t texasru_t;
+typedef uint32_t texasrl_t;
+typedef uintptr_t tfiar_t;
+typedef uintptr_t tfhar_t;
+
+#define _HTM_STATE(CR0) ((CR0 >> 1) & 0x3)
+#define _HTM_NONTRANSACTIONAL 0x0
+#define _HTM_SUSPENDED        0x1
+#define _HTM_TRANSACTIONAL    0x2
+
+/* The following macros use the IBM bit numbering for BITNUM
+   as used in the ISA documentation.  */
+
+#define _TEXASR_EXTRACT_BITS(TEXASR,BITNUM,SIZE) \
+  (((TEXASR) >> (63-(BITNUM))) & ((1<<(SIZE))-1))
+#define _TEXASRU_EXTRACT_BITS(TEXASR,BITNUM,SIZE) \
+  (((TEXASR) >> (31-(BITNUM))) & ((1<<(SIZE))-1))
+
+#define _TEXASR_FAILURE_CODE(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 7, 8)
+#define _TEXASRU_FAILURE_CODE(TEXASRU) \
+  _TEXASRU_EXTRACT_BITS(TEXASRU, 7, 8)
+
+#define _TEXASR_FAILURE_PERSISTENT(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 7, 1)
+#define _TEXASRU_FAILURE_PERSISTENT(TEXASRU) \
+  _TEXASRU_EXTRACT_BITS(TEXASRU, 7, 1)
+
+#define _TEXASR_DISALLOWED(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 8, 1)
+#define _TEXASRU_DISALLOWED(TEXASRU) \
+  _TEXASRU_EXTRACT_BITS(TEXASRU, 8, 1)
+
+#define _TEXASR_NESTING_OVERFLOW(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 9, 1)
+#define _TEXASRU_NESTING_OVERFLOW(TEXASRU) \
+  _TEXASRU_EXTRACT_BITS(TEXASRU, 9, 1)
+
+#define _TEXASR_FOOTPRINT_OVERFLOW(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 10, 1)
+#define _TEXASRU_FOOTPRINT_OVERFLOW(TEXASRU) \
+  _TEXASRU_EXTRACT_BITS(TEXASRU, 10, 1)
+
+#define _TEXASR_SELF_INDUCED_CONFLICT(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 11, 1)
+#define _TEXASRU_SELF_INDUCED_CONFLICT(TEXASRU) \
+  _TEXASRU_EXTRACT_BITS(TEXASRU, 11, 1)
+
+#define _TEXASR_NON_TRANSACTIONAL_CONFLICT(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 12, 1)
+#define _TEXASRU_NON_TRANSACTIONAL_CONFLICT(TEXASRU) \
+  _TEXASRU_EXTRACT_BITS(TEXASRU, 12, 1)
+
+#define _TEXASR_TRANSACTION_CONFLICT(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 13, 1)
+#define _TEXASRU_TRANSACTION_CONFLICT(TEXASRU) \
+  _TEXASRU_EXTRACT_BITS(TEXASRU, 13, 1)
+
+#define _TEXASR_TRANSLATION_INVALIDATION_CONFLICT(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 14, 1)
+#define _TEXASRU_TRANSLATION_INVALIDATION_CONFLICT(TEXASRU) \
+  _TEXASRU_EXTRACT_BITS(TEXASRU, 14, 1)
+
+#define _TEXASR_IMPLEMENTAION_SPECIFIC(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 15, 1)
+#define _TEXASRU_IMPLEMENTAION_SPECIFIC(TEXASRU) \
+  _TEXASRU_EXTRACT_BITS(TEXASRU, 15, 1)
+
+#define _TEXASR_INSRUCTION_FETCH_CONFLICT(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 16, 1)
+#define _TEXASRU_INSRUCTION_FETCH_CONFLICT(TEXASRU) \
+  _TEXASRU_EXTRACT_BITS(TEXASRU, 16, 1)
+
+#define _TEXASR_ABORT(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 31, 1)
+#define _TEXASRU_ABORT(TEXASRU) \
+  _TEXASRU_EXTRACT_BITS(TEXASRU, 31, 1)
+
+
+#define _TEXASR_SUSPENDED(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 32, 1)
+
+#define _TEXASR_PRIVILEGE(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 35, 2)
+
+#define _TEXASR_FAILURE_SUMMARY(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 36, 1)
+
+#define _TEXASR_TFIAR_EXACT(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 37, 1)
+
+#define _TEXASR_ROT(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 38, 1)
+
+#define _TEXASR_TRANSACTION_LEVEL(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 63, 12)
+
+#endif /* _HTMINTRIN_H */
diff --git a/gcc/config/rs6000/htmxlintrin.h b/gcc/config/rs6000/htmxlintrin.h
new file mode 100644 (file)
index 0000000..c2077d2
--- /dev/null
@@ -0,0 +1,208 @@
+/* XL compiler Hardware Transactional Memory (HTM) execution intrinsics.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   Contributed by Peter Bergner <bergner@vnet.ibm.com>.
+
+   This file is free software; you can redistribute it and/or modify it under
+   the terms of the GNU General Public License as published by the Free
+   Software Foundation; either version 3 of the License, or (at your option)
+   any later version.
+
+   This file is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+   for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef __HTM__
+# error "HTM instruction set not enabled"
+#endif /* __HTM__ */
+
+#ifndef _HTMXLINTRIN_H
+#define _HTMXLINTRIN_H
+
+#include <stdint.h>
+#include <htmintrin.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _TEXASR_PTR(TM_BUF) \
+  ((texasr_t *)((TM_BUF)+0))
+#define _TEXASRU_PTR(TM_BUF) \
+  ((texasru_t *)((TM_BUF)+0))
+#define _TEXASRL_PTR(TM_BUF) \
+  ((texasrl_t *)((TM_BUF)+4))
+#define _TFIAR_PTR(TM_BUF) \
+  ((tfiar_t *)((TM_BUF)+8))
+
+typedef char TM_buff_type[16];
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_simple_begin (void)
+{
+  if (__builtin_expect (__builtin_tbegin (0), 1))
+    return 1;
+  return 0;
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_begin (void* const TM_buff)
+{
+  *_TEXASRL_PTR (TM_buff) = 0;
+  if (__builtin_expect (__builtin_tbegin (0), 1))
+    return 1;
+#ifdef __powerpc64__
+  *_TEXASR_PTR (TM_buff) = __builtin_get_texasr ();
+#else
+  *_TEXASRU_PTR (TM_buff) = __builtin_get_texasru ();
+  *_TEXASRL_PTR (TM_buff) = __builtin_get_texasr ();
+#endif
+  *_TFIAR_PTR (TM_buff) = __builtin_get_tfiar ();
+  return 0;
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_end (void)
+{
+  if (__builtin_expect (__builtin_tend (0), 1))
+    return 1;
+  return 0;
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_abort (void)
+{
+  __builtin_tabort (0);
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_named_abort (unsigned char const code)
+{
+  __builtin_tabort (code);
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_resume (void)
+{
+  __builtin_tresume ();
+}
+
+extern __inline void
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_suspend (void)
+{
+  __builtin_tsuspend ();
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_is_user_abort (void* const TM_buff)
+{
+  texasru_t texasru = *_TEXASRU_PTR (TM_buff);
+  return _TEXASRU_ABORT (texasru);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_is_named_user_abort (void* const TM_buff, unsigned char *code)
+{
+  texasru_t texasru = *_TEXASRU_PTR (TM_buff);
+
+  *code = _TEXASRU_FAILURE_CODE (texasru);
+  return _TEXASRU_ABORT (texasru);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_is_illegal (void* const TM_buff)
+{
+  texasru_t texasru = *_TEXASRU_PTR (TM_buff);
+  return _TEXASRU_DISALLOWED (texasru);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_is_footprint_exceeded (void* const TM_buff)
+{
+  texasru_t texasru = *_TEXASRU_PTR (TM_buff);
+  return _TEXASRU_FOOTPRINT_OVERFLOW (texasru);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_nesting_depth (void* const TM_buff)
+{
+  texasrl_t texasrl;
+
+  if (_HTM_STATE (__builtin_ttest ()) == _HTM_NONTRANSACTIONAL)
+    {
+      texasrl = *_TEXASRL_PTR (TM_buff);
+      if (!_TEXASR_FAILURE_SUMMARY (texasrl))
+        texasrl = 0;
+    }
+  else
+    texasrl = (texasrl_t) __builtin_get_texasr ();
+
+  return _TEXASR_TRANSACTION_LEVEL (texasrl);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_is_nested_too_deep(void* const TM_buff)
+{
+  texasru_t texasru = *_TEXASRU_PTR (TM_buff);
+  return _TEXASRU_NESTING_OVERFLOW (texasru);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_is_conflict(void* const TM_buff)
+{
+  texasru_t texasru = *_TEXASRU_PTR (TM_buff);
+  /* Return TEXASR bits 11 (Self-Induced Conflict) through
+     14 (Translation Invalidation Conflict).  */
+  return (_TEXASRU_EXTRACT_BITS (texasru, 14, 4)) ? 1 : 0;
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_is_failure_persistent(void* const TM_buff)
+{
+  texasru_t texasru = *_TEXASRU_PTR (TM_buff);
+  return _TEXASRU_FAILURE_PERSISTENT (texasru);
+}
+
+extern __inline long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_failure_address(void* const TM_buff)
+{
+  return *_TFIAR_PTR (TM_buff);
+}
+
+extern __inline long long
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+__TM_failure_code(void* const TM_buff)
+{
+  return *_TEXASR_PTR (TM_buff);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _HTMXLINTRIN_H */
index f47967a48aa77e486f41502c8939d57a964adfbe..18912f15a4a9a944c7d7e6990b6f19d3171659ae 100644 (file)
   (and (match_code "const_int")
        (match_test "INTVAL (op) >= -16 && INTVAL (op) <= 15")))
 
+;; Return 1 if op is a unsigned 3-bit constant integer.
+(define_predicate "u3bit_cint_operand"
+  (and (match_code "const_int")
+       (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 7")))
+
 ;; Return 1 if op is a unsigned 5-bit constant integer.
 (define_predicate "u5bit_cint_operand"
   (and (match_code "const_int")
   (and (match_code "const_int")
        (match_test "INTVAL (op) >= -128 && INTVAL (op) <= 127")))
 
+;; Return 1 if op is a unsigned 10-bit constant integer.
+(define_predicate "u10bit_cint_operand"
+  (and (match_code "const_int")
+       (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 1023")))
+
 ;; Return 1 if op is a constant integer that can fit in a D field.
 (define_predicate "short_cint_operand"
   (and (match_code "const_int")
   return (REGNO (op) != FIRST_GPR_REGNO);
 })
 
+;; Return 1 if op is a HTM specific SPR register.
+(define_predicate "htm_spr_reg_operand"
+  (match_operand 0 "register_operand")
+{
+  if (!TARGET_HTM)
+    return 0;
+
+  if (GET_CODE (op) == SUBREG)
+    op = SUBREG_REG (op);
+
+  if (!REG_P (op))
+    return 0;
+
+  switch (REGNO (op))
+    {
+      case TFHAR_REGNO:
+      case TFIAR_REGNO:
+      case TEXASR_REGNO:
+       return 1;
+      default:
+       break;
+    }
+  
+  /* Unknown SPR.  */
+  return 0;
+})
+
 ;; Return 1 if op is a general purpose register that is an even register
 ;; which suitable for a load/store quad operation
 (define_predicate "quad_int_reg_operand"
index 1a5a709751d630530c0db0977dee7bb52bd49b25..672604406d5c2df690233aac3d10e9e02e6c8860 100644 (file)
@@ -30,6 +30,7 @@
    RS6000_BUILTIN_A -- ABS builtins
    RS6000_BUILTIN_D -- DST builtins
    RS6000_BUILTIN_E -- SPE EVSEL builtins.
+   RS6000_BUILTIN_H -- HTM builtins
    RS6000_BUILTIN_P -- Altivec, VSX, ISA 2.07 vector predicate builtins
    RS6000_BUILTIN_Q -- Paired floating point VSX predicate builtins
    RS6000_BUILTIN_S -- SPE predicate builtins
   #error "RS6000_BUILTIN_E is not defined."
 #endif
 
+#ifndef RS6000_BUILTIN_H
+  #error "RS6000_BUILTIN_H is not defined."
+#endif
+
 #ifndef RS6000_BUILTIN_P
   #error "RS6000_BUILTIN_P is not defined."
 #endif
                     | RS6000_BTC_TERNARY),                             \
                    CODE_FOR_nothing)                   /* ICODE */
 
+/* HTM convenience macros.  */
+#define BU_HTM_0(ENUM, NAME, ATTR, ICODE)                              \
+  RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM,              /* ENUM */      \
+                   "__builtin_" NAME,                  /* NAME */      \
+                   RS6000_BTM_HTM,                     /* MASK */      \
+                   RS6000_BTC_ ## ATTR,                /* ATTR */      \
+                   CODE_FOR_ ## ICODE)                 /* ICODE */
+
+#define BU_HTM_1(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),                               \
+                   CODE_FOR_ ## ICODE)                 /* ICODE */
+
+#define BU_HTM_2(ENUM, NAME, ATTR, ICODE)                              \
+  RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM,              /* ENUM */      \
+                   "__builtin_" NAME,                  /* NAME */      \
+                   RS6000_BTM_HTM,                     /* MASK */      \
+                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
+                    | RS6000_BTC_BINARY),                              \
+                   CODE_FOR_ ## ICODE)                 /* ICODE */
+
+#define BU_HTM_3(ENUM, NAME, ATTR, ICODE)                              \
+  RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM,              /* ENUM */      \
+                   "__builtin_" NAME,                  /* NAME */      \
+                   RS6000_BTM_HTM,                     /* MASK */      \
+                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
+                    | 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)                           \
+  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 */
+
 /* SPE convenience macros.  */
 #define BU_SPE_1(ENUM, NAME, ATTR, ICODE)                              \
   RS6000_BUILTIN_1 (SPE_BUILTIN_ ## ENUM,              /* ENUM */      \
@@ -1366,6 +1421,33 @@ BU_CRYPTO_OVERLOAD_2 (VPMSUM,     "vpmsum")
 BU_CRYPTO_OVERLOAD_3 (VPERMXOR,         "vpermxor")
 BU_CRYPTO_OVERLOAD_3 (VSHASIGMA, "vshasigma")
 
+\f
+/* 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)
+
 \f
 /* 3 argument paired floating point builtins.  */
 BU_PAIRED_3 (MSUB,            "msub",           FP,    fmsv2sf4)
@@ -1665,10 +1747,10 @@ BU_SPECIAL_X (RS6000_BUILTIN_RSQRTF, "__builtin_rsqrtf", RS6000_BTM_FRSQRTES,
              RS6000_BTC_FP)
 
 BU_SPECIAL_X (RS6000_BUILTIN_GET_TB, "__builtin_ppc_get_timebase",
-            RS6000_BTM_ALWAYS, RS6000_BTC_MISC)
+             RS6000_BTM_ALWAYS, RS6000_BTC_MISC)
 
 BU_SPECIAL_X (RS6000_BUILTIN_MFTB, "__builtin_ppc_mftb",
-            RS6000_BTM_ALWAYS, RS6000_BTC_MISC)
+             RS6000_BTM_ALWAYS, RS6000_BTC_MISC)
 
 /* Darwin CfString builtin.  */
 BU_SPECIAL_X (RS6000_BUILTIN_CFSTRING, "__builtin_cfstring", RS6000_BTM_ALWAYS,
index 593b772ebd13f67635790ad445a041d2fe35879a..d58e6865193e65e5b62bb64648c5e183d3bca4d0 100644 (file)
@@ -333,6 +333,8 @@ rs6000_target_modify_macros (bool define_p, HOST_WIDE_INT flags,
     }
   if ((flags & OPTION_MASK_VSX) != 0)
     rs6000_define_or_undefine_macro (define_p, "__VSX__");
+  if ((flags & OPTION_MASK_HTM) != 0)
+    rs6000_define_or_undefine_macro (define_p, "__HTM__");
   if ((flags & OPTION_MASK_P8_VECTOR) != 0)
     rs6000_define_or_undefine_macro (define_p, "__POWER8_VECTOR__");
   if ((flags & OPTION_MASK_CRYPTO) != 0)
index 08346b61d17e65c889ab4301707f624376292870..c177512ddfdcb536dfb6ad0e9112d548d3cd0027 100644 (file)
@@ -51,6 +51,7 @@
                                 | OPTION_MASK_P8_VECTOR                \
                                 | OPTION_MASK_CRYPTO                   \
                                 | OPTION_MASK_DIRECT_MOVE              \
+                                | OPTION_MASK_HTM                      \
                                 | OPTION_MASK_QUAD_MEMORY)
 
 #define POWERPC_7400_MASK      (OPTION_MASK_PPC_GFXOPT | OPTION_MASK_ALTIVEC)
@@ -74,6 +75,7 @@
                                 | OPTION_MASK_DIRECT_MOVE              \
                                 | OPTION_MASK_DLMZB                    \
                                 | OPTION_MASK_FPRND                    \
+                                | OPTION_MASK_HTM                      \
                                 | OPTION_MASK_ISEL                     \
                                 | OPTION_MASK_MFCRF                    \
                                 | OPTION_MASK_MFPGPR                   \
index aabef7f703c128756ac1888ba797eb5b06b892ae..742a530effa464e431db6b3f589150b62bae245f 100644 (file)
@@ -910,6 +910,7 @@ struct processor_costs ppca2_cost = {
 #undef RS6000_BUILTIN_A
 #undef RS6000_BUILTIN_D
 #undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
 #undef RS6000_BUILTIN_P
 #undef RS6000_BUILTIN_Q
 #undef RS6000_BUILTIN_S
@@ -933,6 +934,9 @@ struct processor_costs ppca2_cost = {
 #define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)  \
   { NAME, ICODE, MASK, ATTR },
 
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)  \
+  { NAME, ICODE, MASK, ATTR },
+
 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)  \
   { NAME, ICODE, MASK, ATTR },
 
@@ -963,6 +967,7 @@ static const struct rs6000_builtin_info_type rs6000_builtin_info[] =
 #undef RS6000_BUILTIN_A
 #undef RS6000_BUILTIN_D
 #undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
 #undef RS6000_BUILTIN_P
 #undef RS6000_BUILTIN_Q
 #undef RS6000_BUILTIN_S
@@ -1003,6 +1008,7 @@ static void rs6000_common_init_builtins (void);
 static void paired_init_builtins (void);
 static rtx paired_expand_predicate_builtin (enum insn_code, tree, rtx);
 static void spe_init_builtins (void);
+static void htm_init_builtins (void);
 static rtx spe_expand_predicate_builtin (enum insn_code, tree, rtx);
 static rtx spe_expand_evsel_builtin (enum insn_code, tree, rtx);
 static int rs6000_emit_int_cmove (rtx, rtx, rtx, rtx);
@@ -1130,7 +1136,9 @@ char rs6000_reg_names[][8] =
       /* SPE registers.  */
       "spe_acc", "spefscr",
       /* Soft frame pointer.  */
-      "sfp"
+      "sfp",
+      /* HTM SPR registers.  */
+      "tfhar", "tfiar", "texasr"
 };
 
 #ifdef TARGET_REGNAMES
@@ -1156,7 +1164,9 @@ static const char alt_reg_names[][8] =
   /* SPE registers.  */
   "spe_acc", "spefscr",
   /* Soft frame pointer.  */
-  "sfp"
+  "sfp",
+  /* HTM SPR registers.  */
+  "tfhar", "tfiar", "texasr"
 };
 #endif
 
@@ -2190,6 +2200,9 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
   rs6000_regno_regclass[VSCR_REGNO] = VRSAVE_REGS;
   rs6000_regno_regclass[SPE_ACC_REGNO] = SPE_ACC_REGS;
   rs6000_regno_regclass[SPEFSCR_REGNO] = SPEFSCR_REGS;
+  rs6000_regno_regclass[TFHAR_REGNO] = SPR_REGS;
+  rs6000_regno_regclass[TFIAR_REGNO] = SPR_REGS;
+  rs6000_regno_regclass[TEXASR_REGNO] = SPR_REGS;
   rs6000_regno_regclass[ARG_POINTER_REGNUM] = BASE_REGS;
   rs6000_regno_regclass[FRAME_POINTER_REGNUM] = BASE_REGS;
 
@@ -2711,7 +2724,8 @@ rs6000_builtin_mask_calculate (void)
          | ((TARGET_POPCNTD)               ? RS6000_BTM_POPCNTD   : 0)
          | ((rs6000_cpu == PROCESSOR_CELL) ? RS6000_BTM_CELL      : 0)
          | ((TARGET_P8_VECTOR)             ? RS6000_BTM_P8_VECTOR : 0)
-         | ((TARGET_CRYPTO)                ? RS6000_BTM_CRYPTO    : 0));
+         | ((TARGET_CRYPTO)                ? RS6000_BTM_CRYPTO    : 0)
+         | ((TARGET_HTM)                   ? RS6000_BTM_HTM       : 0));
 }
 
 /* Override command line options.  Mostly we process the processor type and
@@ -2985,7 +2999,7 @@ rs6000_option_override_internal (bool global_init_p)
 
   /* For the newer switches (vsx, dfp, etc.) set some of the older options,
      unless the user explicitly used the -mno-<option> to disable the code.  */
-  if (TARGET_P8_VECTOR || TARGET_DIRECT_MOVE || TARGET_CRYPTO)
+  if (TARGET_P8_VECTOR || TARGET_DIRECT_MOVE || TARGET_CRYPTO || TARGET_HTM)
     rs6000_isa_flags |= (ISA_2_7_MASKS_SERVER & ~rs6000_isa_flags_explicit);
   else if (TARGET_VSX)
     rs6000_isa_flags |= (ISA_2_6_MASKS_SERVER & ~rs6000_isa_flags_explicit);
@@ -10144,6 +10158,7 @@ def_builtin (const char *name, tree type, enum rs6000_builtins code)
 #undef RS6000_BUILTIN_A
 #undef RS6000_BUILTIN_D
 #undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
 #undef RS6000_BUILTIN_P
 #undef RS6000_BUILTIN_Q
 #undef RS6000_BUILTIN_S
@@ -10157,6 +10172,7 @@ def_builtin (const char *name, tree type, enum rs6000_builtins code)
 #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE)
@@ -10175,6 +10191,7 @@ static const struct builtin_description bdesc_3arg[] =
 #undef RS6000_BUILTIN_A
 #undef RS6000_BUILTIN_D
 #undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
 #undef RS6000_BUILTIN_P
 #undef RS6000_BUILTIN_Q
 #undef RS6000_BUILTIN_S
@@ -10188,6 +10205,7 @@ static const struct builtin_description bdesc_3arg[] =
   { MASK, ICODE, NAME, ENUM },
 
 #define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE)
@@ -10206,6 +10224,7 @@ static const struct builtin_description bdesc_dst[] =
 #undef RS6000_BUILTIN_A
 #undef RS6000_BUILTIN_D
 #undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
 #undef RS6000_BUILTIN_P
 #undef RS6000_BUILTIN_Q
 #undef RS6000_BUILTIN_S
@@ -10219,6 +10238,7 @@ static const struct builtin_description bdesc_dst[] =
 #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE)
@@ -10235,6 +10255,7 @@ static const struct builtin_description bdesc_2arg[] =
 #undef RS6000_BUILTIN_A
 #undef RS6000_BUILTIN_D
 #undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
 #undef RS6000_BUILTIN_P
 #undef RS6000_BUILTIN_Q
 #undef RS6000_BUILTIN_S
@@ -10246,6 +10267,7 @@ static const struct builtin_description bdesc_2arg[] =
 #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) \
   { MASK, ICODE, NAME, ENUM },
 
@@ -10267,6 +10289,7 @@ static const struct builtin_description bdesc_altivec_preds[] =
 #undef RS6000_BUILTIN_A
 #undef RS6000_BUILTIN_D
 #undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
 #undef RS6000_BUILTIN_P
 #undef RS6000_BUILTIN_Q
 #undef RS6000_BUILTIN_S
@@ -10278,6 +10301,7 @@ static const struct builtin_description bdesc_altivec_preds[] =
 #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) \
@@ -10297,6 +10321,7 @@ static const struct builtin_description bdesc_spe_predicates[] =
 #undef RS6000_BUILTIN_A
 #undef RS6000_BUILTIN_D
 #undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
 #undef RS6000_BUILTIN_P
 #undef RS6000_BUILTIN_Q
 #undef RS6000_BUILTIN_S
@@ -10310,6 +10335,7 @@ static const struct builtin_description bdesc_spe_predicates[] =
 #define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) \
   { MASK, ICODE, NAME, ENUM },
 
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE)
@@ -10327,6 +10353,7 @@ static const struct builtin_description bdesc_spe_evsel[] =
 #undef RS6000_BUILTIN_A
 #undef RS6000_BUILTIN_D
 #undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
 #undef RS6000_BUILTIN_P
 #undef RS6000_BUILTIN_Q
 #undef RS6000_BUILTIN_S
@@ -10338,6 +10365,7 @@ static const struct builtin_description bdesc_spe_evsel[] =
 #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) \
   { MASK, ICODE, NAME, ENUM },
@@ -10358,6 +10386,7 @@ static const struct builtin_description bdesc_paired_preds[] =
 #undef RS6000_BUILTIN_A
 #undef RS6000_BUILTIN_D
 #undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
 #undef RS6000_BUILTIN_P
 #undef RS6000_BUILTIN_Q
 #undef RS6000_BUILTIN_S
@@ -10371,6 +10400,7 @@ static const struct builtin_description bdesc_paired_preds[] =
 
 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE)
@@ -10388,8 +10418,9 @@ static const struct builtin_description bdesc_abs[] =
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
 #undef RS6000_BUILTIN_A
-#undef RS6000_BUILTIN_E
 #undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
 #undef RS6000_BUILTIN_P
 #undef RS6000_BUILTIN_Q
 #undef RS6000_BUILTIN_S
@@ -10403,6 +10434,7 @@ static const struct builtin_description bdesc_abs[] =
 #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
 #define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE)
@@ -10413,17 +10445,49 @@ static const struct builtin_description bdesc_1arg[] =
 #include "rs6000-builtin.def"
 };
 
+/* HTM builtins.  */
 #undef RS6000_BUILTIN_1
 #undef RS6000_BUILTIN_2
 #undef RS6000_BUILTIN_3
 #undef RS6000_BUILTIN_A
 #undef RS6000_BUILTIN_D
 #undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
 #undef RS6000_BUILTIN_P
 #undef RS6000_BUILTIN_Q
 #undef RS6000_BUILTIN_S
 #undef RS6000_BUILTIN_X
 
+#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE) \
+  { MASK, ICODE, NAME, ENUM },
+
+#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
+
+static const struct builtin_description bdesc_htm[] =
+{
+#include "rs6000-builtin.def"
+};
+
+#undef RS6000_BUILTIN_1
+#undef RS6000_BUILTIN_2
+#undef RS6000_BUILTIN_3
+#undef RS6000_BUILTIN_A
+#undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
+#undef RS6000_BUILTIN_P
+#undef RS6000_BUILTIN_Q
+#undef RS6000_BUILTIN_S
+
 /* Return true if a builtin function is overloaded.  */
 bool
 rs6000_overloaded_builtin_p (enum rs6000_builtins fncode)
@@ -10893,6 +10957,197 @@ altivec_expand_stv_builtin (enum insn_code icode, tree exp)
   return NULL_RTX;
 }
 
+/* Return the appropriate SPR number associated with the given builtin.  */
+static inline HOST_WIDE_INT
+htm_spr_num (enum rs6000_builtins code)
+{
+  if (code == HTM_BUILTIN_GET_TFHAR
+      || code == HTM_BUILTIN_SET_TFHAR)
+    return TFHAR_SPR;
+  else if (code == HTM_BUILTIN_GET_TFIAR
+          || code == HTM_BUILTIN_SET_TFIAR)
+    return TFIAR_SPR;
+  else if (code == HTM_BUILTIN_GET_TEXASR
+          || code == HTM_BUILTIN_SET_TEXASR)
+    return TEXASR_SPR;
+  gcc_assert (code == HTM_BUILTIN_GET_TEXASRU
+             || code == HTM_BUILTIN_SET_TEXASRU);
+  return TEXASRU_SPR;
+}
+
+/* Return the appropriate SPR regno associated with the given builtin.  */
+static inline HOST_WIDE_INT
+htm_spr_regno (enum rs6000_builtins code)
+{
+  if (code == HTM_BUILTIN_GET_TFHAR
+      || code == HTM_BUILTIN_SET_TFHAR)
+    return TFHAR_REGNO;
+  else if (code == HTM_BUILTIN_GET_TFIAR
+          || code == HTM_BUILTIN_SET_TFIAR)
+    return TFIAR_REGNO;
+  gcc_assert (code == HTM_BUILTIN_GET_TEXASR
+             || code == HTM_BUILTIN_SET_TEXASR
+             || code == HTM_BUILTIN_GET_TEXASRU
+             || code == HTM_BUILTIN_SET_TEXASRU);
+  return TEXASR_REGNO;
+}
+
+/* Return the correct ICODE value depending on whether we are
+   setting or reading the HTM SPRs.  */
+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;
+  else
+    return (TARGET_64BIT) ? CODE_FOR_htm_mtspr_di : CODE_FOR_htm_mtspr_si;
+}
+
+/* Expand the HTM builtin in EXP and store the result in TARGET.
+   Store true in *EXPANDEDP if we found a builtin to expand.  */
+static rtx
+htm_expand_builtin (tree exp, rtx target, bool * expandedp)
+{
+  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
+  bool nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
+  enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+  const struct builtin_description *d;
+  size_t i;
+
+  *expandedp = false;
+
+  /* Expand the HTM builtins.  */
+  d = bdesc_htm;
+  for (i = 0; i < ARRAY_SIZE (bdesc_htm); i++, d++)
+    if (d->code == fcode)
+      {
+       rtx op[MAX_HTM_OPERANDS], pat;
+       int nopnds = 0;
+       tree arg;
+       call_expr_arg_iterator iter;
+       unsigned attr = rs6000_builtin_info[fcode].attr;
+       enum insn_code icode = d->icode;
+
+       if (attr & RS6000_BTC_SPR)
+         icode = rs6000_htm_spr_icode (nonvoid);
+
+       if (nonvoid)
+         {
+           enum machine_mode tmode = insn_data[icode].operand[0].mode;
+           if (!target
+               || GET_MODE (target) != tmode
+               || !(*insn_data[icode].operand[0].predicate) (target, tmode))
+             target = gen_reg_rtx (tmode);
+           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;
+
+         insn_op = &insn_data[icode].operand[nopnds];
+
+         op[nopnds] = expand_normal (arg);
+
+         if (!(*insn_op->predicate) (op[nopnds], insn_op->mode))
+           {
+             if (!strcmp (insn_op->constraint, "n"))
+               {
+                 int arg_num = (nonvoid) ? nopnds : nopnds + 1;
+                 if (!CONST_INT_P (op[nopnds]))
+                   error ("argument %d must be an unsigned literal", arg_num);
+                 else
+                   error ("argument %d is an unsigned literal that is "
+                          "out of range", arg_num);
+                 return const0_rtx;
+               }
+             op[nopnds] = copy_to_mode_reg (insn_op->mode, op[nopnds]);
+           }
+
+         nopnds++;
+       }
+
+       /* Handle the builtins for extended mnemonics.  These accept
+          no arguments, but map to builtins that take arguments.  */
+       switch (fcode)
+         {
+         case HTM_BUILTIN_TENDALL:  /* Alias for: tend. 1  */
+         case HTM_BUILTIN_TRESUME:  /* Alias for: tsr. 1  */
+           op[nopnds++] = GEN_INT (1);
+#ifdef ENABLE_CHECKING
+           attr |= RS6000_BTC_UNARY;
+#endif
+           break;
+         case HTM_BUILTIN_TSUSPEND: /* Alias for: tsr. 0  */
+           op[nopnds++] = GEN_INT (0);
+#ifdef ENABLE_CHECKING
+           attr |= RS6000_BTC_UNARY;
+#endif
+           break;
+         default:
+           break;
+         }
+
+       /* 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)
+         {
+           op[nopnds++] = gen_rtx_CONST_INT (Pmode, htm_spr_num (fcode));
+           op[nopnds++] = gen_rtx_REG (Pmode, htm_spr_regno (fcode));
+         }
+
+#ifdef ENABLE_CHECKING
+       int expected_nopnds = 0;
+       if ((attr & RS6000_BTC_TYPE_MASK) == RS6000_BTC_UNARY)
+         expected_nopnds = 1;
+       else if ((attr & RS6000_BTC_TYPE_MASK) == RS6000_BTC_BINARY)
+         expected_nopnds = 2;
+       else if ((attr & RS6000_BTC_TYPE_MASK) == RS6000_BTC_TERNARY)
+         expected_nopnds = 3;
+       if (!(attr & RS6000_BTC_VOID))
+         expected_nopnds += 1;
+       if (attr & RS6000_BTC_SPR)
+         expected_nopnds += 2;
+
+       gcc_assert (nopnds == expected_nopnds && nopnds <= MAX_HTM_OPERANDS);
+#endif
+
+       switch (nopnds)
+         {
+         case 0:
+           pat = GEN_FCN (icode) (NULL_RTX);
+           break;
+         case 1:
+           pat = GEN_FCN (icode) (op[0]);
+           break;
+         case 2:
+           pat = GEN_FCN (icode) (op[0], op[1]);
+           break;
+         case 3:
+           pat = GEN_FCN (icode) (op[0], op[1], op[2]);
+           break;
+         case 4:
+           pat = GEN_FCN (icode) (op[0], op[1], op[2], op[3]);
+           break;
+         default:
+           gcc_unreachable ();
+         }
+       if (!pat)
+         return NULL_RTX;
+       emit_insn (pat);
+
+       *expandedp = true;
+       if (nonvoid)
+         return target;
+       return const0_rtx;
+      }
+
+  return NULL_RTX;
+}
+
 static rtx
 rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
 {
@@ -11974,6 +12229,8 @@ rs6000_invalid_builtin (enum rs6000_builtins fncode)
     error ("Builtin function %s is only valid for the cell processor", name);
   else if ((fnmask & RS6000_BTM_VSX) != 0)
     error ("Builtin function %s requires the -mvsx option", name);
+  else if ((fnmask & RS6000_BTM_HTM) != 0)
+    error ("Builtin function %s requires the -mhtm option", name);
   else if ((fnmask & RS6000_BTM_ALTIVEC) != 0)
     error ("Builtin function %s requires the -maltivec option", name);
   else if ((fnmask & RS6000_BTM_PAIRED) != 0)
@@ -12150,6 +12407,13 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
     {
       ret = paired_expand_builtin (exp, target, &success);
 
+      if (success)
+       return ret;
+    }  
+  if (TARGET_HTM)
+    {
+      ret = htm_expand_builtin (exp, target, &success);
+
       if (success)
        return ret;
     }  
@@ -12335,6 +12599,9 @@ rs6000_init_builtins (void)
     spe_init_builtins ();
   if (TARGET_EXTRA_BUILTINS)
     altivec_init_builtins ();
+  if (TARGET_HTM)
+    htm_init_builtins ();
+
   if (TARGET_EXTRA_BUILTINS || TARGET_SPE || TARGET_PAIRED_FLOAT)
     rs6000_common_init_builtins ();
 
@@ -13074,6 +13341,79 @@ altivec_init_builtins (void)
   def_builtin ("__builtin_vec_ext_v2di", ftype, VSX_BUILTIN_VEC_EXT_V2DI);
 }
 
+static void
+htm_init_builtins (void)
+{
+  HOST_WIDE_INT builtin_mask = rs6000_builtin_mask;
+  const struct builtin_description *d;
+  size_t i;
+
+  d = bdesc_htm;
+  for (i = 0; i < ARRAY_SIZE (bdesc_htm); i++, d++)
+    {
+      tree op[MAX_HTM_OPERANDS], type;
+      HOST_WIDE_INT mask = d->mask;
+      unsigned attr = rs6000_builtin_info[d->code].attr;
+      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;
+
+      if ((mask & builtin_mask) != mask)
+       {
+         if (TARGET_DEBUG_BUILTIN)
+           fprintf (stderr, "htm_builtin, skip binary %s\n", d->name);
+         continue;
+       }
+
+      if (d->name == 0)
+       {
+         if (TARGET_DEBUG_BUILTIN)
+           fprintf (stderr, "htm_builtin, bdesc_htm[%ld] no name\n",
+                    (long unsigned) i);
+         continue;
+       }
+
+      op[nopnds++] = (void_func) ? void_type_node : argtype;
+
+      if (attr_args == RS6000_BTC_UNARY)
+       op[nopnds++] = argtype;
+      else if (attr_args == RS6000_BTC_BINARY)
+       {
+         op[nopnds++] = argtype;
+         op[nopnds++] = argtype;
+       }
+      else if (attr_args == RS6000_BTC_TERNARY)
+       {
+         op[nopnds++] = argtype;
+         op[nopnds++] = argtype;
+         op[nopnds++] = argtype;
+       }
+
+      switch (nopnds)
+       {
+       case 1:
+         type = build_function_type_list (op[0], NULL_TREE);
+         break;
+       case 2:
+         type = build_function_type_list (op[0], op[1], NULL_TREE);
+         break;
+       case 3:
+         type = build_function_type_list (op[0], op[1], op[2], NULL_TREE);
+         break;
+       case 4:
+         type = build_function_type_list (op[0], op[1], op[2], op[3],
+                                          NULL_TREE);
+         break;
+       default:
+         gcc_unreachable ();
+       }
+
+      def_builtin (d->name, type, d->code);
+    }
+}
+
 /* Hash function for builtin functions with up to 3 arguments and a return
    type.  */
 static unsigned
@@ -28777,6 +29117,7 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] =
   { "dlmzb",                   OPTION_MASK_DLMZB,              false, true  },
   { "fprnd",                   OPTION_MASK_FPRND,              false, true  },
   { "hard-dfp",                        OPTION_MASK_DFP,                false, true  },
+  { "htm",                     OPTION_MASK_HTM,                false, true  },
   { "isel",                    OPTION_MASK_ISEL,               false, true  },
   { "mfcrf",                   OPTION_MASK_MFCRF,              false, true  },
   { "mfpgpr",                  OPTION_MASK_MFPGPR,             false, true  },
@@ -28836,6 +29177,7 @@ static struct rs6000_opt_mask const rs6000_builtin_mask_names[] =
   { "cell",             RS6000_BTM_CELL,       false, false },
   { "power8-vector",    RS6000_BTM_P8_VECTOR,  false, false },
   { "crypto",           RS6000_BTM_CRYPTO,     false, false },
+  { "htm",              RS6000_BTM_HTM,        false, false },
 };
 
 /* Option variables that we want to support inside attribute((target)) and
index 98a44aa32e19f62a3174215c83b9072873659f72..6e2d9166f33eafeb4b3fb0c925c8e5f27e81616e 100644 (file)
 %{mcpu=e6500: -me6500} \
 %{maltivec: -maltivec} \
 %{mvsx: -mvsx %{!maltivec: -maltivec} %{!mcpu*: %(asm_cpu_power7)}} \
-%{mpower8-vector|mcrypto|mdirect-move: %{!mcpu*: %(asm_cpu_power8)}} \
+%{mpower8-vector|mcrypto|mdirect-move|mhtm: %{!mcpu*: %(asm_cpu_power8)}} \
 -many"
 
 #define CPP_DEFAULT_SPEC ""
@@ -285,9 +285,11 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 #ifndef HAVE_AS_POWER8
 #undef  TARGET_DIRECT_MOVE
 #undef  TARGET_CRYPTO
+#undef  TARGET_HTM
 #undef  TARGET_P8_VECTOR
 #define TARGET_DIRECT_MOVE 0
 #define TARGET_CRYPTO 0
+#define TARGET_HTM 0
 #define TARGET_P8_VECTOR 0
 #endif
 
@@ -543,6 +545,7 @@ extern int rs6000_vector_align[];
 #define MASK_FPRND                     OPTION_MASK_FPRND
 #define MASK_P8_FUSION                 OPTION_MASK_P8_FUSION
 #define MASK_HARD_FLOAT                        OPTION_MASK_HARD_FLOAT
+#define MASK_HTM                       OPTION_MASK_HTM
 #define MASK_ISEL                      OPTION_MASK_ISEL
 #define MASK_MFCRF                     OPTION_MASK_MFCRF
 #define MASK_MFPGPR                    OPTION_MASK_MFPGPR
@@ -891,7 +894,7 @@ enum data_align { align_abi, align_opt, align_both };
    Another pseudo (not included in DWARF_FRAME_REGISTERS) is soft frame
    pointer, which is eventually eliminated in favor of SP or FP.  */
 
-#define FIRST_PSEUDO_REGISTER 114
+#define FIRST_PSEUDO_REGISTER 117
 
 /* This must be included for pre gcc 3.0 glibc compatibility.  */
 #define PRE_GCC3_DWARF_FRAME_REGISTERS 77
@@ -953,7 +956,7 @@ enum data_align { align_abi, align_opt, align_both };
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
    1, 1                                                   \
-   , 1, 1, 1                                       \
+   , 1, 1, 1, 1, 1, 1                             \
 }
 
 /* 1 for registers not available across function calls.
@@ -973,7 +976,7 @@ enum data_align { align_abi, align_opt, align_both };
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
    1, 1                                                   \
-   , 1, 1, 1                                       \
+   , 1, 1, 1, 1, 1, 1                             \
 }
 
 /* Like `CALL_USED_REGISTERS' except this macro doesn't require that
@@ -992,7 +995,7 @@ enum data_align { align_abi, align_opt, align_both };
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
    0, 0                                                   \
-   , 0, 0, 0                                       \
+   , 0, 0, 0, 0, 0, 0                             \
 }
 
 #define TOTAL_ALTIVEC_REGS     (LAST_ALTIVEC_REGNO - FIRST_ALTIVEC_REGNO + 1)
@@ -1031,6 +1034,9 @@ enum data_align { align_abi, align_opt, align_both };
        vrsave, vscr    (fixed)
        spe_acc, spefscr (fixed)
        sfp             (fixed)
+       tfhar           (fixed)
+       tfiar           (fixed)
+       texasr          (fixed)
 */
 
 #if FIXED_R2 == 1
@@ -1072,7 +1078,7 @@ enum data_align { align_abi, align_opt, align_both };
    96, 95, 94, 93, 92, 91,                                     \
    108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97,    \
    109, 110,                                                   \
-   111, 112, 113                                               \
+   111, 112, 113, 114, 115, 116                                        \
 }
 
 /* True if register is floating-point.  */
@@ -1299,6 +1305,7 @@ enum reg_class
   VSCR_REGS,
   SPE_ACC_REGS,
   SPEFSCR_REGS,
+  SPR_REGS,
   NON_SPECIAL_REGS,
   LINK_REGS,
   CTR_REGS,
@@ -1329,6 +1336,7 @@ enum reg_class
   "VSCR_REGS",                                                         \
   "SPE_ACC_REGS",                                                       \
   "SPEFSCR_REGS",                                                       \
+  "SPR_REGS",                                                          \
   "NON_SPECIAL_REGS",                                                  \
   "LINK_REGS",                                                         \
   "CTR_REGS",                                                          \
@@ -1358,6 +1366,7 @@ enum reg_class
   { 0x00000000, 0x00000000, 0x00000000, 0x00004000 }, /* VSCR_REGS */       \
   { 0x00000000, 0x00000000, 0x00000000, 0x00008000 }, /* SPE_ACC_REGS */     \
   { 0x00000000, 0x00000000, 0x00000000, 0x00010000 }, /* SPEFSCR_REGS */     \
+  { 0x00000000, 0x00000000, 0x00000000, 0x00040000 }, /* SPR_REGS */     \
   { 0xffffffff, 0xffffffff, 0x00000008, 0x00020000 }, /* NON_SPECIAL_REGS */ \
   { 0x00000000, 0x00000000, 0x00000002, 0x00000000 }, /* LINK_REGS */       \
   { 0x00000000, 0x00000000, 0x00000004, 0x00000000 }, /* CTR_REGS */        \
@@ -1368,7 +1377,7 @@ enum reg_class
   { 0x00000000, 0x00000000, 0x00000ff0, 0x00000000 }, /* CR_REGS */         \
   { 0xffffffff, 0x00000000, 0x00000ffe, 0x00020000 }, /* NON_FLOAT_REGS */   \
   { 0x00000000, 0x00000000, 0x00001000, 0x00000000 }, /* CA_REGS */         \
-  { 0xffffffff, 0xffffffff, 0xfffffffe, 0x0003ffff }  /* ALL_REGS */        \
+  { 0xffffffff, 0xffffffff, 0xfffffffe, 0x0007ffff }  /* ALL_REGS */        \
 }
 
 /* The same information, inverted:
@@ -2282,6 +2291,9 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0).  */
   &rs6000_reg_names[111][0],   /* spe_acc */                           \
   &rs6000_reg_names[112][0],   /* spefscr */                           \
   &rs6000_reg_names[113][0],   /* sfp  */                              \
+  &rs6000_reg_names[114][0],   /* tfhar  */                            \
+  &rs6000_reg_names[115][0],   /* tfiar  */                            \
+  &rs6000_reg_names[116][0],   /* texasr  */                           \
 }
 
 /* Table of additional register names to use in user input.  */
@@ -2335,7 +2347,9 @@ extern char rs6000_reg_names[][8];        /* register names (0 vs. %r0).  */
   {"vs48", 93}, {"vs49", 94}, {"vs50", 95}, {"vs51", 96},       \
   {"vs52", 97}, {"vs53", 98}, {"vs54", 99}, {"vs55", 100},     \
   {"vs56", 101},{"vs57", 102},{"vs58", 103},{"vs59", 104},      \
-  {"vs60", 105},{"vs61", 106},{"vs62", 107},{"vs63", 108} }
+  {"vs60", 105},{"vs61", 106},{"vs62", 107},{"vs63", 108},     \
+  /* Transactional Memory Facility (HTM) Registers.  */                \
+  {"tfhar",  114}, {"tfiar",  115}, {"texasr",  116} }
 
 /* This is how to output an element of a case-vector that is relative.  */
 
@@ -2424,7 +2438,12 @@ extern int frame_pointer_needed;
 #define RS6000_BTC_ATTR_MASK   0x00000700      /* Mask of the attributes.  */
 
 /* Miscellaneous information.  */
-#define RS6000_BTC_OVERLOADED  0x4000000       /* function is overloaded.  */
+#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_MISC_MASK   0x1f000000      /* Mask of the misc info.  */
 
 /* Convenience macros to document the instruction type.  */
 #define RS6000_BTC_MEM         RS6000_BTC_MISC /* load/store touches mem.  */
@@ -2438,6 +2457,7 @@ extern int frame_pointer_needed;
 #define RS6000_BTM_VSX         MASK_VSX        /* VSX (vector/scalar).  */
 #define RS6000_BTM_P8_VECTOR   MASK_P8_VECTOR  /* ISA 2.07 vector.  */
 #define RS6000_BTM_CRYPTO      MASK_CRYPTO     /* crypto funcs.  */
+#define RS6000_BTM_HTM         MASK_HTM        /* hardware TM funcs.  */
 #define RS6000_BTM_SPE         MASK_STRING     /* E500 */
 #define RS6000_BTM_PAIRED      MASK_MULHW      /* 750CL paired insns.  */
 #define RS6000_BTM_FRE         MASK_POPCNTB    /* FRE instruction.  */
@@ -2455,6 +2475,7 @@ extern int frame_pointer_needed;
                                 | RS6000_BTM_FRES                      \
                                 | RS6000_BTM_FRSQRTE                   \
                                 | RS6000_BTM_FRSQRTES                  \
+                                | RS6000_BTM_HTM                       \
                                 | RS6000_BTM_POPCNTD                   \
                                 | RS6000_BTM_CELL)
 
@@ -2466,6 +2487,7 @@ extern int frame_pointer_needed;
 #undef RS6000_BUILTIN_A
 #undef RS6000_BUILTIN_D
 #undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
 #undef RS6000_BUILTIN_P
 #undef RS6000_BUILTIN_Q
 #undef RS6000_BUILTIN_S
@@ -2477,6 +2499,7 @@ extern int frame_pointer_needed;
 #define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
 #define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
 #define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
 #define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
 #define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
 #define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
@@ -2495,6 +2518,7 @@ enum rs6000_builtins
 #undef RS6000_BUILTIN_A
 #undef RS6000_BUILTIN_D
 #undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
 #undef RS6000_BUILTIN_P
 #undef RS6000_BUILTIN_Q
 #undef RS6000_BUILTIN_S
index 731cfae930aa05fdbd4487e76f080b7c7adf775c..372c8138fc6b74d7bc14cc1d07cda5416a4f3c98 100644 (file)
@@ -53,6 +53,9 @@
    (SPE_ACC_REGNO              111)
    (SPEFSCR_REGNO              112)
    (FRAME_POINTER_REGNUM       113)
+   (TFHAR_REGNO                        114)
+   (TFIAR_REGNO                        115)
+   (TEXASR_REGNO               116)
 
    ; ABI defined stack offsets for storing the TOC pointer with AIX calls.
    (TOC_SAVE_OFFSET_32BIT      20)
 \f
 ;; Define an insn type attribute.  This is used in function unit delay
 ;; computations.
-(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,var_delayed_compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,vecdouble,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr,isel,popcnt,crypto"
+(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,var_delayed_compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,vecdouble,isync,sync,load_l,store_c,shift,trap,insert_dword,var_shift_rotate,cntlz,exts,mffgpr,mftgpr,isel,popcnt,crypto,htm"
   (const_string "integer"))
 
 ;; Define floating point instruction sub-types for use with Xfpu.md
 (include "dfp.md")
 (include "paired.md")
 (include "crypto.md")
+(include "htm.md")
index 9a0781981306e93095cc28dba719108393393245..f36e47580314ceafc6f95bc059583625a648598f 100644 (file)
@@ -539,6 +539,10 @@ mdirect-move
 Target Report Mask(DIRECT_MOVE) Var(rs6000_isa_flags)
 Use ISA 2.07 direct move between GPR & VSX register instructions
 
+mhtm
+Target Report Mask(HTM) Var(rs6000_isa_flags)
+Use ISA 2.07 transactional memory (HTM) instructions
+
 mquad-memory
 Target Report Mask(QUAD_MEMORY) Var(rs6000_isa_flags)
 Generate the quad word memory instructions (lq/stq/lqarx/stqcx).
index 5889d6d82d4261c02bce290285ae2455bd2d61b4..81372dfb140322ae5cc582c67c668389201d8740 100644 (file)
@@ -72,6 +72,7 @@ MD_INCLUDES = $(srcdir)/config/rs6000/rs64.md \
        $(srcdir)/config/rs6000/vsx.md \
        $(srcdir)/config/rs6000/altivec.md \
        $(srcdir)/config/rs6000/crypto.md \
+       $(srcdir)/config/rs6000/htm.md \
        $(srcdir)/config/rs6000/spe.md \
        $(srcdir)/config/rs6000/dfp.md \
        $(srcdir)/config/rs6000/paired.md
index 3ec449ade4197933ea46b5006721d4e8b5829899..817d2dcc4d0cef5ec469491f36aac83c6c3ded23 100644 (file)
@@ -1,3 +1,10 @@
+2013-07-15  Peter Bergner  <bergner@vnet.ibm.com>
+
+       * lib/target-supports.exp (check_effective_target_powerpc_htm_ok): New
+       function to test if HTM is available.
+       * gcc.target/powerpc/htm-xl-intrin-1.c: New test.
+       * gcc.target/powerpc/htm-builtin-1.c: New test.
+
 2013-07-15  Tobias Burnus  <burnus@net-b.de>
 
        * gfortran.dg/coarray_lib_realloc_1.f90: New.
diff --git a/gcc/testsuite/gcc.target/powerpc/htm-builtin-1.c b/gcc/testsuite/gcc.target/powerpc/htm-builtin-1.c
new file mode 100644 (file)
index 0000000..e58816a
--- /dev/null
@@ -0,0 +1,51 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_htm_ok } */
+/* { dg-options "-O2 -mhtm" } */
+
+/* { 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 "tabortwc\\." 1 } } */
+/* { dg-final { scan-assembler-times "tabortwci\\." 2 } } */
+/* { dg-final { scan-assembler-times "tcheck\\." 1 } } */
+/* { dg-final { scan-assembler-times "trechkpt\\." 1 } } */
+/* { dg-final { scan-assembler-times "treclaim\\." 1 } } */
+/* { dg-final { scan-assembler-times "tsr\\." 3 } } */
+/* { dg-final { scan-assembler-times "mfspr" 4 } } */
+/* { dg-final { scan-assembler-times "mtspr" 4 } } */
+
+void use_builtins (long *p, char code, long *a, long *b)
+{
+  p[0] = __builtin_tbegin (0);
+  p[1] = __builtin_tend (0);
+  p[2] = __builtin_tendall ();
+  p[3] = __builtin_tabort (0);
+  p[4] = __builtin_tabort (code);
+
+  p[5] = __builtin_tabortdc (0xf, a[5], b[5]);
+  p[6] = __builtin_tabortdci (0xf, a[6], 13);
+  p[7] = __builtin_tabortwc (0xf, a[7], b[7]);
+  p[8] = __builtin_tabortwci (0xf, a[8], 13);
+
+  p[9] = __builtin_tcheck (5);
+  p[10] = __builtin_trechkpt ();
+  p[11] = __builtin_treclaim (0);
+  p[12] = __builtin_tresume ();
+  p[13] = __builtin_tsuspend ();
+  p[14] = __builtin_tsr (0);
+  p[15] = __builtin_ttest (); /* This expands to a tabortwci.  */
+
+
+  p[16] = __builtin_get_texasr ();
+  p[17] = __builtin_get_texasru ();
+  p[18] = __builtin_get_tfhar ();
+  p[19] = __builtin_get_tfiar ();
+
+  __builtin_set_texasr (a[20]);
+  __builtin_set_texasru (a[21]);
+  __builtin_set_tfhar (a[22]);
+  __builtin_set_tfiar (a[23]);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/htm-xl-intrin-1.c b/gcc/testsuite/gcc.target/powerpc/htm-xl-intrin-1.c
new file mode 100644 (file)
index 0000000..5e92814
--- /dev/null
@@ -0,0 +1,32 @@
+/* This checks the availability of the XL compiler intrinsics for
+   transactional execution with the expected prototypes.  */
+
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_htm_ok } */
+/* { dg-options "-O2 -mhtm" } */
+
+#include <htmxlintrin.h>
+
+void
+foo (void *TM_buff, long *result, unsigned char *code)
+{
+  *result++ = __TM_simple_begin ();
+  *result++ = __TM_begin (TM_buff);
+  *result++ = __TM_end ();
+  __TM_abort ();
+  __TM_named_abort (*code);
+  __TM_resume ();
+  __TM_suspend ();
+  *result++ = __TM_is_user_abort (TM_buff);
+  *result++ = __TM_is_named_user_abort (TM_buff, code);
+  *result++ = __TM_is_illegal (TM_buff);
+  *result++ = __TM_is_footprint_exceeded (TM_buff);
+  *result++ = __TM_nesting_depth (TM_buff);
+  *result++ = __TM_is_nested_too_deep (TM_buff);
+  *result++ = __TM_is_conflict (TM_buff);
+  *result++ = __TM_is_failure_persistent (TM_buff);
+  *result++ = __TM_failure_address (TM_buff);
+  *result++ = __TM_failure_code (TM_buff);
+}
+
index c7936119b312aada5024ec69a480fc605b43e7fa..936c97af9067f484a889a216a3cdff8efb3bace5 100644 (file)
@@ -2839,6 +2839,27 @@ proc check_effective_target_powerpc_vsx_ok { } {
     }
 }
 
+# Return 1 if this is a PowerPC target supporting -mhtm
+
+proc check_effective_target_powerpc_htm_ok { } {
+    if { ([istarget powerpc*-*-*]
+         && ![istarget powerpc-*-linux*paired*])
+        || [istarget rs6000-*-*] } {
+       # HTM is not supported on AIX yet.
+       if { [istarget powerpc*-*-aix*] } {
+           return 0
+       }
+       return [check_no_compiler_messages powerpc_htm_ok object {
+           int main (void) {
+               asm volatile ("tbegin. 0");
+               return 0;
+           }
+       } "-mhtm"]
+    } else {
+       return 0
+    }
+}
+
 # Return 1 if this is a PowerPC target supporting -mcpu=cell.
 
 proc check_effective_target_powerpc_ppu_ok { } {
index 27474d7b348e763e629ddb772c5d43e50ac3d3dc..6b8ac0be157de4b47bd603aa5f2f8f15d06c5f14 100644 (file)
@@ -1,3 +1,18 @@
+2013-07-15  Peter Bergner  <bergner@vnet.ibm.com>
+
+       * acinclude.m4 (LIBITM_CHECK_AS_HTM): New.
+       * configure.ac: Use it.
+       (AC_CHECK_HEADERS): Check for sys/auxv.h.
+       (AC_CHECK_FUNCS): Check for getauxval.
+       * config.h.in, configure: Rebuild.
+       * configure.tgt (target_cpu): Add -mhtm to XCFLAGS.
+       * config/powerpc/target.h: Include sys/auxv.h and htmintrin.h.
+       (USE_HTM_FASTPATH): Define.
+       (_TBEGIN_STARTED, _TBEGIN_INDETERMINATE, _TBEGIN_PERSISTENT,
+       _HTM_RETRIES) New macros.
+       (htm_abort, htm_abort_should_retry, htm_available, htm_begin, htm_init,
+       htm_begin_success, htm_commit, htm_transaction_active): New functions.
+
 2013-06-27  Andreas Krebbel  <Andreas.Krebbel@de.ibm.com>
 
        * config/s390/target.h: Include htmintrin.h.
index fe32fe3e4a032b52fe3b01bb1d93adfb7a037702..eacf8d4538310c70e3291b948c72619eb7026039 100644 (file)
@@ -123,6 +123,20 @@ i[[34567]]86 | x86_64)
   ;;
 esac])
 
+dnl Check if as supports HTM instructions.
+AC_DEFUN([LIBITM_CHECK_AS_HTM], [
+case "${target_cpu}" in
+powerpc*)
+  AC_CACHE_CHECK([if the assembler supports HTM], libitm_cv_as_htm, [
+    AC_TRY_COMPILE([], [asm("tbegin. 0; tend. 0");],
+                  [libitm_cv_as_htm=yes], [libitm_cv_as_htm=no])
+  ])
+  if test x$libitm_cv_as_htm = xyes; then
+    AC_DEFINE(HAVE_AS_HTM, 1, [Define to 1 if the assembler supports HTM.])
+  fi
+  ;;
+esac])
+
 sinclude(../libtool.m4)
 dnl The lines below arrange for aclocal not to bring an installed
 dnl libtool.m4 into aclocal.m4, while still arranging for automake to
index 10de95ba02a3cef3d2d27e7e9f567a423a6fbde9..26972c7e43e5b5ccb858001e49efd618057e8ca8 100644 (file)
@@ -12,6 +12,9 @@
 /* Define if your assembler supports .cfi_* directives. */
 #undef HAVE_AS_CFI_PSEUDO_OP
 
+/* Define to 1 if the assembler supports HTM. */
+#undef HAVE_AS_HTM
+
 /* Define to 1 if the assembler supports RTM. */
 #undef HAVE_AS_RTM
 
@@ -36,6 +39,9 @@
 /* Define to 1 if target has a weakref that works like the ELF one. */
 #undef HAVE_ELF_STYLE_WEAKREF
 
+/* Define to 1 if you have the `getauxval' function. */
+#undef HAVE_GETAUXVAL
+
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
@@ -81,6 +87,9 @@
 /* Define to 1 if the target supports __sync_*_compare_and_swap */
 #undef HAVE_SYNC_BUILTINS
 
+/* Define to 1 if you have the <sys/auxv.h> header file. */
+#undef HAVE_SYS_AUXV_H
+
 /* Define to 1 if you have the <sys/stat.h> header file. */
 #undef HAVE_SYS_STAT_H
 
index 67c02188452a0d1eed2a5dcc616a668003eebf1f..cf01a57248d08072de82e4f0f69bfabd74d16b19 100644 (file)
    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
+#ifdef HAVE_SYS_AUXV_H
+#include <sys/auxv.h>
+#endif
+
 namespace GTM HIDDEN {
 
 typedef int v128 __attribute__((vector_size(16), may_alias, aligned(16)));
@@ -55,4 +59,82 @@ cpu_relax (void)
   __asm volatile ("" : : : "memory");
 }
 
+// Use HTM if it is supported by the system.
+// See gtm_thread::begin_transaction for how these functions are used.
+#if defined (__linux__) \
+    && defined (HAVE_AS_HTM) \
+    && defined (HAVE_GETAUXVAL) \
+    && defined (AT_HWCAP2) \
+    && defined (PPC_FEATURE2_HAS_HTM)
+
+#include <htmintrin.h>
+
+#define USE_HTM_FASTPATH
+
+#define _TBEGIN_STARTED       0
+#define _TBEGIN_INDETERMINATE 1
+#define _TBEGIN_PERSISTENT    2
+
+/* Number of retries for transient failures.  */
+#define _HTM_RETRIES 10
+
+static inline bool
+htm_available (void)
+{
+  return (getauxval (AT_HWCAP2) & PPC_FEATURE2_HAS_HTM) ? true : false;
+}
+
+static inline uint32_t
+htm_init (void)
+{
+  // Maximum number of times we try to execute a transaction
+  // as a HW transaction.
+  return htm_available () ? _HTM_RETRIES : 0;
+}
+
+static inline uint32_t
+htm_begin (void)
+{
+  if (__builtin_expect (__builtin_tbegin (0), 1))
+    return _TBEGIN_STARTED;
+
+  if (_TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ()))
+    return _TBEGIN_PERSISTENT;
+
+  return _TBEGIN_INDETERMINATE;
+}
+
+static inline bool
+htm_begin_success (uint32_t begin_ret)
+{
+  return begin_ret == _TBEGIN_STARTED;
+}
+
+static inline void
+htm_commit (void)
+{
+  __builtin_tend (0);
+}
+
+static inline void
+htm_abort (void)
+{
+  __builtin_tabort (0);
+}
+
+static inline bool
+htm_abort_should_retry (uint32_t begin_ret)
+{
+  return begin_ret != _TBEGIN_PERSISTENT;
+}
+
+/* Returns true iff a hardware transaction is currently being executed.  */
+static inline bool
+htm_transaction_active (void)
+{
+  return (_HTM_STATE (__builtin_ttest ()) == _HTM_TRANSACTIONAL);
+}
+
+#endif
+
 } // namespace GTM
index d0d1abdf651d07cf2e6b82aac317d36c5d4ab255..7b3c0692e8f77d5d4f2e1c16ada32cb6859f7658 100644 (file)
@@ -15349,7 +15349,7 @@ $as_echo "#define STRING_WITH_STRINGS 1" >>confdefs.h
 
 fi
 
-for ac_header in unistd.h semaphore.h sys/time.h malloc.h
+for ac_header in unistd.h semaphore.h sys/time.h sys/auxv.h malloc.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -16184,7 +16184,7 @@ rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
 
 # Check for functions needed.
-for ac_func in strtoull memalign posix_memalign
+for ac_func in strtoull memalign posix_memalign getauxval
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -17364,6 +17364,43 @@ $as_echo "#define HAVE_AS_RTM 1" >>confdefs.h
   ;;
 esac
 
+case "${target_cpu}" in
+powerpc*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the assembler supports HTM" >&5
+$as_echo_n "checking if the assembler supports HTM... " >&6; }
+if test "${libitm_cv_as_htm+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+asm("tbegin. 0; tend. 0");
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  libitm_cv_as_htm=yes
+else
+  libitm_cv_as_htm=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libitm_cv_as_htm" >&5
+$as_echo "$libitm_cv_as_htm" >&6; }
+  if test x$libitm_cv_as_htm = xyes; then
+
+$as_echo "#define HAVE_AS_HTM 1" >>confdefs.h
+
+  fi
+  ;;
+esac
+
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether weak refs work like ELF" >&5
 $as_echo_n "checking whether weak refs work like ELF... " >&6; }
index ff41266a461f81c2ec4572e8f0bf24b628fbab3f..584a23bee200caede5406d908bb0a87e48412ca6 100644 (file)
@@ -160,7 +160,7 @@ AC_SUBST(libtool_VERSION)
 AC_STDC_HEADERS
 AC_HEADER_TIME
 ACX_HEADER_STRING
-AC_CHECK_HEADERS(unistd.h semaphore.h sys/time.h malloc.h)
+AC_CHECK_HEADERS(unistd.h semaphore.h sys/time.h sys/auxv.h malloc.h)
 
 GCC_HEADER_STDINT(gstdint.h)
 
@@ -193,7 +193,7 @@ AC_LINK_IFELSE(
    [AC_MSG_ERROR([Pthreads are required to build libitm])])])
 
 # Check for functions needed.
-AC_CHECK_FUNCS(strtoull memalign posix_memalign)
+AC_CHECK_FUNCS(strtoull memalign posix_memalign getauxval)
 
 # Check for broken semaphore implementation on darwin.
 # sem_init returns: sem_init error: Function not implemented.
@@ -245,6 +245,7 @@ LIBITM_CHECK_SYNC_BUILTINS
 LIBITM_CHECK_64BIT_SYNC_BUILTINS
 LIBITM_CHECK_AS_AVX
 LIBITM_CHECK_AS_RTM
+LIBITM_CHECK_AS_HTM
 
 GCC_CHECK_ELF_STYLE_WEAKREF
 
index ab3953b16d726962fd1f1b661b3973a9762a7e22..d8f3ca52876a15be7f7ac03a4561dedef70a2587 100644 (file)
@@ -47,7 +47,10 @@ fi
 # work out any special compilation flags as necessary.
 case "${target_cpu}" in
   alpha*)              ARCH=alpha ;;
-  rs6000 | powerpc*)   ARCH=powerpc ;;
+  rs6000 | powerpc*)
+       XCFLAGS="${XCFLAGS} -mhtm"
+       ARCH=powerpc
+       ;;
 
   arm*)                ARCH=arm ;;