summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorNemanja Ivanovic <nemanja.i.ibm@gmail.com>2015-04-09 23:58:16 +0000
committerNemanja Ivanovic <nemanja.i.ibm@gmail.com>2015-04-09 23:58:16 +0000
commit239eec732ebf303bf88c9354a5aa8cdaa00528d9 (patch)
treed0e5331b11782b212d8db6aa7e03dcf22767156b /clang
parentc09047916a139ebc07f789bae4c213753906e341 (diff)
downloadbcm5719-llvm-239eec732ebf303bf88c9354a5aa8cdaa00528d9.tar.gz
bcm5719-llvm-239eec732ebf303bf88c9354a5aa8cdaa00528d9.zip
Add Clang support for remaining integer divide and permute instructions from ISA 2.06
This patch corresponds to review: http://reviews.llvm.org/D8398 It adds some builtin functions to access the extended divide and bit permute instructions. llvm-svn: 234547
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/BuiltinsPPC.def7
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--clang/lib/Basic/Targets.cpp27
-rw-r--r--clang/lib/Sema/SemaChecking.cpp22
-rw-r--r--clang/test/CodeGen/builtins-ppc-p7-disabled.c33
-rw-r--r--clang/test/CodeGen/builtins-ppc-p7.c52
6 files changed, 144 insertions, 1 deletions
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index 8cc50db39d6..09968182b09 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -283,6 +283,13 @@ BUILTIN(__builtin_set_tfiar, "vLUi", "c")
BUILTIN(__builtin_ttest, "LUi", "")
+// Scalar built-ins
+BUILTIN(__builtin_divwe, "SiSiSi", "")
+BUILTIN(__builtin_divweu, "UiUiUi", "")
+BUILTIN(__builtin_divde, "SLLiSLLiSLLi", "")
+BUILTIN(__builtin_divdeu, "ULLiULLiULLi", "")
+BUILTIN(__builtin_bpermd, "SLLiSLLiSLLi", "")
+
// FIXME: Obviously incomplete.
#undef BUILTIN
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 901d50028da..bb2f55c5a07 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7045,6 +7045,10 @@ def note_neon_vector_initializer_non_portable_q : Note<
"constants">;
def err_systemz_invalid_tabort_code : Error<
"invalid transaction abort code">;
+def err_64_bit_builtin_32_bit_tgt : Error<
+ "this builtin is only available on 64-bit targets">;
+def err_ppc_builtin_only_on_pwr7 : Error<
+ "this builtin is only valid on POWER7 or later CPUs">;
def err_builtin_longjmp_unsupported : Error<
"__builtin_longjmp is not supported for the current target">;
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 6d6a5d77e8b..1512eb7a165 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -744,6 +744,8 @@ class PPCTargetInfo : public TargetInfo {
bool HasP8Crypto;
bool HasQPX;
bool HasHTM;
+ bool HasBPERMD;
+ bool HasExtDiv;
protected:
std::string ABI;
@@ -751,7 +753,8 @@ protected:
public:
PPCTargetInfo(const llvm::Triple &Triple)
: TargetInfo(Triple), HasVSX(false), HasP8Vector(false),
- HasP8Crypto(false), HasQPX(false), HasHTM(false) {
+ HasP8Crypto(false), HasQPX(false), HasHTM(false),
+ HasBPERMD(false), HasExtDiv(false) {
BigEndian = (Triple.getArch() != llvm::Triple::ppc64le);
LongDoubleWidth = LongDoubleAlign = 128;
LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble;
@@ -1011,6 +1014,16 @@ bool PPCTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
continue;
}
+ if (Feature == "bpermd") {
+ HasBPERMD = true;
+ continue;
+ }
+
+ if (Feature == "extdiv") {
+ HasExtDiv = true;
+ continue;
+ }
+
if (Feature == "power8-vector") {
HasP8Vector = true;
continue;
@@ -1233,6 +1246,16 @@ void PPCTargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
.Case("ppc64le", true)
.Case("pwr8", true)
.Default(false);
+ Features["bpermd"] = llvm::StringSwitch<bool>(CPU)
+ .Case("ppc64le", true)
+ .Case("pwr8", true)
+ .Case("pwr7", true)
+ .Default(false);
+ Features["extdiv"] = llvm::StringSwitch<bool>(CPU)
+ .Case("ppc64le", true)
+ .Case("pwr8", true)
+ .Case("pwr7", true)
+ .Default(false);
}
bool PPCTargetInfo::hasFeature(StringRef Feature) const {
@@ -1243,6 +1266,8 @@ bool PPCTargetInfo::hasFeature(StringRef Feature) const {
.Case("crypto", HasP8Crypto)
.Case("qpx", HasQPX)
.Case("htm", HasHTM)
+ .Case("bpermd", HasBPERMD)
+ .Case("extdiv", HasExtDiv)
.Default(false);
}
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index d4390e53f0b..05eaaec5792 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -907,6 +907,28 @@ bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
bool Sema::CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
unsigned i = 0, l = 0, u = 0;
+ bool Is64BitBltin = BuiltinID == PPC::BI__builtin_divde ||
+ BuiltinID == PPC::BI__builtin_divdeu ||
+ BuiltinID == PPC::BI__builtin_bpermd;
+ bool IsTarget64Bit = Context.getTargetInfo()
+ .getTypeWidth(Context
+ .getTargetInfo()
+ .getIntPtrType()) == 64;
+ bool IsBltinExtDiv = BuiltinID == PPC::BI__builtin_divwe ||
+ BuiltinID == PPC::BI__builtin_divweu ||
+ BuiltinID == PPC::BI__builtin_divde ||
+ BuiltinID == PPC::BI__builtin_divdeu;
+
+ if (Is64BitBltin && !IsTarget64Bit)
+ return Diag(TheCall->getLocStart(), diag::err_64_bit_builtin_32_bit_tgt)
+ << TheCall->getSourceRange();
+
+ if ((IsBltinExtDiv && !Context.getTargetInfo().hasFeature("extdiv")) ||
+ (BuiltinID == PPC::BI__builtin_bpermd &&
+ !Context.getTargetInfo().hasFeature("bpermd")))
+ return Diag(TheCall->getLocStart(), diag::err_ppc_builtin_only_on_pwr7)
+ << TheCall->getSourceRange();
+
switch (BuiltinID) {
default: return false;
case PPC::BI__builtin_altivec_crypto_vshasigmaw:
diff --git a/clang/test/CodeGen/builtins-ppc-p7-disabled.c b/clang/test/CodeGen/builtins-ppc-p7-disabled.c
new file mode 100644
index 00000000000..9ccedd2ce89
--- /dev/null
+++ b/clang/test/CodeGen/builtins-ppc-p7-disabled.c
@@ -0,0 +1,33 @@
+// REQUIRES: powerpc-registered-target
+// RUN: not %clang_cc1 -triple powerpc64-unknown-unknown \
+// RUN: -target-cpu pwr6 -emit-llvm %s -o - 2>&1 \
+// RUN: | FileCheck %s
+
+// RUN: not %clang_cc1 -triple powerpc-unknown-unknown -emit-llvm %s -o - 2>&1 \
+// RUN: -target-cpu pwr7 | FileCheck %s -check-prefix=CHECK-32
+
+void call_p7_builtins(void)
+{
+ int a = __builtin_divwe(33, 11);
+ unsigned int b = __builtin_divweu(33U, 11U);
+ unsigned long long d = __builtin_divde(33ULL, 11ULL);
+ unsigned long long e = __builtin_divdeu(33ULL, 11ULL);
+ unsigned long long f = __builtin_bpermd(33ULL, 11ULL);
+}
+
+// CHECK: error: this builtin is only valid on POWER7 or later CPUs
+// CHECK: __builtin_divwe
+// CHECK: error: this builtin is only valid on POWER7 or later CPUs
+// CHECK: __builtin_divweu
+// CHECK: error: this builtin is only valid on POWER7 or later CPUs
+// CHECK: __builtin_divde
+// CHECK: error: this builtin is only valid on POWER7 or later CPUs
+// CHECK: __builtin_divdeu
+// CHECK: error: this builtin is only valid on POWER7 or later CPUs
+// CHECK: __builtin_bpermd
+// CHECK-32: error: this builtin is only available on 64-bit targets
+// CHECK-32: __builtin_divde
+// CHECK-32: error: this builtin is only available on 64-bit targets
+// CHECK-32: __builtin_divdeu
+// CHECK-32: error: this builtin is only available on 64-bit targets
+// CHECK-32: __builtin_bpermd
diff --git a/clang/test/CodeGen/builtins-ppc-p7.c b/clang/test/CodeGen/builtins-ppc-p7.c
new file mode 100644
index 00000000000..f5844103080
--- /dev/null
+++ b/clang/test/CodeGen/builtins-ppc-p7.c
@@ -0,0 +1,52 @@
+// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -triple powerpc64-unknown-unknown -target-cpu pwr7 \
+// RUN: -emit-llvm %s -o - | FileCheck %s
+
+// RUN: %clang_cc1 -triple powerpc64le-unknown-unknown -target-cpu pwr8 \
+// RUN: -emit-llvm %s -o - | FileCheck %s
+
+// CHECK-LABEL: define signext i32 @test_divwe
+int test_divwe(void)
+{
+ int a = 74;
+ int b = 32;
+ return __builtin_divwe(a, b);
+// CHECK @llvm.ppc.divwe
+}
+
+// CHECK-LABEL: define zeroext i32 @test_divweu
+unsigned int test_divweu(void)
+{
+ unsigned int a = 74;
+ unsigned int b = 32;
+ return __builtin_divweu(a, b);
+// CHECK @llvm.ppc.divweu
+}
+
+// CHECK-LABEL: define i64 @test_divde
+long long test_divde(void)
+{
+ long long a = 74LL;
+ long long b = 32LL;
+ return __builtin_divde(a, b);
+// CHECK @llvm.ppc.divde
+}
+
+// CHECK-LABEL: define i64 @test_divdeu
+unsigned long long test_divdeu(void)
+{
+ unsigned long long a = 74ULL;
+ unsigned long long b = 32ULL;
+ return __builtin_divdeu(a, b);
+// CHECK @llvm.ppc.divdeu
+}
+
+// CHECK-LABEL: define i64 @test_bpermd
+long long test_bpermd(void)
+{
+ long long a = 74LL;
+ long long b = 32LL;
+ return __builtin_bpermd(a, b);
+// CHECK @llvm.ppc.bpermd
+}
+
OpenPOWER on IntegriCloud