diff mbox

[4.8,2/26] Backport Power8 and LE support: HTM support

Message ID 1395257103.17148.4.camel@gnopaine
State New
Headers show

Commit Message

Bill Schmidt March 19, 2014, 7:25 p.m. UTC
Hi,

This patch (diff-p8-htm) backports hardware transactional memory
support.  Copying Jakub and Richard for the libitm support.

Thanks,
Bill


[gcc]

2014-03-29  Bill Schmidt <wschmidt@linux.vnet.ibm.com>

	Backport from mainline
	2013-12-03  Peter Bergner  <bergner@vnet.ibm.com>

	* config/rs6000/htmintrin.h (_TEXASR_INSTRUCTION_FETCH_CONFLICT): Fix
	typo in macro name.
	(_TEXASRU_INSTRUCTION_FETCH_CONFLICT): Likewise.

	Backport from mainline r205233.
	2013-11-21  Peter Bergner  <bergner@vnet.ibm.com>

	* doc/extend.texi: Document htm builtins.

	Backport from mainline
	2013-07-17  Iain Sandoe  <iain@codesourcery.com>

	* config/rs6000/darwin.h (REGISTER_NAMES): Add HTM registers.

	Backport from mainline
	2013-07-16  Peter Bergner <bergner@vnet.ibm.com>

	* config/rs6000/rs6000.c (rs6000_option_override_internal): Do not
	enable extra ISA flags with TARGET_HTM.

	2013-07-16  Jakub Jelinek  <jakub@redhat.com>
		    Peter Bergner  <bergner@vnet.ibm.com>

	* config/rs6000/rs6000.h (FIRST_PSEUDO_REGISTERS): Mention HTM
	registers in the comment.
	(DWARF_FRAME_REGISTERS): Subtract also the 3 HTM registers.
	(DWARF_REG_TO_UNWIND_COLUMN): Use DWARF_FRAME_REGISTERS
	rather than FIRST_PSEUDO_REGISTERS.

	* 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.

[libitm]

2014-03-29  Bill Schmidt <wschmidt@linux.vnet.ibm.com>

	Backport from mainline
	* acinclude.m4 (LIBITM_CHECK_AS_HTM): New.
	* 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/testsuite]

2014-03-29  Bill Schmidt <wschmidt@linux.vnet.ibm.com>

	Backport from mainline
        * 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.

Comments

Richard Biener March 24, 2014, 10:12 a.m. UTC | #1
On Wed, 19 Mar 2014, Bill Schmidt wrote:

> Hi,
> 
> This patch (diff-p8-htm) backports hardware transactional memory
> support.  Copying Jakub and Richard for the libitm support.

Works for me.

Thanks,
Richard.

