diff -u gcc-4.8-4.8.4/debian/changelog gcc-4.8-4.8.4/debian/changelog --- gcc-4.8-4.8.4/debian/changelog +++ gcc-4.8-4.8.4/debian/changelog @@ -1,3 +1,14 @@ +gcc-4.8 (4.8.4-2ubuntu1~14.04.1) trusty-proposed; urgency=medium + + * SRU: + * Fix auto-loading of gdb pretty printers. LP: #1446828. + * Fix PR libstdc++/56158, taken from the trunk. + Addresses: #804521. LP: #1514309. + * Backport PR target/64579 and PR target/67281 from the trunk (HTM fixes). + LP: #1517093. + + -- Matthias Klose Wed, 18 Nov 2015 17:48:36 +0100 + gcc-4.8 (4.8.4-2ubuntu1~14.04) trusty-proposed; urgency=medium * SRU LP: #1311866. diff -u gcc-4.8-4.8.4/debian/patches/gcc-multiarch.diff gcc-4.8-4.8.4/debian/patches/gcc-multiarch.diff --- gcc-4.8-4.8.4/debian/patches/gcc-multiarch.diff +++ gcc-4.8-4.8.4/debian/patches/gcc-multiarch.diff @@ -17,14 +17,12 @@ =================================================================== --- a/src/libstdc++-v3/python/hook.in +++ b/src/libstdc++-v3/python/hook.in -@@ -47,14 +47,18 @@ if gdb.current_objfile () is not None: +@@ -47,14 +47,16 @@ libdir = libdir[len (prefix):] # Compute the ".."s needed to get from libdir to the prefix. - dotdots = ('..' + os.sep) * len (libdir.split (os.sep)) + backdirs = len (libdir.split (os.sep)) -+ if not os.path.basename(os.path.dirname(__file__)).startswith('lib'): -+ backdirs += 1 # multiarch subdir + dotdots = ('..' + os.sep) * backdirs objfile = gdb.current_objfile ().filename @@ -53,7 +51,7 @@ =================================================================== --- a/src/gcc/config/sparc/t-linux64 +++ b/src/gcc/config/sparc/t-linux64 -@@ -27,3 +27,5 @@ MULTILIB_OPTIONS = m64/m32 +@@ -27,3 +27,5 @@ MULTILIB_DIRNAMES = 64 32 MULTILIB_OSDIRNAMES = ../lib64$(call if_multiarch,:sparc64-linux-gnu) MULTILIB_OSDIRNAMES += $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:sparc-linux-gnu) @@ -63,7 +61,7 @@ =================================================================== --- a/src/gcc/config/s390/t-linux64 +++ b/src/gcc/config/s390/t-linux64 -@@ -9,3 +9,5 @@ MULTILIB_OPTIONS = m64/m31 +@@ -9,3 +9,5 @@ MULTILIB_DIRNAMES = 64 32 MULTILIB_OSDIRNAMES = ../lib64$(call if_multiarch,:s390x-linux-gnu) MULTILIB_OSDIRNAMES += $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:s390-linux-gnu) @@ -73,7 +71,7 @@ =================================================================== --- a/src/gcc/config/rs6000/t-linux +++ b/src/gcc/config/rs6000/t-linux -@@ -5,7 +5,7 @@ ifneq (,$(findstring powerpc64,$(target) +@@ -5,7 +5,7 @@ MULTILIB_OSDIRNAMES := .=../lib64$(call if_multiarch,:powerpc64-linux-gnu) else ifneq (,$(findstring spe,$(target))) @@ -86,7 +84,7 @@ =================================================================== --- a/src/gcc/config/rs6000/t-linux64 +++ b/src/gcc/config/rs6000/t-linux64 -@@ -30,3 +30,5 @@ MULTILIB_DIRNAMES := 64 32 +@@ -30,3 +30,5 @@ MULTILIB_EXTRA_OPTS := MULTILIB_OSDIRNAMES := m64=../lib64$(call if_multiarch,:powerpc64-linux-gnu) MULTILIB_OSDIRNAMES += m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu) @@ -96,7 +94,7 @@ =================================================================== --- a/src/gcc/config/i386/t-linux64 +++ b/src/gcc/config/i386/t-linux64 -@@ -36,3 +36,13 @@ MULTILIB_DIRNAMES = $(patsubst m%, %, +@@ -36,3 +36,13 @@ MULTILIB_OSDIRNAMES = m64=../lib64$(call if_multiarch,:x86_64-linux-gnu) MULTILIB_OSDIRNAMES+= m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:i386-linux-gnu) MULTILIB_OSDIRNAMES+= mx32=../libx32$(call if_multiarch,:x86_64-linux-gnux32) @@ -129,7 +127,7 @@ =================================================================== --- a/src/gcc/config.gcc +++ b/src/gcc/config.gcc -@@ -1806,8 +1806,11 @@ mips*-mti-linux*) +@@ -1806,8 +1806,11 @@ mips64*-*-linux* | mipsisa64*-*-linux*) tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file} mips/gnu-user.h mips/gnu-user64.h mips/linux64.h mips/linux-common.h" tmake_file="${tmake_file} mips/t-linux64" @@ -142,7 +140,7 @@ mips64el-st-linux-gnu) tm_file="${tm_file} mips/st.h" tmake_file="${tmake_file} mips/t-st" -@@ -3761,7 +3764,7 @@ case ${target} in +@@ -3761,7 +3764,7 @@ i[34567]86-*-darwin* | x86_64-*-darwin*) ;; i[34567]86-*-linux* | x86_64-*-linux*) @@ -155,7 +153,7 @@ =================================================================== --- a/src/gcc/java/jvspec.c +++ b/src/gcc/java/jvspec.c -@@ -59,7 +59,7 @@ static const char jvgenmain_spec[] = +@@ -59,7 +59,7 @@ "jvgenmain %{findirect-dispatch} %{D*} %b %m.i |\n\ cc1 %m.i %1 \ %{!Q:-quiet} -dumpbase %b.c %{d*} %{m*}\ @@ -168,7 +166,7 @@ =================================================================== --- a/src/gcc/config/aarch64/t-aarch64-linux +++ b/src/gcc/config/aarch64/t-aarch64-linux -@@ -22,4 +22,4 @@ LIB1ASMSRC = aarch64/lib1funcs.asm +@@ -22,4 +22,4 @@ LIB1ASMFUNCS = _aarch64_sync_cache_range AARCH_BE = $(if $(findstring TARGET_BIG_ENDIAN_DEFAULT=1, $(tm_defines)),_be) diff -u gcc-4.8-4.8.4/debian/rules.parameters gcc-4.8-4.8.4/debian/rules.parameters --- gcc-4.8-4.8.4/debian/rules.parameters +++ gcc-4.8-4.8.4/debian/rules.parameters @@ -2,14 +2,14 @@ GCC_VERSION := 4.8.4 NEXT_GCC_VERSION := 4.8.5 BASE_VERSION := 4.8 -SOURCE_VERSION := 4.8.4-2ubuntu1~14.04 -DEB_VERSION := 4.8.4-2ubuntu1~14.04 -DEB_EVERSION := 1:4.8.4-2ubuntu1~14.04 -DEB_GDC_VERSION := 4.8.4-2ubuntu1~14.04 +SOURCE_VERSION := 4.8.4-2ubuntu1~14.04.1 +DEB_VERSION := 4.8.4-2ubuntu1~14.04.1 +DEB_EVERSION := 1:4.8.4-2ubuntu1~14.04.1 +DEB_GDC_VERSION := 4.8.4-2ubuntu1~14.04.1 DEB_SOVERSION := 4.8 DEB_SOEVERSION := 1:4.8 DEB_LIBGCC_SOVERSION := -DEB_LIBGCC_VERSION := 1:4.8.4-2ubuntu1~14.04 +DEB_LIBGCC_VERSION := 1:4.8.4-2ubuntu1~14.04.1 DEB_STDCXX_SOVERSION := 4.8 DEB_GCJ_SOVERSION := 4.8 PKG_GCJ_EXT := 14 diff -u gcc-4.8-4.8.4/debian/rules.patch gcc-4.8-4.8.4/debian/rules.patch --- gcc-4.8-4.8.4/debian/rules.patch +++ gcc-4.8-4.8.4/debian/rules.patch @@ -33,6 +33,8 @@ debian_patches += \ rename-info-files \ $(if $(with_linaro_branch),gcc-linaro-doc) \ + pr64579-doc \ + pr67281-doc \ # svn-doc-updates \ # $(if $(with_linaro_branch),,svn-doc-updates) \ @@ -104,6 +106,9 @@ pr62032 \ pr59586 \ pr62255 \ + pr56158 \ + pr64579 \ + pr67281 \ # FIXME: still necessary for cross building the native compiler? # gcc-auto-build \ only in patch2: unchanged: --- gcc-4.8-4.8.4.orig/debian/patches/pr56158.diff +++ gcc-4.8-4.8.4/debian/patches/pr56158.diff @@ -0,0 +1,85 @@ +# DP: Fix PR libstdc++/56158, taken from the trunk + +libstdc++-v3/ +2015-11-12 Jonathan Wakely + + PR libstdc++/56158 + * include/bits/ios_base.h (_Ios_Fmtflags, _Ios_Openmode, _Ios_Iostate): + Define enumerators to ensure all values of type int are valid values + of the enumeration type. + * testsuite/27_io/ios_base/types/fmtflags/case_label.cc: Add new cases. + * testsuite/27_io/ios_base/types/iostate/case_label.cc: Likewise. + * testsuite/27_io/ios_base/types/openmode/case_label.cc: Likewise. + + +--- a/src/libstdc++-v3/include/bits/ios_base.h ++++ b/src/libstdc++-v3/include/bits/ios_base.h +@@ -74,7 +74,9 @@ + _S_adjustfield = _S_left | _S_right | _S_internal, + _S_basefield = _S_dec | _S_oct | _S_hex, + _S_floatfield = _S_scientific | _S_fixed, +- _S_ios_fmtflags_end = 1L << 16 ++ _S_ios_fmtflags_end = 1L << 16, ++ _S_ios_fmtflags_max = __INT_MAX__, ++ _S_ios_fmtflags_min = ~__INT_MAX__ + }; + + inline _GLIBCXX_CONSTEXPR _Ios_Fmtflags +@@ -114,7 +116,9 @@ + _S_in = 1L << 3, + _S_out = 1L << 4, + _S_trunc = 1L << 5, +- _S_ios_openmode_end = 1L << 16 ++ _S_ios_openmode_end = 1L << 16, ++ _S_ios_openmode_max = __INT_MAX__, ++ _S_ios_openmode_min = ~__INT_MAX__ + }; + + inline _GLIBCXX_CONSTEXPR _Ios_Openmode +@@ -152,7 +156,9 @@ + _S_badbit = 1L << 0, + _S_eofbit = 1L << 1, + _S_failbit = 1L << 2, +- _S_ios_iostate_end = 1L << 16 ++ _S_ios_iostate_end = 1L << 16, ++ _S_ios_iostate_max = __INT_MAX__, ++ _S_ios_iostate_min = ~__INT_MAX__ + }; + + inline _GLIBCXX_CONSTEXPR _Ios_Iostate +--- a/src/libstdc++-v3/testsuite/27_io/ios_base/types/fmtflags/case_label.cc ++++ b/src/libstdc++-v3/testsuite/27_io/ios_base/types/fmtflags/case_label.cc +@@ -70,5 +70,9 @@ + break; + case std::_S_ios_fmtflags_end: + break; ++ case std::_S_ios_fmtflags_min: ++ break; ++ case std::_S_ios_fmtflags_max: ++ break; + } + } +--- a/src/libstdc++-v3/testsuite/27_io/ios_base/types/openmode/case_label.cc ++++ b/src/libstdc++-v3/testsuite/27_io/ios_base/types/openmode/case_label.cc +@@ -46,5 +46,9 @@ + break; + case std::_S_ios_openmode_end: + break; ++ case std::_S_ios_openmode_min: ++ break; ++ case std::_S_ios_openmode_max: ++ break; + } + } +--- a/src/libstdc++-v3/testsuite/27_io/ios_base/types/iostate/case_label.cc ++++ b/src/libstdc++-v3/testsuite/27_io/ios_base/types/iostate/case_label.cc +@@ -42,5 +42,9 @@ + break; + case std::_S_ios_iostate_end: + break; ++ case std::_S_ios_iostate_min: ++ break; ++ case std::_S_ios_iostate_max: ++ break; + } + } only in patch2: unchanged: --- gcc-4.8-4.8.4.orig/debian/patches/pr64579-doc.diff +++ gcc-4.8-4.8.4/debian/patches/pr64579-doc.diff @@ -0,0 +1,42 @@ +# DP: Fix PR target/64579, taken from the gcc-4_8-branch (documentation). + +--- a/src/gcc/doc/extend.texi ++++ b/src/gcc/doc/extend.texi +@@ -14538,10 +14538,15 @@ + @option{-mhtm} or @option{-mcpu=CPU} where CPU is `power8' or later. + They all generate the machine instruction that is part of the name. + +-The HTM built-ins return true or false depending on their success and +-their arguments match exactly the type and order of the associated +-hardware instruction's operands. Refer to the ISA manual for a +-description of each instruction's operands. ++The HTM builtins (with the exception of @code{__builtin_tbegin}) return ++the full 4-bit condition register value set by their associated hardware ++instruction. The header file @code{htmintrin.h} defines some macros that can ++be used to decipher the return value. The @code{__builtin_tbegin} builtin ++returns a simple true or false value depending on whether a transaction was ++successfully started or not. The arguments of the builtins match exactly the ++type and order of the associated hardware instruction's operands, except for ++the @code{__builtin_tcheck} builtin, which does not take any input arguments. ++Refer to the ISA manual for a description of each instruction's operands. + + @smallexample + unsigned int __builtin_tbegin (unsigned int) +@@ -14553,7 +14558,7 @@ + unsigned int __builtin_tabortwc (unsigned int, unsigned int, unsigned int) + unsigned int __builtin_tabortwci (unsigned int, unsigned int, int) + +-unsigned int __builtin_tcheck (unsigned int) ++unsigned int __builtin_tcheck (void) + unsigned int __builtin_treclaim (unsigned int) + unsigned int __builtin_trechkpt (void) + unsigned int __builtin_tsr (unsigned int) +@@ -14688,7 +14693,7 @@ + + while (1) + @{ +- if (__TM_begin (TM_buff)) ++ if (__TM_begin (TM_buff) == _HTM_TBEGIN_STARTED) + @{ + /* Transaction State Initiated. */ + if (is_locked (lock)) only in patch2: unchanged: --- gcc-4.8-4.8.4.orig/debian/patches/pr64579.diff +++ gcc-4.8-4.8.4/debian/patches/pr64579.diff @@ -0,0 +1,865 @@ +# DP: Fix PR target/64579, taken from the gcc-4_8-branch. + +gcc/ + +2015-05-05 Peter Bergner + + Backport from mainline. + 2015-04-27 Peter Bergner + + PR target/64579 + * config/rs6000/htm.md: Remove all define_expands. + (UNSPECV_HTM_TABORTDC, UNSPECV_HTM_TABORTDCI, UNSPECV_HTM_TABORTWC, + UNSPECV_HTM_TABORTWCI): Remove. + (UNSPECV_HTM_TABORTXC, UNSPECV_HTM_TABORTXCI, UNSPECV_HTM_TTEST): New. + (tabort_internal, tbegin_internal, tcheck_internal, tend_internal, + trechkpt_internal, treclaim_internal, tsr_internal): Rename from this... + (tabort, tbegin, tcheck, tend, trechkpt, treclaim, tsr): ...to this. + (tabortdc_internal, tabortdci_internal, tabortwc_internal, + tabortwci_internal): Remove define_insns. + (tabortc, tabortci): New define_insns. + (tabort): Use gpc_reg_operand. + (tcheck): Remove operand. + (htm_mfspr_, htm_mtspr_): Use GPR mode macro. + * config/rs6000/htmxlintrin.h (__TM_end): Use _HTM_TRANSACTIONAL as + expected value. + * config/rs6000/rs6000-builtin.def (BU_HTM_SPR0): Remove. + (BU_HTM_SPR1): Rename to BU_HTM_V1. Remove use of RS6000_BTC_SPR. + (tabort, tabortdc, tabortdci, tabortwc, tabortwci, tbegin, + tcheck, tend, tendall, trechkpt, treclaim, tresume, tsuspend, + tsr, ttest): Pass in the RS6000_BTC_CR attribute. + (get_tfhar, set_tfhar, get_tfiar, set_tfiar, get_texasr, set_texasr, + get_texasru, set_texasru): Pass in the RS6000_BTC_SPR attribute. + (tcheck): Remove builtin argument. + * config/rs6000/rs6000.c (rs6000_htm_spr_icode): Use TARGET_POWERPC64 + not TARGET_64BIT. + (htm_expand_builtin): Fix usage of expandedp. Disallow usage of the + tabortdc and tabortdci builtins when not in 64-bit mode. + Modify code to handle the loss of the HTM define_expands. + Emit code to copy the CR register to TARGET. + (htm_init_builtins): Modify code to handle the loss of the HTM + define_expands. + * config/rs6000/rs6000.h (RS6000_BTC_32BIT): Delete. + (RS6000_BTC_64BIT): Likewise. + (RS6000_BTC_CR): New macro. + * doc/extend.texi: Update documentation for htm builtins. + +gcc/testsuite/ + +2015-05-05 Peter Bergner + + Backport from mainline. + 2015-04-27 Peter Bergner + + PR target/64579 + * gcc.target/powerpc/htm-1.c: New test. + * gcc.target/powerpc/htm-builtin-1.c (__builtin_tabortdc): Only test + on 64-bit compiles. + (__builtin_tabortdci): Likewise. + (__builtin_tcheck): Remove operand. + * lib/target-supports.exp (check_htm_hw_available): New function. + +--- a/src/gcc/testsuite/gcc.target/powerpc/htm-1.c ++++ b/src/gcc/testsuite/gcc.target/powerpc/htm-1.c +@@ -0,0 +1,52 @@ ++/* { dg-do run { target { powerpc*-*-* && htm_hw } } } */ ++/* { dg-require-effective-target powerpc_htm_ok } */ ++/* { dg-options "-mhtm" } */ ++ ++/* Program to test PowerPC HTM instructions. */ ++ ++#include ++#include ++ ++int ++main (void) ++{ ++ long i; ++ unsigned long mask = 0; ++ ++repeat: ++ if (__builtin_tbegin (0)) ++ { ++ mask++; ++ } ++ else ++ abort(); ++ ++ if (mask == 1) ++ { ++ __builtin_tsuspend (); ++ ++ if (_HTM_STATE (__builtin_tcheck ()) != _HTM_SUSPENDED) ++ abort (); ++ ++ __builtin_tresume (); ++ ++ if (_HTM_STATE (__builtin_tcheck ()) != _HTM_TRANSACTIONAL) ++ abort (); ++ } ++ else ++ mask++; ++ ++ if (_HTM_STATE (__builtin_tendall ()) != _HTM_TRANSACTIONAL) ++ abort (); ++ ++ if (mask == 1) ++ goto repeat; ++ ++ if (_HTM_STATE (__builtin_tendall ()) != _HTM_NONTRANSACTIONAL) ++ abort (); ++ ++ if (mask != 3) ++ abort (); ++ ++ return 0; ++} +--- a/src/gcc/testsuite/gcc.target/powerpc/htm-builtin-1.c ++++ b/src/gcc/testsuite/gcc.target/powerpc/htm-builtin-1.c +@@ -6,8 +6,8 @@ + /* { dg-final { scan-assembler-times "tbegin\\." 1 } } */ + /* { dg-final { scan-assembler-times "tend\\." 2 } } */ + /* { dg-final { scan-assembler-times "tabort\\." 2 } } */ +-/* { dg-final { scan-assembler-times "tabortdc\\." 1 } } */ +-/* { dg-final { scan-assembler-times "tabortdci\\." 1 } } */ ++/* { dg-final { scan-assembler-times "tabortdc\\." 1 { target lp64 } } } */ ++/* { dg-final { scan-assembler-times "tabortdci\\." 1 { target lp64 } } } */ + /* { dg-final { scan-assembler-times "tabortwc\\." 1 } } */ + /* { dg-final { scan-assembler-times "tabortwci\\." 2 } } */ + /* { dg-final { scan-assembler-times "tcheck" 1 } } */ +@@ -25,12 +25,14 @@ + p[3] = __builtin_tabort (0); + p[4] = __builtin_tabort (code); + ++#ifdef __powerpc64__ + p[5] = __builtin_tabortdc (0xf, a[5], b[5]); + p[6] = __builtin_tabortdci (0xf, a[6], 13); ++#endif + p[7] = __builtin_tabortwc (0xf, a[7], b[7]); + p[8] = __builtin_tabortwci (0xf, a[8], 13); + +- p[9] = __builtin_tcheck (5); ++ p[9] = __builtin_tcheck (); + p[10] = __builtin_trechkpt (); + p[11] = __builtin_treclaim (0); + p[12] = __builtin_tresume (); +--- a/src/gcc/testsuite/lib/target-supports.exp ++++ b/src/gcc/testsuite/lib/target-supports.exp +@@ -2808,6 +2808,25 @@ + } + } + ++# Return 1 if the target supports executing HTM hardware instructions, ++# 0 otherwise. Cache the result. ++ ++proc check_htm_hw_available { } { ++ return [check_cached_effective_target htm_hw_available { ++ # For now, disable on Darwin ++ if { [istarget powerpc-*-eabi] || [istarget powerpc*-*-eabispe] || [istarget *-*-darwin*]} { ++ expr 0 ++ } else { ++ check_runtime_nocache htm_hw_available { ++ int main() ++ { ++ __builtin_ttest (); ++ return 0; ++ } ++ } "-mhtm" ++ } ++ }] ++} + # Return 1 if this is a PowerPC target supporting -mcpu=cell. + + proc check_effective_target_powerpc_ppu_ok { } { +@@ -4629,6 +4648,7 @@ + "p8vector_hw" { set selected [check_p8vector_hw_available] } + "ppc_recip_hw" { set selected [check_ppc_recip_hw_available] } + "dfp_hw" { set selected [check_dfp_hw_available] } ++ "htm_hw" { set selected [check_htm_hw_available] } + "named_sections" { set selected [check_named_sections_available] } + "gc_sections" { set selected [check_gc_sections_available] } + "cxa_atexit" { set selected [check_cxa_atexit_available] } +@@ -4652,6 +4672,7 @@ + "p8vector_hw" { return 1 } + "ppc_recip_hw" { return 1 } + "dfp_hw" { return 1 } ++ "htm_hw" { return 1 } + "named_sections" { return 1 } + "gc_sections" { return 1 } + "cxa_atexit" { return 1 } +--- a/src/gcc/config/rs6000/htm.md ++++ b/src/gcc/config/rs6000/htm.md +@@ -1,5 +1,5 @@ + ;; Hardware Transactional Memory (HTM) patterns. +-;; Copyright (C) 2013 Free Software Foundation, Inc. ++;; Copyright (C) 2013-2015 Free Software Foundation, Inc. + ;; Contributed by Peter Bergner . + + ;; This file is part of GCC. +@@ -32,10 +32,8 @@ + + (define_c_enum "unspecv" + [UNSPECV_HTM_TABORT +- UNSPECV_HTM_TABORTDC +- UNSPECV_HTM_TABORTDCI +- UNSPECV_HTM_TABORTWC +- UNSPECV_HTM_TABORTWCI ++ UNSPECV_HTM_TABORTXC ++ UNSPECV_HTM_TABORTXCI + UNSPECV_HTM_TBEGIN + UNSPECV_HTM_TCHECK + UNSPECV_HTM_TEND +@@ -42,29 +40,15 @@ + UNSPECV_HTM_TRECHKPT + UNSPECV_HTM_TRECLAIM + UNSPECV_HTM_TSR ++ UNSPECV_HTM_TTEST + UNSPECV_HTM_MFSPR + UNSPECV_HTM_MTSPR + ]) + + +-(define_expand "tabort" +- [(set (match_dup 2) +- (unspec_volatile:CC [(match_operand:SI 1 "int_reg_operand" "")] +- UNSPECV_HTM_TABORT)) +- (set (match_dup 3) +- (eq:SI (match_dup 2) +- (const_int 0))) +- (set (match_operand:SI 0 "int_reg_operand" "") +- (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" ++(define_insn "tabort" + [(set (match_operand:CC 1 "cc_reg_operand" "=x") +- (unspec_volatile:CC [(match_operand:SI 0 "int_reg_operand" "r")] ++ (unspec_volatile:CC [(match_operand:SI 0 "gpc_reg_operand" "r")] + UNSPECV_HTM_TABORT))] + "TARGET_HTM" + "tabort. %0" +@@ -71,152 +55,29 @@ + [(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" ++(define_insn "tabortc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n") +- (match_operand:SI 1 "gpc_reg_operand" "r") +- (match_operand:SI 2 "gpc_reg_operand" "r")] +- UNSPECV_HTM_TABORTDC))] ++ (match_operand:GPR 1 "gpc_reg_operand" "r") ++ (match_operand:GPR 2 "gpc_reg_operand" "r")] ++ UNSPECV_HTM_TABORTXC))] + "TARGET_HTM" +- "tabortdc. %0,%1,%2" ++ "tabortc. %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" ++(define_insn "tabortci" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n") +- (match_operand:SI 1 "gpc_reg_operand" "r") ++ (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand 2 "s5bit_cint_operand" "n")] +- UNSPECV_HTM_TABORTDCI))] ++ UNSPECV_HTM_TABORTXCI))] + "TARGET_HTM" +- "tabortdci. %0,%1,%2" ++ "tabortci. %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 28))) +- (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" ++(define_insn "tbegin" + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] + UNSPECV_HTM_TBEGIN))] +@@ -225,24 +86,9 @@ + [(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")] ++(define_insn "tcheck" ++ [(set (match_operand:CC 0 "cc_reg_operand" "=y") ++ (unspec_volatile:CC [(const_int 0)] + UNSPECV_HTM_TCHECK))] + "TARGET_HTM" + "tcheck %0" +@@ -249,22 +95,7 @@ + [(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" ++(define_insn "tend" + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] + UNSPECV_HTM_TEND))] +@@ -273,22 +104,7 @@ + [(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" ++(define_insn "trechkpt" + [(set (match_operand:CC 0 "cc_reg_operand" "=x") + (unspec_volatile:CC [(const_int 0)] + UNSPECV_HTM_TRECHKPT))] +@@ -297,22 +113,7 @@ + [(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" ++(define_insn "treclaim" + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand:SI 0 "gpc_reg_operand" "r")] + UNSPECV_HTM_TRECLAIM))] +@@ -321,22 +122,7 @@ + [(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" ++(define_insn "tsr" + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] + UNSPECV_HTM_TSR))] +@@ -345,11 +131,20 @@ + [(set_attr "type" "htm") + (set_attr "length" "4")]) + ++(define_insn "ttest" ++ [(set (match_operand:CC 0 "cc_reg_operand" "=x") ++ (unspec_volatile:CC [(const_int 0)] ++ UNSPECV_HTM_TTEST))] ++ "TARGET_HTM" ++ "tabortwci. 0,1,0" ++ [(set_attr "type" "htm") ++ (set_attr "length" "4")]) ++ + (define_insn "htm_mfspr_" +- [(set (match_operand:P 0 "gpc_reg_operand" "=r") +- (unspec_volatile:P [(match_operand 1 "u10bit_cint_operand" "n") +- (match_operand:P 2 "htm_spr_reg_operand" "")] +- UNSPECV_HTM_MFSPR))] ++ [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") ++ (unspec_volatile:GPR [(match_operand 1 "u10bit_cint_operand" "n") ++ (match_operand:GPR 2 "htm_spr_reg_operand" "")] ++ UNSPECV_HTM_MFSPR))] + "TARGET_HTM" + "mfspr %0,%1"; + [(set_attr "type" "htm") +@@ -356,10 +151,10 @@ + (set_attr "length" "4")]) + + (define_insn "htm_mtspr_" +- [(set (match_operand:P 2 "htm_spr_reg_operand" "") +- (unspec_volatile:P [(match_operand:P 0 "gpc_reg_operand" "r") +- (match_operand 1 "u10bit_cint_operand" "n")] +- UNSPECV_HTM_MTSPR))] ++ [(set (match_operand:GPR 2 "htm_spr_reg_operand" "") ++ (unspec_volatile:GPR [(match_operand:GPR 0 "gpc_reg_operand" "r") ++ (match_operand 1 "u10bit_cint_operand" "n")] ++ UNSPECV_HTM_MTSPR))] + "TARGET_HTM" + "mtspr %1,%0"; + [(set_attr "type" "htm") +--- a/src/gcc/config/rs6000/htmxlintrin.h ++++ b/src/gcc/config/rs6000/htmxlintrin.h +@@ -81,7 +81,8 @@ + __attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) + __TM_end (void) + { +- if (__builtin_expect (__builtin_tend (0), 1)) ++ unsigned char status = _HTM_STATE (__builtin_tend (0)); ++ if (__builtin_expect (status, _HTM_TRANSACTIONAL)) + return 1; + return 0; + } +--- a/src/gcc/config/rs6000/rs6000-builtin.def ++++ b/src/gcc/config/rs6000/rs6000-builtin.def +@@ -480,21 +480,12 @@ + | RS6000_BTC_TERNARY), \ + CODE_FOR_ ## ICODE) /* ICODE */ + +-#define BU_HTM_SPR0(ENUM, NAME, ATTR, ICODE) \ ++#define BU_HTM_V1(ENUM, NAME, ATTR, ICODE) \ + RS6000_BUILTIN_H (HTM_BUILTIN_ ## ENUM, /* ENUM */ \ + "__builtin_" NAME, /* NAME */ \ + RS6000_BTM_HTM, /* MASK */ \ + (RS6000_BTC_ ## ATTR /* ATTR */ \ +- | RS6000_BTC_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 */ + +@@ -1657,30 +1648,30 @@ + + + /* 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_1 (TABORT, "tabort", CR, tabort) ++BU_HTM_3 (TABORTDC, "tabortdc", CR, tabortdc) ++BU_HTM_3 (TABORTDCI, "tabortdci", CR, tabortdci) ++BU_HTM_3 (TABORTWC, "tabortwc", CR, tabortwc) ++BU_HTM_3 (TABORTWCI, "tabortwci", CR, tabortwci) ++BU_HTM_1 (TBEGIN, "tbegin", CR, tbegin) ++BU_HTM_0 (TCHECK, "tcheck", CR, tcheck) ++BU_HTM_1 (TEND, "tend", CR, tend) ++BU_HTM_0 (TENDALL, "tendall", CR, tend) ++BU_HTM_0 (TRECHKPT, "trechkpt", CR, trechkpt) ++BU_HTM_1 (TRECLAIM, "treclaim", CR, treclaim) ++BU_HTM_0 (TRESUME, "tresume", CR, tsr) ++BU_HTM_0 (TSUSPEND, "tsuspend", CR, tsr) ++BU_HTM_1 (TSR, "tsr", CR, tsr) ++BU_HTM_0 (TTEST, "ttest", CR, ttest) + +-BU_HTM_SPR0 (GET_TFHAR, "get_tfhar", MISC, nothing) +-BU_HTM_SPR1 (SET_TFHAR, "set_tfhar", MISC, nothing) +-BU_HTM_SPR0 (GET_TFIAR, "get_tfiar", MISC, nothing) +-BU_HTM_SPR1 (SET_TFIAR, "set_tfiar", MISC, nothing) +-BU_HTM_SPR0 (GET_TEXASR, "get_texasr", MISC, nothing) +-BU_HTM_SPR1 (SET_TEXASR, "set_texasr", MISC, nothing) +-BU_HTM_SPR0 (GET_TEXASRU, "get_texasru", MISC, nothing) +-BU_HTM_SPR1 (SET_TEXASRU, "set_texasru", MISC, nothing) ++BU_HTM_0 (GET_TFHAR, "get_tfhar", SPR, nothing) ++BU_HTM_V1 (SET_TFHAR, "set_tfhar", SPR, nothing) ++BU_HTM_0 (GET_TFIAR, "get_tfiar", SPR, nothing) ++BU_HTM_V1 (SET_TFIAR, "set_tfiar", SPR, nothing) ++BU_HTM_0 (GET_TEXASR, "get_texasr", SPR, nothing) ++BU_HTM_V1 (SET_TEXASR, "set_texasr", SPR, nothing) ++BU_HTM_0 (GET_TEXASRU, "get_texasru", SPR, nothing) ++BU_HTM_V1 (SET_TEXASRU, "set_texasru", SPR, nothing) + + + /* 3 argument paired floating point builtins. */ +--- a/src/gcc/config/rs6000/rs6000.c ++++ b/src/gcc/config/rs6000/rs6000.c +@@ -12418,9 +12418,9 @@ + rs6000_htm_spr_icode (bool nonvoid) + { + if (nonvoid) +- return (TARGET_64BIT) ? CODE_FOR_htm_mfspr_di : CODE_FOR_htm_mfspr_si; ++ return (TARGET_POWERPC64) ? CODE_FOR_htm_mfspr_di : CODE_FOR_htm_mfspr_si; + else +- return (TARGET_64BIT) ? CODE_FOR_htm_mtspr_di : CODE_FOR_htm_mtspr_si; ++ return (TARGET_POWERPC64) ? CODE_FOR_htm_mtspr_di : CODE_FOR_htm_mtspr_si; + } + + /* Expand the HTM builtin in EXP and store the result in TARGET. +@@ -12434,8 +12434,18 @@ + const struct builtin_description *d; + size_t i; + +- *expandedp = false; ++ *expandedp = true; + ++ if (!TARGET_POWERPC64 ++ && (fcode == HTM_BUILTIN_TABORTDC ++ || fcode == HTM_BUILTIN_TABORTDCI)) ++ { ++ size_t uns_fcode = (size_t)fcode; ++ const char *name = rs6000_builtin_info[uns_fcode].name; ++ error ("builtin %s is only valid in 64-bit mode", name); ++ return const0_rtx; ++ } ++ + /* Expand the HTM builtins. */ + d = bdesc_htm; + for (i = 0; i < ARRAY_SIZE (bdesc_htm); i++, d++) +@@ -12447,26 +12457,29 @@ + call_expr_arg_iterator iter; + unsigned attr = rs6000_builtin_info[fcode].attr; + enum insn_code icode = d->icode; ++ const struct insn_operand_data *insn_op; ++ bool uses_spr = (attr & RS6000_BTC_SPR); ++ rtx cr = NULL_RTX; + +- if (attr & RS6000_BTC_SPR) ++ if (uses_spr) + icode = rs6000_htm_spr_icode (nonvoid); ++ insn_op = &insn_data[icode].operand[0]; + + if (nonvoid) + { +- enum machine_mode tmode = insn_data[icode].operand[0].mode; ++ machine_mode tmode = (uses_spr) ? insn_op->mode : SImode; + if (!target + || GET_MODE (target) != tmode +- || !(*insn_data[icode].operand[0].predicate) (target, tmode)) ++ || (uses_spr && !(*insn_op->predicate) (target, tmode))) + target = gen_reg_rtx (tmode); +- op[nopnds++] = target; ++ if (uses_spr) ++ op[nopnds++] = target; + } + + FOR_EACH_CALL_EXPR_ARG (arg, iter, exp) + { +- const struct insn_operand_data *insn_op; +- + if (arg == error_mark_node || nopnds >= MAX_HTM_OPERANDS) +- return NULL_RTX; ++ return const0_rtx; + + insn_op = &insn_data[icode].operand[nopnds]; + +@@ -12513,11 +12526,18 @@ + + /* If this builtin accesses SPRs, then pass in the appropriate + SPR number and SPR regno as the last two operands. */ +- if (attr & RS6000_BTC_SPR) ++ if (uses_spr) + { +- op[nopnds++] = gen_rtx_CONST_INT (Pmode, htm_spr_num (fcode)); +- op[nopnds++] = gen_rtx_REG (Pmode, htm_spr_regno (fcode)); ++ machine_mode mode = (TARGET_POWERPC64) ? DImode : SImode; ++ op[nopnds++] = gen_rtx_CONST_INT (mode, htm_spr_num (fcode)); ++ op[nopnds++] = gen_rtx_REG (mode, htm_spr_regno (fcode)); + } ++ /* If this builtin accesses a CR, then pass in a scratch ++ CR as the last operand. */ ++ else if (attr & RS6000_BTC_CR) ++ { cr = gen_reg_rtx (CCmode); ++ op[nopnds++] = cr; ++ } + + #ifdef ENABLE_CHECKING + int expected_nopnds = 0; +@@ -12529,7 +12549,7 @@ + expected_nopnds = 3; + if (!(attr & RS6000_BTC_VOID)) + expected_nopnds += 1; +- if (attr & RS6000_BTC_SPR) ++ if (uses_spr) + expected_nopnds += 2; + + gcc_assert (nopnds == expected_nopnds && nopnds <= MAX_HTM_OPERANDS); +@@ -12559,12 +12579,41 @@ + return NULL_RTX; + emit_insn (pat); + +- *expandedp = true; ++ if (attr & RS6000_BTC_CR) ++ { ++ if (fcode == HTM_BUILTIN_TBEGIN) ++ { ++ /* Emit code to set TARGET to true or false depending on ++ whether the tbegin. instruction successfully or failed ++ to start a transaction. We do this by placing the 1's ++ complement of CR's EQ bit into TARGET. */ ++ rtx scratch = gen_reg_rtx (SImode); ++ emit_insn (gen_rtx_SET (VOIDmode, scratch, ++ gen_rtx_EQ (SImode, cr, ++ const0_rtx))); ++ emit_insn (gen_rtx_SET (VOIDmode, target, ++ gen_rtx_XOR (SImode, scratch, ++ GEN_INT (1)))); ++ } ++ else ++ { ++ /* Emit code to copy the 4-bit condition register field ++ CR into the least significant end of register TARGET. */ ++ rtx scratch1 = gen_reg_rtx (SImode); ++ rtx scratch2 = gen_reg_rtx (SImode); ++ rtx subreg = simplify_gen_subreg (CCmode, scratch1, SImode, 0); ++ emit_insn (gen_movcc (subreg, cr)); ++ emit_insn (gen_lshrsi3 (scratch2, scratch1, GEN_INT (28))); ++ emit_insn (gen_andsi3 (target, scratch2, GEN_INT (0xf))); ++ } ++ } ++ + if (nonvoid) + return target; + return const0_rtx; + } + ++ *expandedp = false; + return NULL_RTX; + } + +@@ -15041,9 +15090,32 @@ + bool void_func = (attr & RS6000_BTC_VOID); + int attr_args = (attr & RS6000_BTC_TYPE_MASK); + int nopnds = 0; +- tree argtype = (attr & RS6000_BTC_SPR) ? long_unsigned_type_node +- : unsigned_type_node; ++ tree gpr_type_node; ++ tree rettype; ++ tree argtype; + ++ if (TARGET_32BIT && TARGET_POWERPC64) ++ gpr_type_node = long_long_unsigned_type_node; ++ else ++ gpr_type_node = long_unsigned_type_node; ++ ++ if (attr & RS6000_BTC_SPR) ++ { ++ rettype = gpr_type_node; ++ argtype = gpr_type_node; ++ } ++ else if (d->code == HTM_BUILTIN_TABORTDC ++ || d->code == HTM_BUILTIN_TABORTDCI) ++ { ++ rettype = unsigned_type_node; ++ argtype = gpr_type_node; ++ } ++ else ++ { ++ rettype = unsigned_type_node; ++ argtype = unsigned_type_node; ++ } ++ + if ((mask & builtin_mask) != mask) + { + if (TARGET_DEBUG_BUILTIN) +@@ -15059,7 +15131,7 @@ + continue; + } + +- op[nopnds++] = (void_func) ? void_type_node : argtype; ++ op[nopnds++] = (void_func) ? void_type_node : rettype; + + if (attr_args == RS6000_BTC_UNARY) + op[nopnds++] = argtype; +--- a/src/gcc/config/rs6000/rs6000.h ++++ b/src/gcc/config/rs6000/rs6000.h +@@ -2488,9 +2488,8 @@ + /* Miscellaneous information. */ + #define RS6000_BTC_SPR 0x01000000 /* function references SPRs. */ + #define RS6000_BTC_VOID 0x02000000 /* function has no return value. */ +-#define RS6000_BTC_OVERLOADED 0x04000000 /* function is overloaded. */ +-#define RS6000_BTC_32BIT 0x08000000 /* function references SPRs. */ +-#define RS6000_BTC_64BIT 0x10000000 /* function references SPRs. */ ++#define RS6000_BTC_CR 0x04000000 /* function references a CR. */ ++#define RS6000_BTC_OVERLOADED 0x08000000 /* function is overloaded. */ + #define RS6000_BTC_MISC_MASK 0x1f000000 /* Mask of the misc info. */ + + /* Convenience macros to document the instruction type. */ only in patch2: unchanged: --- gcc-4.8-4.8.4.orig/debian/patches/pr67281-doc.diff +++ gcc-4.8-4.8.4/debian/patches/pr67281-doc.diff @@ -0,0 +1,57 @@ +# DP: Backport PR target/67281 from the trunk (HTM fixes) + +Backport from mainline + +2015-10-14 Peter Bergner + Torvald Riegel + + PR target/67281 + * config/rs6000/htm.md (UNSPEC_HTM_FENCE): New. + (tabort, tabortc, tabortci, tbegin, tcheck, tend, + trechkpt, treclaim, tsr, ttest): Rename define_insns from this... + (*tabort, *tabortc, *tabortci, *tbegin, *tcheck, *tend, + *trechkpt, *treclaim, *tsr, *ttest): ...to this. Add memory barrier. + (tabort, tabortc, tabortci, tbegin, tcheck, tend, + trechkpt, treclaim, tsr, ttest): New define_expands. + * config/rs6000/rs6000-c.c (rs6000_target_modify_macros): Define + __TM_FENCE__ for htm. + * doc/extend.texi: Update documentation for htm builtins. + + Backport from mainline: + 2015-08-03 Peter Bergner + + * config/rs6000/htm.md (tabort.): Restrict the source operand to + using a base register. + + +--- a/src/gcc/doc/extend.texi ++++ b/src/gcc/doc/extend.texi +@@ -14573,6 +14573,28 @@ + unsigned int __builtin_tsuspend (void) + @end smallexample + ++Note that the semantics of the above HTM builtins are required to mimic ++the locking semantics used for critical sections. Builtins that are used ++to create a new transaction or restart a suspended transaction must have ++lock acquisition like semantics while those builtins that end or suspend a ++transaction must have lock release like semantics. Specifically, this must ++mimic lock semantics as specified by C++11, for example: Lock acquisition is ++as-if an execution of __atomic_exchange_n(&globallock,1,__ATOMIC_ACQUIRE) ++that returns 0, and lock release is as-if an execution of ++__atomic_store(&globallock,0,__ATOMIC_RELEASE), with globallock being an ++implicit implementation-defined lock used for all transactions. The HTM ++instructions associated with with the builtins inherently provide the ++correct acquisition and release hardware barriers required. However, ++the compiler must also be prohibited from moving loads and stores across ++the builtins in a way that would violate their semantics. This has been ++accomplished by adding memory barriers to the associated HTM instructions ++(which is a conservative approach to provide acquire and release semantics). ++Earlier versions of the compiler did not treat the HTM instructions as ++memory barriers. A @code{__TM_FENCE__} macro has been added, which can ++be used to determine whether the current compiler treats HTM instructions ++as memory barriers or not. This allows the user to explicitly add memory ++barriers to their code when using an older version of the compiler. ++ + The following set of built-in functions are available to gain access + to the HTM specific special purpose registers. + only in patch2: unchanged: --- gcc-4.8-4.8.4.orig/debian/patches/pr67281.diff +++ gcc-4.8-4.8.4/debian/patches/pr67281.diff @@ -0,0 +1,321 @@ +# DP: Backport PR target/67281 from the trunk (HTM fixes) + +Backport from mainline + +2015-10-14 Peter Bergner + Torvald Riegel + + PR target/67281 + * config/rs6000/htm.md (UNSPEC_HTM_FENCE): New. + (tabort, tabortc, tabortci, tbegin, tcheck, tend, + trechkpt, treclaim, tsr, ttest): Rename define_insns from this... + (*tabort, *tabortc, *tabortci, *tbegin, *tcheck, *tend, + *trechkpt, *treclaim, *tsr, *ttest): ...to this. Add memory barrier. + (tabort, tabortc, tabortci, tbegin, tcheck, tend, + trechkpt, treclaim, tsr, ttest): New define_expands. + * config/rs6000/rs6000-c.c (rs6000_target_modify_macros): Define + __TM_FENCE__ for htm. + * doc/extend.texi: Update documentation for htm builtins. + + Backport from mainline: + 2015-08-03 Peter Bergner + + * config/rs6000/htm.md (tabort.): Restrict the source operand to + using a base register. + + +--- a/src/gcc/config/rs6000/htm.md ++++ b/src/gcc/config/rs6000/htm.md +@@ -27,6 +27,14 @@ + ]) + + ;; ++;; UNSPEC usage ++;; ++ ++(define_c_enum "unspec" ++ [UNSPEC_HTM_FENCE ++ ]) ++ ++;; + ;; UNSPEC_VOLATILE usage + ;; + +@@ -45,96 +53,223 @@ + UNSPECV_HTM_MTSPR + ]) + ++(define_expand "tabort" ++ [(parallel ++ [(set (match_operand:CC 1 "cc_reg_operand" "=x") ++ (unspec_volatile:CC [(match_operand:SI 0 "base_reg_operand" "b")] ++ UNSPECV_HTM_TABORT)) ++ (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])] ++ "TARGET_HTM" ++{ ++ operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); ++ MEM_VOLATILE_P (operands[2]) = 1; ++}) + +-(define_insn "tabort" ++(define_insn "*tabort" + [(set (match_operand:CC 1 "cc_reg_operand" "=x") +- (unspec_volatile:CC [(match_operand:SI 0 "gpc_reg_operand" "r")] +- UNSPECV_HTM_TABORT))] ++ (unspec_volatile:CC [(match_operand:SI 0 "base_reg_operand" "b")] ++ UNSPECV_HTM_TABORT)) ++ (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "tabort. %0" + [(set_attr "type" "htm") + (set_attr "length" "4")]) + +-(define_insn "tabortc" ++(define_expand "tabortc" ++ [(parallel ++ [(set (match_operand:CC 3 "cc_reg_operand" "=x") ++ (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n") ++ (match_operand:GPR 1 "gpc_reg_operand" "r") ++ (match_operand:GPR 2 "gpc_reg_operand" "r")] ++ UNSPECV_HTM_TABORTXC)) ++ (set (match_dup 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))])] ++ "TARGET_HTM" ++{ ++ operands[4] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); ++ MEM_VOLATILE_P (operands[4]) = 1; ++}) ++ ++(define_insn "*tabortc" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n") + (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand:GPR 2 "gpc_reg_operand" "r")] +- UNSPECV_HTM_TABORTXC))] ++ UNSPECV_HTM_TABORTXC)) ++ (set (match_operand:BLK 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "tabortc. %0,%1,%2" + [(set_attr "type" "htm") + (set_attr "length" "4")]) + +-(define_insn "tabortci" ++(define_expand "tabortci" ++ [(parallel ++ [(set (match_operand:CC 3 "cc_reg_operand" "=x") ++ (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n") ++ (match_operand:GPR 1 "gpc_reg_operand" "r") ++ (match_operand 2 "s5bit_cint_operand" "n")] ++ UNSPECV_HTM_TABORTXCI)) ++ (set (match_dup 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))])] ++ "TARGET_HTM" ++{ ++ operands[4] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); ++ MEM_VOLATILE_P (operands[4]) = 1; ++}) ++ ++(define_insn "*tabortci" + [(set (match_operand:CC 3 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n") + (match_operand:GPR 1 "gpc_reg_operand" "r") + (match_operand 2 "s5bit_cint_operand" "n")] +- UNSPECV_HTM_TABORTXCI))] ++ UNSPECV_HTM_TABORTXCI)) ++ (set (match_operand:BLK 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "tabortci. %0,%1,%2" + [(set_attr "type" "htm") + (set_attr "length" "4")]) + +-(define_insn "tbegin" ++(define_expand "tbegin" ++ [(parallel ++ [(set (match_operand:CC 1 "cc_reg_operand" "=x") ++ (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] ++ UNSPECV_HTM_TBEGIN)) ++ (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])] ++ "TARGET_HTM" ++{ ++ operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); ++ MEM_VOLATILE_P (operands[2]) = 1; ++}) ++ ++(define_insn "*tbegin" + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] +- UNSPECV_HTM_TBEGIN))] ++ UNSPECV_HTM_TBEGIN)) ++ (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "tbegin. %0" + [(set_attr "type" "htm") + (set_attr "length" "4")]) + +-(define_insn "tcheck" ++(define_expand "tcheck" ++ [(parallel ++ [(set (match_operand:CC 0 "cc_reg_operand" "=y") ++ (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TCHECK)) ++ (set (match_dup 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))])] ++ "TARGET_HTM" ++{ ++ operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); ++ MEM_VOLATILE_P (operands[1]) = 1; ++}) ++ ++(define_insn "*tcheck" + [(set (match_operand:CC 0 "cc_reg_operand" "=y") +- (unspec_volatile:CC [(const_int 0)] +- UNSPECV_HTM_TCHECK))] ++ (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TCHECK)) ++ (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "tcheck %0" + [(set_attr "type" "htm") + (set_attr "length" "4")]) + +-(define_insn "tend" ++(define_expand "tend" ++ [(parallel ++ [(set (match_operand:CC 1 "cc_reg_operand" "=x") ++ (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] ++ UNSPECV_HTM_TEND)) ++ (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])] ++ "TARGET_HTM" ++{ ++ operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); ++ MEM_VOLATILE_P (operands[2]) = 1; ++}) ++ ++(define_insn "*tend" + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] +- UNSPECV_HTM_TEND))] ++ UNSPECV_HTM_TEND)) ++ (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "tend. %0" + [(set_attr "type" "htm") + (set_attr "length" "4")]) + +-(define_insn "trechkpt" ++(define_expand "trechkpt" ++ [(parallel ++ [(set (match_operand:CC 0 "cc_reg_operand" "=x") ++ (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TRECHKPT)) ++ (set (match_dup 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))])] ++ "TARGET_HTM" ++{ ++ operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); ++ MEM_VOLATILE_P (operands[1]) = 1; ++}) ++ ++(define_insn "*trechkpt" + [(set (match_operand:CC 0 "cc_reg_operand" "=x") +- (unspec_volatile:CC [(const_int 0)] +- UNSPECV_HTM_TRECHKPT))] ++ (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TRECHKPT)) ++ (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "trechkpt." + [(set_attr "type" "htm") + (set_attr "length" "4")]) + +-(define_insn "treclaim" ++(define_expand "treclaim" ++ [(parallel ++ [(set (match_operand:CC 1 "cc_reg_operand" "=x") ++ (unspec_volatile:CC [(match_operand:SI 0 "gpc_reg_operand" "r")] ++ UNSPECV_HTM_TRECLAIM)) ++ (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])] ++ "TARGET_HTM" ++{ ++ operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); ++ MEM_VOLATILE_P (operands[2]) = 1; ++}) ++ ++(define_insn "*treclaim" + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand:SI 0 "gpc_reg_operand" "r")] +- UNSPECV_HTM_TRECLAIM))] ++ UNSPECV_HTM_TRECLAIM)) ++ (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "treclaim. %0" + [(set_attr "type" "htm") + (set_attr "length" "4")]) + +-(define_insn "tsr" ++(define_expand "tsr" ++ [(parallel ++ [(set (match_operand:CC 1 "cc_reg_operand" "=x") ++ (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] ++ UNSPECV_HTM_TSR)) ++ (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])] ++ "TARGET_HTM" ++{ ++ operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); ++ MEM_VOLATILE_P (operands[2]) = 1; ++}) ++ ++(define_insn "*tsr" + [(set (match_operand:CC 1 "cc_reg_operand" "=x") + (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")] +- UNSPECV_HTM_TSR))] ++ UNSPECV_HTM_TSR)) ++ (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "tsr. %0" + [(set_attr "type" "htm") + (set_attr "length" "4")]) + +-(define_insn "ttest" ++(define_expand "ttest" ++ [(parallel ++ [(set (match_operand:CC 0 "cc_reg_operand" "=x") ++ (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TTEST)) ++ (set (match_dup 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))])] ++ "TARGET_HTM" ++{ ++ operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); ++ MEM_VOLATILE_P (operands[1]) = 1; ++}) ++ ++(define_insn "*ttest" + [(set (match_operand:CC 0 "cc_reg_operand" "=x") +- (unspec_volatile:CC [(const_int 0)] +- UNSPECV_HTM_TTEST))] ++ (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TTEST)) ++ (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))] + "TARGET_HTM" + "tabortwci. 0,1,0" + [(set_attr "type" "htm") +--- a/src/gcc/config/rs6000/rs6000-c.c ++++ b/src/gcc/config/rs6000/rs6000-c.c +@@ -351,7 +351,11 @@ + 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__"); ++ { ++ rs6000_define_or_undefine_macro (define_p, "__HTM__"); ++ /* Tell the user that our HTM insn patterns act as memory barriers. */ ++ rs6000_define_or_undefine_macro (define_p, "__TM_FENCE__"); ++ } + if ((flags & OPTION_MASK_P8_VECTOR) != 0) + rs6000_define_or_undefine_macro (define_p, "__POWER8_VECTOR__"); + if ((flags & OPTION_MASK_QUAD_MEMORY) != 0) +--- a/src/gcc/testsuite/gcc.target/powerpc/htm-tabort-no-r0.c ++++ b/src/gcc/testsuite/gcc.target/powerpc/htm-tabort-no-r0.c +@@ -0,0 +1,12 @@ ++/* { dg-do compile { target { powerpc*-*-* } } } */ ++/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */ ++/* { dg-require-effective-target powerpc_htm_ok } */ ++/* { dg-options "-O2 -mhtm -ffixed-r3 -ffixed-r4 -ffixed-r5 -ffixed-r6 -ffixed-r7 -ffixed-r8 -ffixed-r9 -ffixed-r10 -ffixed-r11 -ffixed-r12" } */ ++ ++/* { dg-final { scan-assembler-not "tabort\\.\[ \t\]0" } } */ ++ ++int ++foo (void) ++{ ++ return __builtin_tabort (10); ++}