LLVM 19.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"
16#include "llvm/ADT/ArrayRef.h"
21
22namespace llvm {
23
24namespace LoongArchABI {
25
26// Check if ABI has been standardized; issue a warning if it hasn't.
27// FIXME: Once all ABIs are standardized, this will be removed.
29 StringRef ABIName;
30 switch (Abi) {
31 case ABI_ILP32S:
32 ABIName = "ilp32s";
33 break;
34 case ABI_ILP32F:
35 ABIName = "ilp32f";
36 break;
37 case ABI_ILP32D:
38 ABIName = "ilp32d";
39 break;
40 case ABI_LP64F:
41 ABIName = "lp64f";
42 break;
43 case ABI_LP64S:
44 case ABI_LP64D:
45 return Abi;
46 default:
48 }
49 errs() << "warning: '" << ABIName << "' has not been standardized\n";
50 return Abi;
51}
52
53static ABI getTripleABI(const Triple &TT) {
54 bool Is64Bit = TT.isArch64Bit();
55 ABI TripleABI;
56 switch (TT.getEnvironment()) {
58 TripleABI = Is64Bit ? ABI_LP64S : ABI_ILP32S;
59 break;
61 TripleABI = Is64Bit ? ABI_LP64F : ABI_ILP32F;
62 break;
63 // Let the fallback case behave like {ILP32,LP64}D.
65 default:
66 TripleABI = Is64Bit ? ABI_LP64D : ABI_ILP32D;
67 break;
68 }
69 return TripleABI;
70}
71
72ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits,
73 StringRef ABIName) {
74 bool Is64Bit = TT.isArch64Bit();
75 ABI ArgProvidedABI = getTargetABI(ABIName);
76 ABI TripleABI = getTripleABI(TT);
77
78 auto IsABIValidForFeature = [=](ABI Abi) {
79 switch (Abi) {
80 default:
81 return false;
82 case ABI_ILP32S:
83 return !Is64Bit;
84 case ABI_ILP32F:
85 return !Is64Bit && FeatureBits[LoongArch::FeatureBasicF];
86 case ABI_ILP32D:
87 return !Is64Bit && FeatureBits[LoongArch::FeatureBasicD];
88 case ABI_LP64S:
89 return Is64Bit;
90 case ABI_LP64F:
91 return Is64Bit && FeatureBits[LoongArch::FeatureBasicF];
92 case ABI_LP64D:
93 return Is64Bit && FeatureBits[LoongArch::FeatureBasicD];
94 }
95 };
96
97 // 1. If the '-target-abi' is valid, use it.
98 if (IsABIValidForFeature(ArgProvidedABI)) {
99 if (TT.hasEnvironment() && ArgProvidedABI != TripleABI)
100 errs()
101 << "warning: triple-implied ABI conflicts with provided target-abi '"
102 << ABIName << "', using target-abi\n";
103 return checkABIStandardized(ArgProvidedABI);
104 }
105
106 // 2. If the triple-implied ABI is valid, use it.
107 if (IsABIValidForFeature(TripleABI)) {
108 // If target-abi is not specified, use the valid triple-implied ABI.
109 if (ABIName.empty())
110 return checkABIStandardized(TripleABI);
111
112 switch (ArgProvidedABI) {
113 case ABI_Unknown:
114 // Fallback to the triple-implied ABI if ABI name is specified but
115 // invalid.
116 errs() << "warning: the '" << ABIName
117 << "' is not a recognized ABI for this target, ignoring and "
118 "using triple-implied ABI\n";
119 return checkABIStandardized(TripleABI);
120 case ABI_ILP32S:
121 case ABI_ILP32F:
122 case ABI_ILP32D:
123 if (Is64Bit) {
124 errs() << "warning: 32-bit ABIs are not supported for 64-bit targets, "
125 "ignoring and using triple-implied ABI\n";
126 return checkABIStandardized(TripleABI);
127 }
128 break;
129 case ABI_LP64S:
130 case ABI_LP64F:
131 case ABI_LP64D:
132 if (!Is64Bit) {
133 errs() << "warning: 64-bit ABIs are not supported for 32-bit targets, "
134 "ignoring and using triple-implied ABI\n";
135 return checkABIStandardized(TripleABI);
136 }
137 break;
138 }
139
140 switch (ArgProvidedABI) {
141 case ABI_ILP32F:
142 case ABI_LP64F:
143 errs() << "warning: the '" << ABIName
144 << "' ABI can't be used for a target that doesn't support the 'F' "
145 "instruction set, ignoring and using triple-implied ABI\n";
146 break;
147 case ABI_ILP32D:
148 case ABI_LP64D:
149 errs() << "warning: the '" << ABIName
150 << "' ABI can't be used for a target that doesn't support the 'D' "
151 "instruction set, ignoring and using triple-implied ABI\n";
152 break;
153 default:
155 }
156 return checkABIStandardized(TripleABI);
157 }
158
159 // 3. Parse the 'feature-abi', and use it.
160 auto GetFeatureABI = [=]() {
161 if (FeatureBits[LoongArch::FeatureBasicD])
162 return Is64Bit ? ABI_LP64D : ABI_ILP32D;
163 if (FeatureBits[LoongArch::FeatureBasicF])
164 return Is64Bit ? ABI_LP64F : ABI_ILP32F;
165 return Is64Bit ? ABI_LP64S : ABI_ILP32S;
166 };
167 if (ABIName.empty())
168 errs() << "warning: the triple-implied ABI is invalid, ignoring and using "
169 "feature-implied ABI\n";
170 else
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:50
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
#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
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.