AArch64: use RegisterOperand for NEON registers.
[oota-llvm.git] / lib / Target / AArch64 / AArch64RegisterInfo.td
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
14 let Namespace = "AArch64" in {
15 def sub_128 : SubRegIndex<128>;
16 def sub_64 : SubRegIndex<64>;
17 def sub_32 : SubRegIndex<32>;
18 def sub_16 : SubRegIndex<16>;
19 def sub_8  : SubRegIndex<8>;
20 }
21
22 // Registers are identified with 5-bit ID numbers.
23 class AArch64Reg<bits<16> enc, string n> : Register<n> {
24   let HWEncoding = enc;
25   let Namespace = "AArch64";
26 }
27
28 class AArch64RegWithSubs<bits<16> enc, string n, list<Register> subregs = [],
29                          list<SubRegIndex> inds = []>
30       : AArch64Reg<enc, n> {
31   let SubRegs = subregs;
32   let SubRegIndices = inds;
33 }
34
35 //===----------------------------------------------------------------------===//
36 //  Integer registers: w0-w30, wzr, wsp, x0-x30, xzr, sp
37 //===----------------------------------------------------------------------===//
38
39 foreach Index = 0-30 in {
40   def W#Index : AArch64Reg< Index, "w"#Index>, DwarfRegNum<[Index]>;
41 }
42
43 def WSP : AArch64Reg<31, "wsp">, DwarfRegNum<[31]>;
44 def WZR : AArch64Reg<31, "wzr">;
45
46 // Could be combined with previous loop, but this way leaves w and x registers
47 // consecutive as LLVM register numbers, which makes for easier debugging.
48 foreach Index = 0-30 in {
49   def X#Index : AArch64RegWithSubs<Index, "x"#Index,
50                                    [!cast<Register>("W"#Index)], [sub_32]>,
51                 DwarfRegNum<[Index]>;
52 }
53
54 def XSP : AArch64RegWithSubs<31, "sp", [WSP], [sub_32]>, DwarfRegNum<[31]>;
55 def XZR : AArch64RegWithSubs<31, "xzr", [WZR], [sub_32]>;
56
57 // Most instructions treat register 31 as zero for reads and a black-hole for
58 // writes.
59
60 // Note that the order of registers is important for the Disassembler here:
61 // tablegen uses it to form MCRegisterClass::getRegister, which we assume can
62 // take an encoding value.
63 def GPR32 : RegisterClass<"AArch64", [i32], 32,
64                           (add (sequence "W%u", 0, 30), WZR)> {
65 }
66
67 def GPR64 : RegisterClass<"AArch64", [i64], 64,
68                           (add (sequence "X%u", 0, 30), XZR)> {
69 }
70
71 def GPR32nowzr : RegisterClass<"AArch64", [i32], 32,
72                                (sequence "W%u", 0, 30)> {
73 }
74
75 def GPR64noxzr : RegisterClass<"AArch64", [i64], 64,
76                                (sequence "X%u", 0, 30)> {
77 }
78
79 // For tail calls, we can't use callee-saved registers or the structure-return
80 // register, as they are supposed to be live across function calls and may be
81 // clobbered by the epilogue.
82 def tcGPR64 : RegisterClass<"AArch64", [i64], 64,
83                             (add (sequence "X%u", 0, 7),
84                                  (sequence "X%u", 9, 18))> {
85 }
86
87
88 // Certain addressing-useful instructions accept sp directly. Again the order of
89 // registers is important to the Disassembler.
90 def GPR32wsp : RegisterClass<"AArch64", [i32], 32,
91                              (add (sequence "W%u", 0, 30), WSP)> {
92 }
93
94 def GPR64xsp : RegisterClass<"AArch64", [i64], 64,
95                              (add (sequence "X%u", 0, 30), XSP)> {
96 }
97
98 // Some aliases *only* apply to SP (e.g. MOV uses different encoding for SP and
99 // non-SP variants). We can't use a bare register in those patterns because
100 // TableGen doesn't like it, so we need a class containing just stack registers
101 def Rxsp : RegisterClass<"AArch64", [i64], 64,
102                          (add XSP)> {
103 }
104
105 def Rwsp : RegisterClass<"AArch64", [i32], 32,
106                          (add WSP)> {
107 }
108
109 //===----------------------------------------------------------------------===//
110 //  Scalar registers in the vector unit:
111 //  b0-b31, h0-h31, s0-s31, d0-d31, q0-q31
112 //===----------------------------------------------------------------------===//
113
114 foreach Index = 0-31 in {
115   def B # Index : AArch64Reg< Index, "b" # Index>,
116                   DwarfRegNum<[!add(Index, 64)]>;
117
118   def H # Index : AArch64RegWithSubs<Index, "h" # Index,
119                                      [!cast<Register>("B" # Index)], [sub_8]>,
120                   DwarfRegNum<[!add(Index, 64)]>;
121
122   def S # Index : AArch64RegWithSubs<Index, "s" # Index,
123                                      [!cast<Register>("H" # Index)], [sub_16]>,
124                   DwarfRegNum<[!add(Index, 64)]>;
125
126   def D # Index : AArch64RegWithSubs<Index, "d" # Index,
127                                      [!cast<Register>("S" # Index)], [sub_32]>,
128                   DwarfRegNum<[!add(Index, 64)]>;
129
130   def Q # Index : AArch64RegWithSubs<Index, "q" # Index,
131                                      [!cast<Register>("D" # Index)], [sub_64]>,
132                   DwarfRegNum<[!add(Index, 64)]>;
133 }
134
135
136 def FPR8 : RegisterClass<"AArch64", [i8], 8,
137                           (sequence "B%u", 0, 31)> {
138 }
139
140 def FPR16 : RegisterClass<"AArch64", [f16], 16,
141                           (sequence "H%u", 0, 31)> {
142 }
143
144 def FPR32 : RegisterClass<"AArch64", [f32], 32,
145                           (sequence "S%u", 0, 31)> {
146 }
147
148 def FPR64 : RegisterClass<"AArch64", [f64, v2f32, v2i32, v4i16, v8i8, v1i64],
149                           64, (sequence "D%u", 0, 31)>;
150
151 def FPR128 : RegisterClass<"AArch64",
152                            [f128,v2f64, v2i64, v4f32, v4i32, v8i16, v16i8], 128,
153                            (sequence "Q%u", 0, 31)>;
154
155
156
157 //===----------------------------------------------------------------------===//
158 //  Vector registers:
159 //===----------------------------------------------------------------------===//
160
161 def VPR64AsmOperand : AsmOperandClass {
162   let Name = "VPR";
163   let PredicateMethod = "isReg";
164   let RenderMethod = "addRegOperands";
165 }
166
167 def VPR64 : RegisterOperand<FPR64, "printVPRRegister">;
168
169 def VPR128 : RegisterOperand<FPR128, "printVPRRegister">;
170
171 // Flags register
172 def NZCV : Register<"nzcv"> {
173   let Namespace = "AArch64";
174 }
175
176 def FlagClass : RegisterClass<"AArch64", [i32], 32, (add NZCV)> {
177   let CopyCost = -1;
178   let isAllocatable = 0;
179 }