Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:Update
llvm.7809
backport-clang-r233804
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File backport-clang-r233804 of Package llvm.7809
------------------------------------------------------------------------ r233804 | uweigand | 2015-04-01 14:54:25 +0200 (Wed, 01 Apr 2015) | 29 lines [SystemZ] Support transactional execution on zEC12 The zEC12 provides the transactional-execution facility. This is exposed to users via a set of builtin routines on other compilers. This patch adds clang support to enable those builtins. In partciular, the patch: - enables the transactional-execution feature by default on zEC12 - allows to override presence of that feature via the -mhtm/-mno-htm options - adds a predefined macro __HTM__ if the feature is enabled - adds support for the transactional-execution GCC builtins - adds Sema checking to verify the __builtin_tabort abort code - adds the s390intrin.h header file (for GCC compatibility) - adds s390 sections to the htmintrin.h and htmxlintrin.h header files Since this is first use of target-specific intrinsics on the platform, the patch creates the include/clang/Basic/BuiltinsSystemZ.def file and hooks it up in TargetBuiltins.h and lib/Basic/Targets.cpp. An associated LLVM patch adds the required LLVM IR intrinsics. For reference, the transactional-execution instructions are documented in the z/Architecture Principles of Operation for the zEC12: http://publibfp.boulder.ibm.com/cgi-bin/bookmgr/download/DZ9ZR009.pdf The associated builtins are documented in the GCC manual: http://gcc.gnu.org/onlinedocs/gcc/S_002f390-System-z-Built-in-Functions.html The htmxlintrin.h intrinsics provided for compatibility with the IBM XL compiler are documented in the "z/OS XL C/C++ Programming Guide". ------------------------------------------------------------------------ Index: tools/clang/test/Driver/systemz-features.cpp =================================================================== --- /dev/null +++ tools/clang/test/Driver/systemz-features.cpp @@ -0,0 +1,15 @@ + +// RUN: %clang -target s390x-unknown-linux-gnu %s -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-DEFAULT %s +// CHECK-DEFAULT-NOT: "-target-feature" "+transactional-execution" +// CHECK-DEFAULT-NOT: "-target-feature" "-transactional-execution" + +// RUN: %clang -target s390x-unknown-linux-gnu %s -mhtm -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-HTM %s +// RUN: %clang -target s390x-unknown-linux-gnu %s -mno-htm -mhtm -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-HTM %s +// CHECK-HTM: "-target-feature" "+transactional-execution" +// CHECK-HTM-NOT: "-target-feature" "-transactional-execution" + +// RUN: %clang -target s390x-unknown-linux-gnu %s -mno-htm -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOHTM %s +// RUN: %clang -target s390x-unknown-linux-gnu %s -mhtm -mno-htm -### -o %t.o 2>&1 | FileCheck -check-prefix=CHECK-NOHTM %s +// CHECK-NOHTM: "-target-feature" "-transactional-execution" +// CHECK-NOHTM-NOT: "-target-feature" "+transactional-execution" + Index: tools/clang/test/Preprocessor/predefined-arch-macros.c =================================================================== --- tools/clang/test/Preprocessor/predefined-arch-macros.c.orig +++ tools/clang/test/Preprocessor/predefined-arch-macros.c @@ -1446,3 +1446,30 @@ // RUN: | FileCheck %s -check-prefix=CHECK_PPC_VSX_M64 // // CHECK_PPC_VSX_M64: #define __VSX__ + +// Begin SystemZ/GCC/Linux tests ---------------- +// +// RUN: %clang -march=z10 -E -dM %s -o - 2>&1 \ +// RUN: -target s390x-unknown-linux \ +// RUN: | FileCheck %s -check-prefix=CHECK_SYSTEMZ_Z10 +// +// CHECK_SYSTEMZ_Z10: #define __LONG_DOUBLE_128__ 1 +// CHECK_SYSTEMZ_Z10: #define __s390__ 1 +// CHECK_SYSTEMZ_Z10: #define __s390x__ 1 +// CHECK_SYSTEMZ_Z10: #define __zarch__ 1 +// +// RUN: %clang -march=zEC12 -E -dM %s -o - 2>&1 \ +// RUN: -target s390x-unknown-linux \ +// RUN: | FileCheck %s -check-prefix=CHECK_SYSTEMZ_ZEC12 +// +// CHECK_SYSTEMZ_ZEC12: #define __HTM__ 1 +// CHECK_SYSTEMZ_ZEC12: #define __LONG_DOUBLE_128__ 1 +// CHECK_SYSTEMZ_ZEC12: #define __s390__ 1 +// CHECK_SYSTEMZ_ZEC12: #define __s390x__ 1 +// CHECK_SYSTEMZ_ZEC12: #define __zarch__ 1 +// +// RUN: %clang -mhtm -E -dM %s -o - 2>&1 \ +// RUN: -target s390x-unknown-linux \ +// RUN: | FileCheck %s -check-prefix=CHECK_SYSTEMZ_HTM +// +// CHECK_SYSTEMZ_HTM: #define __HTM__ 1 Index: tools/clang/test/CodeGen/builtins-systemz.c =================================================================== --- /dev/null +++ tools/clang/test/CodeGen/builtins-systemz.c @@ -0,0 +1,144 @@ +// REQUIRES: systemz-registered-target +// RUN: %clang_cc1 -target-cpu zEC12 -triple s390x-ibm-linux -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -target-cpu zEC12 -triple s390x-ibm-linux -Wall -Wno-unused -Werror -emit-llvm -x c++ %s -o - | FileCheck %s + +#include <stdint.h> +#include <htmintrin.h> + +int global = 0; +uint64_t g; +struct __htm_tdb global_tdb; + +void test_htm1(struct __htm_tdb *tdb, int reg, int *mem, uint64_t *mem64) { +// CHECK-LABEL: test_htm1 + + __builtin_tbegin ((void *)0); +// CHECK: call i32 @llvm.s390.tbegin(i8* null, i32 65292) + __builtin_tbegin ((void *)0x12345678); +// CHECK: call i32 @llvm.s390.tbegin(i8* inttoptr (i64 305419896 to i8*), i32 65292) + __builtin_tbegin (tdb); +// CHECK: call i32 @llvm.s390.tbegin(i8* %{{.*}}, i32 65292) + __builtin_tbegin (&global_tdb); +// CHECK: call i32 @llvm.s390.tbegin(i8* getelementptr inbounds (%struct.__htm_tdb* @global_tdb, i32 0, i32 0), i32 65292) + + __builtin_tbegin_nofloat ((void *)0); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* null, i32 65292) + __builtin_tbegin_nofloat ((void *)0x12345678); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* inttoptr (i64 305419896 to i8*), i32 65292) + __builtin_tbegin_nofloat (tdb); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* %{{.*}}, i32 65292) + __builtin_tbegin_nofloat (&global_tdb); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* getelementptr inbounds (%struct.__htm_tdb* @global_tdb, i32 0, i32 0), i32 65292) + + __builtin_tbegin_retry ((void *)0, 6); +// CHECK: call i32 @llvm.s390.tbegin(i8* null, i32 65292) +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + __builtin_tbegin_retry ((void *)0x12345678, 6); +// CHECK: call i32 @llvm.s390.tbegin(i8* %{{.*}}, i32 65292) +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + __builtin_tbegin_retry (tdb, 6); +// CHECK: call i32 @llvm.s390.tbegin(i8* %{{.*}}, i32 65292) +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + __builtin_tbegin_retry (&global_tdb, 6); +// CHECK: call i32 @llvm.s390.tbegin(i8* %{{.*}}, i32 65292) +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + + __builtin_tbegin_retry_nofloat ((void *)0, 6); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* null, i32 65292) +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + __builtin_tbegin_retry_nofloat ((void *)0x12345678, 6); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* %{{.*}}, i32 65292) +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + __builtin_tbegin_retry_nofloat (tdb, 6); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* %{{.*}}, i32 65292) +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + __builtin_tbegin_retry_nofloat (&global_tdb, 6); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* %{{.*}}, i32 65292) +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + + __builtin_tbeginc (); +// CHECK: call void @llvm.s390.tbeginc(i8* null, i32 65288) + + __builtin_tabort (256); +// CHECK: call void @llvm.s390.tabort(i64 256) + __builtin_tabort (-1); +// CHECK: call void @llvm.s390.tabort(i64 -1) + __builtin_tabort (reg); +// CHECK: call void @llvm.s390.tabort(i64 %{{.*}}) + + __builtin_tend(); +// CHECK: call i32 @llvm.s390.tend() + + int n = __builtin_tx_nesting_depth(); +// CHECK: call i32 @llvm.s390.etnd() + + __builtin_non_tx_store (mem64, 0); +// CHECK: call void @llvm.s390.ntstg(i64 0, i64* %{{.*}}) + const uint64_t val_var = 0x1122334455667788; + __builtin_non_tx_store (mem64, val_var); +// CHECK: call void @llvm.s390.ntstg(i64 1234605616436508552, i64* %{{.*}}) + __builtin_non_tx_store (mem64, (uint64_t)reg); +// CHECK: call void @llvm.s390.ntstg(i64 %{{.*}}, i64* %{{.*}}) + __builtin_non_tx_store (mem64, g); +// CHECK: call void @llvm.s390.ntstg(i64 %{{.*}}, i64* %{{.*}}) + __builtin_non_tx_store ((uint64_t *)0, 0); +// CHECK: call void @llvm.s390.ntstg(i64 0, i64* null) + __builtin_non_tx_store ((uint64_t *)0x12345678, 0); +// CHECK: call void @llvm.s390.ntstg(i64 0, i64* inttoptr (i64 305419896 to i64*)) + __builtin_non_tx_store (&g, 23); +// CHECK: call void @llvm.s390.ntstg(i64 23, i64* @g) + __builtin_non_tx_store (&g, reg); +// CHECK: call void @llvm.s390.ntstg(i64 %{{.*}}, i64* @g) + __builtin_non_tx_store (&g, *mem); +// CHECK: call void @llvm.s390.ntstg(i64 %{{.*}}, i64* @g) + __builtin_non_tx_store (&g, global); +// CHECK: call void @llvm.s390.ntstg(i64 %{{.*}}, i64* @g) + + __builtin_tx_assist (0); +// CHECK: call void @llvm.s390.ppa.txassist(i32 0) + __builtin_tx_assist (1); +// CHECK: call void @llvm.s390.ppa.txassist(i32 1) + __builtin_tx_assist (reg); +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + __builtin_tx_assist (*mem); +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) + __builtin_tx_assist (global); +// CHECK: call void @llvm.s390.ppa.txassist(i32 %{{.*}}) +} + +#include <htmxlintrin.h> + +void test_htmxl1(void) { +// CHECK-LABEL: test_htmxl1 + + struct __htm_tdb tdb_struct; + void * const tdb = &tdb_struct; + long result; + unsigned char code; + + result = __TM_simple_begin (); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* null, i32 65292) + result = __TM_begin (tdb); +// CHECK: call i32 @llvm.s390.tbegin.nofloat(i8* %{{.*}}, i32 65292) + result = __TM_end (); +// CHECK: call i32 @llvm.s390.tend() + __TM_abort (); +// CHECK: call void @llvm.s390.tabort(i64 256) + __TM_named_abort (42); +// CHECK: call void @llvm.s390.tabort(i64 %{{.*}}) + __TM_non_transactional_store (&g, 42); +// CHECK: call void @llvm.s390.ntstg(i64 %{{.*}}, i64* %{{.*}}) + result = __TM_nesting_depth (tdb); +// CHECK: call i32 @llvm.s390.etnd() + + result = __TM_is_user_abort (tdb); + result = __TM_is_named_user_abort (tdb, &code); + result = __TM_is_illegal (tdb); + result = __TM_is_footprint_exceeded (tdb); + result = __TM_is_nested_too_deep (tdb); + result = __TM_is_conflict (tdb); + result = __TM_is_failure_persistent (result); + result = __TM_failure_address (tdb); + result = __TM_failure_code (tdb); +} + Index: tools/clang/test/CodeGen/builtins-systemz-error.c =================================================================== --- /dev/null +++ tools/clang/test/CodeGen/builtins-systemz-error.c @@ -0,0 +1,9 @@ +// REQUIRES: systemz-registered-target +// RUN: %clang_cc1 -target-cpu zEC12 -triple s390x-unknown-unknown \ +// RUN: -Wall -Wno-unused -Werror -fsyntax-only -verify %s + +void test1(void) { + __builtin_tabort (0); // expected-error {{invalid transaction abort code}} + __builtin_tabort (255); // expected-error {{invalid transaction abort code}} +} + Index: tools/clang/include/clang/Sema/Sema.h =================================================================== --- tools/clang/include/clang/Sema/Sema.h.orig +++ tools/clang/include/clang/Sema/Sema.h @@ -7846,6 +7846,7 @@ private: bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool SemaBuiltinVAStart(CallExpr *TheCall); bool SemaBuiltinUnorderedCompare(CallExpr *TheCall); Index: tools/clang/include/clang/Basic/BuiltinsSystemZ.def =================================================================== --- /dev/null +++ tools/clang/include/clang/Basic/BuiltinsSystemZ.def @@ -0,0 +1,27 @@ +//===-- BuiltinsSystemZ.def - SystemZ Builtin function database -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the SystemZ-specific builtin function database. Users of +// this file must define the BUILTIN macro to make use of this information. +// +//===----------------------------------------------------------------------===// + +// The format of this database matches clang/Basic/Builtins.def. + +// Transactional-memory intrinsics +BUILTIN(__builtin_tbegin, "iv*", "j") +BUILTIN(__builtin_tbegin_nofloat, "iv*", "j") +BUILTIN(__builtin_tbeginc, "v", "nj") +BUILTIN(__builtin_tabort, "vi", "r") +BUILTIN(__builtin_tend, "i", "n") +BUILTIN(__builtin_tx_nesting_depth, "i", "nc") +BUILTIN(__builtin_tx_assist, "vi", "n") +BUILTIN(__builtin_non_tx_store, "vULi*ULi", "") + +#undef BUILTIN Index: tools/clang/include/clang/Basic/TargetBuiltins.h =================================================================== --- tools/clang/include/clang/Basic/TargetBuiltins.h.orig +++ tools/clang/include/clang/Basic/TargetBuiltins.h @@ -142,6 +142,16 @@ namespace clang { LastTSBuiltin }; } + + /// \brief SystemZ builtins + namespace SystemZ { + enum { + LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1, +#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#include "clang/Basic/BuiltinsSystemZ.def" + LastTSBuiltin + }; + } } // end namespace clang. #endif Index: tools/clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- tools/clang/include/clang/Basic/DiagnosticSemaKinds.td.orig +++ tools/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6485,6 +6485,9 @@ def err_invalid_neon_type_code : Error< def err_argument_invalid_range : Error< "argument should be a value from %0 to %1">; +def err_systemz_invalid_tabort_code : Error< + "invalid transaction abort code">; + def err_builtin_longjmp_invalid_val : Error< "argument to __builtin_longjmp must be a constant 1">; Index: tools/clang/lib/Headers/s390intrin.h =================================================================== --- /dev/null +++ tools/clang/lib/Headers/s390intrin.h @@ -0,0 +1,35 @@ +/*===---- s390intrin.h - SystemZ 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 __S390INTRIN_H +#define __S390INTRIN_H + +#ifndef __s390__ +#error "<s390intrin.h> is for s390 only" +#endif + +#ifdef __HTM__ +#include <htmintrin.h> +#endif + +#endif /* __S390INTRIN_H*/ Index: tools/clang/lib/Headers/htmxlintrin.h =================================================================== --- /dev/null +++ tools/clang/lib/Headers/htmxlintrin.h @@ -0,0 +1,180 @@ +/*===---- 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 __s390__ + +#include <stdint.h> + +/* These intrinsics are being made available for compatibility with + the IBM XL compiler. For documentation please see the "z/OS XL + C/C++ Programming Guide" publically available on the web. */ + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_simple_begin () +{ + return __builtin_tbegin_nofloat (0); +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_begin (void* const tdb) +{ + return __builtin_tbegin_nofloat (tdb); +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_end () +{ + return __builtin_tend (); +} + +static __inline void __attribute__((__always_inline__)) +__TM_abort () +{ + return __builtin_tabort (_HTM_FIRST_USER_ABORT_CODE); +} + +static __inline void __attribute__((__always_inline__, __nodebug__)) +__TM_named_abort (unsigned char const code) +{ + return __builtin_tabort ((int)_HTM_FIRST_USER_ABORT_CODE + code); +} + +static __inline void __attribute__((__always_inline__, __nodebug__)) +__TM_non_transactional_store (void* const addr, long long const value) +{ + __builtin_non_tx_store ((uint64_t*)addr, (uint64_t)value); +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_nesting_depth (void* const tdb_ptr) +{ + int depth = __builtin_tx_nesting_depth (); + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + if (depth != 0) + return depth; + + if (tdb->format != 1) + return 0; + return tdb->nesting_depth; +} + +/* Transaction failure diagnostics */ + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_is_user_abort (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + if (tdb->format != 1) + return 0; + + return !!(tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE); +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_is_named_user_abort (void* const tdb_ptr, unsigned char* code) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + if (tdb->format != 1) + return 0; + + if (tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE) + { + *code = tdb->abort_code - _HTM_FIRST_USER_ABORT_CODE; + return 1; + } + return 0; +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_is_illegal (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + return (tdb->format == 1 + && (tdb->abort_code == 4 /* unfiltered program interruption */ + || tdb->abort_code == 11 /* restricted instruction */)); +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_is_footprint_exceeded (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + return (tdb->format == 1 + && (tdb->abort_code == 7 /* fetch overflow */ + || tdb->abort_code == 8 /* store overflow */)); +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_is_nested_too_deep (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + return tdb->format == 1 && tdb->abort_code == 13; /* depth exceeded */ +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_is_conflict (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + return (tdb->format == 1 + && (tdb->abort_code == 9 /* fetch conflict */ + || tdb->abort_code == 10 /* store conflict */)); +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_is_failure_persistent (long const result) +{ + return result == _HTM_TBEGIN_PERSISTENT; +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_failure_address (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + return tdb->atia; +} + +static __inline long __attribute__((__always_inline__, __nodebug__)) +__TM_failure_code (void* const tdb_ptr) +{ + struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr; + + return tdb->abort_code; +} + +#endif /* __s390__ */ + +#endif /* __HTMXLINTRIN_H */ Index: tools/clang/lib/Basic/Targets.cpp =================================================================== --- tools/clang/lib/Basic/Targets.cpp.orig +++ tools/clang/lib/Basic/Targets.cpp @@ -4590,10 +4590,14 @@ public: namespace { class SystemZTargetInfo : public TargetInfo { + static const Builtin::Info BuiltinInfo[]; static const char *const GCCRegNames[]; + std::string CPU; + bool HasTransactionalExecution; public: - SystemZTargetInfo(const llvm::Triple &Triple) : TargetInfo(Triple) { + SystemZTargetInfo(const llvm::Triple &Triple) + : TargetInfo(Triple), CPU("z10"), HasTransactionalExecution(false) { IntMaxType = SignedLong; UIntMaxType = UnsignedLong; Int64Type = SignedLong; @@ -4615,12 +4619,13 @@ namespace { Builder.defineMacro("__s390x__"); Builder.defineMacro("__zarch__"); Builder.defineMacro("__LONG_DOUBLE_128__"); + if (HasTransactionalExecution) + Builder.defineMacro("__HTM__"); } virtual void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords) const { - // FIXME: Implement. - Records = 0; - NumRecords = 0; + Records = BuiltinInfo; + NumRecords = clang::SystemZ::LastTSBuiltin-Builtin::FirstTSBuiltin; } virtual void getGCCRegNames(const char *const *&Names, @@ -4641,16 +4646,41 @@ namespace { return TargetInfo::SystemZBuiltinVaList; } virtual bool setCPU(const std::string &Name) { + CPU = Name; bool CPUKnown = llvm::StringSwitch<bool>(Name) .Case("z10", true) .Case("z196", true) .Case("zEC12", true) .Default(false); - // No need to store the CPU yet. There aren't any CPU-specific - // macros to define. return CPUKnown; } + virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const { + if (CPU == "zEC12") + Features["transactional-execution"] = true; + } + + virtual bool handleTargetFeatures(std::vector<std::string> &Features, + DiagnosticsEngine &Diags) { + HasTransactionalExecution = false; + for (unsigned i = 0, e = Features.size(); i != e; ++i) { + if (Features[i] == "+transactional-execution") + HasTransactionalExecution = true; + } + return true; + } + + virtual bool hasFeature(StringRef Feature) const { + return llvm::StringSwitch<bool>(Feature) + .Case("transactional-execution", HasTransactionalExecution) + .Default(false); + } + }; + + const Builtin::Info SystemZTargetInfo::BuiltinInfo[] = { +#define BUILTIN(ID, TYPE, ATTRS) \ + { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES }, +#include "clang/Basic/BuiltinsSystemZ.def" }; const char *const SystemZTargetInfo::GCCRegNames[] = { Index: tools/clang/lib/Sema/SemaChecking.cpp =================================================================== --- tools/clang/lib/Sema/SemaChecking.cpp.orig +++ tools/clang/lib/Sema/SemaChecking.cpp @@ -317,6 +317,10 @@ Sema::CheckBuiltinFunctionCall(unsigned if (CheckMipsBuiltinFunctionCall(BuiltinID, TheCall)) return ExprError(); break; + case llvm::Triple::systemz: + if (CheckSystemZBuiltinFunctionCall(BuiltinID, TheCall)) + return ExprError(); + break; default: break; } @@ -639,6 +643,20 @@ bool Sema::CheckMipsBuiltinFunctionCall( return SemaBuiltinConstantArgRange(TheCall, i, l, u); } +bool Sema::CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, + CallExpr *TheCall) { + if (BuiltinID == SystemZ::BI__builtin_tabort) { + Expr *Arg = TheCall->getArg(0); + llvm::APSInt AbortCode(32); + if (Arg->isIntegerConstantExpr(AbortCode, Context) && + AbortCode.getSExtValue() >= 0 && AbortCode.getSExtValue() < 256) + return Diag(Arg->getLocStart(), diag::err_systemz_invalid_tabort_code) + << Arg->getSourceRange(); + } + + return false; +} + /// Given a FunctionDecl's FormatAttr, attempts to populate the FomatStringInfo /// parameter with the FormatAttr's correct format_idx and firstDataArg. /// Returns true when the format fits the function and the FormatStringInfo has Index: tools/clang/lib/Driver/Tools.cpp =================================================================== --- tools/clang/lib/Driver/Tools.cpp.orig +++ tools/clang/lib/Driver/Tools.cpp @@ -1275,6 +1275,18 @@ static const char *getSystemZTargetCPU(c return "z10"; } +static void getSystemZTargetFeatures(const ArgList &Args, + std::vector<const char *> &Features) { + // -m(no-)htm overrides use of the transactional-execution facility. + if (Arg *A = Args.getLastArg(options::OPT_mhtm, + options::OPT_mno_htm)) { + if (A->getOption().matches(options::OPT_mhtm)) + Features.push_back("+transactional-execution"); + else + Features.push_back("-transactional-execution"); + } +} + static const char *getX86TargetCPU(const ArgList &Args, const llvm::Triple &Triple) { if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { @@ -1531,6 +1543,9 @@ static void getTargetFeatures(const Driv case llvm::Triple::sparc: getSparcTargetFeatures(Args, Features); break; + case llvm::Triple::systemz: + getSystemZTargetFeatures(Args, Features); + break; case llvm::Triple::aarch64: getAArch64TargetFeatures(D, Args, Features); break; Index: tools/clang/lib/CodeGen/CodeGenFunction.h =================================================================== --- tools/clang/lib/CodeGen/CodeGenFunction.h.orig +++ tools/clang/lib/CodeGen/CodeGenFunction.h @@ -2172,6 +2172,7 @@ public: llvm::Value *BuildVector(ArrayRef<llvm::Value*> Ops); llvm::Value *EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitPPCBuiltinExpr(unsigned BuiltinID, const CallExpr *E); + llvm::Value *EmitSystemZBuiltinExpr(unsigned BuiltinID, const CallExpr *E); llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E); llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E); Index: tools/clang/lib/CodeGen/CGBuiltin.cpp =================================================================== --- tools/clang/lib/CodeGen/CGBuiltin.cpp.orig +++ tools/clang/lib/CodeGen/CGBuiltin.cpp @@ -1602,6 +1602,8 @@ Value *CodeGenFunction::EmitTargetBuilti case llvm::Triple::ppc64: case llvm::Triple::ppc64le: return EmitPPCBuiltinExpr(BuiltinID, E); + case llvm::Triple::systemz: + return EmitSystemZBuiltinExpr(BuiltinID, E); default: return 0; } @@ -5285,3 +5287,41 @@ Value *CodeGenFunction::EmitPPCBuiltinEx } } } + +Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID, + const CallExpr *E) { + switch (BuiltinID) { + case SystemZ::BI__builtin_tbegin: { + Value *TDB = EmitScalarExpr(E->getArg(0)); + Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c); + Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin); + return Builder.CreateCall2(F, TDB, Control); + } + case SystemZ::BI__builtin_tbegin_nofloat: { + Value *TDB = EmitScalarExpr(E->getArg(0)); + Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c); + Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin_nofloat); + return Builder.CreateCall2(F, TDB, Control); + } + case SystemZ::BI__builtin_tbeginc: { + Value *TDB = llvm::ConstantPointerNull::get(Int8PtrTy); + Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff08); + Value *F = CGM.getIntrinsic(Intrinsic::s390_tbeginc); + return Builder.CreateCall2(F, TDB, Control); + } + case SystemZ::BI__builtin_tabort: { + Value *Data = EmitScalarExpr(E->getArg(0)); + Value *F = CGM.getIntrinsic(Intrinsic::s390_tabort); + return Builder.CreateCall(F, Builder.CreateSExt(Data, Int64Ty, "tabort")); + } + case SystemZ::BI__builtin_non_tx_store: { + Value *Address = EmitScalarExpr(E->getArg(0)); + Value *Data = EmitScalarExpr(E->getArg(1)); + Value *F = CGM.getIntrinsic(Intrinsic::s390_ntstg); + return Builder.CreateCall2(F, Data, Address); + } + + default: + return 0; + } +} Index: tools/clang/lib/Headers/htmintrin.h =================================================================== --- /dev/null +++ tools/clang/lib/Headers/htmintrin.h @@ -0,0 +1,125 @@ +/*===---- 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 + +#ifdef __s390__ + +/* Condition codes generated by tbegin */ +#define _HTM_TBEGIN_STARTED 0 +#define _HTM_TBEGIN_INDETERMINATE 1 +#define _HTM_TBEGIN_TRANSIENT 2 +#define _HTM_TBEGIN_PERSISTENT 3 + +/* The abort codes below this threshold are reserved for machine use. */ +#define _HTM_FIRST_USER_ABORT_CODE 256 + +/* The transaction diagnostic block is it is defined in the Principles + of Operation chapter 5-91. */ + +struct __htm_tdb { + unsigned char format; /* 0 */ + unsigned char flags; + unsigned char reserved1[4]; + unsigned short nesting_depth; + unsigned long long abort_code; /* 8 */ + unsigned long long conflict_token; /* 16 */ + unsigned long long atia; /* 24 */ + unsigned char eaid; /* 32 */ + unsigned char dxc; + unsigned char reserved2[2]; + unsigned int program_int_id; + unsigned long long exception_id; /* 40 */ + unsigned long long bea; /* 48 */ + unsigned char reserved3[72]; /* 56 */ + unsigned long long gprs[16]; /* 128 */ +} __attribute__((__packed__, __aligned__ (8))); + + +/* Helper intrinsics to retry tbegin in case of transient failure. */ + +static __inline int __attribute__((__always_inline__, __nodebug__)) +__builtin_tbegin_retry_null (int retry) +{ + int cc, i = 0; + + while ((cc = __builtin_tbegin(0)) == _HTM_TBEGIN_TRANSIENT + && i++ < retry) + __builtin_tx_assist(i); + + return cc; +} + +static __inline int __attribute__((__always_inline__, __nodebug__)) +__builtin_tbegin_retry_tdb (void *tdb, int retry) +{ + int cc, i = 0; + + while ((cc = __builtin_tbegin(tdb)) == _HTM_TBEGIN_TRANSIENT + && i++ < retry) + __builtin_tx_assist(i); + + return cc; +} + +#define __builtin_tbegin_retry(tdb, retry) \ + (__builtin_constant_p(tdb == 0) && tdb == 0 ? \ + __builtin_tbegin_retry_null(retry) : \ + __builtin_tbegin_retry_tdb(tdb, retry)) + +static __inline int __attribute__((__always_inline__, __nodebug__)) +__builtin_tbegin_retry_nofloat_null (int retry) +{ + int cc, i = 0; + + while ((cc = __builtin_tbegin_nofloat(0)) == _HTM_TBEGIN_TRANSIENT + && i++ < retry) + __builtin_tx_assist(i); + + return cc; +} + +static __inline int __attribute__((__always_inline__, __nodebug__)) +__builtin_tbegin_retry_nofloat_tdb (void *tdb, int retry) +{ + int cc, i = 0; + + while ((cc = __builtin_tbegin_nofloat(tdb)) == _HTM_TBEGIN_TRANSIENT + && i++ < retry) + __builtin_tx_assist(i); + + return cc; +} + +#define __builtin_tbegin_retry_nofloat(tdb, retry) \ + (__builtin_constant_p(tdb == 0) && tdb == 0 ? \ + __builtin_tbegin_retry_nofloat_null(retry) : \ + __builtin_tbegin_retry_nofloat_tdb(tdb, retry)) + +#endif /* __s390__ */ + +#endif /* __HTMINTRIN_H */ Index: tools/clang/include/clang/Driver/Options.td =================================================================== --- tools/clang/include/clang/Driver/Options.td.orig +++ tools/clang/include/clang/Driver/Options.td @@ -1057,6 +1057,9 @@ def mno_popcntd : Flag<["-"], "mno-popcn def mqpx : Flag<["-"], "mqpx">, Group<m_ppc_Features_Group>; def mno_qpx : Flag<["-"], "mno-qpx">, Group<m_ppc_Features_Group>; +def mhtm : Flag<["-"], "mhtm">, Group<m_Group>; +def mno_htm : Flag<["-"], "mno-htm">, Group<m_Group>; + def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable AltiVec vector initializer syntax">; def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>, Flags<[CC1Option]>;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor