|
62 | 62 | #include "llvm/Support/MathExtras.h" |
63 | 63 | #include "llvm/Support/ScopedPrinter.h" |
64 | 64 | #include "llvm/TargetParser/AArch64TargetParser.h" |
| 65 | +#include "llvm/TargetParser/RISCVISAInfo.h" |
| 66 | +#include "llvm/TargetParser/RISCVTargetParser.h" |
65 | 67 | #include "llvm/TargetParser/X86TargetParser.h" |
66 | 68 | #include <optional> |
67 | 69 | #include <sstream> |
@@ -14215,6 +14217,16 @@ Value *CodeGenFunction::EmitAArch64CpuInit() { |
14215 | 14217 | return Builder.CreateCall(Func); |
14216 | 14218 | } |
14217 | 14219 |
|
| 14220 | +Value *CodeGenFunction::EmitRISCVCpuInit() { |
| 14221 | + llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); |
| 14222 | + llvm::FunctionCallee Func = |
| 14223 | + CGM.CreateRuntimeFunction(FTy, "__init_riscv_feature_bits"); |
| 14224 | + auto *CalleeGV = cast<llvm::GlobalValue>(Func.getCallee()); |
| 14225 | + CalleeGV->setDSOLocal(true); |
| 14226 | + CalleeGV->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass); |
| 14227 | + return Builder.CreateCall(Func); |
| 14228 | +} |
| 14229 | + |
14218 | 14230 | Value *CodeGenFunction::EmitX86CpuInit() { |
14219 | 14231 | llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, |
14220 | 14232 | /*Variadic*/ false); |
@@ -14267,6 +14279,43 @@ CodeGenFunction::EmitAArch64CpuSupports(ArrayRef<StringRef> FeaturesStrs) { |
14267 | 14279 | return Result; |
14268 | 14280 | } |
14269 | 14281 |
|
| 14282 | +Value *CodeGenFunction::EmitRISCVCpuSupports(const CallExpr *E) { |
| 14283 | + |
| 14284 | + const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts(); |
| 14285 | + StringRef FeatureStr = cast<StringLiteral>(FeatureExpr)->getString(); |
| 14286 | + if (!getContext().getTargetInfo().validateCpuSupports(FeatureStr)) |
| 14287 | + return Builder.getFalse(); |
| 14288 | + |
| 14289 | + // Note: We are making an unchecked assumption that the size of the |
| 14290 | + // feature array is >= 1. This holds for any version of compiler-rt |
| 14291 | + // which defines this interface. |
| 14292 | + llvm::ArrayType *ArrayOfInt64Ty = |
| 14293 | + llvm::ArrayType::get(Int64Ty, 1); |
| 14294 | + llvm::Type *StructTy = llvm::StructType::get(Int32Ty, ArrayOfInt64Ty); |
| 14295 | + llvm::Constant *RISCVFeaturesBits = |
| 14296 | + CGM.CreateRuntimeVariable(StructTy, "__riscv_feature_bits"); |
| 14297 | + auto *GV = cast<llvm::GlobalValue>(RISCVFeaturesBits); |
| 14298 | + GV->setDSOLocal(true); |
| 14299 | + |
| 14300 | + auto LoadFeatureBit = [&](unsigned Index) { |
| 14301 | + // Create GEP then load. |
| 14302 | + Value *IndexVal = llvm::ConstantInt::get(Int32Ty, Index); |
| 14303 | + llvm::Value *GEPIndices[] = {Builder.getInt32(0), Builder.getInt32(1), |
| 14304 | + IndexVal}; |
| 14305 | + Value *Ptr = |
| 14306 | + Builder.CreateInBoundsGEP(StructTy, RISCVFeaturesBits, GEPIndices); |
| 14307 | + Value *FeaturesBit = |
| 14308 | + Builder.CreateAlignedLoad(Int64Ty, Ptr, CharUnits::fromQuantity(8)); |
| 14309 | + return FeaturesBit; |
| 14310 | + }; |
| 14311 | + |
| 14312 | + int BitPos = RISCVISAInfo::getRISCVFeaturesBitPosition(FeatureStr); |
| 14313 | + assert(BitPos != -1 && "validation should have rejected this feature"); |
| 14314 | + Value *MaskV = Builder.getInt64(1ULL << BitPos); |
| 14315 | + Value *Bitset = Builder.CreateAnd(LoadFeatureBit(0), MaskV); |
| 14316 | + return Builder.CreateICmpEQ(Bitset, MaskV); |
| 14317 | +} |
| 14318 | + |
14270 | 14319 | Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, |
14271 | 14320 | const CallExpr *E) { |
14272 | 14321 | if (BuiltinID == Builtin::BI__builtin_cpu_is) |
@@ -21728,6 +21777,12 @@ Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID, |
21728 | 21777 | Value *CodeGenFunction::EmitRISCVBuiltinExpr(unsigned BuiltinID, |
21729 | 21778 | const CallExpr *E, |
21730 | 21779 | ReturnValueSlot ReturnValue) { |
| 21780 | + |
| 21781 | + if (BuiltinID == Builtin::BI__builtin_cpu_supports) |
| 21782 | + return EmitRISCVCpuSupports(E); |
| 21783 | + if (BuiltinID == Builtin::BI__builtin_cpu_init) |
| 21784 | + return EmitRISCVCpuInit(); |
| 21785 | + |
21731 | 21786 | SmallVector<Value *, 4> Ops; |
21732 | 21787 | llvm::Type *ResultType = ConvertType(E->getType()); |
21733 | 21788 |
|
|
0 commit comments