Path: blob/main/contrib/llvm-project/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchBaseInfo.cpp
35294 views
//= LoongArchBaseInfo.cpp - Top level definitions for LoongArch MC -*- C++ -*-//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements helper functions for the LoongArch target useful for the9// compiler back-end and the MC libraries.10//11//===----------------------------------------------------------------------===//1213#include "LoongArchBaseInfo.h"14#include "LoongArchMCTargetDesc.h"15#include "llvm/ADT/ArrayRef.h"16#include "llvm/MC/MCSubtargetInfo.h"17#include "llvm/Support/ErrorHandling.h"18#include "llvm/Support/raw_ostream.h"19#include "llvm/TargetParser/Triple.h"2021namespace llvm {2223namespace LoongArchABI {2425// Check if ABI has been standardized; issue a warning if it hasn't.26// FIXME: Once all ABIs are standardized, this will be removed.27static ABI checkABIStandardized(ABI Abi) {28StringRef ABIName;29switch (Abi) {30case ABI_ILP32S:31ABIName = "ilp32s";32break;33case ABI_ILP32F:34ABIName = "ilp32f";35break;36case ABI_ILP32D:37ABIName = "ilp32d";38break;39case ABI_LP64F:40ABIName = "lp64f";41break;42case ABI_LP64S:43case ABI_LP64D:44return Abi;45default:46llvm_unreachable("");47}48errs() << "warning: '" << ABIName << "' has not been standardized\n";49return Abi;50}5152static ABI getTripleABI(const Triple &TT) {53bool Is64Bit = TT.isArch64Bit();54ABI TripleABI;55switch (TT.getEnvironment()) {56case llvm::Triple::EnvironmentType::GNUSF:57TripleABI = Is64Bit ? ABI_LP64S : ABI_ILP32S;58break;59case llvm::Triple::EnvironmentType::GNUF32:60TripleABI = Is64Bit ? ABI_LP64F : ABI_ILP32F;61break;62// Let the fallback case behave like {ILP32,LP64}D.63case llvm::Triple::EnvironmentType::GNUF64:64default:65TripleABI = Is64Bit ? ABI_LP64D : ABI_ILP32D;66break;67}68return TripleABI;69}7071ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits,72StringRef ABIName) {73bool Is64Bit = TT.isArch64Bit();74ABI ArgProvidedABI = getTargetABI(ABIName);75ABI TripleABI = getTripleABI(TT);7677auto IsABIValidForFeature = [=](ABI Abi) {78switch (Abi) {79default:80return false;81case ABI_ILP32S:82return !Is64Bit;83case ABI_ILP32F:84return !Is64Bit && FeatureBits[LoongArch::FeatureBasicF];85case ABI_ILP32D:86return !Is64Bit && FeatureBits[LoongArch::FeatureBasicD];87case ABI_LP64S:88return Is64Bit;89case ABI_LP64F:90return Is64Bit && FeatureBits[LoongArch::FeatureBasicF];91case ABI_LP64D:92return Is64Bit && FeatureBits[LoongArch::FeatureBasicD];93}94};9596// 1. If the '-target-abi' is valid, use it.97if (IsABIValidForFeature(ArgProvidedABI)) {98if (TT.hasEnvironment() && ArgProvidedABI != TripleABI)99errs()100<< "warning: triple-implied ABI conflicts with provided target-abi '"101<< ABIName << "', using target-abi\n";102return checkABIStandardized(ArgProvidedABI);103}104105// 2. If the triple-implied ABI is valid, use it.106if (IsABIValidForFeature(TripleABI)) {107// If target-abi is not specified, use the valid triple-implied ABI.108if (ABIName.empty())109return checkABIStandardized(TripleABI);110111switch (ArgProvidedABI) {112case ABI_Unknown:113// Fallback to the triple-implied ABI if ABI name is specified but114// invalid.115errs() << "warning: the '" << ABIName116<< "' is not a recognized ABI for this target, ignoring and "117"using triple-implied ABI\n";118return checkABIStandardized(TripleABI);119case ABI_ILP32S:120case ABI_ILP32F:121case ABI_ILP32D:122if (Is64Bit) {123errs() << "warning: 32-bit ABIs are not supported for 64-bit targets, "124"ignoring and using triple-implied ABI\n";125return checkABIStandardized(TripleABI);126}127break;128case ABI_LP64S:129case ABI_LP64F:130case ABI_LP64D:131if (!Is64Bit) {132errs() << "warning: 64-bit ABIs are not supported for 32-bit targets, "133"ignoring and using triple-implied ABI\n";134return checkABIStandardized(TripleABI);135}136break;137}138139switch (ArgProvidedABI) {140case ABI_ILP32F:141case ABI_LP64F:142errs() << "warning: the '" << ABIName143<< "' ABI can't be used for a target that doesn't support the 'F' "144"instruction set, ignoring and using triple-implied ABI\n";145break;146case ABI_ILP32D:147case ABI_LP64D:148errs() << "warning: the '" << ABIName149<< "' ABI can't be used for a target that doesn't support the 'D' "150"instruction set, ignoring and using triple-implied ABI\n";151break;152default:153llvm_unreachable("");154}155return checkABIStandardized(TripleABI);156}157158// 3. Parse the 'feature-abi', and use it.159auto GetFeatureABI = [=]() {160if (FeatureBits[LoongArch::FeatureBasicD])161return Is64Bit ? ABI_LP64D : ABI_ILP32D;162if (FeatureBits[LoongArch::FeatureBasicF])163return Is64Bit ? ABI_LP64F : ABI_ILP32F;164return Is64Bit ? ABI_LP64S : ABI_ILP32S;165};166if (ABIName.empty())167errs() << "warning: the triple-implied ABI is invalid, ignoring and using "168"feature-implied ABI\n";169else170errs() << "warning: both target-abi and the triple-implied ABI are "171"invalid, ignoring and using feature-implied ABI\n";172return checkABIStandardized(GetFeatureABI());173}174175ABI getTargetABI(StringRef ABIName) {176auto TargetABI = StringSwitch<ABI>(ABIName)177.Case("ilp32s", ABI_ILP32S)178.Case("ilp32f", ABI_ILP32F)179.Case("ilp32d", ABI_ILP32D)180.Case("lp64s", ABI_LP64S)181.Case("lp64f", ABI_LP64F)182.Case("lp64d", ABI_LP64D)183.Default(ABI_Unknown);184return TargetABI;185}186187// To avoid the BP value clobbered by a function call, we need to choose a188// callee saved register to save the value. The `last` `S` register (s9) is189// used for FP. So we choose the previous (s8) as BP.190MCRegister getBPReg() { return LoongArch::R31; }191192} // end namespace LoongArchABI193194} // end namespace llvm195196197