[PATCH v2] [PowerPC] Add Hardware Transaction Memory builtins support

Bill Schmidt wschmidt at linux.vnet.ibm.com
Thu Mar 5 13:31:09 PST 2015


Hi Adhemerval,

Just a couple of inline comments.

On Thu, 2015-03-05 at 15:17 -0300, Adhemerval Zanella wrote:
> This patch adds Hardware Transaction Memory (HTM) support supported by
> ISA 2.07 (POWER8).  The intrinsic support is based on GCC one [1], with
> both 'PowerPC HTM Low Level Built-in Functions' and 'PowerPC HTM High
> Level Inline Functions' implemented.
> 
> Along with builtins a new driver switch is added to enable/disable HTM
> instruction support (-mhtm) and a header with common definitions (mostly
> to parse the TFHAR register value).  The HTM switch also sets a
> preprocessor builtin __HTM__.
> 
> The HTM usage requires a recently newer kernel with PPC HTM enabled.
> Tested on powerpc64 and powerpc64le.
> 
> This is send along a llvm patch to enabled the builtins and option
> switch.
> 
> [1] https://gcc.gnu.org/onlinedocs/gcc/PowerPC-Hardware-Transactional-Memory-Built-in-Functions.html
> 
> --
> 
> Changes from previous version:
> 
> - Fixed grammatical error raised by Will Schmidt
> - Change __builtin_tcheck signature to no accept any arguments.  The CR fiels
>   will be selected by the backend and the result will be adjusted accordingly.
> - The return value for __builtin_tend, __builtin_tabort* has changed to return
>   the full 4-bit CR value as its return value (similar to the __built_ttest).
>   The __builtin_tbegin continue to return 0 or 1 as previous patch.
> 
> ---
> 
> diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def
> index 274f9a8..d83c109 100644
> --- a/include/clang/Basic/BuiltinsPPC.def
> +++ b/include/clang/Basic/BuiltinsPPC.def
> @@ -237,6 +237,37 @@ BUILTIN(__builtin_vsx_xsmindp, "ddd", "")
>  BUILTIN(__builtin_vsx_xvdivdp, "V2dV2dV2d", "")
>  BUILTIN(__builtin_vsx_xvdivsp, "V4fV4fV4f", "")
> 
> +// HTM builtins
> +BUILTIN(__builtin_tbegin, "UiUIi", "")
> +BUILTIN(__builtin_tend, "UiUIi", "")
> +
> +BUILTIN(__builtin_tabort, "UiUi", "")
> +BUILTIN(__builtin_tabortdc, "UiUiUiUi", "")
> +BUILTIN(__builtin_tabortdci, "UiUiUii", "")
> +BUILTIN(__builtin_tabortwc, "UiUiUiUi", "")
> +BUILTIN(__builtin_tabortwci, "UiUiUii", "")
> +
> +BUILTIN(__builtin_tcheck, "Ui", "")
> +BUILTIN(__builtin_treclaim, "UiUi", "")
> +BUILTIN(__builtin_trechkpt, "Ui", "")
> +BUILTIN(__builtin_tsr, "UiUi", "")
> +
> +BUILTIN(__builtin_tendall, "Ui", "")
> +BUILTIN(__builtin_tresume, "Ui", "")
> +BUILTIN(__builtin_tsuspend, "Ui", "")
> +
> +BUILTIN(__builtin_get_texasr, "LUi", "c")
> +BUILTIN(__builtin_get_texasru, "LUi", "c")
> +BUILTIN(__builtin_get_tfhar, "LUi", "c")
> +BUILTIN(__builtin_get_tfiar, "LUi", "c")
> +
> +BUILTIN(__builtin_set_texasr, "vLUi", "c")
> +BUILTIN(__builtin_set_texasru, "vLUi", "c")
> +BUILTIN(__builtin_set_tfhar, "vLUi", "c")
> +BUILTIN(__builtin_set_tfiar, "vLUi", "c")
> +
> +BUILTIN(__builtin_ttest, "LUi", "")
> +
>  // FIXME: Obviously incomplete.
> 
>  #undef BUILTIN
> diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
> index bcb6ec0..5d073ff 100644
> --- a/include/clang/Driver/Options.td
> +++ b/include/clang/Driver/Options.td
> @@ -1254,6 +1254,8 @@ def mpower8_crypto : Flag<["-"], "mcrypto">,
>      Group<m_ppc_Features_Group>;
>  def mnopower8_crypto : Flag<["-"], "mno-crypto">,
>      Group<m_ppc_Features_Group>;
> +def mhtm : Flag<["-"], "mhtm">, Group<m_ppc_Features_Group>;
> +def mno_htm : Flag<["-"], "mno-htm">, Group<m_ppc_Features_Group>;
>  def mfprnd : Flag<["-"], "mfprnd">, Group<m_ppc_Features_Group>;
>  def mno_fprnd : Flag<["-"], "mno-fprnd">, Group<m_ppc_Features_Group>;
>  def mcmpb : Flag<["-"], "mcmpb">, Group<m_ppc_Features_Group>;
> diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
> index 56b884d..6cfd545 100644
> --- a/lib/Basic/Targets.cpp
> +++ b/lib/Basic/Targets.cpp
> @@ -720,6 +720,7 @@ class PPCTargetInfo : public TargetInfo {
>    bool HasVSX;
>    bool HasP8Vector;
>    bool HasP8Crypto;
> +  bool HasHTM;
> 
>  protected:
>    std::string ABI;
> @@ -727,7 +728,7 @@ protected:
>  public:
>    PPCTargetInfo(const llvm::Triple &Triple)
>      : TargetInfo(Triple), HasVSX(false), HasP8Vector(false),
> -      HasP8Crypto(false) {
> +      HasP8Crypto(false), HasHTM(false) {
>      BigEndian = (Triple.getArch() != llvm::Triple::ppc64le);
>      LongDoubleWidth = LongDoubleAlign = 128;
>      LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble;
> @@ -993,6 +994,11 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
>        continue;
>      }
> 
> +    if (Feature == "htm") {
> +      HasHTM = true;
> +      continue;
> +    }
> +
>      // TODO: Finish this list and add an assert that we've handled them
>      // all.
>    }
> @@ -1147,6 +1153,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions &Opts,
>      Builder.defineMacro("__POWER8_VECTOR__");
>    if (HasP8Crypto)
>      Builder.defineMacro("__CRYPTO__");
> +  if (HasHTM)
> +    Builder.defineMacro("__HTM__");
> 
>    // FIXME: The following are not yet generated here by Clang, but are
>    //        generated by GCC:
> @@ -1201,6 +1209,7 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const {
>      .Case("vsx", HasVSX)
>      .Case("power8-vector", HasP8Vector)
>      .Case("crypto", HasP8Crypto)
> +    .Case("htm", HasHTM)
>      .Default(false);
>  }
> 
> diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
> index eae5f02..cb52ede 100644
> --- a/lib/CodeGen/CGBuiltin.cpp
> +++ b/lib/CodeGen/CGBuiltin.cpp
> @@ -6349,6 +6349,7 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
>      llvm::Function *F = CGM.getIntrinsic(ID);
>      return Builder.CreateCall(F, Ops, "");
>    }
> +
>    // P8 Crypto builtins
>    case PPC::BI__builtin_altivec_crypto_vshasigmaw:
>    case PPC::BI__builtin_altivec_crypto_vshasigmad:
> @@ -6378,6 +6379,87 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
>      llvm::Function *F = CGM.getIntrinsic(ID);
>      return Builder.CreateCall(F, Ops, "");
>    }
> +
> +  // HTM builtins
> +  case PPC::BI__builtin_tbegin:
> +  case PPC::BI__builtin_tend:
> +  case PPC::BI__builtin_tsr: {
> +    unsigned int MaxValue;
> +    // The HTM instructions only accept one argument and with limited range.
> +    ConstantInt *CI = dyn_cast<ConstantInt>(Ops[0]);
> +    assert(CI);
> +    switch (BuiltinID) {
> +    case PPC::BI__builtin_tbegin:
> +      ID = Intrinsic::ppc_tbegin;
> +      MaxValue = 1;

Is it possible for Ops[0] to contain a negative number?  I.e., do you
need a MinValue of 0 as well?

> +      break;
> +    case PPC::BI__builtin_tend:
> +      ID = Intrinsic::ppc_tend;
> +      MaxValue = 1;
> +      break;
> +    case PPC::BI__builtin_tsr:
> +      ID = Intrinsic::ppc_tsr;
> +      MaxValue = 7;
> +      break;
> +    }
> +    if (CI->getZExtValue() > MaxValue) {
> +      CGM.ErrorUnsupported(E->getArg(0), "argument out of range (should be 0 or 1)");

The error message is incorrect for BI__builtin_tsr.  Should be 0-7 in
that case.

As Nemanja pointed out, you want to use CGM.Error() instead.

> +      return llvm::UndefValue::get(Ops[0]->getType());
> +    }
> +
> +    llvm::Function *F = CGM.getIntrinsic(ID);
> +    return Builder.CreateCall(F, Ops, "");
> +  }
> +  case PPC::BI__builtin_tabortdc:
> +  case PPC::BI__builtin_tabortwc: {
> +    // For wd and dc variant of tabort first argument must be a 5-bit constant
> +    // integer
> +    ConstantInt *CI = dyn_cast<ConstantInt>(Ops[0]);
> +    assert(CI);
> +    if (CI->getZExtValue() > 31) {

Any concern about negative numbers?

> +      CGM.ErrorUnsupported(E->getArg(0), "argument out of range (should be 0-31)");
> +      return llvm::UndefValue::get(Ops[0]->getType());
> +    }
> +    switch (BuiltinID) {
> +    case PPC::BI__builtin_tabortdc:
> +      ID = Intrinsic::ppc_tabortdc;
> +      break;
> +    case PPC::BI__builtin_tabortwc:
> +      ID = Intrinsic::ppc_tabortwc;
> +      break;
> +    }
> +    llvm::Function *F = CGM.getIntrinsic(ID);
> +    return Builder.CreateCall(F, Ops, "");
> +  }
> +  case PPC::BI__builtin_tabortdci:
> +  case PPC::BI__builtin_tabortwci: {
> +    // For wd and dc variant of tabort first and third argument must be a
> +    // 5-bit constant integer
> +    ConstantInt *CI = dyn_cast<ConstantInt>(Ops[0]);
> +    assert(CI);
> +    if (CI->getZExtValue() > 31) {

Negative numbers?

Thanks,
Bill

> +      CGM.ErrorUnsupported(E->getArg(0), "argument out of range (should be 0-31)");
> +      return llvm::UndefValue::get(Ops[0]->getType());
> +    }
> +    CI = dyn_cast<ConstantInt>(Ops[2]);
> +    assert(CI);
> +    if (CI->getZExtValue() > 31) {
> +      CGM.ErrorUnsupported(E->getArg(2), "argument out of range (should be 0-31)");
> +      return llvm::UndefValue::get(Ops[2]->getType());
> +    }
> +    switch (BuiltinID) {
> +    default: llvm_unreachable("Unsupported htm intrinsic!");
> +    case PPC::BI__builtin_tabortdci:
> +      ID = Intrinsic::ppc_tabortdci;
> +      break;
> +    case PPC::BI__builtin_tabortwci:
> +      ID = Intrinsic::ppc_tabortwci;
> +      break;
> +    }
> +    llvm::Function *F = CGM.getIntrinsic(ID);
> +    return Builder.CreateCall(F, Ops, "");
> +  }
> +
>    }
>  }
> 
> diff --git a/lib/Headers/htmintrin.h b/lib/Headers/htmintrin.h
> new file mode 100644
> index 0000000..9f6b166
> --- /dev/null
> +++ b/lib/Headers/htmintrin.h
> @@ -0,0 +1,127 @@
> +/*===---- htmintrin.h - Standard header for PowerPC HTM ---------------===*\
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to deal
> + * in the Software without restriction, including without limitation the rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + *
> +\*===----------------------------------------------------------------------===*/
> +
> +#ifndef __HTMINTRIN_H
> +#define __HTMINTRIN_H
> +
> +#ifndef __HTM__
> +#error "HTM instruction set not enabled"
> +#endif
> +
> +#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
> +
> +#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 */
> diff --git a/lib/Headers/htmxlintrin.h b/lib/Headers/htmxlintrin.h
> new file mode 100644
> index 0000000..5d2eb11
> --- /dev/null
> +++ b/lib/Headers/htmxlintrin.h
> @@ -0,0 +1,211 @@
> +/*===---- htmxlintrin.h - XL compiler HTM execution intrinsics-------------===*\
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a copy
> + * of this software and associated documentation files (the "Software"), to deal
> + * in the Software without restriction, including without limitation the rights
> + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
> + * copies of the Software, and to permit persons to whom the Software is
> + * furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included in
> + * all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
> + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
> + * THE SOFTWARE.
> + *
> +\*===----------------------------------------------------------------------===*/
> +
> +#ifndef __HTMXLINTRIN_H
> +#define __HTMXLINTRIN_H
> +
> +#ifndef __HTM__
> +#error "HTM instruction set not enabled"
> +#endif
> +
> +#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];
> +
> +/* This macro can be used to determine whether a transaction was successfully 
> +   started from the __TM_begin() and __TM_simple_begin() intrinsic functions
> +   below.  */
> +#define _HTM_TBEGIN_STARTED     1
> +
> +extern __inline long
> +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
> +__TM_simple_begin (void)
> +{
> +  if (__builtin_expect (__builtin_tbegin (0), 1))
> +    return _HTM_TBEGIN_STARTED;
> +  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 _HTM_TBEGIN_STARTED;
> +#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  */
> diff --git a/test/CodeGen/builtins-ppc-htm.c b/test/CodeGen/builtins-ppc-htm.c
> new file mode 100644
> index 0000000..87baa77
> --- /dev/null
> +++ b/test/CodeGen/builtins-ppc-htm.c
> @@ -0,0 +1,62 @@
> +// REQUIRES: powerpc-registered-target
> +// RUN: %clang_cc1 -faltivec -target-feature +htm -triple powerpc64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
> +
> +void test1(long int *r, int code, long int *a, long int *b) {
> +// CHECK-LABEL: define void @test1
> +
> +  r[0] = __builtin_tbegin (0);
> +// CHECK: @llvm.ppc.tbegin
> +  r[1] = __builtin_tbegin (1);
> +// CHECK: @llvm.ppc.tbegin
> +  r[2] = __builtin_tend (0);
> +// CHECK: @llvm.ppc.tend
> +  r[3] = __builtin_tendall ();
> +// CHECK: @llvm.ppc.tendall
> +
> +  r[4] = __builtin_tabort (code);
> +// CHECK: @llvm.ppc.tabort
> +  r[5] = __builtin_tabort (0x1);
> +// CHECK: @llvm.ppc.tabort
> +  r[6] = __builtin_tabortdc (0xf, a[0], b[0]);
> +// CHECK: @llvm.ppc.tabortdc
> +  r[7] = __builtin_tabortdci (0xf, a[1], 0x1);
> +// CHECK: @llvm.ppc.tabortdc
> +  r[8] = __builtin_tabortwc (0xf, a[2], b[2]);
> +// CHECK: @llvm.ppc.tabortwc
> +  r[9] = __builtin_tabortwci (0xf, a[3], 0x1);
> +// CHECK: @llvm.ppc.tabortwc
> +
> +  r[10] = __builtin_tcheck ();
> +// CHECK: @llvm.ppc.tcheck
> +  r[11] = __builtin_trechkpt ();
> +// CHECK: @llvm.ppc.trechkpt
> +  r[12] = __builtin_treclaim (0);
> +// CHECK: @llvm.ppc.treclaim
> +  r[13] = __builtin_tresume ();
> +// CHECK: @llvm.ppc.tresume
> +  r[14] = __builtin_tsuspend ();
> +// CHECK: @llvm.ppc.tsuspend
> +  r[15] = __builtin_tsr (0);
> +// CHECK: @llvm.ppc.tsr
> +
> +  r[16] = __builtin_ttest ();
> +// CHECK: @llvm.ppc.ttest
> +
> +  r[17] = __builtin_get_texasr ();
> +// CHECK: @llvm.ppc.get.texasr
> +  r[18] = __builtin_get_texasru ();
> +// CHECK: @llvm.ppc.get.texasru
> +  r[19] = __builtin_get_tfhar ();
> +// CHECK: @llvm.ppc.get.tfhar
> +  r[20] = __builtin_get_tfiar ();
> +// CHECK: @llvm.ppc.get.tfiar
> +
> +  __builtin_set_texasr (a[21]);
> +// CHECK: @llvm.ppc.set.texasr
> +  __builtin_set_texasru (a[22]);
> +// CHECK: @llvm.ppc.set.texasru
> +  __builtin_set_tfhar (a[23]);
> +// CHECK: @llvm.ppc.set.tfhar
> +  __builtin_set_tfiar (a[24]);
> +// CHECK: @llvm.ppc.set.tfiar
> +}
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
> 





More information about the cfe-commits mailing list