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 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 } // end namespace ARMCC 68 69 namespace ARMVCC { 70 enum VPTCodes { 71 None = 0, 72 Then, 73 Else 74 }; 75 } 76 77 inline static const char *ARMVPTPredToString(ARMVCC::VPTCodes CC) { 78 switch (CC) { 79 case ARMVCC::None: return "none"; 80 case ARMVCC::Then: return "t"; 81 case ARMVCC::Else: return "e"; 82 } 83 llvm_unreachable("Unknown VPT code"); 84 } 85 86 inline static unsigned ARMVectorCondCodeFromString(StringRef CC) { 87 return StringSwitch<unsigned>(CC.lower()) 88 .Case("t", ARMVCC::Then) 89 .Case("e", ARMVCC::Else) 90 .Default(~0U); 91 } 92 93 inline static const char *ARMCondCodeToString(ARMCC::CondCodes CC) { 94 switch (CC) { 95 case ARMCC::EQ: return "eq"; 96 case ARMCC::NE: return "ne"; 97 case ARMCC::HS: return "hs"; 98 case ARMCC::LO: return "lo"; 99 case ARMCC::MI: return "mi"; 100 case ARMCC::PL: return "pl"; 101 case ARMCC::VS: return "vs"; 102 case ARMCC::VC: return "vc"; 103 case ARMCC::HI: return "hi"; 104 case ARMCC::LS: return "ls"; 105 case ARMCC::GE: return "ge"; 106 case ARMCC::LT: return "lt"; 107 case ARMCC::GT: return "gt"; 108 case ARMCC::LE: return "le"; 109 case ARMCC::AL: return "al"; 110 } 111 llvm_unreachable("Unknown condition code"); 112 } 113 114 inline static unsigned ARMCondCodeFromString(StringRef CC) { 115 return StringSwitch<unsigned>(CC.lower()) 116 .Case("eq", ARMCC::EQ) 117 .Case("ne", ARMCC::NE) 118 .Case("hs", ARMCC::HS) 119 .Case("cs", ARMCC::HS) 120 .Case("lo", ARMCC::LO) 121 .Case("cc", ARMCC::LO) 122 .Case("mi", ARMCC::MI) 123 .Case("pl", ARMCC::PL) 124 .Case("vs", ARMCC::VS) 125 .Case("vc", ARMCC::VC) 126 .Case("hi", ARMCC::HI) 127 .Case("ls", ARMCC::LS) 128 .Case("ge", ARMCC::GE) 129 .Case("lt", ARMCC::LT) 130 .Case("gt", ARMCC::GT) 131 .Case("le", ARMCC::LE) 132 .Case("al", ARMCC::AL) 133 .Default(~0U); 134 } 135 136 // System Registers 137 namespace ARMSysReg { 138 struct MClassSysReg { 139 const char *Name; 140 uint16_t M1Encoding12; 141 uint16_t M2M3Encoding8; 142 uint16_t Encoding; 143 FeatureBitset FeaturesRequired; 144 145 // return true if FeaturesRequired are all present in ActiveFeatures 146 bool hasRequiredFeatures(FeatureBitset ActiveFeatures) const { 147 return (FeaturesRequired & ActiveFeatures) == FeaturesRequired; 148 } 149 150 // returns true if TestFeatures are all present in FeaturesRequired 151 bool isInRequiredFeatures(FeatureBitset TestFeatures) const { 152 return (FeaturesRequired & TestFeatures) == TestFeatures; 153 } 154 }; 155 156 #define GET_MCLASSSYSREG_DECL 157 #include "ARMGenSystemRegister.inc" 158 159 // lookup system register using 12-bit SYSm value. 160 // Note: the search is uniqued using M1 mask 161 const MClassSysReg *lookupMClassSysRegBy12bitSYSmValue(unsigned SYSm); 162 163 // returns APSR with _<bits> qualifier. 164 // Note: ARMv7-M deprecates using MSR APSR without a _<bits> qualifier 165 const MClassSysReg *lookupMClassSysRegAPSRNonDeprecated(unsigned SYSm); 166 167 // lookup system registers using 8-bit SYSm value 168 const MClassSysReg *lookupMClassSysRegBy8bitSYSmValue(unsigned SYSm); 169 170 } // end namespace ARMSysReg 171 172 // Banked Registers 173 namespace ARMBankedReg { 174 struct BankedReg { 175 const char *Name; 176 uint16_t Encoding; 177 }; 178 #define GET_BANKEDREG_DECL 179 #include "ARMGenSystemRegister.inc" 180 } // end namespace ARMBankedReg 181 182 } // end namespace llvm 183 184 #endif // LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H 185