ARMBaseInfo.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  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_MCTARGETDESC_ARMBASEINFO_H
  16. #define LLVM_LIB_TARGET_ARM_MCTARGETDESC_ARMBASEINFO_H
  17. #include "ARMMCTargetDesc.h"
  18. #include "llvm/Support/ErrorHandling.h"
  19. #include "Utils/ARMBaseInfo.h"
  20. namespace llvm {
  21. namespace ARM_PROC {
  22. enum IMod {
  23. IE = 2,
  24. ID = 3
  25. };
  26. enum IFlags {
  27. F = 1,
  28. I = 2,
  29. A = 4
  30. };
  31. inline static const char *IFlagsToString(unsigned val) {
  32. switch (val) {
  33. default: llvm_unreachable("Unknown iflags operand");
  34. case F: return "f";
  35. case I: return "i";
  36. case A: return "a";
  37. }
  38. }
  39. inline static const char *IModToString(unsigned val) {
  40. switch (val) {
  41. default: llvm_unreachable("Unknown imod operand");
  42. case IE: return "ie";
  43. case ID: return "id";
  44. }
  45. }
  46. }
  47. namespace ARM_MB {
  48. // The Memory Barrier Option constants map directly to the 4-bit encoding of
  49. // the option field for memory barrier operations.
  50. enum MemBOpt {
  51. RESERVED_0 = 0,
  52. OSHLD = 1,
  53. OSHST = 2,
  54. OSH = 3,
  55. RESERVED_4 = 4,
  56. NSHLD = 5,
  57. NSHST = 6,
  58. NSH = 7,
  59. RESERVED_8 = 8,
  60. ISHLD = 9,
  61. ISHST = 10,
  62. ISH = 11,
  63. RESERVED_12 = 12,
  64. LD = 13,
  65. ST = 14,
  66. SY = 15
  67. };
  68. inline static const char *MemBOptToString(unsigned val, bool HasV8) {
  69. switch (val) {
  70. default: llvm_unreachable("Unknown memory operation");
  71. case SY: return "sy";
  72. case ST: return "st";
  73. case LD: return HasV8 ? "ld" : "#0xd";
  74. case RESERVED_12: return "#0xc";
  75. case ISH: return "ish";
  76. case ISHST: return "ishst";
  77. case ISHLD: return HasV8 ? "ishld" : "#0x9";
  78. case RESERVED_8: return "#0x8";
  79. case NSH: return "nsh";
  80. case NSHST: return "nshst";
  81. case NSHLD: return HasV8 ? "nshld" : "#0x5";
  82. case RESERVED_4: return "#0x4";
  83. case OSH: return "osh";
  84. case OSHST: return "oshst";
  85. case OSHLD: return HasV8 ? "oshld" : "#0x1";
  86. case RESERVED_0: return "#0x0";
  87. }
  88. }
  89. } // namespace ARM_MB
  90. namespace ARM_TSB {
  91. enum TraceSyncBOpt {
  92. CSYNC = 0
  93. };
  94. inline static const char *TraceSyncBOptToString(unsigned val) {
  95. switch (val) {
  96. default:
  97. llvm_unreachable("Unknown trace synchronization barrier operation");
  98. case CSYNC: return "csync";
  99. }
  100. }
  101. } // namespace ARM_TSB
  102. namespace ARM_ISB {
  103. enum InstSyncBOpt {
  104. RESERVED_0 = 0,
  105. RESERVED_1 = 1,
  106. RESERVED_2 = 2,
  107. RESERVED_3 = 3,
  108. RESERVED_4 = 4,
  109. RESERVED_5 = 5,
  110. RESERVED_6 = 6,
  111. RESERVED_7 = 7,
  112. RESERVED_8 = 8,
  113. RESERVED_9 = 9,
  114. RESERVED_10 = 10,
  115. RESERVED_11 = 11,
  116. RESERVED_12 = 12,
  117. RESERVED_13 = 13,
  118. RESERVED_14 = 14,
  119. SY = 15
  120. };
  121. inline static const char *InstSyncBOptToString(unsigned val) {
  122. switch (val) {
  123. default:
  124. llvm_unreachable("Unknown memory operation");
  125. case RESERVED_0: return "#0x0";
  126. case RESERVED_1: return "#0x1";
  127. case RESERVED_2: return "#0x2";
  128. case RESERVED_3: return "#0x3";
  129. case RESERVED_4: return "#0x4";
  130. case RESERVED_5: return "#0x5";
  131. case RESERVED_6: return "#0x6";
  132. case RESERVED_7: return "#0x7";
  133. case RESERVED_8: return "#0x8";
  134. case RESERVED_9: return "#0x9";
  135. case RESERVED_10: return "#0xa";
  136. case RESERVED_11: return "#0xb";
  137. case RESERVED_12: return "#0xc";
  138. case RESERVED_13: return "#0xd";
  139. case RESERVED_14: return "#0xe";
  140. case SY: return "sy";
  141. }
  142. }
  143. } // namespace ARM_ISB
  144. /// isARMLowRegister - Returns true if the register is a low register (r0-r7).
  145. ///
  146. static inline bool isARMLowRegister(unsigned Reg) {
  147. using namespace ARM;
  148. switch (Reg) {
  149. case R0: case R1: case R2: case R3:
  150. case R4: case R5: case R6: case R7:
  151. return true;
  152. default:
  153. return false;
  154. }
  155. }
  156. /// ARMII - This namespace holds all of the target specific flags that
  157. /// instruction info tracks.
  158. ///
  159. namespace ARMII {
  160. /// ARM Index Modes
  161. enum IndexMode {
  162. IndexModeNone = 0,
  163. IndexModePre = 1,
  164. IndexModePost = 2,
  165. IndexModeUpd = 3
  166. };
  167. /// ARM Addressing Modes
  168. enum AddrMode {
  169. AddrModeNone = 0,
  170. AddrMode1 = 1,
  171. AddrMode2 = 2,
  172. AddrMode3 = 3,
  173. AddrMode4 = 4,
  174. AddrMode5 = 5,
  175. AddrMode6 = 6,
  176. AddrModeT1_1 = 7,
  177. AddrModeT1_2 = 8,
  178. AddrModeT1_4 = 9,
  179. AddrModeT1_s = 10, // i8 * 4 for pc and sp relative data
  180. AddrModeT2_i12 = 11,
  181. AddrModeT2_i8 = 12, // +/- i8
  182. AddrModeT2_i8pos = 13, // + i8
  183. AddrModeT2_i8neg = 14, // - i8
  184. AddrModeT2_so = 15,
  185. AddrModeT2_pc = 16, // +/- i12 for pc relative data
  186. AddrModeT2_i8s4 = 17, // i8 * 4
  187. AddrMode_i12 = 18,
  188. AddrMode5FP16 = 19, // i8 * 2
  189. AddrModeT2_ldrex = 20, // i8 * 4, with unscaled offset in MCInst
  190. AddrModeT2_i7s4 = 21, // i7 * 4
  191. AddrModeT2_i7s2 = 22, // i7 * 2
  192. AddrModeT2_i7 = 23, // i7 * 1
  193. };
  194. inline static const char *AddrModeToString(AddrMode addrmode) {
  195. switch (addrmode) {
  196. case AddrModeNone: return "AddrModeNone";
  197. case AddrMode1: return "AddrMode1";
  198. case AddrMode2: return "AddrMode2";
  199. case AddrMode3: return "AddrMode3";
  200. case AddrMode4: return "AddrMode4";
  201. case AddrMode5: return "AddrMode5";
  202. case AddrMode5FP16: return "AddrMode5FP16";
  203. case AddrMode6: return "AddrMode6";
  204. case AddrModeT1_1: return "AddrModeT1_1";
  205. case AddrModeT1_2: return "AddrModeT1_2";
  206. case AddrModeT1_4: return "AddrModeT1_4";
  207. case AddrModeT1_s: return "AddrModeT1_s";
  208. case AddrModeT2_i12: return "AddrModeT2_i12";
  209. case AddrModeT2_i8: return "AddrModeT2_i8";
  210. case AddrModeT2_i8pos: return "AddrModeT2_i8pos";
  211. case AddrModeT2_i8neg: return "AddrModeT2_i8neg";
  212. case AddrModeT2_so: return "AddrModeT2_so";
  213. case AddrModeT2_pc: return "AddrModeT2_pc";
  214. case AddrModeT2_i8s4: return "AddrModeT2_i8s4";
  215. case AddrMode_i12: return "AddrMode_i12";
  216. case AddrModeT2_ldrex:return "AddrModeT2_ldrex";
  217. case AddrModeT2_i7s4: return "AddrModeT2_i7s4";
  218. case AddrModeT2_i7s2: return "AddrModeT2_i7s2";
  219. case AddrModeT2_i7: return "AddrModeT2_i7";
  220. }
  221. }
  222. /// Target Operand Flag enum.
  223. enum TOF {
  224. //===------------------------------------------------------------------===//
  225. // ARM Specific MachineOperand flags.
  226. MO_NO_FLAG = 0,
  227. /// MO_LO16 - On a symbol operand, this represents a relocation containing
  228. /// lower 16 bit of the address. Used only via movw instruction.
  229. MO_LO16 = 0x1,
  230. /// MO_HI16 - On a symbol operand, this represents a relocation containing
  231. /// higher 16 bit of the address. Used only via movt instruction.
  232. MO_HI16 = 0x2,
  233. /// MO_OPTION_MASK - Most flags are mutually exclusive; this mask selects
  234. /// just that part of the flag set.
  235. MO_OPTION_MASK = 0x3,
  236. /// MO_COFFSTUB - On a symbol operand "FOO", this indicates that the
  237. /// reference is actually to the ".refptr.FOO" symbol. This is used for
  238. /// stub symbols on windows.
  239. MO_COFFSTUB = 0x4,
  240. /// MO_GOT - On a symbol operand, this represents a GOT relative relocation.
  241. MO_GOT = 0x8,
  242. /// MO_SBREL - On a symbol operand, this represents a static base relative
  243. /// relocation. Used in movw and movt instructions.
  244. MO_SBREL = 0x10,
  245. /// MO_DLLIMPORT - On a symbol operand, this represents that the reference
  246. /// to the symbol is for an import stub. This is used for DLL import
  247. /// storage class indication on Windows.
  248. MO_DLLIMPORT = 0x20,
  249. /// MO_SECREL - On a symbol operand this indicates that the immediate is
  250. /// the offset from beginning of section.
  251. ///
  252. /// This is the TLS offset for the COFF/Windows TLS mechanism.
  253. MO_SECREL = 0x40,
  254. /// MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it
  255. /// represents a symbol which, if indirect, will get special Darwin mangling
  256. /// as a non-lazy-ptr indirect symbol (i.e. "L_FOO$non_lazy_ptr"). Can be
  257. /// combined with MO_LO16, MO_HI16 or MO_NO_FLAG (in a constant-pool, for
  258. /// example).
  259. MO_NONLAZY = 0x80,
  260. // It's undefined behaviour if an enum overflows the range between its
  261. // smallest and largest values, but since these are |ed together, it can
  262. // happen. Put a sentinel in (values of this enum are stored as "unsigned
  263. // char").
  264. MO_UNUSED_MAXIMUM = 0xff
  265. };
  266. enum {
  267. //===------------------------------------------------------------------===//
  268. // Instruction Flags.
  269. //===------------------------------------------------------------------===//
  270. // This four-bit field describes the addressing mode used.
  271. AddrModeMask = 0x1f, // The AddrMode enums are declared in ARMBaseInfo.h
  272. // IndexMode - Unindex, pre-indexed, or post-indexed are valid for load
  273. // and store ops only. Generic "updating" flag is used for ld/st multiple.
  274. // The index mode enums are declared in ARMBaseInfo.h
  275. IndexModeShift = 5,
  276. IndexModeMask = 3 << IndexModeShift,
  277. //===------------------------------------------------------------------===//
  278. // Instruction encoding formats.
  279. //
  280. FormShift = 7,
  281. FormMask = 0x3f << FormShift,
  282. // Pseudo instructions
  283. Pseudo = 0 << FormShift,
  284. // Multiply instructions
  285. MulFrm = 1 << FormShift,
  286. // Branch instructions
  287. BrFrm = 2 << FormShift,
  288. BrMiscFrm = 3 << FormShift,
  289. // Data Processing instructions
  290. DPFrm = 4 << FormShift,
  291. DPSoRegFrm = 5 << FormShift,
  292. // Load and Store
  293. LdFrm = 6 << FormShift,
  294. StFrm = 7 << FormShift,
  295. LdMiscFrm = 8 << FormShift,
  296. StMiscFrm = 9 << FormShift,
  297. LdStMulFrm = 10 << FormShift,
  298. LdStExFrm = 11 << FormShift,
  299. // Miscellaneous arithmetic instructions
  300. ArithMiscFrm = 12 << FormShift,
  301. SatFrm = 13 << FormShift,
  302. // Extend instructions
  303. ExtFrm = 14 << FormShift,
  304. // VFP formats
  305. VFPUnaryFrm = 15 << FormShift,
  306. VFPBinaryFrm = 16 << FormShift,
  307. VFPConv1Frm = 17 << FormShift,
  308. VFPConv2Frm = 18 << FormShift,
  309. VFPConv3Frm = 19 << FormShift,
  310. VFPConv4Frm = 20 << FormShift,
  311. VFPConv5Frm = 21 << FormShift,
  312. VFPLdStFrm = 22 << FormShift,
  313. VFPLdStMulFrm = 23 << FormShift,
  314. VFPMiscFrm = 24 << FormShift,
  315. // Thumb format
  316. ThumbFrm = 25 << FormShift,
  317. // Miscelleaneous format
  318. MiscFrm = 26 << FormShift,
  319. // NEON formats
  320. NGetLnFrm = 27 << FormShift,
  321. NSetLnFrm = 28 << FormShift,
  322. NDupFrm = 29 << FormShift,
  323. NLdStFrm = 30 << FormShift,
  324. N1RegModImmFrm= 31 << FormShift,
  325. N2RegFrm = 32 << FormShift,
  326. NVCVTFrm = 33 << FormShift,
  327. NVDupLnFrm = 34 << FormShift,
  328. N2RegVShLFrm = 35 << FormShift,
  329. N2RegVShRFrm = 36 << FormShift,
  330. N3RegFrm = 37 << FormShift,
  331. N3RegVShFrm = 38 << FormShift,
  332. NVExtFrm = 39 << FormShift,
  333. NVMulSLFrm = 40 << FormShift,
  334. NVTBLFrm = 41 << FormShift,
  335. N3RegCplxFrm = 43 << FormShift,
  336. //===------------------------------------------------------------------===//
  337. // Misc flags.
  338. // UnaryDP - Indicates this is a unary data processing instruction, i.e.
  339. // it doesn't have a Rn operand.
  340. UnaryDP = 1 << 13,
  341. // Xform16Bit - Indicates this Thumb2 instruction may be transformed into
  342. // a 16-bit Thumb instruction if certain conditions are met.
  343. Xform16Bit = 1 << 14,
  344. // ThumbArithFlagSetting - The instruction is a 16-bit flag setting Thumb
  345. // instruction. Used by the parser to determine whether to require the 'S'
  346. // suffix on the mnemonic (when not in an IT block) or preclude it (when
  347. // in an IT block).
  348. ThumbArithFlagSetting = 1 << 19,
  349. // Whether an instruction can be included in an MVE tail-predicated loop,
  350. // though extra validity checks may need to be performed too.
  351. ValidForTailPredication = 1 << 20,
  352. // Whether an instruction writes to the top/bottom half of a vector element
  353. // and leaves the other half untouched.
  354. RetainsPreviousHalfElement = 1 << 21,
  355. // Whether the instruction produces a scalar result from vector operands.
  356. HorizontalReduction = 1 << 22,
  357. // Whether this instruction produces a vector result that is larger than
  358. // its input, typically reading from the top/bottom halves of the input(s).
  359. DoubleWidthResult = 1 << 23,
  360. // The vector element size for MVE instructions. 00 = i8, 01 = i16, 10 = i32
  361. // and 11 = i64. This is the largest type if multiple are present, so a
  362. // MVE_VMOVLs8bh is ize 01=i16, as it extends from a i8 to a i16. There are
  363. // some caveats so cannot be used blindly, such as exchanging VMLADAVA's and
  364. // complex instructions, which may use different input lanes.
  365. VecSizeShift = 24,
  366. VecSize = 3 << VecSizeShift,
  367. //===------------------------------------------------------------------===//
  368. // Code domain.
  369. DomainShift = 15,
  370. DomainMask = 15 << DomainShift,
  371. DomainGeneral = 0 << DomainShift,
  372. DomainVFP = 1 << DomainShift,
  373. DomainNEON = 2 << DomainShift,
  374. DomainNEONA8 = 4 << DomainShift,
  375. DomainMVE = 8 << DomainShift,
  376. //===------------------------------------------------------------------===//
  377. // Field shifts - such shifts are used to set field while generating
  378. // machine instructions.
  379. //
  380. // FIXME: This list will need adjusting/fixing as the MC code emitter
  381. // takes shape and the ARMCodeEmitter.cpp bits go away.
  382. ShiftTypeShift = 4,
  383. M_BitShift = 5,
  384. ShiftImmShift = 5,
  385. ShiftShift = 7,
  386. N_BitShift = 7,
  387. ImmHiShift = 8,
  388. SoRotImmShift = 8,
  389. RegRsShift = 8,
  390. ExtRotImmShift = 10,
  391. RegRdLoShift = 12,
  392. RegRdShift = 12,
  393. RegRdHiShift = 16,
  394. RegRnShift = 16,
  395. S_BitShift = 20,
  396. W_BitShift = 21,
  397. AM3_I_BitShift = 22,
  398. D_BitShift = 22,
  399. U_BitShift = 23,
  400. P_BitShift = 24,
  401. I_BitShift = 25,
  402. CondShift = 28
  403. };
  404. } // end namespace ARMII
  405. } // end namespace llvm;
  406. #endif