Hi Adhemerval, Looks good. Just a couple grammatical comments inline (I will trust you on the htmintrin.h file's correctness/completeness ;-):
On Fri, 2015-02-20 at 11:22 -0200, 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], but > currently only the 'PowerPC HTM Low Level Built-in Function' are > 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 > --- > include/clang/Basic/BuiltinsPPC.def | 31 +++++++++ > include/clang/Driver/Options.td | 2 + > lib/Basic/Targets.cpp | 11 +++- > lib/CodeGen/CGBuiltin.cpp | 86 ++++++++++++++++++++++++ > lib/Headers/htmintrin.h | 127 > ++++++++++++++++++++++++++++++++++++ > test/CodeGen/builtins-ppc-htm.c | 62 ++++++++++++++++++ > 6 files changed, 318 insertions(+), 1 deletion(-) > create mode 100644 lib/Headers/htmintrin.h > create mode 100644 test/CodeGen/builtins-ppc-htm.c > > diff --git a/include/clang/Basic/BuiltinsPPC.def > b/include/clang/Basic/BuiltinsPPC.def > index e42af42..cfaceb5 100644 > --- a/include/clang/Basic/BuiltinsPPC.def > +++ b/include/clang/Basic/BuiltinsPPC.def > @@ -223,6 +223,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, "UiUi", "") > +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 80f68ef..30553aa 100644 > --- a/include/clang/Driver/Options.td > +++ b/include/clang/Driver/Options.td > @@ -1230,6 +1230,8 @@ def mpower8_vector : Flag<["-"], "mpower8-vector">, > Group<m_ppc_Features_Group>; > def mno_power8_vector : Flag<["-"], "mno-power8-vector">, > 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 f9da2bf..6c8183b 100644 > --- a/lib/Basic/Targets.cpp > +++ b/lib/Basic/Targets.cpp > @@ -704,13 +704,14 @@ class PPCTargetInfo : public TargetInfo { > // Target cpu features. > bool HasVSX; > bool HasP8Vector; > + bool HasHTM; > > protected: > std::string ABI; > > public: > PPCTargetInfo(const llvm::Triple &Triple) > - : TargetInfo(Triple), HasVSX(false), HasP8Vector(false) { > + : TargetInfo(Triple), HasVSX(false), HasP8Vector(false), HasHTM(false) { > BigEndian = (Triple.getArch() != llvm::Triple::ppc64le); > LongDoubleWidth = LongDoubleAlign = 128; > LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble; > @@ -971,6 +972,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. > } > @@ -1123,6 +1129,8 @@ void PPCTargetInfo::getTargetDefines(const LangOptions > &Opts, > Builder.defineMacro("__VSX__"); > if (HasP8Vector) > Builder.defineMacro("__POWER8_VECTOR__"); > + if (HasHTM) > + Builder.defineMacro("__HTM__"); > > // FIXME: The following are not yet generated here by Clang, but are > // generated by GCC: > @@ -1168,6 +1176,7 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const > { > .Case("powerpc", true) > .Case("vsx", HasVSX) > .Case("power8-vector", HasP8Vector) > + .Case("htm", HasHTM) > .Default(false); > } > > diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp > index 859ad3e..b622d59 100644 > --- a/lib/CodeGen/CGBuiltin.cpp > +++ b/lib/CodeGen/CGBuiltin.cpp > @@ -6347,6 +6347,92 @@ 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_tcheck: > + case PPC::BI__builtin_tsr: { > + unsigned int MaxValue; > + // The HTM instructions only accepts one argument and with limited range. "accepts" => "accept" > + ConstantInt *CI = dyn_cast<ConstantInt>(Ops[0]); > + assert(CI); > + switch (BuiltinID) { > + case PPC::BI__builtin_tbegin: > + ID = Intrinsic::ppc_tbegin; > + MaxValue = 1; > + 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; > + case PPC::BI__builtin_tcheck: > + ID = Intrinsic::ppc_tcheck; > + MaxValue = 7; > + break; > + } > + if (CI->getZExtValue() > MaxValue) { > + CGM.ErrorUnsupported(E->getArg(0), "argument out of range (should be 0 > or 1)"); > + 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-bits > constant "bits" => "bit" > + // integer > + ConstantInt *CI = dyn_cast<ConstantInt>(Ops[0]); > + assert(CI); > + if (CI->getZExtValue() > 31) { > + 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-bits constant integer Likewise. > + ConstantInt *CI = dyn_cast<ConstantInt>(Ops[0]); > + assert(CI); > + if (CI->getZExtValue() > 31) { > + 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/test/CodeGen/builtins-ppc-htm.c b/test/CodeGen/builtins-ppc-htm.c > new file mode 100644 > index 0000000..663c814 > --- /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 (0x1); > +// 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 [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
