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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements helper functions for the LoongArch target useful for the 10 // compiler back-end and the MC libraries. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "LoongArchBaseInfo.h" 15 #include "llvm/ADT/ArrayRef.h" 16 #include "llvm/MC/MCSubtargetInfo.h" 17 #include "llvm/Support/raw_ostream.h" 18 #include "llvm/TargetParser/Triple.h" 19 20 namespace llvm { 21 22 namespace LoongArchABI { 23 24 ABI computeTargetABI(const Triple &TT, StringRef ABIName) { 25 ABI ArgProvidedABI = getTargetABI(ABIName); 26 bool Is64Bit = TT.isArch64Bit(); 27 ABI TripleABI; 28 29 // Figure out the ABI explicitly requested via the triple's environment type. 30 switch (TT.getEnvironment()) { 31 case llvm::Triple::EnvironmentType::GNUSF: 32 TripleABI = Is64Bit ? LoongArchABI::ABI_LP64S : LoongArchABI::ABI_ILP32S; 33 break; 34 case llvm::Triple::EnvironmentType::GNUF32: 35 TripleABI = Is64Bit ? LoongArchABI::ABI_LP64F : LoongArchABI::ABI_ILP32F; 36 break; 37 38 // Let the fallback case behave like {ILP32,LP64}D. 39 case llvm::Triple::EnvironmentType::GNUF64: 40 default: 41 TripleABI = Is64Bit ? LoongArchABI::ABI_LP64D : LoongArchABI::ABI_ILP32D; 42 break; 43 } 44 45 switch (ArgProvidedABI) { 46 case LoongArchABI::ABI_Unknown: 47 // Fallback to the triple-implied ABI if ABI name is not specified or 48 // invalid. 49 if (!ABIName.empty()) 50 errs() << "'" << ABIName 51 << "' is not a recognized ABI for this target, ignoring and using " 52 "triple-implied ABI\n"; 53 return TripleABI; 54 55 case LoongArchABI::ABI_ILP32S: 56 case LoongArchABI::ABI_ILP32F: 57 case LoongArchABI::ABI_ILP32D: 58 if (Is64Bit) { 59 errs() << "32-bit ABIs are not supported for 64-bit targets, ignoring " 60 "target-abi and using triple-implied ABI\n"; 61 return TripleABI; 62 } 63 break; 64 65 case LoongArchABI::ABI_LP64S: 66 case LoongArchABI::ABI_LP64F: 67 case LoongArchABI::ABI_LP64D: 68 if (!Is64Bit) { 69 errs() << "64-bit ABIs are not supported for 32-bit targets, ignoring " 70 "target-abi and using triple-implied ABI\n"; 71 return TripleABI; 72 } 73 break; 74 } 75 76 if (!ABIName.empty() && TT.hasEnvironment() && ArgProvidedABI != TripleABI) 77 errs() << "warning: triple-implied ABI conflicts with provided target-abi '" 78 << ABIName << "', using target-abi\n"; 79 80 return ArgProvidedABI; 81 } 82 83 ABI getTargetABI(StringRef ABIName) { 84 auto TargetABI = StringSwitch<ABI>(ABIName) 85 .Case("ilp32s", ABI_ILP32S) 86 .Case("ilp32f", ABI_ILP32F) 87 .Case("ilp32d", ABI_ILP32D) 88 .Case("lp64s", ABI_LP64S) 89 .Case("lp64f", ABI_LP64F) 90 .Case("lp64d", ABI_LP64D) 91 .Default(ABI_Unknown); 92 return TargetABI; 93 } 94 95 // To avoid the BP value clobbered by a function call, we need to choose a 96 // callee saved register to save the value. The `last` `S` register (s9) is 97 // used for FP. So we choose the previous (s8) as BP. 98 MCRegister getBPReg() { return LoongArch::R31; } 99 100 } // end namespace LoongArchABI 101 102 } // end namespace llvm 103