AArch64RegisterInfo.td revision 249259
1249259Sdim//===- AArch64RegisterInfo.td - ARM Register defs ----------*- tablegen -*-===//
2249259Sdim//
3249259Sdim//                     The LLVM Compiler Infrastructure
4249259Sdim//
5249259Sdim// This file is distributed under the University of Illinois Open Source
6249259Sdim// License. See LICENSE.TXT for details.
7249259Sdim//
8249259Sdim//===----------------------------------------------------------------------===//
9249259Sdim//
10249259Sdim//  This file contains declarations that describe the AArch64 register file
11249259Sdim//
12249259Sdim//===----------------------------------------------------------------------===//
13249259Sdim
14249259Sdimlet Namespace = "AArch64" in {
15249259Sdimdef sub_128 : SubRegIndex;
16249259Sdimdef sub_64 : SubRegIndex;
17249259Sdimdef sub_32 : SubRegIndex;
18249259Sdimdef sub_16 : SubRegIndex;
19249259Sdimdef sub_8  : SubRegIndex;
20249259Sdim
21249259Sdim// The VPR registers are handled as sub-registers of FPR equivalents, but
22249259Sdim// they're really the same thing. We give this concept a special index.
23249259Sdimdef sub_alias : SubRegIndex;
24249259Sdim}
25249259Sdim
26249259Sdim// Registers are identified with 5-bit ID numbers.
27249259Sdimclass AArch64Reg<bits<16> enc, string n> : Register<n> {
28249259Sdim  let HWEncoding = enc;
29249259Sdim  let Namespace = "AArch64";
30249259Sdim}
31249259Sdim
32249259Sdimclass AArch64RegWithSubs<bits<16> enc, string n, list<Register> subregs = [],
33249259Sdim                         list<SubRegIndex> inds = []>
34249259Sdim      : AArch64Reg<enc, n> {
35249259Sdim  let SubRegs = subregs;
36249259Sdim  let SubRegIndices = inds;
37249259Sdim}
38249259Sdim
39249259Sdim//===----------------------------------------------------------------------===//
40249259Sdim//  Integer registers: w0-w30, wzr, wsp, x0-x30, xzr, sp
41249259Sdim//===----------------------------------------------------------------------===//
42249259Sdim
43249259Sdimforeach Index = 0-30 in {
44249259Sdim  def W#Index : AArch64Reg< Index, "w"#Index>, DwarfRegNum<[Index]>;
45249259Sdim}
46249259Sdim
47249259Sdimdef WSP : AArch64Reg<31, "wsp">, DwarfRegNum<[31]>;
48249259Sdimdef WZR : AArch64Reg<31, "wzr">;
49249259Sdim
50249259Sdim// Could be combined with previous loop, but this way leaves w and x registers
51249259Sdim// consecutive as LLVM register numbers, which makes for easier debugging.
52249259Sdimforeach Index = 0-30 in {
53249259Sdim  def X#Index : AArch64RegWithSubs<Index, "x"#Index,
54249259Sdim                                   [!cast<Register>("W"#Index)], [sub_32]>,
55249259Sdim                DwarfRegNum<[Index]>;
56249259Sdim}
57249259Sdim
58249259Sdimdef XSP : AArch64RegWithSubs<31, "sp", [WSP], [sub_32]>, DwarfRegNum<[31]>;
59249259Sdimdef XZR : AArch64RegWithSubs<31, "xzr", [WZR], [sub_32]>;
60249259Sdim
61249259Sdim// Most instructions treat register 31 as zero for reads and a black-hole for
62249259Sdim// writes.
63249259Sdim
64249259Sdim// Note that the order of registers is important for the Disassembler here:
65249259Sdim// tablegen uses it to form MCRegisterClass::getRegister, which we assume can
66249259Sdim// take an encoding value.
67249259Sdimdef GPR32 : RegisterClass<"AArch64", [i32], 32,
68249259Sdim                          (add (sequence "W%u", 0, 30), WZR)> {
69249259Sdim}
70249259Sdim
71249259Sdimdef GPR64 : RegisterClass<"AArch64", [i64], 64,
72249259Sdim                          (add (sequence "X%u", 0, 30), XZR)> {
73249259Sdim}
74249259Sdim
75249259Sdimdef GPR32nowzr : RegisterClass<"AArch64", [i32], 32,
76249259Sdim                               (sequence "W%u", 0, 30)> {
77249259Sdim}
78249259Sdim
79249259Sdimdef GPR64noxzr : RegisterClass<"AArch64", [i64], 64,
80249259Sdim                               (sequence "X%u", 0, 30)> {
81249259Sdim}
82249259Sdim
83249259Sdim// For tail calls, we can't use callee-saved registers or the structure-return
84249259Sdim// register, as they are supposed to be live across function calls and may be
85249259Sdim// clobbered by the epilogue.
86249259Sdimdef tcGPR64 : RegisterClass<"AArch64", [i64], 64,
87249259Sdim                            (add (sequence "X%u", 0, 7),
88249259Sdim                                 (sequence "X%u", 9, 18))> {
89249259Sdim}
90249259Sdim
91249259Sdim
92249259Sdim// Certain addressing-useful instructions accept sp directly. Again the order of
93249259Sdim// registers is important to the Disassembler.
94249259Sdimdef GPR32wsp : RegisterClass<"AArch64", [i32], 32,
95249259Sdim                             (add (sequence "W%u", 0, 30), WSP)> {
96249259Sdim}
97249259Sdim
98249259Sdimdef GPR64xsp : RegisterClass<"AArch64", [i64], 64,
99249259Sdim                             (add (sequence "X%u", 0, 30), XSP)> {
100249259Sdim}
101249259Sdim
102249259Sdim// Some aliases *only* apply to SP (e.g. MOV uses different encoding for SP and
103249259Sdim// non-SP variants). We can't use a bare register in those patterns because
104249259Sdim// TableGen doesn't like it, so we need a class containing just stack registers
105249259Sdimdef Rxsp : RegisterClass<"AArch64", [i64], 64,
106249259Sdim                         (add XSP)> {
107249259Sdim}
108249259Sdim
109249259Sdimdef Rwsp : RegisterClass<"AArch64", [i32], 32,
110249259Sdim                         (add WSP)> {
111249259Sdim}
112249259Sdim
113249259Sdim//===----------------------------------------------------------------------===//
114249259Sdim//  Scalar registers in the vector unit:
115249259Sdim//  b0-b31, h0-h31, s0-s31, d0-d31, q0-q31
116249259Sdim//===----------------------------------------------------------------------===//
117249259Sdim
118249259Sdimforeach Index = 0-31 in {
119249259Sdim  def B # Index : AArch64Reg< Index, "b" # Index>,
120249259Sdim                  DwarfRegNum<[!add(Index, 64)]>;
121249259Sdim
122249259Sdim  def H # Index : AArch64RegWithSubs<Index, "h" # Index,
123249259Sdim                                     [!cast<Register>("B" # Index)], [sub_8]>,
124249259Sdim                  DwarfRegNum<[!add(Index, 64)]>;
125249259Sdim
126249259Sdim  def S # Index : AArch64RegWithSubs<Index, "s" # Index,
127249259Sdim                                     [!cast<Register>("H" # Index)], [sub_16]>,
128249259Sdim                  DwarfRegNum<[!add(Index, 64)]>;
129249259Sdim
130249259Sdim  def D # Index : AArch64RegWithSubs<Index, "d" # Index,
131249259Sdim                                     [!cast<Register>("S" # Index)], [sub_32]>,
132249259Sdim                  DwarfRegNum<[!add(Index, 64)]>;
133249259Sdim
134249259Sdim  def Q # Index : AArch64RegWithSubs<Index, "q" # Index,
135249259Sdim                                     [!cast<Register>("D" # Index)], [sub_64]>,
136249259Sdim                  DwarfRegNum<[!add(Index, 64)]>;
137249259Sdim}
138249259Sdim
139249259Sdim
140249259Sdimdef FPR8 : RegisterClass<"AArch64", [i8], 8,
141249259Sdim                          (sequence "B%u", 0, 31)> {
142249259Sdim}
143249259Sdim
144249259Sdimdef FPR16 : RegisterClass<"AArch64", [f16], 16,
145249259Sdim                          (sequence "H%u", 0, 31)> {
146249259Sdim}
147249259Sdim
148249259Sdimdef FPR32 : RegisterClass<"AArch64", [f32], 32,
149249259Sdim                          (sequence "S%u", 0, 31)> {
150249259Sdim}
151249259Sdim
152249259Sdimdef FPR64 : RegisterClass<"AArch64", [f64], 64,
153249259Sdim                          (sequence "D%u", 0, 31)> {
154249259Sdim}
155249259Sdim
156249259Sdimdef FPR128 : RegisterClass<"AArch64", [f128], 128,
157249259Sdim                          (sequence "Q%u", 0, 31)> {
158249259Sdim}
159249259Sdim
160249259Sdim
161249259Sdim//===----------------------------------------------------------------------===//
162249259Sdim//  Vector registers:
163249259Sdim//===----------------------------------------------------------------------===//
164249259Sdim
165249259Sdim// NEON registers simply specify the overall vector, and it's expected that
166249259Sdim// Instructions will individually specify the acceptable data layout. In
167249259Sdim// principle this leaves two approaches open:
168249259Sdim//   + An operand, giving a single ADDvvv instruction (for example). This turns
169249259Sdim//     out to be unworkable in the assembly parser (without every Instruction
170249259Sdim//     having a "cvt" function, at least) because the constraints can't be
171249259Sdim//     properly enforced. It also complicates specifying patterns since each
172249259Sdim//     instruction will accept many types.
173249259Sdim//  + A bare token (e.g. ".2d"). This means the AsmParser has to know specific
174249259Sdim//    details about NEON registers, but simplifies most other details.
175249259Sdim//
176249259Sdim// The second approach was taken.
177249259Sdim
178249259Sdimforeach Index = 0-31 in {
179249259Sdim  def V # Index  : AArch64RegWithSubs<Index, "v" # Index,
180249259Sdim                                      [!cast<Register>("Q" # Index)],
181249259Sdim                                      [sub_alias]>,
182249259Sdim            DwarfRegNum<[!add(Index, 64)]>;
183249259Sdim}
184249259Sdim
185249259Sdim// These two classes contain the same registers, which should be reasonably
186249259Sdim// sensible for MC and allocation purposes, but allows them to be treated
187249259Sdim// separately for things like stack spilling.
188249259Sdimdef VPR64 : RegisterClass<"AArch64", [v2f32, v2i32, v4i16, v8i8], 64,
189249259Sdim                          (sequence "V%u", 0, 31)>;
190249259Sdim
191249259Sdimdef VPR128 : RegisterClass<"AArch64",
192249259Sdim                           [v2f64, v2i64, v4f32, v4i32, v8i16, v16i8], 128,
193249259Sdim                           (sequence "V%u", 0, 31)>;
194249259Sdim
195249259Sdim// Flags register
196249259Sdimdef NZCV : Register<"nzcv"> {
197249259Sdim  let Namespace = "AArch64";
198249259Sdim}
199249259Sdim
200249259Sdimdef FlagClass : RegisterClass<"AArch64", [i32], 32, (add NZCV)> {
201249259Sdim  let CopyCost = -1;
202249259Sdim  let isAllocatable = 0;
203249259Sdim}
204