Home | History | Annotate | Line # | Download | only in Utils
      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 
     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