> Thanks,
> Bill
> 
> 
> [gcc]
> 
> 2014-03-29  Bill Schmidt <wschmidt@linux.vnet.ibm.com>
> 
> 	Backport from mainline
> 	2013-12-03  Peter Bergner  <bergner@vnet.ibm.com>
> 
> 	* config/rs6000/htmintrin.h (_TEXASR_INSTRUCTION_FETCH_CONFLICT): Fix
> 	typo in macro name.
> 	(_TEXASRU_INSTRUCTION_FETCH_CONFLICT): Likewise.
> 
> 	Backport from mainline r205233.
> 	2013-11-21  Peter Bergner  <bergner@vnet.ibm.com>
> 
> 	* doc/extend.texi: Document htm builtins.
> 
> 	Backport from mainline
> 	2013-07-17  Iain Sandoe  <iain@codesourcery.com>
> 
> 	* config/rs6000/darwin.h (REGISTER_NAMES): Add HTM registers.
> 
> 	Backport from mainline
> 	2013-07-16  Peter Bergner <bergner@vnet.ibm.com>
> 
> 	* config/rs6000/rs6000.c (rs6000_option_override_internal): Do not
> 	enable extra ISA flags with TARGET_HTM.
> 
> 	2013-07-16  Jakub Jelinek  <jakub@redhat.com>
> 		    Peter Bergner  <bergner@vnet.ibm.com>
> 
> 	* config/rs6000/rs6000.h (FIRST_PSEUDO_REGISTERS): Mention HTM
> 	registers in the comment.
> 	(DWARF_FRAME_REGISTERS): Subtract also the 3 HTM registers.
> 	(DWARF_REG_TO_UNWIND_COLUMN): Use DWARF_FRAME_REGISTERS
> 	rather than FIRST_PSEUDO_REGISTERS.
> 
> 	* 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.
> 
> [libitm]
> 
> 2014-03-29  Bill Schmidt <wschmidt@linux.vnet.ibm.com>
> 
> 	Backport from mainline
> 	* acinclude.m4 (LIBITM_CHECK_AS_HTM): New.
> 	* 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/testsuite]
> 
> 2014-03-29  Bill Schmidt <wschmidt@linux.vnet.ibm.com>
> 
> 	Backport from mainline
>         * 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.
> 
> 
> Index: gcc-4_8-test/gcc/config.gcc
> ===================================================================
> --- gcc-4_8-test.orig/gcc/config.gcc
> +++ gcc-4_8-test/gcc/config.gcc
> @@ -420,7 +420,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)
> Index: gcc-4_8-test/gcc/config/rs6000/htm.md
> ===================================================================
> --- /dev/null
> +++ gcc-4_8-test/gcc/config/rs6000/htm.md
> @@ -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")])
> Index: gcc-4_8-test/gcc/config/rs6000/htmintrin.h
> ===================================================================
> --- /dev/null
> +++ gcc-4_8-test/gcc/config/rs6000/htmintrin.h
> @@ -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_INSTRUCTION_FETCH_CONFLICT(TEXASR) \
> +  _TEXASR_EXTRACT_BITS(TEXASR, 16, 1)
> +#define _TEXASRU_INSTRUCTION_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 */
> Index: gcc-4_8-test/gcc/config/rs6000/htmxlintrin.h
> ===================================================================
> --- /dev/null
> +++ gcc-4_8-test/gcc/config/rs6000/htmxlintrin.h
> @@ -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: gcc-4_8-test/gcc/config/rs6000/predicates.md
> ===================================================================
> --- gcc-4_8-test.orig/gcc/config/rs6000/predicates.md
> +++ gcc-4_8-test/gcc/config/rs6000/predicates.md
> @@ -124,6 +124,11 @@
>    (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")
> @@ -135,6 +140,11 @@
>    (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")
> @@ -226,6 +236,33 @@
>    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: gcc-4_8-test/gcc/config/rs6000/rs6000-builtin.def
> ===================================================================
> --- gcc-4_8-test.orig/gcc/config/rs6000/rs6000-builtin.def
> +++ gcc-4_8-test/gcc/config/rs6000/rs6000-builtin.def
> @@ -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
> @@ -66,6 +67,10 @@
>    #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
> @@ -403,6 +408,56 @@
>  		     | 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 */	\
> @@ -1367,6 +1422,33 @@ BU_CRYPTO_OVERLOAD_3 (VPERMXOR,	 "vpermx
>  BU_CRYPTO_OVERLOAD_3 (VSHASIGMA, "vshasigma")
>  
>  
> +/* 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)
> +
> +
>  /* 3 argument paired floating point builtins.  */
>  BU_PAIRED_3 (MSUB,            "msub",           FP, 	fmsv2sf4)
>  BU_PAIRED_3 (MADD,            "madd",           FP, 	fmav2sf4)
> @@ -1665,10 +1747,10 @@ BU_SPECIAL_X (RS6000_BUILTIN_RSQRTF, "__
>  	      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: gcc-4_8-test/gcc/config/rs6000/rs6000-c.c
> ===================================================================
> --- gcc-4_8-test.orig/gcc/config/rs6000/rs6000-c.c
> +++ gcc-4_8-test/gcc/config/rs6000/rs6000-c.c
> @@ -333,6 +333,8 @@ rs6000_target_modify_macros (bool define
>      }
>    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: gcc-4_8-test/gcc/config/rs6000/rs6000-cpus.def
> ===================================================================
> --- gcc-4_8-test.orig/gcc/config/rs6000/rs6000-cpus.def
> +++ gcc-4_8-test/gcc/config/rs6000/rs6000-cpus.def
> @@ -52,6 +52,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)
> @@ -75,6 +76,7 @@
>  				 | OPTION_MASK_DIRECT_MOVE		\
>  				 | OPTION_MASK_DLMZB			\
>  				 | OPTION_MASK_FPRND			\
> +				 | OPTION_MASK_HTM			\
>  				 | OPTION_MASK_ISEL			\
>  				 | OPTION_MASK_MFCRF			\
>  				 | OPTION_MASK_MFPGPR			\
> Index: gcc-4_8-test/gcc/config/rs6000/rs6000.c
> ===================================================================
> --- gcc-4_8-test.orig/gcc/config/rs6000/rs6000.c
> +++ gcc-4_8-test/gcc/config/rs6000/rs6000.c
> @@ -970,6 +970,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
> @@ -993,6 +994,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 },
>  
> @@ -1023,6 +1027,7 @@ static const struct 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
> @@ -1063,6 +1068,7 @@ static void rs6000_common_init_builtins
>  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);
> @@ -1190,7 +1196,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
> @@ -1216,7 +1224,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
>  
> @@ -2396,6 +2406,9 @@ rs6000_init_hard_regno_mode_ok (bool glo
>    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;
>  
> @@ -2954,7 +2967,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
> @@ -10394,6 +10408,7 @@ def_builtin (const char *name, tree type
>  #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
> @@ -10407,6 +10422,7 @@ def_builtin (const char *name, tree type
>  #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)
> @@ -10425,6 +10441,7 @@ static const struct builtin_description
>  #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
> @@ -10438,6 +10455,7 @@ static const struct builtin_description
>    { 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)
> @@ -10456,6 +10474,7 @@ static const struct builtin_description
>  #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
> @@ -10469,6 +10488,7 @@ static const struct builtin_description
>  #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)
> @@ -10485,6 +10505,7 @@ static const struct builtin_description
>  #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
> @@ -10496,6 +10517,7 @@ static const struct builtin_description
>  #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 },
>  
> @@ -10517,6 +10539,7 @@ static const struct builtin_description
>  #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
> @@ -10528,6 +10551,7 @@ static const struct builtin_description
>  #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) \
> @@ -10547,6 +10571,7 @@ static const struct builtin_description
>  #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
> @@ -10560,6 +10585,7 @@ static const struct builtin_description
>  #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)
> @@ -10577,6 +10603,7 @@ static const struct builtin_description
>  #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
> @@ -10588,6 +10615,7 @@ static const struct builtin_description
>  #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 },
> @@ -10608,6 +10636,7 @@ static const struct builtin_description
>  #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
> @@ -10621,6 +10650,7 @@ static const struct builtin_description
>  
>  #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)
> @@ -10638,8 +10668,9 @@ static const struct builtin_description
>  #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
> @@ -10653,6 +10684,7 @@ static const struct builtin_description
>  #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)
> @@ -10663,17 +10695,49 @@ static const struct builtin_description
>  #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)
> @@ -11143,6 +11207,197 @@ altivec_expand_stv_builtin (enum insn_co
>    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)
>  {
> @@ -12224,6 +12479,8 @@ rs6000_invalid_builtin (enum rs6000_buil
>      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)
> @@ -12403,6 +12660,13 @@ rs6000_expand_builtin (tree exp, rtx tar
>        if (success)
>  	return ret;
>      }  
> +  if (TARGET_HTM)
> +    {
> +      ret = htm_expand_builtin (exp, target, &success);
> +
> +      if (success)
> +	return ret;
> +    }  
>  
>    gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
>  
> @@ -12585,6 +12849,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 ();
>  
> @@ -13324,6 +13591,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
> @@ -29201,6 +29541,7 @@ static struct rs6000_opt_mask const rs60
>    { "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  },
> @@ -29262,6 +29603,7 @@ static struct rs6000_opt_mask const rs60
>    { "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: gcc-4_8-test/gcc/config/rs6000/rs6000.h
> ===================================================================
> --- gcc-4_8-test.orig/gcc/config/rs6000/rs6000.h
> +++ gcc-4_8-test/gcc/config/rs6000/rs6000.h
> @@ -164,7 +164,7 @@
>  %{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
>  #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
> @@ -917,15 +920,17 @@ extern unsigned rs6000_pointer_size;
>     in inline functions.
>  
>     Another pseudo (not included in DWARF_FRAME_REGISTERS) is soft frame
> -   pointer, which is eventually eliminated in favor of SP or FP.  */
> +   pointer, which is eventually eliminated in favor of SP or FP.
>  
> -#define FIRST_PSEUDO_REGISTER 114
> +   The 3 HTM registers aren't also included in DWARF_FRAME_REGISTERS.  */
> +
> +#define FIRST_PSEUDO_REGISTER 117
>  
>  /* This must be included for pre gcc 3.0 glibc compatibility.  */
>  #define PRE_GCC3_DWARF_FRAME_REGISTERS 77
>  
>  /* Add 32 dwarf columns for synthetic SPE registers.  */
> -#define DWARF_FRAME_REGISTERS ((FIRST_PSEUDO_REGISTER - 1) + 32)
> +#define DWARF_FRAME_REGISTERS ((FIRST_PSEUDO_REGISTER - 4) + 32)
>  
>  /* The SPE has an additional 32 synthetic registers, with DWARF debug
>     info numbering for these registers starting at 1200.  While eh_frame
> @@ -941,7 +946,7 @@ extern unsigned rs6000_pointer_size;
>     We must map them here to avoid huge unwinder tables mostly consisting
>     of unused space.  */
>  #define DWARF_REG_TO_UNWIND_COLUMN(r) \
> -  ((r) > 1200 ? ((r) - 1200 + FIRST_PSEUDO_REGISTER - 1) : (r))
> +  ((r) > 1200 ? ((r) - 1200 + (DWARF_FRAME_REGISTERS - 32)) : (r))
>  
>  /* Use standard DWARF numbering for DWARF debugging information.  */
>  #define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO)
> @@ -981,7 +986,7 @@ extern unsigned rs6000_pointer_size;
>     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.
> @@ -1001,7 +1006,7 @@ extern unsigned rs6000_pointer_size;
>     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
> @@ -1020,7 +1025,7 @@ extern unsigned rs6000_pointer_size;
>     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)
> @@ -1059,6 +1064,9 @@ extern unsigned rs6000_pointer_size;
>  	vrsave, vscr	(fixed)
>  	spe_acc, spefscr (fixed)
>  	sfp		(fixed)
> +	tfhar		(fixed)
> +	tfiar		(fixed)
> +	texasr		(fixed)
>  */
>  
>  #if FIXED_R2 == 1
> @@ -1100,7 +1108,7 @@ extern unsigned rs6000_pointer_size;
>     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.  */
> @@ -1324,6 +1332,7 @@ enum reg_class
>    VSCR_REGS,
>    SPE_ACC_REGS,
>    SPEFSCR_REGS,
> +  SPR_REGS,
>    NON_SPECIAL_REGS,
>    LINK_REGS,
>    CTR_REGS,
> @@ -1354,6 +1363,7 @@ enum reg_class
>    "VSCR_REGS",								\
>    "SPE_ACC_REGS",                                                       \
>    "SPEFSCR_REGS",                                                       \
> +  "SPR_REGS",								\
>    "NON_SPECIAL_REGS",							\
>    "LINK_REGS",								\
>    "CTR_REGS",								\
> @@ -1383,6 +1393,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 */	     \
> @@ -1393,7 +1404,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:
> @@ -2310,6 +2321,9 @@ extern char rs6000_reg_names[][8];	/* re
>    &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.  */
> @@ -2363,7 +2377,9 @@ extern char rs6000_reg_names[][8];	/* re
>    {"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.  */
>  
> @@ -2452,7 +2468,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.  */
> @@ -2466,6 +2487,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.  */
> @@ -2483,6 +2505,7 @@ extern int frame_pointer_needed;
>  				 | RS6000_BTM_FRES			\
>  				 | RS6000_BTM_FRSQRTE			\
>  				 | RS6000_BTM_FRSQRTES			\
> +				 | RS6000_BTM_HTM			\
>  				 | RS6000_BTM_POPCNTD			\
>  				 | RS6000_BTM_CELL)
>  
> @@ -2494,6 +2517,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
> @@ -2505,6 +2529,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,
> @@ -2523,6 +2548,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: gcc-4_8-test/gcc/config/rs6000/rs6000.md
> ===================================================================
> --- gcc-4_8-test.orig/gcc/config/rs6000/rs6000.md
> +++ gcc-4_8-test/gcc/config/rs6000/rs6000.md
> @@ -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)
> @@ -152,7 +155,7 @@
>  
>  ;; 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
> @@ -15145,3 +15148,4 @@
>  (include "dfp.md")
>  (include "paired.md")
>  (include "crypto.md")
> +(include "htm.md")
> Index: gcc-4_8-test/gcc/config/rs6000/rs6000.opt
> ===================================================================
> --- gcc-4_8-test.orig/gcc/config/rs6000/rs6000.opt
> +++ gcc-4_8-test/gcc/config/rs6000/rs6000.opt
> @@ -542,6 +542,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: gcc-4_8-test/gcc/config/rs6000/t-rs6000
> ===================================================================
> --- gcc-4_8-test.orig/gcc/config/rs6000/t-rs6000
> +++ gcc-4_8-test/gcc/config/rs6000/t-rs6000
> @@ -72,6 +72,7 @@ MD_INCLUDES = $(srcdir)/config/rs6000/rs
>  	$(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: gcc-4_8-test/gcc/testsuite/gcc.target/powerpc/htm-builtin-1.c
> ===================================================================
> --- /dev/null
> +++ gcc-4_8-test/gcc/testsuite/gcc.target/powerpc/htm-builtin-1.c
> @@ -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]);
> +}
> Index: gcc-4_8-test/gcc/testsuite/gcc.target/powerpc/htm-xl-intrin-1.c
> ===================================================================
> --- /dev/null
> +++ gcc-4_8-test/gcc/testsuite/gcc.target/powerpc/htm-xl-intrin-1.c
> @@ -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: gcc-4_8-test/gcc/testsuite/lib/target-supports.exp
> ===================================================================
> --- gcc-4_8-test.orig/gcc/testsuite/lib/target-supports.exp
> +++ gcc-4_8-test/gcc/testsuite/lib/target-supports.exp
> @@ -2752,6 +2752,27 @@ proc check_effective_target_powerpc_vsx_
>      }
>  }
>  
> +# 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: gcc-4_8-test/libitm/config/powerpc/target.h
> ===================================================================
> --- gcc-4_8-test.orig/libitm/config/powerpc/target.h
> +++ gcc-4_8-test/libitm/config/powerpc/target.h
> @@ -22,6 +22,10 @@
>     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: gcc-4_8-test/libitm/configure.tgt
> ===================================================================
> --- gcc-4_8-test.orig/libitm/configure.tgt
> +++ gcc-4_8-test/libitm/configure.tgt
> @@ -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 ;;
>  
> Index: gcc-4_8-test/gcc/config/rs6000/darwin.h
> ===================================================================
> --- gcc-4_8-test.orig/gcc/config/rs6000/darwin.h
> +++ gcc-4_8-test/gcc/config/rs6000/darwin.h
> @@ -205,7 +205,8 @@ extern int darwin_emit_branch_islands;
>      "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",             \
>      "vrsave", "vscr",							\
>      "spe_acc", "spefscr",                                               \
> -    "sfp"								\
> +    "sfp",								\
> +    "tfhar", "tfiar", "texasr"						\
>  }
>  
>  /* This outputs NAME to FILE.  */
> Index: gcc-4_8-test/gcc/doc/extend.texi
> ===================================================================
> --- gcc-4_8-test.orig/gcc/doc/extend.texi
> +++ gcc-4_8-test/gcc/doc/extend.texi
> @@ -8804,6 +8804,7 @@ instructions, but allow the compiler to
>  * picoChip Built-in Functions::
>  * PowerPC Built-in Functions::
>  * PowerPC AltiVec/VSX Built-in Functions::
> +* PowerPC Hardware Transactional Memory Built-in Functions::
>  * RX Built-in Functions::
>  * S/390 System z Built-in Functions::
>  * SH Built-in Functions::
> @@ -14266,6 +14267,196 @@ The second argument to the @var{__builti
>  integer that is 0 or 1.  The third argument to these builtin functions
>  must be a constant integer in the range of 0 to 15.
>  
> +@node PowerPC Hardware Transactional Memory Built-in Functions
> +@subsection PowerPC Hardware Transactional Memory Built-in Functions
> +GCC provides two interfaces for accessing the Hardware Transactional
> +Memory (HTM) instructions available on some of the PowerPC family
> +of prcoessors (eg, POWER8).  The two interfaces come in a low level
> +interface, consisting of built-in functions specific to PowerPC and a
> +higher level interface consisting of inline functions that are common
> +between PowerPC and S/390.
> +
> +@subsubsection PowerPC HTM Low Level Built-in Functions
> +
> +The following low level built-in functions are available with
> +@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.
> +
> +@smallexample
> +unsigned int __builtin_tbegin (unsigned int)
> +unsigned int __builtin_tend (unsigned int)
> +
> +unsigned int __builtin_tabort (unsigned int)
> +unsigned int __builtin_tabortdc (unsigned int, unsigned int, unsigned int)
> +unsigned int __builtin_tabortdci (unsigned int, unsigned int, int)
> +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_treclaim (unsigned int)
> +unsigned int __builtin_trechkpt (void)
> +unsigned int __builtin_tsr (unsigned int)
> +@end smallexample
> +
> +In addition to the above HTM built-ins, we have added built-ins for
> +some common extended mnemonics of the HTM instructions:
> +
> +@smallexample
> +unsigned int __builtin_tendall (void)
> +unsigned int __builtin_tresume (void)
> +unsigned int __builtin_tsuspend (void)
> +@end smallexample
> +
> +The following set of built-in functions are available to gain access
> +to the HTM specific special purpose registers.
> +
> +@smallexample
> +unsigned long __builtin_get_texasr (void)
> +unsigned long __builtin_get_texasru (void)
> +unsigned long __builtin_get_tfhar (void)
> +unsigned long __builtin_get_tfiar (void)
> +
> +void __builtin_set_texasr (unsigned long);
> +void __builtin_set_texasru (unsigned long);
> +void __builtin_set_tfhar (unsigned long);
> +void __builtin_set_tfiar (unsigned long);
> +@end smallexample
> +
> +Example usage of these low level built-in functions may look like:
> +
> +@smallexample
> +#include <htmintrin.h>
> +
> +int num_retries = 10;
> +
> +while (1)
> +  @{
> +    if (__builtin_tbegin (0))
> +      @{
> +        /* Transaction State Initiated.  */
> +        if (is_locked (lock))
> +          __builtin_tabort (0);
> +        ... transaction code...
> +        __builtin_tend (0);
> +        break;
> +      @}
> +    else
> +      @{
> +        /* Transaction State Failed.  Use locks if the transaction
> +           failure is "persistent" or we've tried too many times.  */
> +        if (num_retries-- <= 0
> +            || _TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ()))
> +          @{
> +            acquire_lock (lock);
> +            ... non transactional fallback path...
> +            release_lock (lock);
> +            break;
> +          @}
> +      @}
> +  @}
> +@end smallexample
> +
> +One final built-in function has been added that returns the value of
> +the 2-bit Transaction State field of the Machine Status Register (MSR)
> +as stored in @code{CR0}.
> +
> +@smallexample
> +unsigned long __builtin_ttest (void)
> +@end smallexample
> +
> +This built-in can be used to determine the current transaction state
> +using the following code example:
> +
> +@smallexample
> +#include <htmintrin.h>
> +
> +unsigned char tx_state = _HTM_STATE (__builtin_ttest ());
> +
> +if (tx_state == _HTM_TRANSACTIONAL)
> +  @{
> +    /* Code to use in transactional state.  */
> +  @}
> +else if (tx_state == _HTM_NONTRANSACTIONAL)
> +  @{
> +    /* Code to use in non-transactional state.  */
> +  @}
> +else if (tx_state == _HTM_SUSPENDED)
> +  @{
> +    /* Code to use in transaction suspended state.  */
> +  @}
> +@end smallexample
> +
> +@subsubsection PowerPC HTM High Level Inline Functions
> +
> +The following high level HTM interface is made available by including
> +@code{<htmxlintrin.h>} and using @option{-mhtm} or @option{-mcpu=CPU}
> +where CPU is `power8' or later.  This interface is common between PowerPC
> +and S/390, allowing users to write one HTM source implementation that
> +can be compiled and executed on either system.
> +
> +@smallexample
> +long __TM_simple_begin (void)
> +long __TM_begin (void* const TM_buff)
> +long __TM_end (void)
> +void __TM_abort (void)
> +void __TM_named_abort (unsigned char const code)
> +void __TM_resume (void)
> +void __TM_suspend (void)
> +
> +long __TM_is_user_abort (void* const TM_buff)
> +long __TM_is_named_user_abort (void* const TM_buff, unsigned char *code)
> +long __TM_is_illegal (void* const TM_buff)
> +long __TM_is_footprint_exceeded (void* const TM_buff)
> +long __TM_nesting_depth (void* const TM_buff)
> +long __TM_is_nested_too_deep(void* const TM_buff)
> +long __TM_is_conflict(void* const TM_buff)
> +long __TM_is_failure_persistent(void* const TM_buff)
> +long __TM_failure_address(void* const TM_buff)
> +long long __TM_failure_code(void* const TM_buff)
> +@end smallexample
> +
> +Using these common set of HTM inline functions, we can create
> +a more portable version of the HTM example in the previous
> +section that will work on either PowerPC or S/390:
> +
> +@smallexample
> +#include <htmxlintrin.h>
> +
> +int num_retries = 10;
> +TM_buff_type TM_buff;
> +
> +while (1)
> +  @{
> +    if (__TM_begin (TM_buff))
> +      @{
> +        /* Transaction State Initiated.  */
> +        if (is_locked (lock))
> +          __TM_abort ();
> +        ... transaction code...
> +        __TM_end ();
> +        break;
> +      @}
> +    else
> +      @{
> +        /* Transaction State Failed.  Use locks if the transaction
> +           failure is "persistent" or we've tried too many times.  */
> +        if (num_retries-- <= 0
> +            || __TM_is_failure_persistent (TM_buff))
> +          @{
> +            acquire_lock (lock);
> +            ... non transactional fallback path...
> +            release_lock (lock);
> +            break;
> +          @}
> +      @}
> +  @}
> +@end smallexample
> +
>  @node RX Built-in Functions
>  @subsection RX Built-in Functions
>  GCC supports some of the RX instructions which cannot be expressed in
> Index: gcc-4_8-test/libitm/acinclude.m4
> ===================================================================
> --- gcc-4_8-test.orig/libitm/acinclude.m4
> +++ gcc-4_8-test/libitm/acinclude.m4
> @@ -134,6 +134,20 @@ s390*)
>    ;;
>  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: gcc-4_8-test/libitm/configure
> ===================================================================
> --- gcc-4_8-test.orig/libitm/configure
> +++ gcc-4_8-test/libitm/configure
> @@ -17401,6 +17401,43 @@ $as_echo "#define HAVE_AS_HTM 1" >>confd
>  esac
>  LIBITM_CHECK_AS_HTM
>  
> +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; }
> 
> 
> 
>
David Edelsohn April 3, 2014, 2:27 p.m. UTC | #2
On Wed, Mar 19, 2014 at 3:25 PM, Bill Schmidt
<wschmidt@linux.vnet.ibm.com> wrote:
> Hi,
>
> This patch (diff-p8-htm) backports hardware transactional memory
> support.  Copying Jakub and Richard for the libitm support.
>
> Thanks,
> Bill
>
>
> [gcc]
>
> 2014-03-29  Bill Schmidt <wschmidt@linux.vnet.ibm.com>
>
>         Backport from mainline
>         2013-12-03  Peter Bergner  <bergner@vnet.ibm.com>
>
>         * config/rs6000/htmintrin.h (_TEXASR_INSTRUCTION_FETCH_CONFLICT): Fix
>         typo in macro name.
>         (_TEXASRU_INSTRUCTION_FETCH_CONFLICT): Likewise.
>
>         Backport from mainline r205233.
>         2013-11-21  Peter Bergner  <bergner@vnet.ibm.com>
>
>         * doc/extend.texi: Document htm builtins.
>
>         Backport from mainline
>         2013-07-17  Iain Sandoe  <iain@codesourcery.com>
>
>         * config/rs6000/darwin.h (REGISTER_NAMES): Add HTM registers.
>
>         Backport from mainline
>         2013-07-16  Peter Bergner <bergner@vnet.ibm.com>
>
>         * config/rs6000/rs6000.c (rs6000_option_override_internal): Do not
>         enable extra ISA flags with TARGET_HTM.
>
>         2013-07-16  Jakub Jelinek  <jakub@redhat.com>
>                     Peter Bergner  <bergner@vnet.ibm.com>
>
>         * config/rs6000/rs6000.h (FIRST_PSEUDO_REGISTERS): Mention HTM
>         registers in the comment.
>         (DWARF_FRAME_REGISTERS): Subtract also the 3 HTM registers.
>         (DWARF_REG_TO_UNWIND_COLUMN): Use DWARF_FRAME_REGISTERS
>         rather than FIRST_PSEUDO_REGISTERS.
>
>         * 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.
>
> [libitm]
>
> 2014-03-29  Bill Schmidt <wschmidt@linux.vnet.ibm.com>
>
>         Backport from mainline
>         * acinclude.m4 (LIBITM_CHECK_AS_HTM): New.
>         * 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/testsuite]
>
> 2014-03-29  Bill Schmidt <wschmidt@linux.vnet.ibm.com>
>
>         Backport from mainline
>         * 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.

The PowerPC bits are okay.

Thanks, David
diff mbox

Patch

Index: gcc-4_8-test/gcc/config.gcc
===================================================================
--- gcc-4_8-test.orig/gcc/config.gcc
+++ gcc-4_8-test/gcc/config.gcc
@@ -420,7 +420,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)
Index: gcc-4_8-test/gcc/config/rs6000/htm.md
===================================================================
--- /dev/null
+++ gcc-4_8-test/gcc/config/rs6000/htm.md
@@ -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")])
Index: gcc-4_8-test/gcc/config/rs6000/htmintrin.h
===================================================================
--- /dev/null
+++ gcc-4_8-test/gcc/config/rs6000/htmintrin.h
@@ -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_INSTRUCTION_FETCH_CONFLICT(TEXASR) \
+  _TEXASR_EXTRACT_BITS(TEXASR, 16, 1)
+#define _TEXASRU_INSTRUCTION_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 */
Index: gcc-4_8-test/gcc/config/rs6000/htmxlintrin.h
===================================================================
--- /dev/null
+++ gcc-4_8-test/gcc/config/rs6000/htmxlintrin.h
@@ -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: gcc-4_8-test/gcc/config/rs6000/predicates.md
===================================================================
--- gcc-4_8-test.orig/gcc/config/rs6000/predicates.md
+++ gcc-4_8-test/gcc/config/rs6000/predicates.md
@@ -124,6 +124,11 @@ 
   (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")
@@ -135,6 +140,11 @@ 
   (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")
@@ -226,6 +236,33 @@ 
   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: gcc-4_8-test/gcc/config/rs6000/rs6000-builtin.def
===================================================================
--- gcc-4_8-test.orig/gcc/config/rs6000/rs6000-builtin.def
+++ gcc-4_8-test/gcc/config/rs6000/rs6000-builtin.def
@@ -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
@@ -66,6 +67,10 @@ 
   #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
@@ -403,6 +408,56 @@ 
 		     | 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 */	\
@@ -1367,6 +1422,33 @@  BU_CRYPTO_OVERLOAD_3 (VPERMXOR,	 "vpermx
 BU_CRYPTO_OVERLOAD_3 (VSHASIGMA, "vshasigma")
 
 
+/* 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)
+
+
 /* 3 argument paired floating point builtins.  */
 BU_PAIRED_3 (MSUB,            "msub",           FP, 	fmsv2sf4)
 BU_PAIRED_3 (MADD,            "madd",           FP, 	fmav2sf4)
@@ -1665,10 +1747,10 @@  BU_SPECIAL_X (RS6000_BUILTIN_RSQRTF, "__
 	      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: gcc-4_8-test/gcc/config/rs6000/rs6000-c.c
===================================================================
--- gcc-4_8-test.orig/gcc/config/rs6000/rs6000-c.c
+++ gcc-4_8-test/gcc/config/rs6000/rs6000-c.c
@@ -333,6 +333,8 @@  rs6000_target_modify_macros (bool define
     }
   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: gcc-4_8-test/gcc/config/rs6000/rs6000-cpus.def
===================================================================
--- gcc-4_8-test.orig/gcc/config/rs6000/rs6000-cpus.def
+++ gcc-4_8-test/gcc/config/rs6000/rs6000-cpus.def
@@ -52,6 +52,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)
@@ -75,6 +76,7 @@ 
 				 | OPTION_MASK_DIRECT_MOVE		\
 				 | OPTION_MASK_DLMZB			\
 				 | OPTION_MASK_FPRND			\
+				 | OPTION_MASK_HTM			\
 				 | OPTION_MASK_ISEL			\
 				 | OPTION_MASK_MFCRF			\
 				 | OPTION_MASK_MFPGPR			\
Index: gcc-4_8-test/gcc/config/rs6000/rs6000.c
===================================================================
--- gcc-4_8-test.orig/gcc/config/rs6000/rs6000.c
+++ gcc-4_8-test/gcc/config/rs6000/rs6000.c
@@ -970,6 +970,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
@@ -993,6 +994,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 },
 
@@ -1023,6 +1027,7 @@  static const struct 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
@@ -1063,6 +1068,7 @@  static void rs6000_common_init_builtins
 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);
@@ -1190,7 +1196,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
@@ -1216,7 +1224,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
 
@@ -2396,6 +2406,9 @@  rs6000_init_hard_regno_mode_ok (bool glo
   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;
 
@@ -2954,7 +2967,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
@@ -10394,6 +10408,7 @@  def_builtin (const char *name, tree type
 #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
@@ -10407,6 +10422,7 @@  def_builtin (const char *name, tree type
 #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)
@@ -10425,6 +10441,7 @@  static const struct builtin_description
 #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
@@ -10438,6 +10455,7 @@  static const struct builtin_description
   { 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)
@@ -10456,6 +10474,7 @@  static const struct builtin_description
 #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
@@ -10469,6 +10488,7 @@  static const struct builtin_description
 #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)
@@ -10485,6 +10505,7 @@  static const struct builtin_description
 #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
@@ -10496,6 +10517,7 @@  static const struct builtin_description
 #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 },
 
@@ -10517,6 +10539,7 @@  static const struct builtin_description
 #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
@@ -10528,6 +10551,7 @@  static const struct builtin_description
 #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) \
@@ -10547,6 +10571,7 @@  static const struct builtin_description
 #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
@@ -10560,6 +10585,7 @@  static const struct builtin_description
 #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)
@@ -10577,6 +10603,7 @@  static const struct builtin_description
 #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
@@ -10588,6 +10615,7 @@  static const struct builtin_description
 #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 },
@@ -10608,6 +10636,7 @@  static const struct builtin_description
 #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
@@ -10621,6 +10650,7 @@  static const struct builtin_description
 
 #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)
@@ -10638,8 +10668,9 @@  static const struct builtin_description
 #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
@@ -10653,6 +10684,7 @@  static const struct builtin_description
 #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)
@@ -10663,17 +10695,49 @@  static const struct builtin_description
 #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)
@@ -11143,6 +11207,197 @@  altivec_expand_stv_builtin (enum insn_co
   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)
 {
@@ -12224,6 +12479,8 @@  rs6000_invalid_builtin (enum rs6000_buil
     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)
@@ -12403,6 +12660,13 @@  rs6000_expand_builtin (tree exp, rtx tar
       if (success)
 	return ret;
     }  
+  if (TARGET_HTM)
+    {
+      ret = htm_expand_builtin (exp, target, &success);
+
+      if (success)
+	return ret;
+    }  
 
   gcc_assert (TARGET_ALTIVEC || TARGET_VSX || TARGET_SPE || TARGET_PAIRED_FLOAT);
 
@@ -12585,6 +12849,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 ();
 
@@ -13324,6 +13591,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
@@ -29201,6 +29541,7 @@  static struct rs6000_opt_mask const rs60
   { "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  },
@@ -29262,6 +29603,7 @@  static struct rs6000_opt_mask const rs60
   { "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: gcc-4_8-test/gcc/config/rs6000/rs6000.h
===================================================================
--- gcc-4_8-test.orig/gcc/config/rs6000/rs6000.h
+++ gcc-4_8-test/gcc/config/rs6000/rs6000.h
@@ -164,7 +164,7 @@ 
 %{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
 #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
@@ -917,15 +920,17 @@  extern unsigned rs6000_pointer_size;
    in inline functions.
 
    Another pseudo (not included in DWARF_FRAME_REGISTERS) is soft frame
-   pointer, which is eventually eliminated in favor of SP or FP.  */
+   pointer, which is eventually eliminated in favor of SP or FP.
 
-#define FIRST_PSEUDO_REGISTER 114
+   The 3 HTM registers aren't also included in DWARF_FRAME_REGISTERS.  */
+
+#define FIRST_PSEUDO_REGISTER 117
 
 /* This must be included for pre gcc 3.0 glibc compatibility.  */
 #define PRE_GCC3_DWARF_FRAME_REGISTERS 77
 
 /* Add 32 dwarf columns for synthetic SPE registers.  */
-#define DWARF_FRAME_REGISTERS ((FIRST_PSEUDO_REGISTER - 1) + 32)
+#define DWARF_FRAME_REGISTERS ((FIRST_PSEUDO_REGISTER - 4) + 32)
 
 /* The SPE has an additional 32 synthetic registers, with DWARF debug
    info numbering for these registers starting at 1200.  While eh_frame
@@ -941,7 +946,7 @@  extern unsigned rs6000_pointer_size;
    We must map them here to avoid huge unwinder tables mostly consisting
    of unused space.  */
 #define DWARF_REG_TO_UNWIND_COLUMN(r) \
-  ((r) > 1200 ? ((r) - 1200 + FIRST_PSEUDO_REGISTER - 1) : (r))
+  ((r) > 1200 ? ((r) - 1200 + (DWARF_FRAME_REGISTERS - 32)) : (r))
 
 /* Use standard DWARF numbering for DWARF debugging information.  */
 #define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO)
@@ -981,7 +986,7 @@  extern unsigned rs6000_pointer_size;
    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.
@@ -1001,7 +1006,7 @@  extern unsigned rs6000_pointer_size;
    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
@@ -1020,7 +1025,7 @@  extern unsigned rs6000_pointer_size;
    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)
@@ -1059,6 +1064,9 @@  extern unsigned rs6000_pointer_size;
 	vrsave, vscr	(fixed)
 	spe_acc, spefscr (fixed)
 	sfp		(fixed)
+	tfhar		(fixed)
+	tfiar		(fixed)
+	texasr		(fixed)
 */
 
 #if FIXED_R2 == 1
@@ -1100,7 +1108,7 @@  extern unsigned rs6000_pointer_size;
    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.  */
@@ -1324,6 +1332,7 @@  enum reg_class
   VSCR_REGS,
   SPE_ACC_REGS,
   SPEFSCR_REGS,
+  SPR_REGS,
   NON_SPECIAL_REGS,
   LINK_REGS,
   CTR_REGS,
@@ -1354,6 +1363,7 @@  enum reg_class
   "VSCR_REGS",								\
   "SPE_ACC_REGS",                                                       \
   "SPEFSCR_REGS",                                                       \
+  "SPR_REGS",								\
   "NON_SPECIAL_REGS",							\
   "LINK_REGS",								\
   "CTR_REGS",								\
@@ -1383,6 +1393,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 */	     \
@@ -1393,7 +1404,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:
@@ -2310,6 +2321,9 @@  extern char rs6000_reg_names[][8];	/* re
   &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.  */
@@ -2363,7 +2377,9 @@  extern char rs6000_reg_names[][8];	/* re
   {"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.  */
 
@@ -2452,7 +2468,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.  */
@@ -2466,6 +2487,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.  */
@@ -2483,6 +2505,7 @@  extern int frame_pointer_needed;
 				 | RS6000_BTM_FRES			\
 				 | RS6000_BTM_FRSQRTE			\
 				 | RS6000_BTM_FRSQRTES			\
+				 | RS6000_BTM_HTM			\
 				 | RS6000_BTM_POPCNTD			\
 				 | RS6000_BTM_CELL)
 
@@ -2494,6 +2517,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
@@ -2505,6 +2529,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,
@@ -2523,6 +2548,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: gcc-4_8-test/gcc/config/rs6000/rs6000.md
===================================================================
--- gcc-4_8-test.orig/gcc/config/rs6000/rs6000.md
+++ gcc-4_8-test/gcc/config/rs6000/rs6000.md
@@ -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)
@@ -152,7 +155,7 @@ 
 
 ;; 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
@@ -15145,3 +15148,4 @@ 
 (include "dfp.md")
 (include "paired.md")
 (include "crypto.md")
+(include "htm.md")
Index: gcc-4_8-test/gcc/config/rs6000/rs6000.opt
===================================================================
--- gcc-4_8-test.orig/gcc/config/rs6000/rs6000.opt
+++ gcc-4_8-test/gcc/config/rs6000/rs6000.opt
@@ -542,6 +542,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: gcc-4_8-test/gcc/config/rs6000/t-rs6000
===================================================================
--- gcc-4_8-test.orig/gcc/config/rs6000/t-rs6000
+++ gcc-4_8-test/gcc/config/rs6000/t-rs6000
@@ -72,6 +72,7 @@  MD_INCLUDES = $(srcdir)/config/rs6000/rs
 	$(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: gcc-4_8-test/gcc/testsuite/gcc.target/powerpc/htm-builtin-1.c
===================================================================
--- /dev/null
+++ gcc-4_8-test/gcc/testsuite/gcc.target/powerpc/htm-builtin-1.c
@@ -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]);
+}
Index: gcc-4_8-test/gcc/testsuite/gcc.target/powerpc/htm-xl-intrin-1.c
===================================================================
--- /dev/null
+++ gcc-4_8-test/gcc/testsuite/gcc.target/powerpc/htm-xl-intrin-1.c
@@ -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: gcc-4_8-test/gcc/testsuite/lib/target-supports.exp
===================================================================
--- gcc-4_8-test.orig/gcc/testsuite/lib/target-supports.exp
+++ gcc-4_8-test/gcc/testsuite/lib/target-supports.exp
@@ -2752,6 +2752,27 @@  proc check_effective_target_powerpc_vsx_
     }
 }
 
+# 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: gcc-4_8-test/libitm/config/powerpc/target.h
===================================================================
--- gcc-4_8-test.orig/libitm/config/powerpc/target.h
+++ gcc-4_8-test/libitm/config/powerpc/target.h
@@ -22,6 +22,10 @@ 
    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: gcc-4_8-test/libitm/configure.tgt
===================================================================
--- gcc-4_8-test.orig/libitm/configure.tgt
+++ gcc-4_8-test/libitm/configure.tgt
@@ -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 ;;
 
Index: gcc-4_8-test/gcc/config/rs6000/darwin.h
===================================================================
--- gcc-4_8-test.orig/gcc/config/rs6000/darwin.h
+++ gcc-4_8-test/gcc/config/rs6000/darwin.h
@@ -205,7 +205,8 @@  extern int darwin_emit_branch_islands;
     "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31",             \
     "vrsave", "vscr",							\
     "spe_acc", "spefscr",                                               \
-    "sfp"								\
+    "sfp",								\
+    "tfhar", "tfiar", "texasr"						\
 }
 
 /* This outputs NAME to FILE.  */
Index: gcc-4_8-test/gcc/doc/extend.texi
===================================================================
--- gcc-4_8-test.orig/gcc/doc/extend.texi
+++ gcc-4_8-test/gcc/doc/extend.texi
@@ -8804,6 +8804,7 @@  instructions, but allow the compiler to
 * picoChip Built-in Functions::
 * PowerPC Built-in Functions::
 * PowerPC AltiVec/VSX Built-in Functions::
+* PowerPC Hardware Transactional Memory Built-in Functions::
 * RX Built-in Functions::
 * S/390 System z Built-in Functions::
 * SH Built-in Functions::
@@ -14266,6 +14267,196 @@  The second argument to the @var{__builti
 integer that is 0 or 1.  The third argument to these builtin functions
 must be a constant integer in the range of 0 to 15.
 
+@node PowerPC Hardware Transactional Memory Built-in Functions
+@subsection PowerPC Hardware Transactional Memory Built-in Functions
+GCC provides two interfaces for accessing the Hardware Transactional
+Memory (HTM) instructions available on some of the PowerPC family
+of prcoessors (eg, POWER8).  The two interfaces come in a low level
+interface, consisting of built-in functions specific to PowerPC and a
+higher level interface consisting of inline functions that are common
+between PowerPC and S/390.
+
+@subsubsection PowerPC HTM Low Level Built-in Functions
+
+The following low level built-in functions are available with
+@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.
+
+@smallexample
+unsigned int __builtin_tbegin (unsigned int)
+unsigned int __builtin_tend (unsigned int)
+
+unsigned int __builtin_tabort (unsigned int)
+unsigned int __builtin_tabortdc (unsigned int, unsigned int, unsigned int)
+unsigned int __builtin_tabortdci (unsigned int, unsigned int, int)
+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_treclaim (unsigned int)
+unsigned int __builtin_trechkpt (void)
+unsigned int __builtin_tsr (unsigned int)
+@end smallexample
+
+In addition to the above HTM built-ins, we have added built-ins for
+some common extended mnemonics of the HTM instructions:
+
+@smallexample
+unsigned int __builtin_tendall (void)
+unsigned int __builtin_tresume (void)
+unsigned int __builtin_tsuspend (void)
+@end smallexample
+
+The following set of built-in functions are available to gain access
+to the HTM specific special purpose registers.
+
+@smallexample
+unsigned long __builtin_get_texasr (void)
+unsigned long __builtin_get_texasru (void)
+unsigned long __builtin_get_tfhar (void)
+unsigned long __builtin_get_tfiar (void)
+
+void __builtin_set_texasr (unsigned long);
+void __builtin_set_texasru (unsigned long);
+void __builtin_set_tfhar (unsigned long);
+void __builtin_set_tfiar (unsigned long);
+@end smallexample
+
+Example usage of these low level built-in functions may look like:
+
+@smallexample
+#include <htmintrin.h>
+
+int num_retries = 10;
+
+while (1)
+  @{
+    if (__builtin_tbegin (0))
+      @{
+        /* Transaction State Initiated.  */
+        if (is_locked (lock))
+          __builtin_tabort (0);
+        ... transaction code...
+        __builtin_tend (0);
+        break;
+      @}
+    else
+      @{
+        /* Transaction State Failed.  Use locks if the transaction
+           failure is "persistent" or we've tried too many times.  */
+        if (num_retries-- <= 0
+            || _TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ()))
+          @{
+            acquire_lock (lock);
+            ... non transactional fallback path...
+            release_lock (lock);
+            break;
+          @}
+      @}
+  @}
+@end smallexample
+
+One final built-in function has been added that returns the value of
+the 2-bit Transaction State field of the Machine Status Register (MSR)
+as stored in @code{CR0}.
+
+@smallexample
+unsigned long __builtin_ttest (void)
+@end smallexample
+
+This built-in can be used to determine the current transaction state
+using the following code example:
+
+@smallexample
+#include <htmintrin.h>
+
+unsigned char tx_state = _HTM_STATE (__builtin_ttest ());
+
+if (tx_state == _HTM_TRANSACTIONAL)
+  @{
+    /* Code to use in transactional state.  */
+  @}
+else if (tx_state == _HTM_NONTRANSACTIONAL)
+  @{
+    /* Code to use in non-transactional state.  */
+  @}
+else if (tx_state == _HTM_SUSPENDED)
+  @{
+    /* Code to use in transaction suspended state.  */
+  @}
+@end smallexample
+
+@subsubsection PowerPC HTM High Level Inline Functions
+
+The following high level HTM interface is made available by including
+@code{<htmxlintrin.h>} and using @option{-mhtm} or @option{-mcpu=CPU}
+where CPU is `power8' or later.  This interface is common between PowerPC
+and S/390, allowing users to write one HTM source implementation that
+can be compiled and executed on either system.
+
+@smallexample
+long __TM_simple_begin (void)
+long __TM_begin (void* const TM_buff)
+long __TM_end (void)
+void __TM_abort (void)
+void __TM_named_abort (unsigned char const code)
+void __TM_resume (void)
+void __TM_suspend (void)
+
+long __TM_is_user_abort (void* const TM_buff)
+long __TM_is_named_user_abort (void* const TM_buff, unsigned char *code)
+long __TM_is_illegal (void* const TM_buff)
+long __TM_is_footprint_exceeded (void* const TM_buff)
+long __TM_nesting_depth (void* const TM_buff)
+long __TM_is_nested_too_deep(void* const TM_buff)
+long __TM_is_conflict(void* const TM_buff)
+long __TM_is_failure_persistent(void* const TM_buff)
+long __TM_failure_address(void* const TM_buff)
+long long __TM_failure_code(void* const TM_buff)
+@end smallexample
+
+Using these common set of HTM inline functions, we can create
+a more portable version of the HTM example in the previous
+section that will work on either PowerPC or S/390:
+
+@smallexample
+#include <htmxlintrin.h>
+
+int num_retries = 10;
+TM_buff_type TM_buff;
+
+while (1)
+  @{
+    if (__TM_begin (TM_buff))
+      @{
+        /* Transaction State Initiated.  */
+        if (is_locked (lock))
+          __TM_abort ();
+        ... transaction code...
+        __TM_end ();
+        break;
+      @}
+    else
+      @{
+        /* Transaction State Failed.  Use locks if the transaction
+           failure is "persistent" or we've tried too many times.  */
+        if (num_retries-- <= 0
+            || __TM_is_failure_persistent (TM_buff))
+          @{
+            acquire_lock (lock);
+            ... non transactional fallback path...
+            release_lock (lock);
+            break;
+          @}
+      @}
+  @}
+@end smallexample
+
 @node RX Built-in Functions
 @subsection RX Built-in Functions
 GCC supports some of the RX instructions which cannot be expressed in
Index: gcc-4_8-test/libitm/acinclude.m4
===================================================================
--- gcc-4_8-test.orig/libitm/acinclude.m4
+++ gcc-4_8-test/libitm/acinclude.m4
@@ -134,6 +134,20 @@  s390*)
   ;;
 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: gcc-4_8-test/libitm/configure
===================================================================
--- gcc-4_8-test.orig/libitm/configure
+++ gcc-4_8-test/libitm/configure
@@ -17401,6 +17401,43 @@  $as_echo "#define HAVE_AS_HTM 1" >>confd
 esac
 LIBITM_CHECK_AS_HTM
 
+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; }