ARMBaseInfo.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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. #ifndef LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H
  16. #define LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H
  17. #include "llvm/ADT/StringSwitch.h"
  18. #include "llvm/Support/ErrorHandling.h"
  19. #include "llvm/MC/SubtargetFeature.h"
  20. #include "MCTargetDesc/ARMMCTargetDesc.h"
  21. namespace llvm {
  22. // Enums corresponding to ARM condition codes
  23. namespace ARMCC {
  24. // The CondCodes constants map directly to the 4-bit encoding of the
  25. // condition field for predicated instructions.
  26. enum CondCodes { // Meaning (integer) Meaning (floating-point)
  27. EQ, // Equal Equal
  28. NE, // Not equal Not equal, or unordered
  29. HS, // Carry set >, ==, or unordered
  30. LO, // Carry clear Less than
  31. MI, // Minus, negative Less than
  32. PL, // Plus, positive or zero >, ==, or unordered
  33. VS, // Overflow Unordered
  34. VC, // No overflow Not unordered
  35. HI, // Unsigned higher Greater than, or unordered
  36. LS, // Unsigned lower or same Less than or equal
  37. GE, // Greater than or equal Greater than or equal
  38. LT, // Less than Less than, or unordered
  39. GT, // Greater than Greater than
  40. LE, // Less than or equal <, ==, or unordered
  41. AL // Always (unconditional) Always (unconditional)
  42. };
  43. inline static CondCodes getOppositeCondition(CondCodes CC) {
  44. switch (CC) {
  45. default: llvm_unreachable("Unknown condition code");
  46. case EQ: return NE;
  47. case NE: return EQ;
  48. case HS: return LO;
  49. case LO: return HS;
  50. case MI: return PL;
  51. case PL: return MI;
  52. case VS: return VC;
  53. case VC: return VS;
  54. case HI: return LS;
  55. case LS: return HI;
  56. case GE: return LT;
  57. case LT: return GE;
  58. case GT: return LE;
  59. case LE: return GT;
  60. }
  61. }
  62. /// getSwappedCondition - assume the flags are set by MI(a,b), return
  63. /// the condition code if we modify the instructions such that flags are
  64. /// set by MI(b,a).
  65. inline static ARMCC::CondCodes getSwappedCondition(ARMCC::CondCodes CC) {
  66. switch (CC) {
  67. default: return ARMCC::AL;
  68. case ARMCC::EQ: return ARMCC::EQ;
  69. case ARMCC::NE: return ARMCC::NE;
  70. case ARMCC::HS: return ARMCC::LS;
  71. case ARMCC::LO: return ARMCC::HI;
  72. case ARMCC::HI: return ARMCC::LO;
  73. case ARMCC::LS: return ARMCC::HS;
  74. case ARMCC::GE: return ARMCC::LE;
  75. case ARMCC::LT: return ARMCC::GT;
  76. case ARMCC::GT: return ARMCC::LT;
  77. case ARMCC::LE: return ARMCC::GE;
  78. }
  79. }
  80. } // end namespace ARMCC
  81. namespace ARMVCC {
  82. enum VPTCodes {
  83. None = 0,
  84. Then,
  85. Else
  86. };
  87. } // namespace ARMVCC
  88. namespace ARM {
  89. /// Mask values for IT and VPT Blocks, to be used by MCOperands.
  90. /// Note that this is different from the "real" encoding used by the
  91. /// instructions. In this encoding, the lowest set bit indicates the end of
  92. /// the encoding, and above that, "1" indicates an else, while "0" indicates
  93. /// a then.
  94. /// Tx = x100
  95. /// Txy = xy10
  96. /// Txyz = xyz1
  97. enum class PredBlockMask {
  98. T = 0b1000,
  99. TT = 0b0100,
  100. TE = 0b1100,
  101. TTT = 0b0010,
  102. TTE = 0b0110,
  103. TEE = 0b1110,
  104. TET = 0b1010,
  105. TTTT = 0b0001,
  106. TTTE = 0b0011,
  107. TTEE = 0b0111,
  108. TTET = 0b0101,
  109. TEEE = 0b1111,
  110. TEET = 0b1101,
  111. TETT = 0b1001,
  112. TETE = 0b1011
  113. };
  114. } // namespace ARM
  115. // Expands a PredBlockMask by adding an E or a T at the end, depending on Kind.
  116. // e.g ExpandPredBlockMask(T, Then) = TT, ExpandPredBlockMask(TT, Else) = TTE,
  117. // and so on.
  118. ARM::PredBlockMask expandPredBlockMask(ARM::PredBlockMask BlockMask,
  119. ARMVCC::VPTCodes Kind);
  120. inline static const char *ARMVPTPredToString(ARMVCC::VPTCodes CC) {
  121. switch (CC) {
  122. case ARMVCC::None: return "none";
  123. case ARMVCC::Then: return "t";
  124. case ARMVCC::Else: return "e";
  125. }
  126. llvm_unreachable("Unknown VPT code");
  127. }
  128. inline static unsigned ARMVectorCondCodeFromString(StringRef CC) {
  129. return StringSwitch<unsigned>(CC.lower())
  130. .Case("t", ARMVCC::Then)
  131. .Case("e", ARMVCC::Else)
  132. .Default(~0U);
  133. }
  134. inline static const char *ARMCondCodeToString(ARMCC::CondCodes CC) {
  135. switch (CC) {
  136. case ARMCC::EQ: return "eq";
  137. case ARMCC::NE: return "ne";
  138. case ARMCC::HS: return "hs";
  139. case ARMCC::LO: return "lo";
  140. case ARMCC::MI: return "mi";
  141. case ARMCC::PL: return "pl";
  142. case ARMCC::VS: return "vs";
  143. case ARMCC::VC: return "vc";
  144. case ARMCC::HI: return "hi";
  145. case ARMCC::LS: return "ls";
  146. case ARMCC::GE: return "ge";
  147. case ARMCC::LT: return "lt";
  148. case ARMCC::GT: return "gt";
  149. case ARMCC::LE: return "le";
  150. case ARMCC::AL: return "al";
  151. }
  152. llvm_unreachable("Unknown condition code");
  153. }
  154. inline static unsigned ARMCondCodeFromString(StringRef CC) {
  155. return StringSwitch<unsigned>(CC.lower())
  156. .Case("eq", ARMCC::EQ)
  157. .Case("ne", ARMCC::NE)
  158. .Case("hs", ARMCC::HS)
  159. .Case("cs", ARMCC::HS)
  160. .Case("lo", ARMCC::LO)
  161. .Case("cc", ARMCC::LO)
  162. .Case("mi", ARMCC::MI)
  163. .Case("pl", ARMCC::PL)
  164. .Case("vs", ARMCC::VS)
  165. .Case("vc", ARMCC::VC)
  166. .Case("hi", ARMCC::HI)
  167. .Case("ls", ARMCC::LS)
  168. .Case("ge", ARMCC::GE)
  169. .Case("lt", ARMCC::LT)
  170. .Case("gt", ARMCC::GT)
  171. .Case("le", ARMCC::LE)
  172. .Case("al", ARMCC::AL)
  173. .Default(~0U);
  174. }
  175. // System Registers
  176. namespace ARMSysReg {
  177. struct MClassSysReg {
  178. const char *Name;
  179. uint16_t M1Encoding12;
  180. uint16_t M2M3Encoding8;
  181. uint16_t Encoding;
  182. FeatureBitset FeaturesRequired;
  183. // return true if FeaturesRequired are all present in ActiveFeatures
  184. bool hasRequiredFeatures(FeatureBitset ActiveFeatures) const {
  185. return (FeaturesRequired & ActiveFeatures) == FeaturesRequired;
  186. }
  187. // returns true if TestFeatures are all present in FeaturesRequired
  188. bool isInRequiredFeatures(FeatureBitset TestFeatures) const {
  189. return (FeaturesRequired & TestFeatures) == TestFeatures;
  190. }
  191. };
  192. #define GET_MCLASSSYSREG_DECL
  193. #include "ARMGenSystemRegister.inc"
  194. // lookup system register using 12-bit SYSm value.
  195. // Note: the search is uniqued using M1 mask
  196. const MClassSysReg *lookupMClassSysRegBy12bitSYSmValue(unsigned SYSm);
  197. // returns APSR with _<bits> qualifier.
  198. // Note: ARMv7-M deprecates using MSR APSR without a _<bits> qualifier
  199. const MClassSysReg *lookupMClassSysRegAPSRNonDeprecated(unsigned SYSm);
  200. // lookup system registers using 8-bit SYSm value
  201. const MClassSysReg *lookupMClassSysRegBy8bitSYSmValue(unsigned SYSm);
  202. } // end namespace ARMSysReg
  203. // Banked Registers
  204. namespace ARMBankedReg {
  205. struct BankedReg {
  206. const char *Name;
  207. uint16_t Encoding;
  208. };
  209. #define GET_BANKEDREG_DECL
  210. #include "ARMGenSystemRegister.inc"
  211. } // end namespace ARMBankedReg
  212. } // end namespace llvm
  213. #endif // LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H