1 //===-- ARMBaseInfo.h - Top level definitions for ARM ---*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains small standalone helper functions and enum definitions for
11 // the ARM target useful for the compiler back-end and the MC libraries.
12 // As such, it deliberately does not include references to LLVM core
13 // code gen types, passes, etc..
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #ifndef LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H
18 #define LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H
19 
20 #include "llvm/ADT/StringSwitch.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/MC/SubtargetFeature.h"
23 #include "MCTargetDesc/ARMMCTargetDesc.h"
24 
25 namespace llvm {
26 
27 // Enums corresponding to ARM condition codes
28 namespace ARMCC {
29 // The CondCodes constants map directly to the 4-bit encoding of the
30 // condition field for predicated instructions.
31 enum CondCodes { // Meaning (integer)          Meaning (floating-point)
32   EQ,            // Equal                      Equal
33   NE,            // Not equal                  Not equal, or unordered
34   HS,            // Carry set                  >, ==, or unordered
35   LO,            // Carry clear                Less than
36   MI,            // Minus, negative            Less than
37   PL,            // Plus, positive or zero     >, ==, or unordered
38   VS,            // Overflow                   Unordered
39   VC,            // No overflow                Not unordered
40   HI,            // Unsigned higher            Greater than, or unordered
41   LS,            // Unsigned lower or same     Less than or equal
42   GE,            // Greater than or equal      Greater than or equal
43   LT,            // Less than                  Less than, or unordered
44   GT,            // Greater than               Greater than
45   LE,            // Less than or equal         <, ==, or unordered
46   AL             // Always (unconditional)     Always (unconditional)
47 };
48 
getOppositeCondition(CondCodes CC)49 inline static CondCodes getOppositeCondition(CondCodes CC) {
50   switch (CC) {
51   default: llvm_unreachable("Unknown condition code");
52   case EQ: return NE;
53   case NE: return EQ;
54   case HS: return LO;
55   case LO: return HS;
56   case MI: return PL;
57   case PL: return MI;
58   case VS: return VC;
59   case VC: return VS;
60   case HI: return LS;
61   case LS: return HI;
62   case GE: return LT;
63   case LT: return GE;
64   case GT: return LE;
65   case LE: return GT;
66   }
67 }
68 } // end namespace ARMCC
69 
ARMCondCodeToString(ARMCC::CondCodes CC)70 inline static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {
71   switch (CC) {
72   case ARMCC::EQ:  return "eq";
73   case ARMCC::NE:  return "ne";
74   case ARMCC::HS:  return "hs";
75   case ARMCC::LO:  return "lo";
76   case ARMCC::MI:  return "mi";
77   case ARMCC::PL:  return "pl";
78   case ARMCC::VS:  return "vs";
79   case ARMCC::VC:  return "vc";
80   case ARMCC::HI:  return "hi";
81   case ARMCC::LS:  return "ls";
82   case ARMCC::GE:  return "ge";
83   case ARMCC::LT:  return "lt";
84   case ARMCC::GT:  return "gt";
85   case ARMCC::LE:  return "le";
86   case ARMCC::AL:  return "al";
87   }
88   llvm_unreachable("Unknown condition code");
89 }
90 
ARMCondCodeFromString(StringRef CC)91 inline static unsigned ARMCondCodeFromString(StringRef CC) {
92   return StringSwitch<unsigned>(CC.lower())
93     .Case("eq", ARMCC::EQ)
94     .Case("ne", ARMCC::NE)
95     .Case("hs", ARMCC::HS)
96     .Case("cs", ARMCC::HS)
97     .Case("lo", ARMCC::LO)
98     .Case("cc", ARMCC::LO)
99     .Case("mi", ARMCC::MI)
100     .Case("pl", ARMCC::PL)
101     .Case("vs", ARMCC::VS)
102     .Case("vc", ARMCC::VC)
103     .Case("hi", ARMCC::HI)
104     .Case("ls", ARMCC::LS)
105     .Case("ge", ARMCC::GE)
106     .Case("lt", ARMCC::LT)
107     .Case("gt", ARMCC::GT)
108     .Case("le", ARMCC::LE)
109     .Case("al", ARMCC::AL)
110     .Default(~0U);
111 }
112 
113 // System Registers
114 namespace ARMSysReg {
115   struct MClassSysReg {
116     const char *Name;
117     uint16_t M1Encoding12;
118     uint16_t M2M3Encoding8;
119     uint16_t Encoding;
120     FeatureBitset FeaturesRequired;
121 
122     // return true if FeaturesRequired are all present in ActiveFeatures
hasRequiredFeaturesMClassSysReg123     bool hasRequiredFeatures(FeatureBitset ActiveFeatures) const {
124       return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
125     }
126 
127     // returns true if TestFeatures are all present in FeaturesRequired
isInRequiredFeaturesMClassSysReg128     bool isInRequiredFeatures(FeatureBitset TestFeatures) const {
129       return (FeaturesRequired & TestFeatures) == TestFeatures;
130     }
131   };
132 
133   #define GET_MCLASSSYSREG_DECL
134   #include "ARMGenSystemRegister.inc"
135 
136   // lookup system register using 12-bit SYSm value.
137   // Note: the search is uniqued using M1 mask
138   const MClassSysReg *lookupMClassSysRegBy12bitSYSmValue(unsigned SYSm);
139 
140   // returns APSR with _<bits> qualifier.
141   // Note: ARMv7-M deprecates using MSR APSR without a _<bits> qualifier
142   const MClassSysReg *lookupMClassSysRegAPSRNonDeprecated(unsigned SYSm);
143 
144   // lookup system registers using 8-bit SYSm value
145   const MClassSysReg *lookupMClassSysRegBy8bitSYSmValue(unsigned SYSm);
146 
147 } // end namespace ARMSysReg
148 
149 // Banked Registers
150 namespace ARMBankedReg {
151   struct BankedReg {
152     const char *Name;
153     uint16_t Encoding;
154   };
155   #define GET_BANKEDREG_DECL
156   #include "ARMGenSystemRegister.inc"
157 } // end namespace ARMBankedReg
158 
159 } // end namespace llvm
160 
161 #endif // LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H
162