src/plugins/thirdParty/LLVM/tools/clang/lib/Basic/Targets.cpp
/// handleTargetFeatures - Perform initialization based on the user
/// configured set of features.
Perform initialization based on the user
configured set of features.
Perform initialization based on the user configured set of features .
bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
                                         DiagnosticsEngine &Diags) {
  for (unsigned i = 0, e = Features.size(); i !=e; ++i) {
    if (Features[i][0] == '-')
      continue;
    StringRef Feature = StringRef(Features[i]).substr(1);
    if (Feature == "aes") {
      HasAES = true;
      continue;
    }
    if (Feature == "pclmul") {
      HasPCLMUL = true;
      continue;
    }
    if (Feature == "lzcnt") {
      HasLZCNT = true;
      continue;
    }
    if (Feature == "rdrnd") {
      HasRDRND = true;
      continue;
    }
    if (Feature == "fsgsbase") {
      HasFSGSBASE = true;
      continue;
    }
    if (Feature == "bmi") {
      HasBMI = true;
      continue;
    }
    if (Feature == "bmi2") {
      HasBMI2 = true;
      continue;
    }
    if (Feature == "popcnt") {
      HasPOPCNT = true;
      continue;
    }
    if (Feature == "rtm") {
      HasRTM = true;
      continue;
    }
    if (Feature == "prfchw") {
      HasPRFCHW = true;
      continue;
    }
    if (Feature == "rdseed") {
      HasRDSEED = true;
      continue;
    }
    if (Feature == "adx") {
      HasADX = true;
      continue;
    }
    if (Feature == "tbm") {
      HasTBM = true;
      continue;
    }
    if (Feature == "fma") {
      HasFMA = true;
      continue;
    }
    if (Feature == "f16c") {
      HasF16C = true;
      continue;
    }
    if (Feature == "avx512cd") {
      HasAVX512CD = true;
      continue;
    }
    if (Feature == "avx512er") {
      HasAVX512ER = true;
      continue;
    }
    if (Feature == "avx512pf") {
      HasAVX512PF = true;
      continue;
    }
    if (Feature == "avx512dq") {
      HasAVX512DQ = true;
      continue;
    }
    if (Feature == "avx512bw") {
      HasAVX512BW = true;
      continue;
    }
    if (Feature == "avx512vl") {
      HasAVX512VL = true;
      continue;
    }
    if (Feature == "sha") {
      HasSHA = true;
      continue;
    }
    if (Feature == "cx16") {
      HasCX16 = true;
      continue;
    }
    assert(Features[i][0] == '+' && "Invalid target feature!");
    X86SSEEnum Level = llvm::StringSwitch<X86SSEEnum>(Feature)
      .Case("avx512f", AVX512F)
      .Case("avx2", AVX2)
      .Case("avx", AVX)
      .Case("sse4.2", SSE42)
      .Case("sse4.1", SSE41)
      .Case("ssse3", SSSE3)
      .Case("sse3", SSE3)
      .Case("sse2", SSE2)
      .Case("sse", SSE1)
      .Default(NoSSE);
    SSELevel = std::max(SSELevel, Level);
    MMX3DNowEnum ThreeDNowLevel =
      llvm::StringSwitch<MMX3DNowEnum>(Feature)
        .Case("3dnowa", AMD3DNowAthlon)
        .Case("3dnow", AMD3DNow)
        .Case("mmx", MMX)
        .Default(NoMMX3DNow);
    MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel);
    XOPEnum XLevel = llvm::StringSwitch<XOPEnum>(Feature)
        .Case("xop", XOP)
        .Case("fma4", FMA4)
        .Case("sse4a", SSE4A)
        .Default(NoXOP);
    XOPLevel = std::max(XOPLevel, XLevel);
  }
  if (!HasPOPCNT && SSELevel >= SSE42 &&
      std::find(Features.begin(), Features.end(), "-popcnt") == Features.end()){
    HasPOPCNT = true;
    Features.push_back("+popcnt");
  }
  if (!HasPRFCHW && MMX3DNowLevel >= AMD3DNow &&
      std::find(Features.begin(), Features.end(), "-prfchw") == Features.end()){
    HasPRFCHW = true;
    Features.push_back("+prfchw");
  }
  if (FPMath == FP_SSE && SSELevel < SSE1) {
    Diags.Report(diag::err_target_unsupported_fpmath) << "sse";
    return false;
  } else if (FPMath == FP_387 && SSELevel >= SSE1) {
    Diags.Report(diag::err_target_unsupported_fpmath) << "387";
    return false;
  }
  std::vector<std::string>::iterator it;
  it = std::find(Features.begin(), Features.end(), "-mmx");
  if (it != Features.end())
    Features.erase(it);
  else if (SSELevel > NoSSE)
    MMX3DNowLevel = std::max(MMX3DNowLevel, MMX);
  return true;
}
bool X86TargetInfo :: handleTargetFeatures ( std :: vector < std :: string > & Features , DiagnosticsEngine & Diags ) { for ( unsigned i = 0 , e = Features . size ( ) ; i != e ; ++ i ) { if ( Features [ i ] [ 0 ] == ' ' ) continue ; StringRef Feature = StringRef ( Features [ i ] ) . substr ( 1 ) ; if ( Feature == " " ) { HasAES = true ; continue ; } if ( Feature == " " ) { HasPCLMUL = true ; continue ; } if ( Feature == " " ) { HasLZCNT = true ; continue ; } if ( Feature == " " ) { HasRDRND = true ; continue ; } if ( Feature == " " ) { HasFSGSBASE = true ; continue ; } if ( Feature == " " ) { HasBMI = true ; continue ; } if ( Feature == " " ) { HasBMI2 = true ; continue ; } if ( Feature == " " ) { HasPOPCNT = true ; continue ; } if ( Feature == " " ) { HasRTM = true ; continue ; } if ( Feature == " " ) { HasPRFCHW = true ; continue ; } if ( Feature == " " ) { HasRDSEED = true ; continue ; } if ( Feature == " " ) { HasADX = true ; continue ; } if ( Feature == " " ) { HasTBM = true ; continue ; } if ( Feature == " " ) { HasFMA = true ; continue ; } if ( Feature == " " ) { HasF16C = true ; continue ; } if ( Feature == " " ) { HasAVX512CD = true ; continue ; } if ( Feature == " " ) { HasAVX512ER = true ; continue ; } if ( Feature == " " ) { HasAVX512PF = true ; continue ; } if ( Feature == " " ) { HasAVX512DQ = true ; continue ; } if ( Feature == " " ) { HasAVX512BW = true ; continue ; } if ( Feature == " " ) { HasAVX512VL = true ; continue ; } if ( Feature == " " ) { HasSHA = true ; continue ; } if ( Feature == " " ) { HasCX16 = true ; continue ; } assert ( Features [ i ] [ 0 ] == ' ' && " " ) ; X86SSEEnum Level = llvm :: StringSwitch < X86SSEEnum > ( Feature ) . Case ( " " , AVX512F ) . Case ( " " , AVX2 ) . Case ( " " , AVX ) . Case ( " " , SSE42 ) . Case ( " " , SSE41 ) . Case ( " " , SSSE3 ) . Case ( " " , SSE3 ) . Case ( " " , SSE2 ) . Case ( " " , SSE1 ) . Default ( NoSSE ) ; SSELevel = std :: max ( SSELevel , Level ) ; MMX3DNowEnum ThreeDNowLevel = llvm :: StringSwitch < MMX3DNowEnum > ( Feature ) . Case ( " " , AMD3DNowAthlon ) . Case ( " " , AMD3DNow ) . Case ( " " , MMX ) . Default ( NoMMX3DNow ) ; MMX3DNowLevel = std :: max ( MMX3DNowLevel , ThreeDNowLevel ) ; XOPEnum XLevel = llvm :: StringSwitch < XOPEnum > ( Feature ) . Case ( " " , XOP ) . Case ( " " , FMA4 ) . Case ( " " , SSE4A ) . Default ( NoXOP ) ; XOPLevel = std :: max ( XOPLevel , XLevel ) ; } if ( ! HasPOPCNT && SSELevel >= SSE42 && std :: find ( Features . begin ( ) , Features . end ( ) , " " ) == Features . end ( ) ) { HasPOPCNT = true ; Features . push_back ( " " ) ; } if ( ! HasPRFCHW && MMX3DNowLevel >= AMD3DNow && std :: find ( Features . begin ( ) , Features . end ( ) , " " ) == Features . end ( ) ) { HasPRFCHW = true ; Features . push_back ( " " ) ; } if ( FPMath == FP_SSE && SSELevel < SSE1 ) { Diags . Report ( diag :: err_target_unsupported_fpmath ) << " " ; return false ; } else if ( FPMath == FP_387 && SSELevel >= SSE1 ) { Diags . Report ( diag :: err_target_unsupported_fpmath ) << " " ; return false ; } std :: vector < std :: string > :: iterator it ; it = std :: find ( Features . begin ( ) , Features . end ( ) , " " ) ; if ( it != Features . end ( ) ) Features . erase ( it ) ; else if ( SSELevel > NoSSE ) MMX3DNowLevel = std :: max ( MMX3DNowLevel , MMX ) ; return true ; }
handleTargetFeatures - Perform initialization based on the user
configured set of features.
handleTargetFeatures - Perform initialization based on the user configured set of features .
// Remember the maximum enabled sselevel. // Ignore disabled features. // Enable popcnt if sse4.2 is enabled and popcnt is not explicitly disabled. // Can't do this earlier because we need to be able to explicitly enable // popcnt and still disable sse4.2. // Enable prfchw if 3DNow! is enabled and prfchw is not explicitly disabled. // LLVM doesn't have a separate switch for fpmath, so only accept it if it // matches the selected sse level. // Don't tell the backend if we're turning off mmx; it will end up disabling // SSE, which we don't want. // Additionally, if SSE is enabled and mmx is not explicitly disabled, // then enable MMX.