mirror of https://github.com/microsoft/clang.git
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@234547 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7e9f4eeaf9
commit
1ed200ed06
|
@ -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
|
||||
|
|
|
@ -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">;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue