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 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 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). 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 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 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 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 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 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 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