ARMRegisterInfo.td 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. //===-- ARMRegisterInfo.td - ARM Register defs -------------*- tablegen -*-===//
  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. include "ARMSystemRegister.td"
  9. //===----------------------------------------------------------------------===//
  10. // Declarations that describe the ARM register file
  11. //===----------------------------------------------------------------------===//
  12. // Registers are identified with 4-bit ID numbers.
  13. class ARMReg<bits<16> Enc, string n, list<Register> subregs = [],
  14. list<string> altNames = []> : Register<n, altNames> {
  15. let HWEncoding = Enc;
  16. let Namespace = "ARM";
  17. let SubRegs = subregs;
  18. // All bits of ARM registers with sub-registers are covered by sub-registers.
  19. let CoveredBySubRegs = 1;
  20. }
  21. class ARMFReg<bits<16> Enc, string n> : Register<n> {
  22. let HWEncoding = Enc;
  23. let Namespace = "ARM";
  24. }
  25. let Namespace = "ARM",
  26. FallbackRegAltNameIndex = NoRegAltName in {
  27. def RegNamesRaw : RegAltNameIndex;
  28. }
  29. // Subregister indices.
  30. let Namespace = "ARM" in {
  31. def qqsub_0 : SubRegIndex<256>;
  32. def qqsub_1 : SubRegIndex<256, 256>;
  33. // Note: Code depends on these having consecutive numbers.
  34. def qsub_0 : SubRegIndex<128>;
  35. def qsub_1 : SubRegIndex<128, 128>;
  36. def qsub_2 : ComposedSubRegIndex<qqsub_1, qsub_0>;
  37. def qsub_3 : ComposedSubRegIndex<qqsub_1, qsub_1>;
  38. def dsub_0 : SubRegIndex<64>;
  39. def dsub_1 : SubRegIndex<64, 64>;
  40. def dsub_2 : ComposedSubRegIndex<qsub_1, dsub_0>;
  41. def dsub_3 : ComposedSubRegIndex<qsub_1, dsub_1>;
  42. def dsub_4 : ComposedSubRegIndex<qsub_2, dsub_0>;
  43. def dsub_5 : ComposedSubRegIndex<qsub_2, dsub_1>;
  44. def dsub_6 : ComposedSubRegIndex<qsub_3, dsub_0>;
  45. def dsub_7 : ComposedSubRegIndex<qsub_3, dsub_1>;
  46. def ssub_0 : SubRegIndex<32>;
  47. def ssub_1 : SubRegIndex<32, 32>;
  48. def ssub_2 : ComposedSubRegIndex<dsub_1, ssub_0>;
  49. def ssub_3 : ComposedSubRegIndex<dsub_1, ssub_1>;
  50. def ssub_4 : ComposedSubRegIndex<dsub_2, ssub_0>;
  51. def ssub_5 : ComposedSubRegIndex<dsub_2, ssub_1>;
  52. def ssub_6 : ComposedSubRegIndex<dsub_3, ssub_0>;
  53. def ssub_7 : ComposedSubRegIndex<dsub_3, ssub_1>;
  54. def ssub_8 : ComposedSubRegIndex<dsub_4, ssub_0>;
  55. def ssub_9 : ComposedSubRegIndex<dsub_4, ssub_1>;
  56. def ssub_10 : ComposedSubRegIndex<dsub_5, ssub_0>;
  57. def ssub_11 : ComposedSubRegIndex<dsub_5, ssub_1>;
  58. def ssub_12 : ComposedSubRegIndex<dsub_6, ssub_0>;
  59. def ssub_13 : ComposedSubRegIndex<dsub_6, ssub_1>;
  60. def ssub_14 : ComposedSubRegIndex<dsub_7, ssub_0>;
  61. def ssub_15 : ComposedSubRegIndex<dsub_7, ssub_1>;
  62. def gsub_0 : SubRegIndex<32>;
  63. def gsub_1 : SubRegIndex<32, 32>;
  64. // Let TableGen synthesize the remaining 12 ssub_* indices.
  65. // We don't need to name them.
  66. }
  67. // Integer registers
  68. def R0 : ARMReg< 0, "r0">, DwarfRegNum<[0]>;
  69. def R1 : ARMReg< 1, "r1">, DwarfRegNum<[1]>;
  70. def R2 : ARMReg< 2, "r2">, DwarfRegNum<[2]>;
  71. def R3 : ARMReg< 3, "r3">, DwarfRegNum<[3]>;
  72. def R4 : ARMReg< 4, "r4">, DwarfRegNum<[4]>;
  73. def R5 : ARMReg< 5, "r5">, DwarfRegNum<[5]>;
  74. def R6 : ARMReg< 6, "r6">, DwarfRegNum<[6]>;
  75. def R7 : ARMReg< 7, "r7">, DwarfRegNum<[7]>;
  76. // These require 32-bit instructions.
  77. let CostPerUse = [1] in {
  78. def R8 : ARMReg< 8, "r8">, DwarfRegNum<[8]>;
  79. def R9 : ARMReg< 9, "r9">, DwarfRegNum<[9]>;
  80. def R10 : ARMReg<10, "r10">, DwarfRegNum<[10]>;
  81. def R11 : ARMReg<11, "r11">, DwarfRegNum<[11]>;
  82. def R12 : ARMReg<12, "r12">, DwarfRegNum<[12]>;
  83. let RegAltNameIndices = [RegNamesRaw] in {
  84. def SP : ARMReg<13, "sp", [], ["r13"]>, DwarfRegNum<[13]>;
  85. def LR : ARMReg<14, "lr", [], ["r14"]>, DwarfRegNum<[14]>;
  86. def PC : ARMReg<15, "pc", [], ["r15"]>, DwarfRegNum<[15]>;
  87. }
  88. }
  89. // Float registers
  90. def S0 : ARMFReg< 0, "s0">; def S1 : ARMFReg< 1, "s1">;
  91. def S2 : ARMFReg< 2, "s2">; def S3 : ARMFReg< 3, "s3">;
  92. def S4 : ARMFReg< 4, "s4">; def S5 : ARMFReg< 5, "s5">;
  93. def S6 : ARMFReg< 6, "s6">; def S7 : ARMFReg< 7, "s7">;
  94. def S8 : ARMFReg< 8, "s8">; def S9 : ARMFReg< 9, "s9">;
  95. def S10 : ARMFReg<10, "s10">; def S11 : ARMFReg<11, "s11">;
  96. def S12 : ARMFReg<12, "s12">; def S13 : ARMFReg<13, "s13">;
  97. def S14 : ARMFReg<14, "s14">; def S15 : ARMFReg<15, "s15">;
  98. def S16 : ARMFReg<16, "s16">; def S17 : ARMFReg<17, "s17">;
  99. def S18 : ARMFReg<18, "s18">; def S19 : ARMFReg<19, "s19">;
  100. def S20 : ARMFReg<20, "s20">; def S21 : ARMFReg<21, "s21">;
  101. def S22 : ARMFReg<22, "s22">; def S23 : ARMFReg<23, "s23">;
  102. def S24 : ARMFReg<24, "s24">; def S25 : ARMFReg<25, "s25">;
  103. def S26 : ARMFReg<26, "s26">; def S27 : ARMFReg<27, "s27">;
  104. def S28 : ARMFReg<28, "s28">; def S29 : ARMFReg<29, "s29">;
  105. def S30 : ARMFReg<30, "s30">; def S31 : ARMFReg<31, "s31">;
  106. // Aliases of the F* registers used to hold 64-bit fp values (doubles)
  107. let SubRegIndices = [ssub_0, ssub_1] in {
  108. def D0 : ARMReg< 0, "d0", [S0, S1]>, DwarfRegNum<[256]>;
  109. def D1 : ARMReg< 1, "d1", [S2, S3]>, DwarfRegNum<[257]>;
  110. def D2 : ARMReg< 2, "d2", [S4, S5]>, DwarfRegNum<[258]>;
  111. def D3 : ARMReg< 3, "d3", [S6, S7]>, DwarfRegNum<[259]>;
  112. def D4 : ARMReg< 4, "d4", [S8, S9]>, DwarfRegNum<[260]>;
  113. def D5 : ARMReg< 5, "d5", [S10, S11]>, DwarfRegNum<[261]>;
  114. def D6 : ARMReg< 6, "d6", [S12, S13]>, DwarfRegNum<[262]>;
  115. def D7 : ARMReg< 7, "d7", [S14, S15]>, DwarfRegNum<[263]>;
  116. def D8 : ARMReg< 8, "d8", [S16, S17]>, DwarfRegNum<[264]>;
  117. def D9 : ARMReg< 9, "d9", [S18, S19]>, DwarfRegNum<[265]>;
  118. def D10 : ARMReg<10, "d10", [S20, S21]>, DwarfRegNum<[266]>;
  119. def D11 : ARMReg<11, "d11", [S22, S23]>, DwarfRegNum<[267]>;
  120. def D12 : ARMReg<12, "d12", [S24, S25]>, DwarfRegNum<[268]>;
  121. def D13 : ARMReg<13, "d13", [S26, S27]>, DwarfRegNum<[269]>;
  122. def D14 : ARMReg<14, "d14", [S28, S29]>, DwarfRegNum<[270]>;
  123. def D15 : ARMReg<15, "d15", [S30, S31]>, DwarfRegNum<[271]>;
  124. }
  125. // VFP3 defines 16 additional double registers
  126. def D16 : ARMFReg<16, "d16">, DwarfRegNum<[272]>;
  127. def D17 : ARMFReg<17, "d17">, DwarfRegNum<[273]>;
  128. def D18 : ARMFReg<18, "d18">, DwarfRegNum<[274]>;
  129. def D19 : ARMFReg<19, "d19">, DwarfRegNum<[275]>;
  130. def D20 : ARMFReg<20, "d20">, DwarfRegNum<[276]>;
  131. def D21 : ARMFReg<21, "d21">, DwarfRegNum<[277]>;
  132. def D22 : ARMFReg<22, "d22">, DwarfRegNum<[278]>;
  133. def D23 : ARMFReg<23, "d23">, DwarfRegNum<[279]>;
  134. def D24 : ARMFReg<24, "d24">, DwarfRegNum<[280]>;
  135. def D25 : ARMFReg<25, "d25">, DwarfRegNum<[281]>;
  136. def D26 : ARMFReg<26, "d26">, DwarfRegNum<[282]>;
  137. def D27 : ARMFReg<27, "d27">, DwarfRegNum<[283]>;
  138. def D28 : ARMFReg<28, "d28">, DwarfRegNum<[284]>;
  139. def D29 : ARMFReg<29, "d29">, DwarfRegNum<[285]>;
  140. def D30 : ARMFReg<30, "d30">, DwarfRegNum<[286]>;
  141. def D31 : ARMFReg<31, "d31">, DwarfRegNum<[287]>;
  142. // Advanced SIMD (NEON) defines 16 quad-word aliases
  143. let SubRegIndices = [dsub_0, dsub_1] in {
  144. def Q0 : ARMReg< 0, "q0", [D0, D1]>;
  145. def Q1 : ARMReg< 1, "q1", [D2, D3]>;
  146. def Q2 : ARMReg< 2, "q2", [D4, D5]>;
  147. def Q3 : ARMReg< 3, "q3", [D6, D7]>;
  148. def Q4 : ARMReg< 4, "q4", [D8, D9]>;
  149. def Q5 : ARMReg< 5, "q5", [D10, D11]>;
  150. def Q6 : ARMReg< 6, "q6", [D12, D13]>;
  151. def Q7 : ARMReg< 7, "q7", [D14, D15]>;
  152. }
  153. let SubRegIndices = [dsub_0, dsub_1] in {
  154. def Q8 : ARMReg< 8, "q8", [D16, D17]>;
  155. def Q9 : ARMReg< 9, "q9", [D18, D19]>;
  156. def Q10 : ARMReg<10, "q10", [D20, D21]>;
  157. def Q11 : ARMReg<11, "q11", [D22, D23]>;
  158. def Q12 : ARMReg<12, "q12", [D24, D25]>;
  159. def Q13 : ARMReg<13, "q13", [D26, D27]>;
  160. def Q14 : ARMReg<14, "q14", [D28, D29]>;
  161. def Q15 : ARMReg<15, "q15", [D30, D31]>;
  162. }
  163. // Current Program Status Register.
  164. // We model fpscr with two registers: FPSCR models the control bits and will be
  165. // reserved. FPSCR_NZCV models the flag bits and will be unreserved. APSR_NZCV
  166. // models the APSR when it's accessed by some special instructions. In such cases
  167. // it has the same encoding as PC.
  168. def CPSR : ARMReg<0, "cpsr">;
  169. def APSR : ARMReg<15, "apsr">;
  170. def APSR_NZCV : ARMReg<15, "apsr_nzcv">;
  171. def SPSR : ARMReg<2, "spsr">;
  172. def FPSCR : ARMReg<3, "fpscr">;
  173. def FPSCR_NZCV : ARMReg<3, "fpscr_nzcv"> {
  174. let Aliases = [FPSCR];
  175. }
  176. def ITSTATE : ARMReg<4, "itstate">;
  177. // Special Registers - only available in privileged mode.
  178. def FPSID : ARMReg<0, "fpsid">;
  179. def MVFR2 : ARMReg<5, "mvfr2">;
  180. def MVFR1 : ARMReg<6, "mvfr1">;
  181. def MVFR0 : ARMReg<7, "mvfr0">;
  182. def FPEXC : ARMReg<8, "fpexc">;
  183. def FPINST : ARMReg<9, "fpinst">;
  184. def FPINST2 : ARMReg<10, "fpinst2">;
  185. // These encodings aren't actual instruction encodings, their encoding depends
  186. // on the instruction they are used in and for VPR 32 was chosen such that it
  187. // always comes last in spr_reglist_with_vpr.
  188. def VPR : ARMReg<32, "vpr">;
  189. def FPSCR_NZCVQC
  190. : ARMReg<2, "fpscr_nzcvqc">;
  191. def P0 : ARMReg<13, "p0">;
  192. def FPCXTNS : ARMReg<14, "fpcxtns">;
  193. def FPCXTS : ARMReg<15, "fpcxts">;
  194. def ZR : ARMReg<15, "zr">, DwarfRegNum<[15]>;
  195. def RA_AUTH_CODE : ARMReg<12, "ra_auth_code">, DwarfRegNum<[143]>;
  196. // Register classes.
  197. //
  198. // pc == Program Counter
  199. // lr == Link Register
  200. // sp == Stack Pointer
  201. // r12 == ip (scratch)
  202. // r7 == Frame Pointer (thumb-style backtraces)
  203. // r9 == May be reserved as Thread Register
  204. // r11 == Frame Pointer (arm-style backtraces)
  205. // r10 == Stack Limit
  206. //
  207. def GPR : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12),
  208. SP, LR, PC)> {
  209. // Allocate LR as the first CSR since it is always saved anyway.
  210. // For Thumb1 mode, we don't want to allocate hi regs at all, as we don't
  211. // know how to spill them. If we make our prologue/epilogue code smarter at
  212. // some point, we can go back to using the above allocation orders for the
  213. // Thumb1 instructions that know how to use hi regs.
  214. let AltOrders = [(add LR, GPR), (trunc GPR, 8),
  215. (add (trunc GPR, 8), R12, LR, (shl GPR, 8))];
  216. let AltOrderSelect = [{
  217. return MF.getSubtarget<ARMSubtarget>().getGPRAllocationOrder(MF);
  218. }];
  219. let DiagnosticString = "operand must be a register in range [r0, r15]";
  220. }
  221. // Register set that excludes registers that are reserved for procedure calls.
  222. // This is used for pseudo-instructions that are actually implemented using a
  223. // procedure call.
  224. def GPRnoip : RegisterClass<"ARM", [i32], 32, (sub GPR, R12, LR)> {
  225. // Allocate LR as the first CSR since it is always saved anyway.
  226. // For Thumb1 mode, we don't want to allocate hi regs at all, as we don't
  227. // know how to spill them. If we make our prologue/epilogue code smarter at
  228. // some point, we can go back to using the above allocation orders for the
  229. // Thumb1 instructions that know how to use hi regs.
  230. let AltOrders = [(add GPRnoip, GPRnoip), (trunc GPRnoip, 8),
  231. (add (trunc GPRnoip, 8), (shl GPRnoip, 8))];
  232. let AltOrderSelect = [{
  233. return MF.getSubtarget<ARMSubtarget>().getGPRAllocationOrder(MF);
  234. }];
  235. let DiagnosticString = "operand must be a register in range [r0, r14]";
  236. }
  237. // GPRs without the PC. Some ARM instructions do not allow the PC in
  238. // certain operand slots, particularly as the destination. Primarily
  239. // useful for disassembly.
  240. def GPRnopc : RegisterClass<"ARM", [i32], 32, (sub GPR, PC)> {
  241. let AltOrders = [(add LR, GPRnopc), (trunc GPRnopc, 8),
  242. (add (trunc GPRnopc, 8), R12, LR, (shl GPRnopc, 8))];
  243. let AltOrderSelect = [{
  244. return MF.getSubtarget<ARMSubtarget>().getGPRAllocationOrder(MF);
  245. }];
  246. let DiagnosticString = "operand must be a register in range [r0, r14]";
  247. }
  248. // GPRs without the PC but with APSR. Some instructions allow accessing the
  249. // APSR, while actually encoding PC in the register field. This is useful
  250. // for assembly and disassembly only.
  251. def GPRwithAPSR : RegisterClass<"ARM", [i32], 32, (add (sub GPR, PC), APSR_NZCV)> {
  252. let AltOrders = [(add LR, GPRnopc), (trunc GPRnopc, 8)];
  253. let AltOrderSelect = [{
  254. return 1 + MF.getSubtarget<ARMSubtarget>().isThumb1Only();
  255. }];
  256. let DiagnosticString = "operand must be a register in range [r0, r14] or apsr_nzcv";
  257. }
  258. // GPRs without the SP register. Used for BXAUT and AUTG
  259. def GPRnosp : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12), LR, PC)> {
  260. let AltOrders = [(add LR, GPRnosp), (trunc GPRnosp, 8),
  261. (add (trunc GPRnosp, 8), R12, LR, (shl GPRnosp, 8))];
  262. let AltOrderSelect = [{
  263. return MF.getSubtarget<ARMSubtarget>().getGPRAllocationOrder(MF);
  264. }];
  265. let DiagnosticString = "operand must be a register in range [r0, r12] or LR or PC";
  266. }
  267. // GPRs without the PC and SP registers but with APSR. Used by CLRM instruction.
  268. def GPRwithAPSRnosp : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12), LR, APSR)> {
  269. let isAllocatable = 0;
  270. }
  271. def GPRwithZR : RegisterClass<"ARM", [i32], 32, (add (sub GPR, PC), ZR)> {
  272. let AltOrders = [(add LR, GPRwithZR), (trunc GPRwithZR, 8)];
  273. let AltOrderSelect = [{
  274. return 1 + MF.getSubtarget<ARMSubtarget>().isThumb1Only();
  275. }];
  276. let DiagnosticString = "operand must be a register in range [r0, r14] or zr";
  277. }
  278. def GPRwithZRnosp : RegisterClass<"ARM", [i32], 32, (sub GPRwithZR, SP)> {
  279. let AltOrders = [(add LR, GPRwithZRnosp), (trunc GPRwithZRnosp, 8)];
  280. let AltOrderSelect = [{
  281. return 1 + MF.getSubtarget<ARMSubtarget>().isThumb1Only();
  282. }];
  283. let DiagnosticString = "operand must be a register in range [r0, r12] or r14 or zr";
  284. }
  285. // GPRsp - Only the SP is legal. Used by Thumb1 instructions that want the
  286. // implied SP argument list.
  287. // FIXME: It would be better to not use this at all and refactor the
  288. // instructions to not have SP an an explicit argument. That makes
  289. // frame index resolution a bit trickier, though.
  290. def GPRsp : RegisterClass<"ARM", [i32], 32, (add SP)> {
  291. let DiagnosticString = "operand must be a register sp";
  292. }
  293. // GPRlr - Only LR is legal. Used by ARMv8.1-M Low Overhead Loop instructions
  294. // where LR is the only legal loop counter register.
  295. def GPRlr : RegisterClass<"ARM", [i32], 32, (add LR)>;
  296. // restricted GPR register class. Many Thumb2 instructions allow the full
  297. // register range for operands, but have undefined behaviours when PC
  298. // or SP (R13 or R15) are used. The ARM ISA refers to these operands
  299. // via the BadReg() pseudo-code description.
  300. def rGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, SP, PC)> {
  301. let AltOrders = [(add LR, rGPR), (trunc rGPR, 8),
  302. (add (trunc rGPR, 8), R12, LR, (shl rGPR, 8))];
  303. let AltOrderSelect = [{
  304. return MF.getSubtarget<ARMSubtarget>().getGPRAllocationOrder(MF);
  305. }];
  306. let DiagnosticType = "rGPR";
  307. }
  308. // GPRs without the PC and SP but with APSR_NZCV.Some instructions allow
  309. // accessing the APSR_NZCV, while actually encoding PC in the register field.
  310. // This is useful for assembly and disassembly only.
  311. // Currently used by the CDE extension.
  312. def GPRwithAPSR_NZCVnosp
  313. : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12), LR, APSR_NZCV)> {
  314. let isAllocatable = 0;
  315. let DiagnosticString =
  316. "operand must be a register in the range [r0, r12], r14 or apsr_nzcv";
  317. }
  318. // Thumb registers are R0-R7 normally. Some instructions can still use
  319. // the general GPR register class above (MOV, e.g.)
  320. def tGPR : RegisterClass<"ARM", [i32], 32, (trunc GPR, 8)> {
  321. let DiagnosticString = "operand must be a register in range [r0, r7]";
  322. }
  323. // Thumb registers R0-R7 and the PC. Some instructions like TBB or THH allow
  324. // the PC to be used as a destination operand as well.
  325. def tGPRwithpc : RegisterClass<"ARM", [i32], 32, (add tGPR, PC)>;
  326. // The high registers in thumb mode, R8-R15.
  327. def hGPR : RegisterClass<"ARM", [i32], 32, (sub GPR, tGPR)> {
  328. let DiagnosticString = "operand must be a register in range [r8, r15]";
  329. }
  330. // For tail calls, we can't use callee-saved registers, as they are restored
  331. // to the saved value before the tail call, which would clobber a call address.
  332. // Note, getMinimalPhysRegClass(R0) returns tGPR because of the names of
  333. // this class and the preceding one(!) This is what we want.
  334. def tcGPR : RegisterClass<"ARM", [i32], 32, (add R0, R1, R2, R3, R12)> {
  335. let AltOrders = [(and tcGPR, tGPR)];
  336. let AltOrderSelect = [{
  337. return MF.getSubtarget<ARMSubtarget>().isThumb1Only();
  338. }];
  339. }
  340. def tGPROdd : RegisterClass<"ARM", [i32], 32, (add R1, R3, R5, R7, R9, R11)> {
  341. let AltOrders = [(and tGPROdd, tGPR)];
  342. let AltOrderSelect = [{
  343. return MF.getSubtarget<ARMSubtarget>().isThumb1Only();
  344. }];
  345. let DiagnosticString =
  346. "operand must be an odd-numbered register in range [r1,r11]";
  347. }
  348. def tGPREven : RegisterClass<"ARM", [i32], 32, (add R0, R2, R4, R6, R8, R10, R12, LR)> {
  349. let AltOrders = [(and tGPREven, tGPR)];
  350. let AltOrderSelect = [{
  351. return MF.getSubtarget<ARMSubtarget>().isThumb1Only();
  352. }];
  353. let DiagnosticString = "operand must be an even-numbered register";
  354. }
  355. // Condition code registers.
  356. def CCR : RegisterClass<"ARM", [i32], 32, (add CPSR)> {
  357. let CopyCost = -1; // Don't allow copying of status registers.
  358. let isAllocatable = 0;
  359. }
  360. // MVE Condition code register.
  361. def VCCR : RegisterClass<"ARM", [i32, v16i1, v8i1, v4i1, v2i1], 32, (add VPR)> {
  362. // let CopyCost = -1; // Don't allow copying of status registers.
  363. }
  364. // FPSCR, when the flags at the top of it are used as the input or
  365. // output to an instruction such as MVE VADC.
  366. def cl_FPSCR_NZCV : RegisterClass<"ARM", [i32], 32, (add FPSCR_NZCV)>;
  367. // Scalar single precision floating point register class..
  368. // FIXME: Allocation order changed to s0, s2, ... or s0, s4, ... as a quick hack
  369. // to avoid partial-write dependencies on D or Q (depending on platform)
  370. // registers (S registers are renamed as portions of D/Q registers).
  371. def SPR : RegisterClass<"ARM", [f32], 32, (sequence "S%u", 0, 31)> {
  372. let AltOrders = [(add (decimate SPR, 2), SPR),
  373. (add (decimate SPR, 4),
  374. (decimate SPR, 2),
  375. (decimate (rotl SPR, 1), 4),
  376. (decimate (rotl SPR, 1), 2))];
  377. let AltOrderSelect = [{
  378. return 1 + MF.getSubtarget<ARMSubtarget>().useStride4VFPs();
  379. }];
  380. let DiagnosticString = "operand must be a register in range [s0, s31]";
  381. }
  382. def HPR : RegisterClass<"ARM", [f16, bf16], 32, (sequence "S%u", 0, 31)> {
  383. let AltOrders = [(add (decimate HPR, 2), SPR),
  384. (add (decimate HPR, 4),
  385. (decimate HPR, 2),
  386. (decimate (rotl HPR, 1), 4),
  387. (decimate (rotl HPR, 1), 2))];
  388. let AltOrderSelect = [{
  389. return 1 + MF.getSubtarget<ARMSubtarget>().useStride4VFPs();
  390. }];
  391. let DiagnosticString = "operand must be a register in range [s0, s31]";
  392. }
  393. // Subset of SPR which can be used as a source of NEON scalars for 16-bit
  394. // operations
  395. def SPR_8 : RegisterClass<"ARM", [f32], 32, (sequence "S%u", 0, 15)> {
  396. let DiagnosticString = "operand must be a register in range [s0, s15]";
  397. }
  398. // Scalar double precision floating point / generic 64-bit vector register
  399. // class.
  400. // ARM requires only word alignment for double. It's more performant if it
  401. // is double-word alignment though.
  402. def DPR : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32, v4f16, v4bf16], 64,
  403. (sequence "D%u", 0, 31)> {
  404. // Allocate non-VFP2 registers D16-D31 first, and prefer even registers on
  405. // Darwin platforms.
  406. let AltOrders = [(rotl DPR, 16),
  407. (add (decimate (rotl DPR, 16), 2), (rotl DPR, 16))];
  408. let AltOrderSelect = [{
  409. return 1 + MF.getSubtarget<ARMSubtarget>().useStride4VFPs();
  410. }];
  411. let DiagnosticType = "DPR";
  412. }
  413. // Scalar single and double precision floating point and VPR register class,
  414. // this is only used for parsing, don't use it anywhere else as the size and
  415. // types don't match!
  416. def FPWithVPR : RegisterClass<"ARM", [f32], 32, (add SPR, DPR, VPR)> {
  417. let isAllocatable = 0;
  418. }
  419. // Subset of DPR that are accessible with VFP2 (and so that also have
  420. // 32-bit SPR subregs).
  421. def DPR_VFP2 : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32, v4f16, v4bf16], 64,
  422. (trunc DPR, 16)> {
  423. let DiagnosticString = "operand must be a register in range [d0, d15]";
  424. }
  425. // Subset of DPR which can be used as a source of NEON scalars for 16-bit
  426. // operations
  427. def DPR_8 : RegisterClass<"ARM", [f64, v8i8, v4i16, v2i32, v1i64, v2f32, v4f16, v4bf16], 64,
  428. (trunc DPR, 8)> {
  429. let DiagnosticString = "operand must be a register in range [d0, d7]";
  430. }
  431. // Generic 128-bit vector register class.
  432. def QPR : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v8f16, v8bf16], 128,
  433. (sequence "Q%u", 0, 15)> {
  434. // Allocate non-VFP2 aliases Q8-Q15 first.
  435. let AltOrders = [(rotl QPR, 8), (trunc QPR, 8)];
  436. let AltOrderSelect = [{
  437. return 1 + MF.getSubtarget<ARMSubtarget>().hasMVEIntegerOps();
  438. }];
  439. let DiagnosticString = "operand must be a register in range [q0, q15]";
  440. }
  441. // Subset of QPR that have 32-bit SPR subregs.
  442. def QPR_VFP2 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
  443. 128, (trunc QPR, 8)> {
  444. let DiagnosticString = "operand must be a register in range [q0, q7]";
  445. }
  446. // Subset of QPR that have DPR_8 and SPR_8 subregs.
  447. def QPR_8 : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
  448. 128, (trunc QPR, 4)> {
  449. let DiagnosticString = "operand must be a register in range [q0, q3]";
  450. }
  451. // MVE 128-bit vector register class. This class is only really needed for
  452. // parsing assembly, since we still have to truncate the register set in the QPR
  453. // class anyway.
  454. def MQPR : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64, v8f16],
  455. 128, (trunc QPR, 8)>;
  456. // Pseudo-registers representing odd-even pairs of D registers. The even-odd
  457. // pairs are already represented by the Q registers.
  458. // These are needed by NEON instructions requiring two consecutive D registers.
  459. // There is no D31_D0 register as that is always an UNPREDICTABLE encoding.
  460. def TuplesOE2D : RegisterTuples<[dsub_0, dsub_1],
  461. [(decimate (shl DPR, 1), 2),
  462. (decimate (shl DPR, 2), 2)]>;
  463. // Register class representing a pair of consecutive D registers.
  464. // Use the Q registers for the even-odd pairs.
  465. def DPair : RegisterClass<"ARM", [v16i8, v8i16, v4i32, v2i64, v4f32, v2f64],
  466. 128, (interleave QPR, TuplesOE2D)> {
  467. // Allocate starting at non-VFP2 registers D16-D31 first.
  468. // Prefer even-odd pairs as they are easier to copy.
  469. let AltOrders = [(add (rotl QPR, 8), (rotl DPair, 16)),
  470. (add (trunc QPR, 8), (trunc DPair, 16))];
  471. let AltOrderSelect = [{
  472. return 1 + MF.getSubtarget<ARMSubtarget>().hasMVEIntegerOps();
  473. }];
  474. }
  475. // Pseudo-registers representing even-odd pairs of GPRs from R1 to R13/SP.
  476. // These are needed by instructions (e.g. ldrexd/strexd) requiring even-odd GPRs.
  477. def Tuples2Rnosp : RegisterTuples<[gsub_0, gsub_1],
  478. [(add R0, R2, R4, R6, R8, R10),
  479. (add R1, R3, R5, R7, R9, R11)]>;
  480. def Tuples2Rsp : RegisterTuples<[gsub_0, gsub_1],
  481. [(add R12), (add SP)]>;
  482. // Register class representing a pair of even-odd GPRs.
  483. def GPRPair : RegisterClass<"ARM", [untyped], 64, (add Tuples2Rnosp, Tuples2Rsp)> {
  484. let Size = 64; // 2 x 32 bits, we have no predefined type of that size.
  485. }
  486. // Register class representing a pair of even-odd GPRs, except (R12, SP).
  487. def GPRPairnosp : RegisterClass<"ARM", [untyped], 64, (add Tuples2Rnosp)> {
  488. let Size = 64; // 2 x 32 bits, we have no predefined type of that size.
  489. }
  490. // Pseudo-registers representing 3 consecutive D registers.
  491. def Tuples3D : RegisterTuples<[dsub_0, dsub_1, dsub_2],
  492. [(shl DPR, 0),
  493. (shl DPR, 1),
  494. (shl DPR, 2)]>;
  495. // 3 consecutive D registers.
  496. def DTriple : RegisterClass<"ARM", [untyped], 64, (add Tuples3D)> {
  497. let Size = 192; // 3 x 64 bits, we have no predefined type of that size.
  498. }
  499. // Pseudo 256-bit registers to represent pairs of Q registers. These should
  500. // never be present in the emitted code.
  501. // These are used for NEON load / store instructions, e.g., vld4, vst3.
  502. def Tuples2Q : RegisterTuples<[qsub_0, qsub_1], [(shl QPR, 0), (shl QPR, 1)]>;
  503. // Pseudo 256-bit vector register class to model pairs of Q registers
  504. // (4 consecutive D registers).
  505. def QQPR : RegisterClass<"ARM", [v4i64], 256, (add Tuples2Q)> {
  506. // Allocate non-VFP2 aliases first.
  507. let AltOrders = [(rotl QQPR, 8)];
  508. let AltOrderSelect = [{ return 1; }];
  509. }
  510. // Same as QQPR but for MVE, containing the 7 register pairs made up from Q0-Q7.
  511. def MQQPR : RegisterClass<"ARM", [v4i64], 256, (trunc QQPR, 7)>;
  512. // Tuples of 4 D regs that isn't also a pair of Q regs.
  513. def TuplesOE4D : RegisterTuples<[dsub_0, dsub_1, dsub_2, dsub_3],
  514. [(decimate (shl DPR, 1), 2),
  515. (decimate (shl DPR, 2), 2),
  516. (decimate (shl DPR, 3), 2),
  517. (decimate (shl DPR, 4), 2)]>;
  518. // 4 consecutive D registers.
  519. def DQuad : RegisterClass<"ARM", [v4i64], 256,
  520. (interleave Tuples2Q, TuplesOE4D)>;
  521. // Pseudo 512-bit registers to represent four consecutive Q registers.
  522. def Tuples2QQ : RegisterTuples<[qqsub_0, qqsub_1],
  523. [(shl QQPR, 0), (shl QQPR, 2)]>;
  524. // Pseudo 512-bit vector register class to model 4 consecutive Q registers
  525. // (8 consecutive D registers).
  526. def QQQQPR : RegisterClass<"ARM", [v8i64], 256, (add Tuples2QQ)> {
  527. // Allocate non-VFP2 aliases first.
  528. let AltOrders = [(rotl QQQQPR, 8)];
  529. let AltOrderSelect = [{ return 1; }];
  530. }
  531. // Same as QQPR but for MVE, containing the 5 register quads made up from Q0-Q7.
  532. def MQQQQPR : RegisterClass<"ARM", [v8i64], 256, (trunc QQQQPR, 5)>;
  533. // Pseudo-registers representing 2-spaced consecutive D registers.
  534. def Tuples2DSpc : RegisterTuples<[dsub_0, dsub_2],
  535. [(shl DPR, 0),
  536. (shl DPR, 2)]>;
  537. // Spaced pairs of D registers.
  538. def DPairSpc : RegisterClass<"ARM", [v2i64], 64, (add Tuples2DSpc)>;
  539. def Tuples3DSpc : RegisterTuples<[dsub_0, dsub_2, dsub_4],
  540. [(shl DPR, 0),
  541. (shl DPR, 2),
  542. (shl DPR, 4)]>;
  543. // Spaced triples of D registers.
  544. def DTripleSpc : RegisterClass<"ARM", [untyped], 64, (add Tuples3DSpc)> {
  545. let Size = 192; // 3 x 64 bits, we have no predefined type of that size.
  546. }
  547. def Tuples4DSpc : RegisterTuples<[dsub_0, dsub_2, dsub_4, dsub_6],
  548. [(shl DPR, 0),
  549. (shl DPR, 2),
  550. (shl DPR, 4),
  551. (shl DPR, 6)]>;
  552. // Spaced quads of D registers.
  553. def DQuadSpc : RegisterClass<"ARM", [v4i64], 64, (add Tuples3DSpc)>;
  554. // FP context payload
  555. def FPCXTRegs : RegisterClass<"ARM", [i32], 32, (add FPCXTNS)>;