LLVM 23.0.0git
LoongArchBaseInfo.cpp
Go to the documentation of this file.
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"
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.
27 StringRef ABIName;
28 switch (Abi) {
29 case ABI_ILP32F:
30 ABIName = "ilp32f";
31 break;
32 case ABI_LP64F:
33 ABIName = "lp64f";
34 break;
35 case ABI_ILP32S:
36 case ABI_ILP32D:
37 case ABI_LP64S:
38 case ABI_LP64D:
39 return Abi;
40 default:
42 }
43 errs() << "warning: '" << ABIName << "' has not been standardized\n";
44 return Abi;
45}
46
47static ABI getTripleABI(const Triple &TT) {
48 bool Is64Bit = TT.isArch64Bit();
49 ABI TripleABI;
50 switch (TT.getEnvironment()) {
52 TripleABI = ABI_Unknown;
53 break;
56 TripleABI = Is64Bit ? ABI_LP64S : ABI_ILP32S;
57 break;
60 TripleABI = Is64Bit ? ABI_LP64F : ABI_ILP32F;
61 break;
62 // Let the fallback case behave like {ILP32,LP64}D.
64 default:
65 TripleABI = Is64Bit ? ABI_LP64D : ABI_ILP32D;
66 break;
67 }
68 return TripleABI;
69}
70
71ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits,
72 StringRef ABIName) {
73 bool Is64Bit = TT.isArch64Bit();
74 ABI ArgProvidedABI = getTargetABI(ABIName);
75 ABI TripleABI = getTripleABI(TT);
76
77 auto IsABIValidForFeature = [=](ABI Abi) {
78 switch (Abi) {
79 default:
80 return false;
81 case ABI_ILP32S:
82 return !Is64Bit;
83 case ABI_ILP32F:
84 return !Is64Bit && FeatureBits[LoongArch::FeatureBasicF];
85 case ABI_ILP32D:
86 return !Is64Bit && FeatureBits[LoongArch::FeatureBasicD];
87 case ABI_LP64S:
88 return Is64Bit;
89 case ABI_LP64F:
90 return Is64Bit && FeatureBits[LoongArch::FeatureBasicF];
91 case ABI_LP64D:
92 return Is64Bit && FeatureBits[LoongArch::FeatureBasicD];
93 }
94 };
95
96 // 1. If the '-target-abi' is valid, use it.
97 if (IsABIValidForFeature(ArgProvidedABI)) {
98 if (IsABIValidForFeature(TripleABI) && ArgProvidedABI != TripleABI)
99 errs()
100 << "warning: triple-implied ABI conflicts with provided target-abi '"
101 << ABIName << "', using target-abi\n";
102 return checkABIStandardized(ArgProvidedABI);
103 }
104
105 // 2. If the triple-implied ABI is valid, use it.
106 if (IsABIValidForFeature(TripleABI)) {
107 // If target-abi is not specified, use the valid triple-implied ABI.
108 if (ABIName.empty())
109 return checkABIStandardized(TripleABI);
110
111 switch (ArgProvidedABI) {
112 case ABI_Unknown:
113 // Fallback to the triple-implied ABI if ABI name is specified but
114 // invalid.
115 errs() << "warning: the '" << ABIName
116 << "' is not a recognized ABI for this target, ignoring and "
117 "using triple-implied ABI\n";
118 return checkABIStandardized(TripleABI);
119 case ABI_ILP32S:
120 case ABI_ILP32F:
121 case ABI_ILP32D:
122 if (Is64Bit) {
123 errs() << "warning: 32-bit ABIs are not supported for 64-bit targets, "
124 "ignoring and using triple-implied ABI\n";
125 return checkABIStandardized(TripleABI);
126 }
127 break;
128 case ABI_LP64S:
129 case ABI_LP64F:
130 case ABI_LP64D:
131 if (!Is64Bit) {
132 errs() << "warning: 64-bit ABIs are not supported for 32-bit targets, "
133 "ignoring and using triple-implied ABI\n";
134 return checkABIStandardized(TripleABI);
135 }
136 break;
137 }
138
139 switch (ArgProvidedABI) {
140 case ABI_ILP32F:
141 case ABI_LP64F:
142 errs() << "warning: the '" << ABIName
143 << "' ABI can't be used for a target that doesn't support the 'F' "
144 "instruction set, ignoring and using triple-implied ABI\n";
145 break;
146 case ABI_ILP32D:
147 case ABI_LP64D:
148 errs() << "warning: the '" << ABIName
149 << "' ABI can't be used for a target that doesn't support the 'D' "
150 "instruction set, ignoring and using triple-implied ABI\n";
151 break;
152 default:
154 }
155 return checkABIStandardized(TripleABI);
156 }
157
158 // 3. Parse the 'feature-abi', and use it.
159 auto GetFeatureABI = [=]() {
160 if (FeatureBits[LoongArch::FeatureBasicD])
161 return Is64Bit ? ABI_LP64D : ABI_ILP32D;
162 if (FeatureBits[LoongArch::FeatureBasicF])
163 return Is64Bit ? ABI_LP64F : ABI_ILP32F;
164 return Is64Bit ? ABI_LP64S : ABI_ILP32S;
165 };
166 if (!ABIName.empty())
167 errs() << "warning: both target-abi and the triple-implied ABI are "
168 "invalid, ignoring and using feature-implied ABI\n";
169 return checkABIStandardized(GetFeatureABI());
170}
171
173 auto TargetABI = StringSwitch<ABI>(ABIName)
174 .Case("ilp32s", ABI_ILP32S)
175 .Case("ilp32f", ABI_ILP32F)
176 .Case("ilp32d", ABI_ILP32D)
177 .Case("lp64s", ABI_LP64S)
178 .Case("lp64f", ABI_LP64F)
179 .Case("lp64d", ABI_LP64D)
181 return TargetABI;
182}
183
184// To avoid the BP value clobbered by a function call, we need to choose a
185// callee saved register to save the value. The `last` `S` register (s9) is
186// used for FP. So we choose the previous (s8) as BP.
187MCRegister getBPReg() { return LoongArch::R31; }
188
189} // end namespace LoongArchABI
190
191} // end namespace llvm
Container class for subtarget features.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:143
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:47
@ UnknownEnvironment
Definition Triple.h:259
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static ABI checkABIStandardized(ABI Abi)
static ABI getTripleABI(const Triple &TT)
ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits, StringRef ABIName)
ABI getTargetABI(StringRef ABIName)
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.