brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.2 KiB · 7cefb3f Raw
196 lines · cpp
1//= LoongArchBaseInfo.cpp - Top level definitions for LoongArch MC -*- C++ -*-//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements helper functions for the LoongArch target useful for the10// compiler back-end and the MC libraries.11//12//===----------------------------------------------------------------------===//13 14#include "LoongArchBaseInfo.h"15#include "LoongArchMCTargetDesc.h"16#include "llvm/Support/ErrorHandling.h"17#include "llvm/Support/raw_ostream.h"18#include "llvm/TargetParser/Triple.h"19 20namespace llvm {21 22namespace LoongArchABI {23 24// Check if ABI has been standardized; issue a warning if it hasn't.25// FIXME: Once all ABIs are standardized, this will be removed.26static ABI checkABIStandardized(ABI Abi) {27  StringRef ABIName;28  switch (Abi) {29  case ABI_ILP32S:30    ABIName = "ilp32s";31    break;32  case ABI_ILP32F:33    ABIName = "ilp32f";34    break;35  case ABI_ILP32D:36    ABIName = "ilp32d";37    break;38  case ABI_LP64F:39    ABIName = "lp64f";40    break;41  case ABI_LP64S:42  case ABI_LP64D:43    return Abi;44  default:45    llvm_unreachable("");46  }47  errs() << "warning: '" << ABIName << "' has not been standardized\n";48  return Abi;49}50 51static ABI getTripleABI(const Triple &TT) {52  bool Is64Bit = TT.isArch64Bit();53  ABI TripleABI;54  switch (TT.getEnvironment()) {55  case llvm::Triple::EnvironmentType::UnknownEnvironment:56    TripleABI = ABI_Unknown;57    break;58  case llvm::Triple::EnvironmentType::GNUSF:59  case llvm::Triple::EnvironmentType::MuslSF:60    TripleABI = Is64Bit ? ABI_LP64S : ABI_ILP32S;61    break;62  case llvm::Triple::EnvironmentType::GNUF32:63  case llvm::Triple::EnvironmentType::MuslF32:64    TripleABI = Is64Bit ? ABI_LP64F : ABI_ILP32F;65    break;66  // Let the fallback case behave like {ILP32,LP64}D.67  case llvm::Triple::EnvironmentType::GNUF64:68  default:69    TripleABI = Is64Bit ? ABI_LP64D : ABI_ILP32D;70    break;71  }72  return TripleABI;73}74 75ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits,76                     StringRef ABIName) {77  bool Is64Bit = TT.isArch64Bit();78  ABI ArgProvidedABI = getTargetABI(ABIName);79  ABI TripleABI = getTripleABI(TT);80 81  auto IsABIValidForFeature = [=](ABI Abi) {82    switch (Abi) {83    default:84      return false;85    case ABI_ILP32S:86      return !Is64Bit;87    case ABI_ILP32F:88      return !Is64Bit && FeatureBits[LoongArch::FeatureBasicF];89    case ABI_ILP32D:90      return !Is64Bit && FeatureBits[LoongArch::FeatureBasicD];91    case ABI_LP64S:92      return Is64Bit;93    case ABI_LP64F:94      return Is64Bit && FeatureBits[LoongArch::FeatureBasicF];95    case ABI_LP64D:96      return Is64Bit && FeatureBits[LoongArch::FeatureBasicD];97    }98  };99 100  // 1. If the '-target-abi' is valid, use it.101  if (IsABIValidForFeature(ArgProvidedABI)) {102    if (IsABIValidForFeature(TripleABI) && ArgProvidedABI != TripleABI)103      errs()104          << "warning: triple-implied ABI conflicts with provided target-abi '"105          << ABIName << "', using target-abi\n";106    return checkABIStandardized(ArgProvidedABI);107  }108 109  // 2. If the triple-implied ABI is valid, use it.110  if (IsABIValidForFeature(TripleABI)) {111    // If target-abi is not specified, use the valid triple-implied ABI.112    if (ABIName.empty())113      return checkABIStandardized(TripleABI);114 115    switch (ArgProvidedABI) {116    case ABI_Unknown:117      // Fallback to the triple-implied ABI if ABI name is specified but118      // invalid.119      errs() << "warning: the '" << ABIName120             << "' is not a recognized ABI for this target, ignoring and "121                "using triple-implied ABI\n";122      return checkABIStandardized(TripleABI);123    case ABI_ILP32S:124    case ABI_ILP32F:125    case ABI_ILP32D:126      if (Is64Bit) {127        errs() << "warning: 32-bit ABIs are not supported for 64-bit targets, "128                  "ignoring and using triple-implied ABI\n";129        return checkABIStandardized(TripleABI);130      }131      break;132    case ABI_LP64S:133    case ABI_LP64F:134    case ABI_LP64D:135      if (!Is64Bit) {136        errs() << "warning: 64-bit ABIs are not supported for 32-bit targets, "137                  "ignoring and using triple-implied ABI\n";138        return checkABIStandardized(TripleABI);139      }140      break;141    }142 143    switch (ArgProvidedABI) {144    case ABI_ILP32F:145    case ABI_LP64F:146      errs() << "warning: the '" << ABIName147             << "' ABI can't be used for a target that doesn't support the 'F' "148                "instruction set, ignoring and using triple-implied ABI\n";149      break;150    case ABI_ILP32D:151    case ABI_LP64D:152      errs() << "warning: the '" << ABIName153             << "' ABI can't be used for a target that doesn't support the 'D' "154                "instruction set, ignoring and using triple-implied ABI\n";155      break;156    default:157      llvm_unreachable("");158    }159    return checkABIStandardized(TripleABI);160  }161 162  // 3. Parse the 'feature-abi', and use it.163  auto GetFeatureABI = [=]() {164    if (FeatureBits[LoongArch::FeatureBasicD])165      return Is64Bit ? ABI_LP64D : ABI_ILP32D;166    if (FeatureBits[LoongArch::FeatureBasicF])167      return Is64Bit ? ABI_LP64F : ABI_ILP32F;168    return Is64Bit ? ABI_LP64S : ABI_ILP32S;169  };170  if (!ABIName.empty())171    errs() << "warning: both target-abi and the triple-implied ABI are "172              "invalid, ignoring and using feature-implied ABI\n";173  return checkABIStandardized(GetFeatureABI());174}175 176ABI getTargetABI(StringRef ABIName) {177  auto TargetABI = StringSwitch<ABI>(ABIName)178                       .Case("ilp32s", ABI_ILP32S)179                       .Case("ilp32f", ABI_ILP32F)180                       .Case("ilp32d", ABI_ILP32D)181                       .Case("lp64s", ABI_LP64S)182                       .Case("lp64f", ABI_LP64F)183                       .Case("lp64d", ABI_LP64D)184                       .Default(ABI_Unknown);185  return TargetABI;186}187 188// To avoid the BP value clobbered by a function call, we need to choose a189// callee saved register to save the value. The `last` `S` register (s9) is190// used for FP. So we choose the previous (s8) as BP.191MCRegister getBPReg() { return LoongArch::R31; }192 193} // end namespace LoongArchABI194 195} // end namespace llvm196