238 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains small standalone helper functions and enum definitions for10// the ARM target useful for the compiler back-end and the MC libraries.11// As such, it deliberately does not include references to LLVM core12// code gen types, passes, etc..13//14//===----------------------------------------------------------------------===//15 16#ifndef LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H17#define LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H18 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 codes27namespace ARMCC {28// The CondCodes constants map directly to the 4-bit encoding of the29// condition field for predicated instructions.30enum CondCodes { // Meaning (integer) Meaning (floating-point)31 EQ, // Equal Equal32 NE, // Not equal Not equal, or unordered33 HS, // Carry set >, ==, or unordered34 LO, // Carry clear Less than35 MI, // Minus, negative Less than36 PL, // Plus, positive or zero >, ==, or unordered37 VS, // Overflow Unordered38 VC, // No overflow Not unordered39 HI, // Unsigned higher Greater than, or unordered40 LS, // Unsigned lower or same Less than or equal41 GE, // Greater than or equal Greater than or equal42 LT, // Less than Less than, or unordered43 GT, // Greater than Greater than44 LE, // Less than or equal <, ==, or unordered45 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), return69/// the condition code if we modify the instructions such that flags are70/// 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 ARMCC87 88namespace ARMVCC {89 enum VPTCodes {90 None = 0,91 Then,92 Else93 };94} // namespace ARMVCC95 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 the99 /// instructions. In this encoding, the lowest set bit indicates the end of100 /// the encoding, and above that, "1" indicates an else, while "0" indicates101 /// a then.102 /// Tx = x100103 /// Txy = xy10104 /// Txyz = xyz1105 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 = 0b1011121 };122} // namespace ARM123 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 Registers190namespace ARMSysReg {191 struct MClassSysReg {192 const char Name[32];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 ActiveFeatures199 bool hasRequiredFeatures(FeatureBitset ActiveFeatures) const {200 return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;201 }202 203 // returns true if TestFeatures are all present in FeaturesRequired204 bool isInRequiredFeatures(FeatureBitset TestFeatures) const {205 return (FeaturesRequired & TestFeatures) == TestFeatures;206 }207 };208 209#define GET_MClassSysRegsList_DECL210#include "ARMGenSystemRegister.inc"211 212 // lookup system register using 12-bit SYSm value.213 // Note: the search is uniqued using M1 mask214 const MClassSysReg *lookupMClassSysRegBy12bitSYSmValue(unsigned SYSm);215 216 // returns APSR with _<bits> qualifier.217 // Note: ARMv7-M deprecates using MSR APSR without a _<bits> qualifier218 const MClassSysReg *lookupMClassSysRegAPSRNonDeprecated(unsigned SYSm);219 220 // lookup system registers using 8-bit SYSm value221 const MClassSysReg *lookupMClassSysRegBy8bitSYSmValue(unsigned SYSm);222 223} // end namespace ARMSysReg224 225// Banked Registers226namespace ARMBankedReg {227 struct BankedReg {228 const char *Name;229 uint16_t Encoding;230 };231#define GET_BankedRegsList_DECL232#include "ARMGenSystemRegister.inc"233} // end namespace ARMBankedReg234 235} // end namespace llvm236 237#endif // LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H238