Add AArch64 as an experimental target.
[oota-llvm.git] / lib / Target / AArch64 / AArch64RegisterInfo.td
1 //===- ARMRegisterInfo.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 //===----------------------------------------------------------------------===//
11 //  Declarations that describe the ARM register file
12 //===----------------------------------------------------------------------===//
13
14 let Namespace = "AArch64" in {
15 def sub_128 : SubRegIndex;
16 def sub_64 : SubRegIndex;
17 def sub_32 : SubRegIndex;
18 def sub_16 : SubRegIndex;
19 def 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.
23 def sub_alias : SubRegIndex;
24 }
25
26 // Registers are identified with 5-bit ID numbers.
27 class AArch64Reg<bits<16> enc, string n> : Register<n> {
28   let HWEncoding = enc;
29   let Namespace = "AArch64";
30 }
31
32 class 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
43 foreach Index = 0-30 in {
44   def W#Index : AArch64Reg< Index, "w"#Index>, DwarfRegNum<[Index]>;
45 }
46
47 def WSP : AArch64Reg<31, "wsp">, DwarfRegNum<[31]>;
48 def 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.
52 foreach Index = 0-30 in {
53   def X#Index : AArch64RegWithSubs<Index, "x"#Index,
54                                    [!cast<Register>("W"#Index)], [sub_32]>,
55                 DwarfRegNum<[Index]>;
56 }
57
58 def XSP : AArch64RegWithSubs<31, "sp", [WSP], [sub_32]>, DwarfRegNum<[31]>;
59 def 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.
67 def GPR32 : RegisterClass<"AArch64", [i32], 32,
68                           (add (sequence "W%u", 0, 30), WZR)> {
69 }
70
71 def GPR64 : RegisterClass<"AArch64", [i64], 64,
72                           (add (sequence "X%u", 0, 30), XZR)> {
73 }
74
75 def GPR32nowzr : RegisterClass<"AArch64", [i32], 32,
76                                (sequence "W%u", 0, 30)> {
77 }
78
79 def 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.
86 def 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.
94 def GPR32wsp : RegisterClass<"AArch64", [i32], 32,
95                              (add (sequence "W%u", 0, 30), WSP)> {
96 }
97
98 def 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
105 def Rxsp : RegisterClass<"AArch64", [i64], 64,
106                          (add XSP)> {
107 }
108
109 def 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
118 foreach 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
140 def FPR8 : RegisterClass<"AArch64", [i8], 8,
141                           (sequence "B%u", 0, 31)> {
142 }
143
144 def FPR16 : RegisterClass<"AArch64", [f16], 16,
145                           (sequence "H%u", 0, 31)> {
146 }
147
148 def FPR32 : RegisterClass<"AArch64", [f32], 32,
149                           (sequence "S%u", 0, 31)> {
150 }
151
152 def FPR64 : RegisterClass<"AArch64", [f64], 64,
153                           (sequence "D%u", 0, 31)> {
154 }
155
156 def 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
178 foreach 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.
188 def VPR64 : RegisterClass<"AArch64", [v2f32, v2i32, v4i16, v8i8], 64,
189                           (sequence "V%u", 0, 31)>;
190
191 def VPR128 : RegisterClass<"AArch64",
192                            [v2f64, v2i64, v4f32, v4i32, v8i16, v16i8], 128,
193                            (sequence "V%u", 0, 31)>;
194
195 // Flags register
196 def NZCV : Register<"nzcv">
197 {
198   let Namespace = "AArch64";
199 }
200
201 def FlagClass : RegisterClass<"AArch64", [i32], 32, (add NZCV)>
202 {
203   let CopyCost = -1;
204   let isAllocatable = 0;
205 }