@@ -16783,32 +16783,53 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
16783
16783
16784
16784
#include "llvm/TargetParser/PPCTargetParser.def"
16785
16785
auto GenAIXPPCBuiltinCpuExpr = [&](unsigned SupportMethod, unsigned FieldIdx,
16786
- unsigned CompOp,
16786
+ unsigned Mask, CmpInst::Predicate CompOp,
16787
16787
unsigned OpValue) -> Value * {
16788
16788
if (SupportMethod == AIX_BUILTIN_PPC_FALSE)
16789
16789
return llvm::ConstantInt::getFalse(ConvertType(E->getType()));
16790
16790
16791
16791
if (SupportMethod == AIX_BUILTIN_PPC_TRUE)
16792
16792
return llvm::ConstantInt::getTrue(ConvertType(E->getType()));
16793
16793
16794
- assert(SupportMethod <= USE_SYS_CONF && "Invalid value for SupportMethod.");
16795
- assert((CompOp == COMP_EQ) && "Only equal comparisons are supported.");
16794
+ assert(SupportMethod <= SYS_CALL && "Invalid value for SupportMethod.");
16795
+
16796
+ llvm::Value *FieldValue = nullptr;
16797
+ if (SupportMethod == USE_SYS_CONF) {
16798
+ llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE);
16799
+ llvm::Constant *SysConf =
16800
+ CGM.CreateRuntimeVariable(STy, "_system_configuration");
16801
+
16802
+ // Grab the appropriate field from _system_configuration.
16803
+ llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0),
16804
+ ConstantInt::get(Int32Ty, FieldIdx)};
16805
+
16806
+ FieldValue = Builder.CreateGEP(STy, SysConf, Idxs);
16807
+ FieldValue = Builder.CreateAlignedLoad(Int32Ty, FieldValue,
16808
+ CharUnits::fromQuantity(4));
16809
+ } else if (SupportMethod == SYS_CALL) {
16810
+ llvm::FunctionType *FTy =
16811
+ llvm::FunctionType::get(Int64Ty, Int32Ty, false);
16812
+ llvm::FunctionCallee Func =
16813
+ CGM.CreateRuntimeFunction(FTy, "getsystemcfg");
16814
+
16815
+ FieldValue =
16816
+ Builder.CreateCall(Func, {ConstantInt::get(Int32Ty, FieldIdx)});
16817
+ }
16818
+ assert(FieldValue &&
16819
+ "SupportMethod value is not defined in PPCTargetParser.def.");
16796
16820
16797
- llvm::Type *STy = llvm::StructType::get(PPC_SYSTEMCONFIG_TYPE);
16798
- llvm::Constant *SysConf =
16799
- CGM.CreateRuntimeVariable(STy, "_system_configuration");
16821
+ if (Mask)
16822
+ FieldValue = Builder.CreateAnd(FieldValue, Mask);
16800
16823
16801
- // Grab the appropriate field from _system_configuration.
16802
- llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0),
16803
- ConstantInt::get(Int32Ty, FieldIdx)};
16824
+ llvm::Type *ValueType = FieldValue->getType();
16825
+ bool IsValueType64Bit = ValueType->isIntegerTy(64);
16826
+ assert(
16827
+ (IsValueType64Bit || ValueType->isIntegerTy(32)) &&
16828
+ "Only 32/64-bit integers are supported in GenAIXPPCBuiltinCpuExpr().");
16804
16829
16805
- llvm::Value *FieldValue = Builder.CreateGEP(STy, SysConf, Idxs);
16806
- FieldValue = Builder.CreateAlignedLoad(Int32Ty, FieldValue,
16807
- CharUnits::fromQuantity(4));
16808
- assert(FieldValue->getType()->isIntegerTy(32) &&
16809
- "Only 32-bit integers are supported in GenAIXPPCBuiltinCpuExpr().");
16810
- return Builder.CreateICmp(ICmpInst::ICMP_EQ, FieldValue,
16811
- ConstantInt::get(Int32Ty, OpValue));
16830
+ return Builder.CreateICmp(
16831
+ CompOp, FieldValue,
16832
+ ConstantInt::get(IsValueType64Bit ? Int64Ty : Int32Ty, OpValue));
16812
16833
};
16813
16834
16814
16835
switch (BuiltinID) {
@@ -16820,15 +16841,18 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
16820
16841
llvm::Triple Triple = getTarget().getTriple();
16821
16842
16822
16843
if (Triple.isOSAIX()) {
16823
- unsigned IsCpuSupport, FieldIdx, CompareOp, CpuIdValue;
16824
- typedef std::tuple<unsigned, unsigned, unsigned, unsigned> CPUType;
16825
- std::tie(IsCpuSupport, FieldIdx, CompareOp, CpuIdValue) =
16844
+ unsigned SupportMethod, FieldIdx, CpuIdValue;
16845
+ CmpInst::Predicate CompareOp;
16846
+ typedef std::tuple<unsigned, unsigned, CmpInst::Predicate, unsigned>
16847
+ CPUType;
16848
+ std::tie(SupportMethod, FieldIdx, CompareOp, CpuIdValue) =
16826
16849
static_cast<CPUType>(StringSwitch<CPUType>(CPUStr)
16827
- #define PPC_AIX_CPU(NAME, SUPPORT_MAGIC , INDEX, COMPARE_OP, VALUE) \
16828
- .Case(NAME, {SUPPORT_MAGIC , INDEX, COMPARE_OP, VALUE})
16850
+ #define PPC_AIX_CPU(NAME, SUPPORT_METHOD , INDEX, COMPARE_OP, VALUE) \
16851
+ .Case(NAME, {SUPPORT_METHOD , INDEX, COMPARE_OP, VALUE})
16829
16852
#include "llvm/TargetParser/PPCTargetParser.def"
16830
- );
16831
- return GenAIXPPCBuiltinCpuExpr(IsCpuSupport, FieldIdx, CompareOp,
16853
+ .Default({AIX_BUILTIN_PPC_FALSE, 0,
16854
+ CmpInst::Predicate(), 0}));
16855
+ return GenAIXPPCBuiltinCpuExpr(SupportMethod, FieldIdx, 0, CompareOp,
16832
16856
CpuIdValue);
16833
16857
}
16834
16858
@@ -16846,10 +16870,31 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
16846
16870
llvm::ConstantInt::get(Int32Ty, NumCPUID));
16847
16871
}
16848
16872
case Builtin::BI__builtin_cpu_supports: {
16849
- unsigned FeatureWord;
16850
- unsigned BitMask;
16873
+ llvm::Triple Triple = getTarget().getTriple();
16851
16874
const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
16852
16875
StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
16876
+ if (Triple.isOSAIX()) {
16877
+ unsigned SupportMethod, FieldIdx, Mask, Value;
16878
+ CmpInst::Predicate CompOp;
16879
+ typedef std::tuple<unsigned, unsigned, unsigned, CmpInst::Predicate,
16880
+ unsigned>
16881
+ CPUSupportType;
16882
+ std::tie(SupportMethod, FieldIdx, Mask, CompOp, Value) =
16883
+ static_cast<CPUSupportType>(StringSwitch<CPUSupportType>(CPUStr)
16884
+ #define PPC_AIX_FEATURE(NAME, DESC, SUPPORT_METHOD, INDEX, MASK, COMP_OP, \
16885
+ VALUE) \
16886
+ .Case(NAME, {SUPPORT_METHOD, INDEX, MASK, COMP_OP, VALUE})
16887
+ #include "llvm/TargetParser/PPCTargetParser.def"
16888
+ .Default({AIX_BUILTIN_PPC_FALSE, 0, 0,
16889
+ CmpInst::Predicate(), 0}));
16890
+ return GenAIXPPCBuiltinCpuExpr(SupportMethod, FieldIdx, Mask, CompOp,
16891
+ Value);
16892
+ }
16893
+
16894
+ assert(Triple.isOSLinux() &&
16895
+ "__builtin_cpu_supports() is only supported for AIX and Linux.");
16896
+ unsigned FeatureWord;
16897
+ unsigned BitMask;
16853
16898
std::tie(FeatureWord, BitMask) =
16854
16899
StringSwitch<std::pair<unsigned, unsigned>>(CPUStr)
16855
16900
#define PPC_LNX_FEATURE(Name, Description, EnumName, Bitmask, FA_WORD) \
0 commit comments