1 //===-- ARMBaseInfo.h - Top level definitions for ARM ---*- 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 contains small standalone helper functions and enum definitions for
10 // the ARM target useful for the compiler back-end and the MC libraries.
11 // As such, it deliberately does not include references to LLVM core
12 // code gen types, passes, etc..
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H
17 #define LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H
18
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/MC/SubtargetFeature.h"
22 #include "MCTargetDesc/ARMMCTargetDesc.h"
23
24 namespace llvm {
25
26 // Enums corresponding to ARM condition codes
27 namespace ARMCC {
28 // The CondCodes constants map directly to the 4-bit encoding of the
29 // condition field for predicated instructions.
30 enum CondCodes { // Meaning (integer) Meaning (floating-point)
31 EQ, // Equal Equal
32 NE, // Not equal Not equal, or unordered
33 HS, // Carry set >, ==, or unordered
34 LO, // Carry clear Less than
35 MI, // Minus, negative Less than
36 PL, // Plus, positive or zero >, ==, or unordered
37 VS, // Overflow Unordered
38 VC, // No overflow Not unordered
39 HI, // Unsigned higher Greater than, or unordered
40 LS, // Unsigned lower or same Less than or equal
41 GE, // Greater than or equal Greater than or equal
42 LT, // Less than Less than, or unordered
43 GT, // Greater than Greater than
44 LE, // Less than or equal <, ==, or unordered
45 AL // Always (unconditional) Always (unconditional)
46 };
47
getOppositeCondition(CondCodes CC)48 inline static CondCodes getOppositeCondition(CondCodes CC) {
49 switch (CC) {
50 default: llvm_unreachable("Unknown condition code");
51 case EQ: return NE;
52 case NE: return EQ;
53 case HS: return LO;
54 case LO: return HS;
55 case MI: return PL;
56 case PL: return MI;
57 case VS: return VC;
58 case VC: return VS;
59 case HI: return LS;
60 case LS: return HI;
61 case GE: return LT;
62 case LT: return GE;
63 case GT: return LE;
64 case LE: return GT;
65 }
66 }
67
68 /// getSwappedCondition - assume the flags are set by MI(a,b), return
69 /// the condition code if we modify the instructions such that flags are
70 /// set by MI(b,a).
getSwappedCondition(ARMCC::CondCodes CC)71 inline static ARMCC::CondCodes getSwappedCondition(ARMCC::CondCodes CC) {
72 switch (CC) {
73 default: return ARMCC::AL;
74 case ARMCC::EQ: return ARMCC::EQ;
75 case ARMCC::NE: return ARMCC::NE;
76 case ARMCC::HS: return ARMCC::LS;
77 case ARMCC::LO: return ARMCC::HI;
78 case ARMCC::HI: return ARMCC::LO;
79 case ARMCC::LS: return ARMCC::HS;
80 case ARMCC::GE: return ARMCC::LE;
81 case ARMCC::LT: return ARMCC::GT;
82 case ARMCC::GT: return ARMCC::LT;
83 case ARMCC::LE: return ARMCC::GE;
84 }
85 }
86 } // end namespace ARMCC
87
88 namespace ARMVCC {
89 enum VPTCodes {
90 None = 0,
91 Then,
92 Else
93 };
94 } // namespace ARMVCC
95
96 namespace ARM {
97 /// Mask values for IT and VPT Blocks, to be used by MCOperands.
98 /// Note that this is different from the "real" encoding used by the
99 /// instructions. In this encoding, the lowest set bit indicates the end of
100 /// the encoding, and above that, "1" indicates an else, while "0" indicates
101 /// a then.
102 /// Tx = x100
103 /// Txy = xy10
104 /// Txyz = xyz1
105 enum class PredBlockMask {
106 T = 0b1000,
107 TT = 0b0100,
108 TE = 0b1100,
109 TTT = 0b0010,
110 TTE = 0b0110,
111 TEE = 0b1110,
112 TET = 0b1010,
113 TTTT = 0b0001,
114 TTTE = 0b0011,
115 TTEE = 0b0111,
116 TTET = 0b0101,
117 TEEE = 0b1111,
118 TEET = 0b1101,
119 TETT = 0b1001,
120 TETE = 0b1011
121 };
122 } // namespace ARM
123
124 // Expands a PredBlockMask by adding an E or a T at the end, depending on Kind.
125 // e.g ExpandPredBlockMask(T, Then) = TT, ExpandPredBlockMask(TT, Else) = TTE,
126 // and so on.
127 ARM::PredBlockMask expandPredBlockMask(ARM::PredBlockMask BlockMask,
128 ARMVCC::VPTCodes Kind);
129
ARMVPTPredToString(ARMVCC::VPTCodes CC)130 inline static const char *ARMVPTPredToString(ARMVCC::VPTCodes CC) {
131 switch (CC) {
132 case ARMVCC::None: return "none";
133 case ARMVCC::Then: return "t";
134 case ARMVCC::Else: return "e";
135 }
136 llvm_unreachable("Unknown VPT code");
137 }
138
ARMVectorCondCodeFromString(StringRef CC)139 inline static unsigned ARMVectorCondCodeFromString(StringRef CC) {
140 return StringSwitch<unsigned>(CC.lower())
141 .Case("t", ARMVCC::Then)
142 .Case("e", ARMVCC::Else)
143 .Default(~0U);
144 }
145
ARMCondCodeToString(ARMCC::CondCodes CC)146 inline static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {
147 switch (CC) {
148 case ARMCC::EQ: return "eq";
149 case ARMCC::NE: return "ne";
150 case ARMCC::HS: return "hs";
151 case ARMCC::LO: return "lo";
152 case ARMCC::MI: return "mi";
153 case ARMCC::PL: return "pl";
154 case ARMCC::VS: return "vs";
155 case ARMCC::VC: return "vc";
156 case ARMCC::HI: return "hi";
157 case ARMCC::LS: return "ls";
158 case ARMCC::GE: return "ge";
159 case ARMCC::LT: return "lt";
160 case ARMCC::GT: return "gt";
161 case ARMCC::LE: return "le";
162 case ARMCC::AL: return "al";
163 }
164 llvm_unreachable("Unknown condition code");
165 }
166
ARMCondCodeFromString(StringRef CC)167 inline static unsigned ARMCondCodeFromString(StringRef CC) {
168 return StringSwitch<unsigned>(CC.lower())
169 .Case("eq", ARMCC::EQ)
170 .Case("ne", ARMCC::NE)
171 .Case("hs", ARMCC::HS)
172 .Case("cs", ARMCC::HS)
173 .Case("lo", ARMCC::LO)
174 .Case("cc", ARMCC::LO)
175 .Case("mi", ARMCC::MI)
176 .Case("pl", ARMCC::PL)
177 .Case("vs", ARMCC::VS)
178 .Case("vc", ARMCC::VC)
179 .Case("hi", ARMCC::HI)
180 .Case("ls", ARMCC::LS)
181 .Case("ge", ARMCC::GE)
182 .Case("lt", ARMCC::LT)
183 .Case("gt", ARMCC::GT)
184 .Case("le", ARMCC::LE)
185 .Case("al", ARMCC::AL)
186 .Default(~0U);
187 }
188
189 // System Registers
190 namespace ARMSysReg {
191 struct MClassSysReg {
192 const char *Name;
193 uint16_t M1Encoding12;
194 uint16_t M2M3Encoding8;
195 uint16_t Encoding;
196 FeatureBitset FeaturesRequired;
197
198 // return true if FeaturesRequired are all present in ActiveFeatures
hasRequiredFeaturesMClassSysReg199 bool hasRequiredFeatures(FeatureBitset ActiveFeatures) const {
200 return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
201 }
202
203 // returns true if TestFeatures are all present in FeaturesRequired
isInRequiredFeaturesMClassSysReg204 bool isInRequiredFeatures(FeatureBitset TestFeatures) const {
205 return (FeaturesRequired & TestFeatures) == TestFeatures;
206 }
207 };
208
209 #define GET_MCLASSSYSREG_DECL
210 #include "ARMGenSystemRegister.inc"
211
212 // lookup system register using 12-bit SYSm value.
213 // Note: the search is uniqued using M1 mask
214 const MClassSysReg *lookupMClassSysRegBy12bitSYSmValue(unsigned SYSm);
215
216 // returns APSR with _<bits> qualifier.
217 // Note: ARMv7-M deprecates using MSR APSR without a _<bits> qualifier
218 const MClassSysReg *lookupMClassSysRegAPSRNonDeprecated(unsigned SYSm);
219
220 // lookup system registers using 8-bit SYSm value
221 const MClassSysReg *lookupMClassSysRegBy8bitSYSmValue(unsigned SYSm);
222
223 } // end namespace ARMSysReg
224
225 // Banked Registers
226 namespace ARMBankedReg {
227 struct BankedReg {
228 const char *Name;
229 uint16_t Encoding;
230 };
231 #define GET_BANKEDREG_DECL
232 #include "ARMGenSystemRegister.inc"
233 } // end namespace ARMBankedReg
234
235 } // end namespace llvm
236
237 #endif // LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H
238