182 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			182 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- TargetParser - Parser for target features ---------------*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| //
 | |
| // This file implements a target parser to recognise CSKY hardware features
 | |
| // such as CPU/ARCH names.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "llvm/Support/CSKYTargetParser.h"
 | |
| #include "llvm/ADT/StringSwitch.h"
 | |
| 
 | |
| using namespace llvm;
 | |
| 
 | |
| bool CSKY::getFPUFeatures(CSKYFPUKind CSKYFPUKind,
 | |
|                           std::vector<StringRef> &Features) {
 | |
| 
 | |
|   if (CSKYFPUKind >= FK_LAST || CSKYFPUKind == FK_INVALID)
 | |
|     return false;
 | |
| 
 | |
|   switch (CSKYFPUKind) {
 | |
|   case FK_AUTO:
 | |
|     Features.push_back("+fpuv2_sf");
 | |
|     Features.push_back("+fpuv2_df");
 | |
|     Features.push_back("+fdivdu");
 | |
|     break;
 | |
|   case FK_FPV2:
 | |
|     Features.push_back("+fpuv2_sf");
 | |
|     Features.push_back("+fpuv2_df");
 | |
|     break;
 | |
|   case FK_FPV2_DIVD:
 | |
|     Features.push_back("+fpuv2_sf");
 | |
|     Features.push_back("+fpuv2_df");
 | |
|     Features.push_back("+fdivdu");
 | |
|     break;
 | |
|   case FK_FPV2_SF:
 | |
|     Features.push_back("+fpuv2_sf");
 | |
|     break;
 | |
|   case FK_FPV3:
 | |
|     Features.push_back("+fpuv3_hf");
 | |
|     Features.push_back("+fpuv3_hi");
 | |
|     Features.push_back("+fpuv3_sf");
 | |
|     Features.push_back("+fpuv3_df");
 | |
|     break;
 | |
|   case FK_FPV3_HF:
 | |
|     Features.push_back("+fpuv3_hf");
 | |
|     Features.push_back("+fpuv3_hi");
 | |
|     break;
 | |
|   case FK_FPV3_HSF:
 | |
|     Features.push_back("+fpuv3_hf");
 | |
|     Features.push_back("+fpuv3_hi");
 | |
|     Features.push_back("+fpuv3_sf");
 | |
|     break;
 | |
|   case FK_FPV3_SDF:
 | |
|     Features.push_back("+fpuv3_sf");
 | |
|     Features.push_back("+fpuv3_df");
 | |
|     break;
 | |
|   default:
 | |
|     llvm_unreachable("Unknown FPU Kind");
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| // ======================================================= //
 | |
| // Information by ID
 | |
| // ======================================================= //
 | |
| 
 | |
| StringRef CSKY::getArchName(ArchKind AK) {
 | |
|   return ARCHNames[static_cast<unsigned>(AK)].getName();
 | |
| }
 | |
| 
 | |
| // The default cpu's name is same as arch name.
 | |
| StringRef CSKY::getDefaultCPU(StringRef Arch) {
 | |
|   ArchKind AK = parseArch(Arch);
 | |
|   if (AK == CSKY::ArchKind::INVALID)
 | |
|     return StringRef();
 | |
| 
 | |
|   return Arch;
 | |
| }
 | |
| 
 | |
| // ======================================================= //
 | |
| // Parsers
 | |
| // ======================================================= //
 | |
| CSKY::ArchKind CSKY::parseArch(StringRef Arch) {
 | |
|   for (const auto A : ARCHNames) {
 | |
|     if (A.getName() == Arch)
 | |
|       return A.ID;
 | |
|   }
 | |
| 
 | |
|   return CSKY::ArchKind::INVALID;
 | |
| }
 | |
| 
 | |
| CSKY::ArchKind CSKY::parseCPUArch(StringRef CPU) {
 | |
|   for (const auto C : CPUNames) {
 | |
|     if (CPU == C.getName())
 | |
|       return C.ArchID;
 | |
|   }
 | |
| 
 | |
|   return CSKY::ArchKind::INVALID;
 | |
| }
 | |
| 
 | |
| uint64_t CSKY::parseArchExt(StringRef ArchExt) {
 | |
|   for (const auto &A : CSKYARCHExtNames) {
 | |
|     if (ArchExt == A.getName())
 | |
|       return A.ID;
 | |
|   }
 | |
|   return AEK_INVALID;
 | |
| }
 | |
| 
 | |
| void CSKY::fillValidCPUArchList(SmallVectorImpl<StringRef> &Values) {
 | |
|   for (const CpuNames<CSKY::ArchKind> &Arch : CPUNames) {
 | |
|     if (Arch.ArchID != CSKY::ArchKind::INVALID)
 | |
|       Values.push_back(Arch.getName());
 | |
|   }
 | |
| }
 | |
| 
 | |
| StringRef CSKY::getFPUName(unsigned FPUKind) {
 | |
|   if (FPUKind >= FK_LAST)
 | |
|     return StringRef();
 | |
|   return FPUNames[FPUKind].getName();
 | |
| }
 | |
| 
 | |
| CSKY::FPUVersion CSKY::getFPUVersion(unsigned FPUKind) {
 | |
|   if (FPUKind >= FK_LAST)
 | |
|     return FPUVersion::NONE;
 | |
|   return FPUNames[FPUKind].FPUVer;
 | |
| }
 | |
| 
 | |
| uint64_t CSKY::getDefaultExtensions(StringRef CPU) {
 | |
|   return StringSwitch<uint64_t>(CPU)
 | |
| #define CSKY_CPU_NAME(NAME, ID, DEFAULT_EXT)                                   \
 | |
|   .Case(NAME, ARCHNames[static_cast<unsigned>(ArchKind::ID)].archBaseExt |     \
 | |
|                   DEFAULT_EXT)
 | |
| #include "llvm/Support/CSKYTargetParser.def"
 | |
|       .Default(CSKY::AEK_INVALID);
 | |
| }
 | |
| 
 | |
| StringRef CSKY::getArchExtName(uint64_t ArchExtKind) {
 | |
|   for (const auto &AE : CSKYARCHExtNames)
 | |
|     if (ArchExtKind == AE.ID)
 | |
|       return AE.getName();
 | |
|   return StringRef();
 | |
| }
 | |
| 
 | |
| static bool stripNegationPrefix(StringRef &Name) {
 | |
|   if (Name.startswith("no")) {
 | |
|     Name = Name.substr(2);
 | |
|     return true;
 | |
|   }
 | |
|   return false;
 | |
| }
 | |
| 
 | |
| StringRef CSKY::getArchExtFeature(StringRef ArchExt) {
 | |
|   bool Negated = stripNegationPrefix(ArchExt);
 | |
|   for (const auto &AE : CSKYARCHExtNames) {
 | |
|     if (AE.Feature && ArchExt == AE.getName())
 | |
|       return StringRef(Negated ? AE.NegFeature : AE.Feature);
 | |
|   }
 | |
| 
 | |
|   return StringRef();
 | |
| }
 | |
| 
 | |
| bool CSKY::getExtensionFeatures(uint64_t Extensions,
 | |
|                                 std::vector<StringRef> &Features) {
 | |
|   if (Extensions == CSKY::AEK_INVALID)
 | |
|     return false;
 | |
| 
 | |
|   for (const auto &AE : CSKYARCHExtNames) {
 | |
|     if ((Extensions & AE.ID) == AE.ID && AE.Feature)
 | |
|       Features.push_back(AE.Feature);
 | |
|   }
 | |
| 
 | |
|   return true;
 | |
| }
 |