LLVM 22.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_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:
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()) {
56 TripleABI = ABI_Unknown;
57 break;
60 TripleABI = Is64Bit ? ABI_LP64S : ABI_ILP32S;
61 break;
64 TripleABI = Is64Bit ? ABI_LP64F : ABI_ILP32F;
65 break;
66 // Let the fallback case behave like {ILP32,LP64}D.
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 but
118 // invalid.
119 errs() << "warning: the '" << ABIName
120 << "' 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 '" << ABIName
147 << "' 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 '" << ABIName
153 << "' 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:
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
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)
185 return TargetABI;
186}
187
188// To avoid the BP value clobbered by a function call, we need to choose a
189// callee saved register to save the value. The `last` `S` register (s9) is
190// used for FP. So we choose the previous (s8) as BP.
191MCRegister getBPReg() { return LoongArch::R31; }
192
193} // end namespace LoongArchABI
194
195} // end namespace llvm
Container class for subtarget features.
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
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:151
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:43
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:68
R Default(T Value)
Definition: StringSwitch.h:177
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:47
@ UnknownEnvironment
Definition: Triple.h:251
#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: AddressRanges.h:18
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.