AArch64RegisterInfo.td revision 263508
1239281Sgonzo//===- AArch64RegisterInfo.td - ARM Register defs ----------*- tablegen -*-===//
2239281Sgonzo//
3239281Sgonzo//                     The LLVM Compiler Infrastructure
4239281Sgonzo//
5239281Sgonzo// This file is distributed under the University of Illinois Open Source
6239281Sgonzo// License. See LICENSE.TXT for details.
7239281Sgonzo//
8239281Sgonzo//===----------------------------------------------------------------------===//
9239281Sgonzo//
10239281Sgonzo//  This file contains declarations that describe the AArch64 register file
11239281Sgonzo//
12239281Sgonzo//===----------------------------------------------------------------------===//
13239281Sgonzo
14239281Sgonzolet Namespace = "AArch64" in {
15239281Sgonzodef sub_128 : SubRegIndex<128>;
16239281Sgonzodef sub_64 : SubRegIndex<64>;
17239281Sgonzodef sub_32 : SubRegIndex<32>;
18239281Sgonzodef sub_16 : SubRegIndex<16>;
19239281Sgonzodef sub_8  : SubRegIndex<8>;
20239281Sgonzo
21239281Sgonzo// Note: Code depends on these having consecutive numbers.
22239281Sgonzodef qqsub : SubRegIndex<256, 256>;
23239281Sgonzo
24239281Sgonzodef qsub_0 : SubRegIndex<128>;
25239281Sgonzodef qsub_1 : SubRegIndex<128, 128>;
26239281Sgonzodef qsub_2 : ComposedSubRegIndex<qqsub, qsub_0>;
27239281Sgonzodef qsub_3 : ComposedSubRegIndex<qqsub, qsub_1>;
28239281Sgonzo
29239281Sgonzodef dsub_0 : SubRegIndex<64>;
30239281Sgonzodef dsub_1 : SubRegIndex<64, 64>;
31239281Sgonzodef dsub_2 : ComposedSubRegIndex<qsub_1, dsub_0>;
32239281Sgonzodef dsub_3 : ComposedSubRegIndex<qsub_1, dsub_1>;
33239281Sgonzodef dsub_4 : ComposedSubRegIndex<qsub_2, dsub_0>;
34278079Sloos}
35239281Sgonzo
36239281Sgonzo// Registers are identified with 5-bit ID numbers.
37239281Sgonzoclass AArch64Reg<bits<16> enc, string n> : Register<n> {
38239281Sgonzo  let HWEncoding = enc;
39239281Sgonzo  let Namespace = "AArch64";
40278079Sloos}
41239281Sgonzo
42239281Sgonzoclass AArch64RegWithSubs<bits<16> enc, string n, list<Register> subregs = [],
43239281Sgonzo                         list<SubRegIndex> inds = []>
44239281Sgonzo      : AArch64Reg<enc, n> {
45239281Sgonzo  let SubRegs = subregs;
46239281Sgonzo  let SubRegIndices = inds;
47239281Sgonzo}
48239281Sgonzo
49239281Sgonzo//===----------------------------------------------------------------------===//
50239281Sgonzo//  Integer registers: w0-w30, wzr, wsp, x0-x30, xzr, sp
51278079Sloos//===----------------------------------------------------------------------===//
52278079Sloos
53239281Sgonzoforeach Index = 0-30 in {
54239281Sgonzo  def W#Index : AArch64Reg< Index, "w"#Index>, DwarfRegNum<[Index]>;
55239281Sgonzo}
56239281Sgonzo
57253025Sgonzodef WSP : AArch64Reg<31, "wsp">, DwarfRegNum<[31]>;
58253025Sgonzodef WZR : AArch64Reg<31, "wzr">;
59239281Sgonzo
60239281Sgonzo// Could be combined with previous loop, but this way leaves w and x registers
61239281Sgonzo// consecutive as LLVM register numbers, which makes for easier debugging.
62239281Sgonzoforeach Index = 0-30 in {
63278079Sloos  def X#Index : AArch64RegWithSubs<Index, "x"#Index,
64278079Sloos                                   [!cast<Register>("W"#Index)], [sub_32]>,
65278079Sloos                DwarfRegNum<[Index]>;
66278079Sloos}
67239281Sgonzo
68239281Sgonzodef XSP : AArch64RegWithSubs<31, "sp", [WSP], [sub_32]>, DwarfRegNum<[31]>;
69239281Sgonzodef XZR : AArch64RegWithSubs<31, "xzr", [WZR], [sub_32]>;
70239281Sgonzo
71239281Sgonzo// Most instructions treat register 31 as zero for reads and a black-hole for
72239281Sgonzo// writes.
73239281Sgonzo
74239281Sgonzo// Note that the order of registers is important for the Disassembler here:
75239281Sgonzo// tablegen uses it to form MCRegisterClass::getRegister, which we assume can
76239281Sgonzo// take an encoding value.
77278079Sloosdef GPR32 : RegisterClass<"AArch64", [i32], 32,
78278079Sloos                          (add (sequence "W%u", 0, 30), WZR)> {
79239281Sgonzo}
80239281Sgonzo
81239281Sgonzodef GPR64 : RegisterClass<"AArch64", [i64], 64,
82239281Sgonzo                          (add (sequence "X%u", 0, 30), XZR)> {
83239281Sgonzo}
84239281Sgonzo
85239281Sgonzodef GPR32nowzr : RegisterClass<"AArch64", [i32], 32,
86239281Sgonzo                               (sequence "W%u", 0, 30)> {
87239281Sgonzo}
88239281Sgonzo
89239281Sgonzodef GPR64noxzr : RegisterClass<"AArch64", [i64], 64,
90239281Sgonzo                               (sequence "X%u", 0, 30)> {
91239281Sgonzo}
92239281Sgonzo
93239281Sgonzo// For tail calls, we can't use callee-saved registers or the structure-return
94239281Sgonzo// register, as they are supposed to be live across function calls and may be
95239281Sgonzo// clobbered by the epilogue.
96239281Sgonzodef tcGPR64 : RegisterClass<"AArch64", [i64], 64,
97239281Sgonzo                            (add (sequence "X%u", 0, 7),
98239281Sgonzo                                 (sequence "X%u", 9, 18))> {
99239281Sgonzo}
100239281Sgonzo
101239281Sgonzo
102239281Sgonzo// Certain addressing-useful instructions accept sp directly. Again the order of
103239281Sgonzo// registers is important to the Disassembler.
104239281Sgonzodef GPR32wsp : RegisterClass<"AArch64", [i32], 32,
105239281Sgonzo                             (add (sequence "W%u", 0, 30), WSP)> {
106239281Sgonzo}
107239281Sgonzo
108239281Sgonzodef GPR64xsp : RegisterClass<"AArch64", [i64], 64,
109239281Sgonzo                             (add (sequence "X%u", 0, 30), XSP)> {
110239281Sgonzo}
111239281Sgonzo
112239281Sgonzo// Some aliases *only* apply to SP (e.g. MOV uses different encoding for SP and
113239281Sgonzo// non-SP variants). We can't use a bare register in those patterns because
114239281Sgonzo// TableGen doesn't like it, so we need a class containing just stack registers
115239281Sgonzodef Rxsp : RegisterClass<"AArch64", [i64], 64,
116239281Sgonzo                         (add XSP)> {
117239281Sgonzo}
118239281Sgonzo
119239281Sgonzodef Rwsp : RegisterClass<"AArch64", [i32], 32,
120239281Sgonzo                         (add WSP)> {
121239281Sgonzo}
122239281Sgonzo
123239281Sgonzo//===----------------------------------------------------------------------===//
124239281Sgonzo//  Scalar registers in the vector unit:
125239281Sgonzo//  b0-b31, h0-h31, s0-s31, d0-d31, q0-q31
126239281Sgonzo//===----------------------------------------------------------------------===//
127239281Sgonzo
128239281Sgonzoforeach Index = 0-31 in {
129239281Sgonzo  def B # Index : AArch64Reg< Index, "b" # Index>,
130239281Sgonzo                  DwarfRegNum<[!add(Index, 64)]>;
131239281Sgonzo
132239281Sgonzo  def H # Index : AArch64RegWithSubs<Index, "h" # Index,
133239281Sgonzo                                     [!cast<Register>("B" # Index)], [sub_8]>,
134239281Sgonzo                  DwarfRegNum<[!add(Index, 64)]>;
135239281Sgonzo
136239281Sgonzo  def S # Index : AArch64RegWithSubs<Index, "s" # Index,
137239281Sgonzo                                     [!cast<Register>("H" # Index)], [sub_16]>,
138239281Sgonzo                  DwarfRegNum<[!add(Index, 64)]>;
139239281Sgonzo
140239281Sgonzo  def D # Index : AArch64RegWithSubs<Index, "d" # Index,
141239281Sgonzo                                     [!cast<Register>("S" # Index)], [sub_32]>,
142239281Sgonzo                  DwarfRegNum<[!add(Index, 64)]>;
143239281Sgonzo
144253025Sgonzo  def Q # Index : AArch64RegWithSubs<Index, "q" # Index,
145253025Sgonzo                                     [!cast<Register>("D" # Index)], [sub_64]>,
146253025Sgonzo                  DwarfRegNum<[!add(Index, 64)]>;
147253025Sgonzo}
148253025Sgonzo
149253025Sgonzo
150239281Sgonzodef FPR8 : RegisterClass<"AArch64", [i8, v1i8], 8,
151239281Sgonzo                          (sequence "B%u", 0, 31)> {
152239281Sgonzo}
153239281Sgonzo
154239281Sgonzodef FPR16 : RegisterClass<"AArch64", [f16, v1i16], 16,
155239281Sgonzo                          (sequence "H%u", 0, 31)> {
156239281Sgonzo}
157278079Sloos
158278079Sloosdef FPR32 : RegisterClass<"AArch64", [f32, v1i32, v1f32], 32,
159278079Sloos                          (sequence "S%u", 0, 31)> {
160239281Sgonzo}
161239281Sgonzo
162239281Sgonzodef FPR64 : RegisterClass<"AArch64",
163239281Sgonzo                          [f64, v2f32, v2i32, v4i16, v8i8, v1i64, v1f64],
164239281Sgonzo                          64, (sequence "D%u", 0, 31)>;
165239281Sgonzo
166239281Sgonzodef FPR128 : RegisterClass<"AArch64",
167239281Sgonzo                           [f128, v2f64, v2i64, v4f32, v4i32, v8i16, v16i8],
168239281Sgonzo                           128, (sequence "Q%u", 0, 31)>;
169239281Sgonzo
170239281Sgonzodef FPR64Lo : RegisterClass<"AArch64",
171239281Sgonzo                            [f64, v2f32, v2i32, v4i16, v8i8, v1i64, v1f64],
172239281Sgonzo                            64, (sequence "D%u", 0, 15)>;
173239281Sgonzo
174239281Sgonzodef FPR128Lo : RegisterClass<"AArch64",
175239281Sgonzo                             [f128, v2f64, v2i64, v4f32, v4i32, v8i16, v16i8],
176239281Sgonzo                             128, (sequence "Q%u", 0, 15)>;
177239281Sgonzo
178239281Sgonzo//===----------------------------------------------------------------------===//
179278079Sloos//  Vector registers:
180278079Sloos//===----------------------------------------------------------------------===//
181278079Sloos
182278079Sloosdef VPR64AsmOperand : AsmOperandClass {
183278079Sloos  let Name = "VPR";
184278079Sloos  let PredicateMethod = "isReg";
185278079Sloos  let RenderMethod = "addRegOperands";
186278079Sloos}
187278079Sloos
188278079Sloosdef VPR64 : RegisterOperand<FPR64, "printVPRRegister">;
189278079Sloos
190278079Sloosdef VPR128 : RegisterOperand<FPR128, "printVPRRegister">;
191278079Sloos
192278079Sloosdef VPR64Lo : RegisterOperand<FPR64Lo, "printVPRRegister">;
193278079Sloos
194278079Sloosdef VPR128Lo : RegisterOperand<FPR128Lo, "printVPRRegister">;
195239281Sgonzo
196239281Sgonzo// Flags register
197239281Sgonzodef NZCV : Register<"nzcv"> {
198239281Sgonzo  let Namespace = "AArch64";
199239281Sgonzo}
200239281Sgonzo
201239281Sgonzodef FlagClass : RegisterClass<"AArch64", [i32], 32, (add NZCV)> {
202239281Sgonzo  let CopyCost = -1;
203239281Sgonzo  let isAllocatable = 0;
204239281Sgonzo}
205239281Sgonzo
206239281Sgonzo//===----------------------------------------------------------------------===//
207239281Sgonzo//  Consecutive vector registers
208239281Sgonzo//===----------------------------------------------------------------------===//
209239281Sgonzo// 2 Consecutive 64-bit registers: D0_D1, D1_D2, ..., D30_D31
210239281Sgonzodef Tuples2D : RegisterTuples<[dsub_0, dsub_1],
211239281Sgonzo                              [(rotl FPR64, 0), (rotl FPR64, 1)]>;
212                              
213// 3 Consecutive 64-bit registers: D0_D1_D2, ..., D31_D0_D1
214def Tuples3D : RegisterTuples<[dsub_0, dsub_1, dsub_2],
215                              [(rotl FPR64, 0), (rotl FPR64, 1),
216                               (rotl FPR64, 2)]>;
217                               
218// 4 Consecutive 64-bit registers: D0_D1_D2_D3, ..., D31_D0_D1_D2
219def Tuples4D : RegisterTuples<[dsub_0, dsub_1, dsub_2, dsub_3],
220                              [(rotl FPR64, 0), (rotl FPR64, 1),
221                               (rotl FPR64, 2), (rotl FPR64, 3)]>;
222
223// 2 Consecutive 128-bit registers: Q0_Q1, Q1_Q2, ..., Q30_Q31
224def Tuples2Q : RegisterTuples<[qsub_0, qsub_1],
225                              [(rotl FPR128, 0), (rotl FPR128, 1)]>;
226
227// 3 Consecutive 128-bit registers: Q0_Q1_Q2, ..., Q31_Q0_Q1
228def Tuples3Q : RegisterTuples<[qsub_0, qsub_1, qsub_2],
229                              [(rotl FPR128, 0), (rotl FPR128, 1),
230                               (rotl FPR128, 2)]>;
231                               
232// 4 Consecutive 128-bit registers: Q0_Q1_Q2_Q3, ..., Q31_Q0_Q1_Q2
233def Tuples4Q : RegisterTuples<[qsub_0, qsub_1, qsub_2, qsub_3],
234                              [(rotl FPR128, 0), (rotl FPR128, 1),
235                               (rotl FPR128, 2), (rotl FPR128, 3)]>;
236
237// The followings are super register classes to model 2/3/4 consecutive
238// 64-bit/128-bit registers.
239
240def DPair : RegisterClass<"AArch64", [v2i64], 64, (add Tuples2D)>;
241
242def DTriple : RegisterClass<"AArch64", [untyped], 64, (add Tuples3D)> {
243  let Size = 192; // 3 x 64 bits, we have no predefined type of that size.
244}
245
246def DQuad : RegisterClass<"AArch64", [v4i64], 64, (add Tuples4D)>;
247
248def QPair : RegisterClass<"AArch64", [v4i64], 128, (add Tuples2Q)>;
249
250def QTriple : RegisterClass<"AArch64", [untyped], 128, (add Tuples3Q)> {
251  let Size = 384; // 3 x 128 bits, we have no predefined type of that size.
252}
253
254def QQuad : RegisterClass<"AArch64", [v8i64], 128, (add Tuples4Q)>;
255
256
257// The followings are vector list operands
258multiclass VectorList_operands<string PREFIX, string LAYOUT, int Count,
259                               RegisterClass RegList> {
260  def _asmoperand : AsmOperandClass {
261    let Name = PREFIX # LAYOUT # Count;
262    let RenderMethod = "addVectorListOperands";
263    let PredicateMethod = 
264        "isVectorList<A64Layout::VL_" # LAYOUT # ", " # Count # ">";
265    let ParserMethod = "ParseVectorList";
266  }
267
268  def _operand : RegisterOperand<RegList,
269        "printVectorList<A64Layout::VL_" # LAYOUT # ", " # Count # ">"> {
270    let ParserMatchClass =
271      !cast<AsmOperandClass>(PREFIX # LAYOUT # "_asmoperand");
272  }
273}
274
275multiclass VectorList_BHSD<string PREFIX, int Count, RegisterClass DRegList,
276                           RegisterClass QRegList> {
277  defm 8B : VectorList_operands<PREFIX, "8B", Count, DRegList>;
278  defm 4H : VectorList_operands<PREFIX, "4H", Count, DRegList>;
279  defm 2S : VectorList_operands<PREFIX, "2S", Count, DRegList>;
280  defm 1D : VectorList_operands<PREFIX, "1D", Count, DRegList>;
281  defm 16B : VectorList_operands<PREFIX, "16B", Count, QRegList>;
282  defm 8H : VectorList_operands<PREFIX, "8H", Count, QRegList>;
283  defm 4S : VectorList_operands<PREFIX, "4S", Count, QRegList>;
284  defm 2D : VectorList_operands<PREFIX, "2D", Count, QRegList>;
285}
286
287// Vector list operand with 1/2/3/4 registers: VOne8B_operand,..., VQuad2D_operand
288defm VOne : VectorList_BHSD<"VOne", 1, FPR64, FPR128>;
289defm VPair : VectorList_BHSD<"VPair", 2, DPair, QPair>;
290defm VTriple : VectorList_BHSD<"VTriple", 3, DTriple, QTriple>;
291defm VQuad : VectorList_BHSD<"VQuad", 4, DQuad, QQuad>;