123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- //===-- ARMBaseInfo.h - Top level definitions for ARM ---*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file contains small standalone helper functions and enum definitions for
- // the ARM target useful for the compiler back-end and the MC libraries.
- // As such, it deliberately does not include references to LLVM core
- // code gen types, passes, etc..
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H
- #define LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H
- #include "llvm/ADT/StringSwitch.h"
- #include "llvm/Support/ErrorHandling.h"
- #include "llvm/MC/SubtargetFeature.h"
- #include "MCTargetDesc/ARMMCTargetDesc.h"
- namespace llvm {
- // Enums corresponding to ARM condition codes
- namespace ARMCC {
- // The CondCodes constants map directly to the 4-bit encoding of the
- // condition field for predicated instructions.
- enum CondCodes { // Meaning (integer) Meaning (floating-point)
- EQ, // Equal Equal
- NE, // Not equal Not equal, or unordered
- HS, // Carry set >, ==, or unordered
- LO, // Carry clear Less than
- MI, // Minus, negative Less than
- PL, // Plus, positive or zero >, ==, or unordered
- VS, // Overflow Unordered
- VC, // No overflow Not unordered
- HI, // Unsigned higher Greater than, or unordered
- LS, // Unsigned lower or same Less than or equal
- GE, // Greater than or equal Greater than or equal
- LT, // Less than Less than, or unordered
- GT, // Greater than Greater than
- LE, // Less than or equal <, ==, or unordered
- AL // Always (unconditional) Always (unconditional)
- };
- inline static CondCodes getOppositeCondition(CondCodes CC) {
- switch (CC) {
- default: llvm_unreachable("Unknown condition code");
- case EQ: return NE;
- case NE: return EQ;
- case HS: return LO;
- case LO: return HS;
- case MI: return PL;
- case PL: return MI;
- case VS: return VC;
- case VC: return VS;
- case HI: return LS;
- case LS: return HI;
- case GE: return LT;
- case LT: return GE;
- case GT: return LE;
- case LE: return GT;
- }
- }
- /// getSwappedCondition - assume the flags are set by MI(a,b), return
- /// the condition code if we modify the instructions such that flags are
- /// set by MI(b,a).
- inline static ARMCC::CondCodes getSwappedCondition(ARMCC::CondCodes CC) {
- switch (CC) {
- default: return ARMCC::AL;
- case ARMCC::EQ: return ARMCC::EQ;
- case ARMCC::NE: return ARMCC::NE;
- case ARMCC::HS: return ARMCC::LS;
- case ARMCC::LO: return ARMCC::HI;
- case ARMCC::HI: return ARMCC::LO;
- case ARMCC::LS: return ARMCC::HS;
- case ARMCC::GE: return ARMCC::LE;
- case ARMCC::LT: return ARMCC::GT;
- case ARMCC::GT: return ARMCC::LT;
- case ARMCC::LE: return ARMCC::GE;
- }
- }
- } // end namespace ARMCC
- namespace ARMVCC {
- enum VPTCodes {
- None = 0,
- Then,
- Else
- };
- } // namespace ARMVCC
- namespace ARM {
- /// Mask values for IT and VPT Blocks, to be used by MCOperands.
- /// Note that this is different from the "real" encoding used by the
- /// instructions. In this encoding, the lowest set bit indicates the end of
- /// the encoding, and above that, "1" indicates an else, while "0" indicates
- /// a then.
- /// Tx = x100
- /// Txy = xy10
- /// Txyz = xyz1
- enum class PredBlockMask {
- T = 0b1000,
- TT = 0b0100,
- TE = 0b1100,
- TTT = 0b0010,
- TTE = 0b0110,
- TEE = 0b1110,
- TET = 0b1010,
- TTTT = 0b0001,
- TTTE = 0b0011,
- TTEE = 0b0111,
- TTET = 0b0101,
- TEEE = 0b1111,
- TEET = 0b1101,
- TETT = 0b1001,
- TETE = 0b1011
- };
- } // namespace ARM
- // Expands a PredBlockMask by adding an E or a T at the end, depending on Kind.
- // e.g ExpandPredBlockMask(T, Then) = TT, ExpandPredBlockMask(TT, Else) = TTE,
- // and so on.
- ARM::PredBlockMask expandPredBlockMask(ARM::PredBlockMask BlockMask,
- ARMVCC::VPTCodes Kind);
- inline static const char *ARMVPTPredToString(ARMVCC::VPTCodes CC) {
- switch (CC) {
- case ARMVCC::None: return "none";
- case ARMVCC::Then: return "t";
- case ARMVCC::Else: return "e";
- }
- llvm_unreachable("Unknown VPT code");
- }
- inline static unsigned ARMVectorCondCodeFromString(StringRef CC) {
- return StringSwitch<unsigned>(CC.lower())
- .Case("t", ARMVCC::Then)
- .Case("e", ARMVCC::Else)
- .Default(~0U);
- }
- inline static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {
- switch (CC) {
- case ARMCC::EQ: return "eq";
- case ARMCC::NE: return "ne";
- case ARMCC::HS: return "hs";
- case ARMCC::LO: return "lo";
- case ARMCC::MI: return "mi";
- case ARMCC::PL: return "pl";
- case ARMCC::VS: return "vs";
- case ARMCC::VC: return "vc";
- case ARMCC::HI: return "hi";
- case ARMCC::LS: return "ls";
- case ARMCC::GE: return "ge";
- case ARMCC::LT: return "lt";
- case ARMCC::GT: return "gt";
- case ARMCC::LE: return "le";
- case ARMCC::AL: return "al";
- }
- llvm_unreachable("Unknown condition code");
- }
- inline static unsigned ARMCondCodeFromString(StringRef CC) {
- return StringSwitch<unsigned>(CC.lower())
- .Case("eq", ARMCC::EQ)
- .Case("ne", ARMCC::NE)
- .Case("hs", ARMCC::HS)
- .Case("cs", ARMCC::HS)
- .Case("lo", ARMCC::LO)
- .Case("cc", ARMCC::LO)
- .Case("mi", ARMCC::MI)
- .Case("pl", ARMCC::PL)
- .Case("vs", ARMCC::VS)
- .Case("vc", ARMCC::VC)
- .Case("hi", ARMCC::HI)
- .Case("ls", ARMCC::LS)
- .Case("ge", ARMCC::GE)
- .Case("lt", ARMCC::LT)
- .Case("gt", ARMCC::GT)
- .Case("le", ARMCC::LE)
- .Case("al", ARMCC::AL)
- .Default(~0U);
- }
- // System Registers
- namespace ARMSysReg {
- struct MClassSysReg {
- const char *Name;
- uint16_t M1Encoding12;
- uint16_t M2M3Encoding8;
- uint16_t Encoding;
- FeatureBitset FeaturesRequired;
- // return true if FeaturesRequired are all present in ActiveFeatures
- bool hasRequiredFeatures(FeatureBitset ActiveFeatures) const {
- return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
- }
- // returns true if TestFeatures are all present in FeaturesRequired
- bool isInRequiredFeatures(FeatureBitset TestFeatures) const {
- return (FeaturesRequired & TestFeatures) == TestFeatures;
- }
- };
- #define GET_MCLASSSYSREG_DECL
- #include "ARMGenSystemRegister.inc"
- // lookup system register using 12-bit SYSm value.
- // Note: the search is uniqued using M1 mask
- const MClassSysReg *lookupMClassSysRegBy12bitSYSmValue(unsigned SYSm);
- // returns APSR with _<bits> qualifier.
- // Note: ARMv7-M deprecates using MSR APSR without a _<bits> qualifier
- const MClassSysReg *lookupMClassSysRegAPSRNonDeprecated(unsigned SYSm);
- // lookup system registers using 8-bit SYSm value
- const MClassSysReg *lookupMClassSysRegBy8bitSYSmValue(unsigned SYSm);
- } // end namespace ARMSysReg
- // Banked Registers
- namespace ARMBankedReg {
- struct BankedReg {
- const char *Name;
- uint16_t Encoding;
- };
- #define GET_BANKEDREG_DECL
- #include "ARMGenSystemRegister.inc"
- } // end namespace ARMBankedReg
- } // end namespace llvm
- #endif // LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H
|