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/TargetParser/SubtargetFeature.h"
22#include "MCTargetDesc/ARMMCTargetDesc.h"
23
24namespace llvm {
25
26// Enums corresponding to ARM condition codes
27namespace ARMCC {
28// The CondCodes constants map directly to the 4-bit encoding of the
29// condition field for predicated instructions.
30enum 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
48inline 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).
71inline 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
88namespace ARMVCC {
89  enum VPTCodes {
90    None = 0,
91    Then,
92    Else
93  };
94} // namespace ARMVCC
95
96namespace 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.
127ARM::PredBlockMask expandPredBlockMask(ARM::PredBlockMask BlockMask,
128                                       ARMVCC::VPTCodes Kind);
129
130inline 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
139inline 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
146inline 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
167inline 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
190namespace 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
199    bool hasRequiredFeatures(FeatureBitset ActiveFeatures) const {
200      return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
201    }
202
203    // returns true if TestFeatures are all present in FeaturesRequired
204    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
226namespace 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