• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1//===- AArch64RegisterInfo.td - ARM Register defs ----------*- tablegen -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file contains declarations that describe the AArch64 register file
11//
12//===----------------------------------------------------------------------===//
13
14let Namespace = "AArch64" in {
15def sub_128 : SubRegIndex;
16def sub_64 : SubRegIndex;
17def sub_32 : SubRegIndex;
18def sub_16 : SubRegIndex;
19def sub_8  : SubRegIndex;
20
21// The VPR registers are handled as sub-registers of FPR equivalents, but
22// they're really the same thing. We give this concept a special index.
23def sub_alias : SubRegIndex;
24}
25
26// Registers are identified with 5-bit ID numbers.
27class AArch64Reg<bits<16> enc, string n> : Register<n> {
28  let HWEncoding = enc;
29  let Namespace = "AArch64";
30}
31
32class AArch64RegWithSubs<bits<16> enc, string n, list<Register> subregs = [],
33                         list<SubRegIndex> inds = []>
34      : AArch64Reg<enc, n> {
35  let SubRegs = subregs;
36  let SubRegIndices = inds;
37}
38
39//===----------------------------------------------------------------------===//
40//  Integer registers: w0-w30, wzr, wsp, x0-x30, xzr, sp
41//===----------------------------------------------------------------------===//
42
43foreach Index = 0-30 in {
44  def W#Index : AArch64Reg< Index, "w"#Index>, DwarfRegNum<[Index]>;
45}
46
47def WSP : AArch64Reg<31, "wsp">, DwarfRegNum<[31]>;
48def WZR : AArch64Reg<31, "wzr">;
49
50// Could be combined with previous loop, but this way leaves w and x registers
51// consecutive as LLVM register numbers, which makes for easier debugging.
52foreach Index = 0-30 in {
53  def X#Index : AArch64RegWithSubs<Index, "x"#Index,
54                                   [!cast<Register>("W"#Index)], [sub_32]>,
55                DwarfRegNum<[Index]>;
56}
57
58def XSP : AArch64RegWithSubs<31, "sp", [WSP], [sub_32]>, DwarfRegNum<[31]>;
59def XZR : AArch64RegWithSubs<31, "xzr", [WZR], [sub_32]>;
60
61// Most instructions treat register 31 as zero for reads and a black-hole for
62// writes.
63
64// Note that the order of registers is important for the Disassembler here:
65// tablegen uses it to form MCRegisterClass::getRegister, which we assume can
66// take an encoding value.
67def GPR32 : RegisterClass<"AArch64", [i32], 32,
68                          (add (sequence "W%u", 0, 30), WZR)> {
69}
70
71def GPR64 : RegisterClass<"AArch64", [i64], 64,
72                          (add (sequence "X%u", 0, 30), XZR)> {
73}
74
75def GPR32nowzr : RegisterClass<"AArch64", [i32], 32,
76                               (sequence "W%u", 0, 30)> {
77}
78
79def GPR64noxzr : RegisterClass<"AArch64", [i64], 64,
80                               (sequence "X%u", 0, 30)> {
81}
82
83// For tail calls, we can't use callee-saved registers or the structure-return
84// register, as they are supposed to be live across function calls and may be
85// clobbered by the epilogue.
86def tcGPR64 : RegisterClass<"AArch64", [i64], 64,
87                            (add (sequence "X%u", 0, 7),
88                                 (sequence "X%u", 9, 18))> {
89}
90
91
92// Certain addressing-useful instructions accept sp directly. Again the order of
93// registers is important to the Disassembler.
94def GPR32wsp : RegisterClass<"AArch64", [i32], 32,
95                             (add (sequence "W%u", 0, 30), WSP)> {
96}
97
98def GPR64xsp : RegisterClass<"AArch64", [i64], 64,
99                             (add (sequence "X%u", 0, 30), XSP)> {
100}
101
102// Some aliases *only* apply to SP (e.g. MOV uses different encoding for SP and
103// non-SP variants). We can't use a bare register in those patterns because
104// TableGen doesn't like it, so we need a class containing just stack registers
105def Rxsp : RegisterClass<"AArch64", [i64], 64,
106                         (add XSP)> {
107}
108
109def Rwsp : RegisterClass<"AArch64", [i32], 32,
110                         (add WSP)> {
111}
112
113//===----------------------------------------------------------------------===//
114//  Scalar registers in the vector unit:
115//  b0-b31, h0-h31, s0-s31, d0-d31, q0-q31
116//===----------------------------------------------------------------------===//
117
118foreach Index = 0-31 in {
119  def B # Index : AArch64Reg< Index, "b" # Index>,
120                  DwarfRegNum<[!add(Index, 64)]>;
121
122  def H # Index : AArch64RegWithSubs<Index, "h" # Index,
123                                     [!cast<Register>("B" # Index)], [sub_8]>,
124                  DwarfRegNum<[!add(Index, 64)]>;
125
126  def S # Index : AArch64RegWithSubs<Index, "s" # Index,
127                                     [!cast<Register>("H" # Index)], [sub_16]>,
128                  DwarfRegNum<[!add(Index, 64)]>;
129
130  def D # Index : AArch64RegWithSubs<Index, "d" # Index,
131                                     [!cast<Register>("S" # Index)], [sub_32]>,
132                  DwarfRegNum<[!add(Index, 64)]>;
133
134  def Q # Index : AArch64RegWithSubs<Index, "q" # Index,
135                                     [!cast<Register>("D" # Index)], [sub_64]>,
136                  DwarfRegNum<[!add(Index, 64)]>;
137}
138
139
140def FPR8 : RegisterClass<"AArch64", [i8], 8,
141                          (sequence "B%u", 0, 31)> {
142}
143
144def FPR16 : RegisterClass<"AArch64", [f16], 16,
145                          (sequence "H%u", 0, 31)> {
146}
147
148def FPR32 : RegisterClass<"AArch64", [f32], 32,
149                          (sequence "S%u", 0, 31)> {
150}
151
152def FPR64 : RegisterClass<"AArch64", [f64], 64,
153                          (sequence "D%u", 0, 31)> {
154}
155
156def FPR128 : RegisterClass<"AArch64", [f128], 128,
157                          (sequence "Q%u", 0, 31)> {
158}
159
160
161//===----------------------------------------------------------------------===//
162//  Vector registers:
163//===----------------------------------------------------------------------===//
164
165// NEON registers simply specify the overall vector, and it's expected that
166// Instructions will individually specify the acceptable data layout. In
167// principle this leaves two approaches open:
168//   + An operand, giving a single ADDvvv instruction (for example). This turns
169//     out to be unworkable in the assembly parser (without every Instruction
170//     having a "cvt" function, at least) because the constraints can't be
171//     properly enforced. It also complicates specifying patterns since each
172//     instruction will accept many types.
173//  + A bare token (e.g. ".2d"). This means the AsmParser has to know specific
174//    details about NEON registers, but simplifies most other details.
175//
176// The second approach was taken.
177
178foreach Index = 0-31 in {
179  def V # Index  : AArch64RegWithSubs<Index, "v" # Index,
180                                      [!cast<Register>("Q" # Index)],
181                                      [sub_alias]>,
182            DwarfRegNum<[!add(Index, 64)]>;
183}
184
185// These two classes contain the same registers, which should be reasonably
186// sensible for MC and allocation purposes, but allows them to be treated
187// separately for things like stack spilling.
188def VPR64 : RegisterClass<"AArch64", [v2f32, v2i32, v4i16, v8i8], 64,
189                          (sequence "V%u", 0, 31)>;
190
191def VPR128 : RegisterClass<"AArch64",
192                           [v2f64, v2i64, v4f32, v4i32, v8i16, v16i8], 128,
193                           (sequence "V%u", 0, 31)>;
194
195// Flags register
196def NZCV : Register<"nzcv"> {
197  let Namespace = "AArch64";
198}
199
200def FlagClass : RegisterClass<"AArch64", [i32], 32, (add NZCV)> {
201  let CopyCost = -1;
202  let isAllocatable = 0;
203}
204